sdelay-sayt-tsifrovoy-pomosc/index.html

309 lines
17 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<!-- Дизайн: Стандартный дизайн. Сохраняй все пять CSS; подробности в design.md. -->
<html lang="ru" data-theme="light">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>AI Legal Assistant — цифровой помощник юриста</title>
<link rel="stylesheet" href="design-system/kt-ai-fonts.css">
<link rel="stylesheet" href="design-system/kt-ai-tokens.css">
<link rel="stylesheet" href="design-system/kt-ai-components.css">
<link rel="stylesheet" href="design-system/kt-ai-page.css">
<link rel="stylesheet" href="design-system/vibe-theme.css">
<script src="design-system/icons/kt-ai-icons.js"></script>
<style>
@layer product {
body { margin: 0; }
a.kt-ai-btn { text-decoration: none; }
.shell-topbar-burger { display: none; }
@media (max-width: 831.98px) { .shell-topbar-burger { display: inline-flex; } }
/* Читаемость: у КД-токенов нет своих тёмных значений, поэтому
вторичный текст держим темнее дефолта, а базовый кегль поднимаем. */
.kt-ai-app { font-size: 15px; }
.kt-ai-app, .kt-ai-shell, .kt-ai-drawer {
--kt-ai-fg-muted: color-mix(in srgb, var(--kt-ai-fg) 68%, var(--kt-ai-bg-soft));
--kt-ai-fg-faint: color-mix(in srgb, var(--kt-ai-fg) 48%, var(--kt-ai-bg-soft));
--kt-ai-primary-subtle: color-mix(in srgb, var(--kt-ai-primary) 14%, var(--kt-ai-bg-elevated));
}
.kt-ai-banner { background: var(--kt-ai-status-info-bg); color: var(--kt-ai-status-info-fg); }
.kt-ai-banner[data-tone="ok"] { background: var(--kt-ai-status-ok-bg); color: var(--kt-ai-status-ok-fg); }
.kt-ai-status-pill[data-status="muted"] { background: var(--kt-ai-chip-gray-bg); color: var(--kt-ai-chip-gray-fg); }
.kt-ai-status-pill[data-status="warn"] { background: var(--kt-ai-chip-orange-bg); color: var(--kt-ai-chip-orange-fg); }
.kt-ai-status-pill[data-status="ok"] { background: var(--kt-ai-chip-green-bg); color: var(--kt-ai-chip-green-fg); }
.kt-ai-empty .icon-spot { background: var(--kt-ai-primary-subtle); color: var(--kt-ai-link); }
.sb-top { display: flex; align-items: center; gap: var(--kt-ai-space-3); padding: 2px 4px 12px; }
.sb-top .sb-orb { width: 28px; height: 28px; border-radius: var(--kt-ai-radius-xl); background: color-mix(in srgb, var(--kt-ai-primary) 70%, var(--kt-ai-bg-elevated)); flex-shrink: 0; }
.sb-top .nm { font-weight: var(--kt-ai-weight-semibold); font-size: var(--kt-ai-text-sm); color: var(--kt-ai-fg); min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; flex: 1; }
.sb-top .nm small { display: block; font-weight: var(--kt-ai-weight-regular); font-size: var(--kt-ai-text-2xs); color: var(--kt-ai-fg-muted); }
.sb-new { margin: 0 4px var(--kt-ai-space-5); }
.sb-new .kt-ai-btn { width: 100%; }
.kt-ai-shell { grid-template-columns: var(--kt-ai-sidebar-width) minmax(0, 1fr); }
.kt-ai-main { min-width: 0; background: var(--kt-ai-bg); }
.topbar-title { display: flex; align-items: baseline; gap: var(--kt-ai-space-4); min-width: 0; }
.topbar-title .t { font-size: var(--kt-ai-text-lg); font-weight: var(--kt-ai-weight-semibold); letter-spacing: -.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.topbar-title .sub { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-muted); white-space: nowrap; }
@media (max-width: 639.98px) { .topbar-title .sub { display: none; } }
#view { width: 100%; max-width: var(--kt-ai-content-table); margin-inline: auto; padding: var(--kt-ai-space-8) var(--kt-ai-space-8) var(--kt-ai-space-11); }
#view .view { display: none; }
#view .view.is-active { display: block; animation: ktai-rise var(--kt-ai-dur-base) var(--kt-ai-ease-enter); }
@media (max-width: 639.98px) { #view { padding: var(--kt-ai-space-6) var(--kt-ai-space-5) var(--kt-ai-space-10); } }
.view-head { margin-bottom: var(--kt-ai-space-7); }
.view-head .kt-ai-h1 { margin: 0 0 var(--kt-ai-space-3); }
.view-head .sub { font-size: var(--kt-ai-text-md); color: var(--kt-ai-fg-muted); }
.sec-head { display: flex; align-items: baseline; gap: var(--kt-ai-space-4); margin: var(--kt-ai-space-9) 0 var(--kt-ai-space-5); }
.sec-head .kt-ai-h2 { margin: 0; }
.sec-head .sub { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-muted); }
.sec-head .spacer { flex: 1; }
.doc-card { display: flex; flex-direction: column; gap: var(--kt-ai-space-4); cursor: pointer; }
.doc-card .doc-ic { width: 34px; height: 34px; display: grid; place-items: center; border-radius: var(--kt-ai-radius-lg); background: var(--kt-ai-primary-subtle); color: var(--kt-ai-link); }
.doc-card h3 { margin: 0; font-size: var(--kt-ai-text-md); font-weight: var(--kt-ai-weight-semibold); }
.doc-card p { margin: 0; font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-muted); flex: 1; }
.doc-card .doc-open { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-link); display: inline-flex; align-items: center; gap: var(--kt-ai-space-2); }
.kpi-strip-wrap { margin-bottom: var(--kt-ai-stack-block); }
.drawer-head { display: flex; align-items: flex-start; gap: var(--kt-ai-space-4); margin-bottom: var(--kt-ai-space-6); }
.drawer-head .t { flex: 1; min-width: 0; }
.drawer-head .kt-ai-h2 { margin: 0 0 var(--kt-ai-space-2); }
.drawer-head .dsub { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-muted); }
.drawer-close { flex-shrink: 0; }
.field-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 0 var(--kt-ai-space-5); }
.field-grid .kt-ai-field[data-span="2"] { grid-column: span 2; }
@media (max-width: 480px) { .field-grid { grid-template-columns: 1fr; } .field-grid .kt-ai-field[data-span="2"] { grid-column: span 1; } }
.ai-gen { display: flex; align-items: center; justify-content: center; gap: var(--kt-ai-space-3); width: 100%; margin-top: var(--kt-ai-space-2); }
.ai-gen .ai-orb-dot { width: 14px; height: 14px; border-radius: 50%; background: var(--kt-ai-ai-orb); flex-shrink: 0; display: block; }
.ai-gen .ai-orb-dot[hidden] { display: none; }
.ai-result { display: none; margin-top: var(--kt-ai-space-5); }
.ai-result.is-shown { display: block; animation: ktai-rise var(--kt-ai-dur-base) var(--kt-ai-ease-enter); }
.rec-box { margin-top: var(--kt-ai-space-5); background: var(--kt-ai-primary-subtle); border-radius: var(--kt-ai-radius-2xl); padding: var(--kt-ai-space-5); font-size: var(--kt-ai-text-sm); }
.rec-box .rec-line { display: flex; gap: var(--kt-ai-space-3); margin-bottom: var(--kt-ai-space-2); align-items: baseline; }
.rec-box .rec-line:last-child { margin-bottom: 0; }
.rec-box .rec-line .k { color: var(--kt-ai-fg-muted); flex-shrink: 0; }
.rec-box .rec-line .v { font-weight: var(--kt-ai-weight-medium); }
.row-num { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-faint); font-variant-numeric: tabular-nums; }
}
</style>
</head>
<body class="kt-ai-app">
<div class="kt-ai-shell">
<aside class="kt-ai-sidebar" id="sidebar" style="display:flex;flex-direction:column;padding:14px 10px;gap:2px">
<div class="sb-top">
<span class="sb-orb" aria-hidden="true"></span>
<span class="nm nav-label">AI Legal Assistant<small>цифровой помощник юриста</small></span>
</div>
<div class="sb-new">
<button class="kt-ai-btn" data-variant="primary" id="btnNew" type="button">
<svg class="kt-icon kt-icon-sm" aria-hidden="true"><use href="#plus"></use></svg>
<span class="nav-label">Новый документ</span>
</button>
</div>
<nav aria-label="Разделы">
<div class="kt-ai-nav-group"><span class="nav-label">Работа</span></div>
<button class="kt-ai-nav-item" data-active="true" data-view="dashboard" type="button">
<svg class="kt-icon" aria-hidden="true"><use href="#dashboard"></use></svg>
<span class="nav-label">Обзор</span>
</button>
<button class="kt-ai-nav-item" data-view="docs" type="button">
<svg class="kt-icon" aria-hidden="true"><use href="#file"></use></svg>
<span class="nav-label">Документы</span>
</button>
<button class="kt-ai-nav-item" data-view="approval" type="button">
<svg class="kt-icon" aria-hidden="true"><use href="#checklist"></use></svg>
<span class="nav-label">Согласование</span>
<span class="count">24</span>
</button>
</nav>
</aside>
<main class="kt-ai-main" style="min-height:100dvh;display:flex;flex-direction:column">
<header class="kt-ai-topbar">
<button class="kt-ai-icon-button shell-topbar-burger" id="btnBurger" aria-label="Меню" type="button">
<svg class="kt-icon" aria-hidden="true" viewBox="0 0 24 24"><path d="M3 6h18M3 12h18M3 18h18"/></svg>
</button>
<nav class="topbar-title" aria-label="Раздел">
<span class="t" id="pageTitle">Обзор</span>
<span class="sub" id="pageSub">Документы юридической службы · сентябрь 2026</span>
</nav>
<span class="spacer" style="flex:1"></span>
<div class="kt-ai-search-field">
<input class="kt-ai-search" id="topSearch" type="search" placeholder="Поиск документов…" aria-label="Поиск документов">
</div>
<button class="kt-ai-icon-button" aria-label="Профиль" type="button">
<span class="kt-ai-avatar">ЮЛ</span>
</button>
</header>
<div id="view">
<!-- ======================= ОБЗОР ======================= -->
<section class="view is-active" id="view-dashboard" aria-label="Обзор">
<div class="kt-ai-banner" data-tone="info" style="margin-bottom:var(--kt-ai-stack-block)">
<svg class="kt-icon" aria-hidden="true"><use href="#sparkles"></use></svg>
<div>Ассистент сформировал 18 документов за 6 недель. Средняя экономия — 4 часа 20 минут на документе против ручной работы.</div>
</div>
<div class="kpi-strip-wrap">
<div class="kt-ai-kpi-strip" data-cards="true">
<div class="kt-ai-kpi">
<span class="label">Документов за месяц</span>
<span class="value" id="kpiMonth">24</span>
<span class="hint">сентябрь, всего сформировано</span>
</div>
<div class="kt-ai-kpi">
<span class="label">В согласовании</span>
<span class="value" id="kpiApproval">7</span>
<span class="hint">на визах и под подписью</span>
</div>
<div class="kt-ai-kpi">
<span class="label">Завершено</span>
<span class="value" id="kpiDone">11</span>
<span class="hint">подписаны и зарегистрированы</span>
</div>
<div class="kt-ai-kpi">
<span class="label">Экономия времени</span>
<span class="value" id="kpiSaved">102 ч</span>
<span class="hint">с начала использования ассистента</span>
</div>
</div>
</div>
<div class="kt-ai-toolbar">
<div class="kt-ai-filterbar">
<span class="kt-ai-label">Сформировано за 6 недель</span>
</div>
</div>
<div class="kt-ai-chart-card" id="chartMonthly" aria-label="Документов за месяц"></div>
<div class="sec-head">
<h2 class="kt-ai-h2">Типы документов</h2>
<span class="sub">выберите тип — откроется форма с полями</span>
<span class="spacer"></span>
</div>
<div class="kt-ai-card-grid" id="docTypes"></div>
<div class="sec-head">
<h2 class="kt-ai-h2">Последние документы</h2>
<span class="sub">все — в разделе «Согласование»</span>
</div>
<div class="kt-ai-table-wrap" data-framed="true">
<table class="kt-ai-table">
<thead>
<tr>
<th>Номер</th>
<th>Документ</th>
<th>Контрагент</th>
<th>Создан</th>
<th>Статус</th>
</tr>
</thead>
<tbody id="dashRecent"></tbody>
</table>
</div>
</section>
<!-- ======================= ДОКУМЕНТЫ ======================= -->
<section class="view" id="view-docs" aria-label="Типы документов">
<div class="view-head">
<h1 class="kt-ai-h1">Типы документов</h1>
<p class="sub">Выберите тип — заполните поля, и ассистент сформирует проект документа с учётом внутренних ограничений (сроков, сумм, юрисдикции).</p>
</div>
<div class="kt-ai-card-grid" id="docTypesAll"></div>
</section>
<!-- ======================= СОГЛАСОВАНИЕ ======================= -->
<section class="view" id="view-approval" aria-label="Согласование">
<div class="view-head">
<h1 class="kt-ai-h1">Согласование</h1>
<p class="sub" id="approvalSummary">Документы службы по этапам: черновик, согласование, подпись, завершение.</p>
</div>
<div class="kt-ai-kpi-strip" data-cards="true" style="display:none" id="approvalKpis" aria-hidden="true"></div>
<div class="kt-ai-toolbar">
<div class="kt-ai-filterbar">
<span class="kt-ai-label">Статус</span>
<select class="kt-ai-select" id="filterStatus" aria-label="Фильтр по статусу">
<option value="all">Все</option>
<option value="Черновик">Черновик</option>
<option value="На согласовании">На согласовании</option>
<option value="На подписи">На подписи</option>
<option value="Завершён">Завершён</option>
</select>
<span class="kt-ai-label" style="margin-left:var(--kt-ai-space-4)">Тип</span>
<select class="kt-ai-select" id="filterType" aria-label="Фильтр по типу"></select>
</div>
</div>
<div class="kt-ai-table-wrap" data-framed="true">
<table class="kt-ai-table">
<thead>
<tr>
<th>Номер</th>
<th>Документ</th>
<th>Контрагент</th>
<th>Создан</th>
<th>Срок виз</th>
<th>Статус</th>
</tr>
</thead>
<tbody id="approvalRows"></tbody>
</table>
</div>
<div class="kt-ai-empty" id="approvalEmpty" style="display:none">
<div class="icon-spot"><svg class="kt-icon kt-icon-lg" aria-hidden="true"><use href="#file"></use></svg></div>
<span class="title">Нет документов с такими фильтрами</span>
<span>Сбросьте фильтры или создайте новый документ — он появится первым в списке.</span>
</div>
</section>
</div>
</main>
</div>
<!-- Drawer: форма нового документа -->
<aside class="kt-ai-drawer" id="drawer" role="dialog" aria-modal="true" aria-labelledby="drawerTitle" tabindex="-1" style="display:none">
<div class="drawer-head">
<div class="t">
<h2 class="kt-ai-h2" id="drawerTitle">Новый документ</h2>
<div class="dsub" id="drawerSub">Заполните поля — ассистент сформирует проект с внутренними ограничениями</div>
</div>
<button class="kt-ai-icon-button drawer-close" id="drawerClose" aria-label="Закрыть" type="button">
<svg class="kt-icon" aria-hidden="true"><use href="#x"></use></svg>
</button>
</div>
<div id="drawerBody"></div>
<div class="kt-ai-drawer-actions">
<button class="kt-ai-btn" id="drawerCancel" type="button">Отмена</button>
<button class="kt-ai-btn ai-gen" id="btnGenerate" type="button">
<span class="ai-orb-dot" aria-hidden="true" hidden></span>
<svg class="kt-icon" aria-hidden="true"><use href="#sparkles"></use></svg>
<span id="btnGenerateLabel">Сформировать документ с помощью AI</span>
</button>
</div>
</aside>
<div class="kt-ai-toast-stack" id="toasts" role="status" aria-live="polite"></div>
<script src="script.js"></script>
</body>
</html>