# KT AI Design System v3.0 «Mono» (токены v5) Канон дизайн-системы KT AI. v3.0 от 2026-06-21 – визуальный язык в духе ElevenLabs: **light-first**, тёплый near-white фон, **near-black primary-кнопка** (в dark инвертируется в near-white), плоские поверхности на hairline-границах и шёпот-тенях, крупные жирные тёмные заголовки, цвет – только функциональный (статусы, чарты, единичная AI-искра орба Төре). Синий **демотирован** в ссылки/фокус/идентичность KT, перестал быть цветом primary-действия. Геометрия и Attio-детали (rounded-rect теги, frameless-таблицы с горизонтальными разделителями рядов — без вертикальных колонок-сепараторов, property-rows) сохранены; aurora-свечение карточек и тяжёлые AI-ореолы убраны. История: CHANGELOG.md. Анатомия shell/таблиц/рядов: COMPONENTS.md. Продуктовый контракт прототипа: PRODUCT_CONTRACT.md. Файлы: | Файл | Роль | |---|---| | `tokens.json` | ЕДИНСТВЕННЫЙ источник значений токенов. Правки только здесь | | `scripts/build_tokens.py` | генератор: tokens.css, print.css, figma-variables.json, tailwind-preset | | `kt-ai-tokens.css` | AUTOGENERATED: переменные, обе темы, @layer kt-tokens | | `kt-ai-print.css` | AUTOGENERATED: @media print (light, A4, скрытие shell) | | `figma-variables.json` | AUTOGENERATED: импорт в Figma Variables (dark/light) | | `kt-ai-tailwind-preset.cjs` | AUTOGENERATED: preset для Next.js/kt-ai-shadcn | | `kt-ai-components.css` | компоненты v2 на токенах, имена классов совместимы с v1 | | `COMPONENTS.md` | нормативная анатомия shell, таблиц, рядов, тулбаров (перенос из v1-архива) | | `showcase.html` | живая галерея всех компонентов с переключателем тем – открыть в браузере | | `icons/kt-ai-lucide-sprite.svg` | локальный monochrome Lucide-sprite | | `COMPONENTS.md` | правила компоновки экрана (активно) | | `ELEVENLABS_DESIGN.md` | эталон эстетики/плотности/деталей (язык ElevenLabs) | | `archive/` | замороженный v1 (kt_design_system, DESIGN_v1_archive, kt_ai_terminal_tokens.css, kt_ai_terminal_routes, kt_ai_atomic_product_system) – только история, вынесен в `08_Дизайн-система_история/archive/` | Брендовые ассеты: `03_База знаний/Логотипы и бренд/` (ktai.svg, kt-logo.svg). ## Принципы Полный контракт UX-принципов (Нильсен, гештальт, законы взаимодействия): `PRINCIPLES.md`. Единый чек-лист «прошло или нет» (Definition of Done, прогонять при любом изменении UI): `CHECKLIST.md`. Оба обязательны при проектировании. 1. Плотный операционный интерфейс: первый экран – рабочая поверхность, не лендинг. 2. Плоские поверхности на hairline-границах: в light – лёгкая тень (`card-shadow`/`shadow-sm`) + рамка, в dark – рамка без тени. Полновесные тени – только у overlay (modal, drawer, dropdown, command, toast). Никаких декоративных свечений/градиентов в контенте. Blur – только на sticky-хроме (топбар `bg-glass`) и overlay. 3. Тихие границы, приглушённые метаданные, один primary-акцент на экран. 4. **Mono-доминанта.** Primary-действие – монохром: `primary` = near-black (light) / near-white (dark), белый/тёмный текст. Синий (`link`, `focus`, `brand-blue`) – ссылки, фокус и идентичность KT, **не** заливка кнопок. AI-градиент (`ai-gradient`) – единичная сдержанная искра только на орбе Төре, send-кнопке и кромке prompt-bar в фокусе; тяжёлые ореолы и aurora-свечение карточек убраны. Остальные цвета – только статусы, чипы и графики. 5. Геометрия компонентов не зависит от темы: темы меняют только цвет. 6. Никаких сырых hex в продуктовом CSS – только semantic-токены. ## Архитектура токенов Три уровня, имена v1 (`--kt-ai-*`) полностью сохранены – старые продукты работают без правок. 1. **Primitives** (`--kt-blue-500`, `--kt-gray-900`, `--kt-green-a22`...) – сырая палитра и шкалы. В продуктах напрямую НЕ используются. 2. **Semantic** – смысловые роли, переключаются темой: - поверхности: `--kt-ai-bg`, `-bg-soft`, `-bg-elevated`, `-bg-sunken`; - state-слои: `-bg-hover`, `-bg-active`, `-selection`; - текст: `-fg`, `-fg-muted`, `-fg-faint`, `-fg-on-fill`; - границы: `-border`, `-border-strong`, `-divider`; - интерактив: `-primary`, `-primary-hover`, `-primary-subtle`, `-link`, `-danger`, `-danger-hover`; - фокус: `-focus-ring`, `-focus-shadow`; - статусы/чипы/чарты: как в v1; - тени: `-shadow-sm/md/lg/xl`. 3. **Component** – размеры контролов: `--kt-ai-control-h-sm/md/lg` (28/32/40), layout-переменные v1. Тема-независимые шкалы (в `:root`): - **Spacing** `--kt-ai-space-1..12`: 2, 4, 6, 8, 12, 16, 20, 24, 32, 40, 48, 64. Всё на 4px-сетке, плотный низ шкалы. - **Типографика** `--kt-ai-text-2xs..3xl`: 11, 12, 13, 14, 15, 18, 26, 32. Body = 13px (`text-sm`). Веса 400/500/600/700. Числа – JetBrains Mono с `tabular-nums`. - **Трекинг зависит от размера** (не одно значение на всё): крупные заголовки — отрицательный (`-.02em` дисплей, `-.01em` H1/H2), body — около `0`. Тесним заголовки, body оставляем нейтральным. - **Leading обратно размеру:** плотный на крупных заголовках (`leading-tight` 1.25), свободнее на body (`leading-normal` 1.5). Иерархия строится связкой вес+размер+leading, а не размером одним. - **Радиусы** (значения — в `tokens.json`, `scales.radius`): xs, sm, md, tag, lg, xl, 2xl, 3xl, full. Nav-ряды lg; кнопки/инпуты xl; карточки, modal, command, prompt-bar – 3xl; теги/статусы – tag (rounded-rect, не pill). - **Моушн** `--kt-ai-dur-fast/base/slow/slower` (100/160/240/400ms), easing standard/enter/exit. `prefers-reduced-motion` обнуляет длительности автоматически. - **Z-index**: sticky 20, dropdown 30, drawer 40, modal 50, toast 60, tooltip 70. ## Темы Light – дефолт (`:root`, `data-theme="light"` или `kt-ai-terminal-light`): тёплый near-white, near-black primary – основной офисный вид (v3 «Mono», light-first). Dark – полноправный паритетный вариант (`data-theme="dark"` или `kt-ai-terminal`): near-black фон, primary инвертируется в near-white. `data-theme="auto"` следует за системной темой. Правила паритета: - каждый semantic-токен определён в обеих темах; добавил токен в dark – обязан добавить в light; - интерактивный синий: dark `#4b9ce2`, light `#0077c8` (AA-контраст на своих фонах); фирменный KT blue `#0096d7` общий; - статусные пары построены зеркально: в dark светлый текст на прозрачной подложке, в light тёмный текст на прозрачной подложке; - проверка паритета – переключателем в `showcase.html`, это обязательный QA-шаг. ## Компоненты (kt-ai-components.css) Имена классов v1 сохранены (`.kt-ai-card`, `.kt-ai-row`, `.kt-ai-chip`, `.kt-ai-nav-item`, `.kt-ai-table*`, `.kt-ai-search`, `.kt-ai-kbd`, `.kt-ai-icon-button`, `.kt-ai-segmented`...). Новое в v2: - **Кнопки** `.kt-ai-btn`: варианты `data-variant="primary|ghost|danger"` (без атрибута – вторичная), размеры `data-size="sm|lg"`. Один primary на экран. - **Формы**: `.kt-ai-field` (label + контрол + hint/error), `.kt-ai-input`, `.kt-ai-select`, `.kt-ai-textarea`, `data-invalid="true"`, `.kt-ai-checkbox`, `.kt-ai-switch`. Фокус: border primary + `--kt-ai-focus-shadow`. - **Tabs** `.kt-ai-tabs/.kt-ai-tab` (`data-active`), сегменты как в v1. - **Banner** `.kt-ai-banner data-tone="info|warn|risk|ok"` – строчные предупреждения в контенте. - **Modal** `.kt-ai-modal-overlay/.kt-ai-modal` – bg-elevated, radius-2xl, shadow-xl, анимация rise. - **Toast** `.kt-ai-toast-stack/.kt-ai-toast data-tone` – нижний правый угол, точка-индикатор тона. - **Tooltip** `.kt-ai-tooltip[data-tip]` – чистый CSS. - **Skeleton** `.kt-ai-skeleton` (shimmer), **Empty** `.kt-ai-empty` (иконка + title + действие). - **KPI** `.kt-ai-kpi-strip/.kt-ai-kpi` – тихая метрик-полоса, не карточки. - **Avatar**, `.kt-ai-divider`, `.kt-ai-status-pill` с точкой-индикатором. - **Drawer** `.kt-ai-drawer` – правая панель деталей (правило: детали в drawer, не на новой странице). - **Документ-артефакт** `.kt-ai-doc` / `.kt-ai-doc-list` – карточка выходного документа (иконка + имя + статус/формат + кнопка «Скачать»). То, что продукт ПРОИЗВОДИТ (ТС, отчёт, СЗ), показывается как скачиваемый документ — в drawer (секция «Документы» из `_docs` строки) и в nav-секции-коллекции (`nav.view="documents"`, фильтр по `docType`). Контракт: `table.rows[]._docs`. Новое в v2.3 «Aurora × Attio»: - **Карточки** – `card-bg/card-border/card-shadow` токены: в dark – hairline-рамка + фиолетовое aurora-свечение из угла (`data-glow="strong"` – усиленный hero-вариант с двойным свечением), в light – белая поверхность с тенью без рамки. Радиус — `radius-3xl`. - **Кнопки (Attio)** – secondary: поверхность bg-elevated + рамка + shadow-sm, радиус 8; ghost/danger без поверхности. - **Теги (Attio)** – chip/status-pill/filter-chip: rounded-rect `radius-tag` (5px), не pill. - **Таблицы (ElevenLabs)** – дефолт frameless full-bleed: hairline под шапкой и между рядами, **без вертикальных колонок-сепараторов** (тихо, воздушно), заголовки sentence-case 12px medium muted; контейнерный вариант – `data-framed="true"`. Для стабильности ширин при фильтрации фильтруемым таблицам задаётся `table-layout:fixed` + colgroup. - **Property-row** `.kt-ai-prop` (`.k` – иконка+метка 148px, `.v` – значение, `data-empty`) – детали объекта в drawer/карточке. - **AI-aurora** – токены `ai-accent`, `ai-gradient` (синий → фиолет): градиентная кромка prompt-bar в фокусе + ореол, градиентные send-кнопка и streaming-каретка, орб-атрибуция вместо ✦, `.kt-ai-btn[data-ai="true"]` – точка входа AI. Градиент НЕ используется вне AI-моментов. - **Тихая ссылка** `.kt-ai-link[data-arrow]` – «Подробнее →», стрелка сдвигается на hover. - **Dot-grid** текстура на `.kt-ai-empty`. Mono-голос: label, cmd-group, время уведомлений, ключи filter-chips. Активный таб – синий. Трекинг заголовков -.02em/-.01em. Sidebar-ряды 26px. Новое в v2.2: - **Topbar** `.kt-ai-topbar` – канонический glass-хром: sticky, `bg-glass` + blur(8). Blur разрешён только здесь и на overlay. - **AI-диалог**: `.kt-ai-chat` + `.kt-ai-msg data-role="user|assistant"` (ассистент – полная ширина без пузыря, пользователь – пузырь bg-soft ≤76%), `data-streaming="true"` – каретка; `.kt-ai-prompt-bar` (autogrow textarea + `.kt-ai-prompt-send`, `data-busy`), `.kt-ai-suggestions/.kt-ai-suggestion` – стартовые подсказки, `.kt-ai-source-pill` – ссылка-источник в ответе, `.kt-ai-gen-label` – атрибуция «Сгенерировано ИИ» (обязательна для AI-контента). - **Menu** `.kt-ai-menu-anchor > .kt-ai-menu[data-open]` – dropdown действий (kebab в рядах таблиц): `.item` (`data-danger`), `.sep`. - **Command palette** – достроена: `.kt-ai-command-overlay`, `.cmd-input`, `.cmd-list`, `.cmd-group`, `.cmd-item[data-active]`, `.cmd-empty`. - **Filter-chips** `.kt-ai-filterbar` + `.kt-ai-filter-chip` (`.k` – имя фильтра, `.remove`) + `.clear-all` – применённые фильтры над таблицей. - **Radio** `.kt-ai-radio`, `.kt-ai-radio-group`. - **Toast**: `.action` (undo-ссылка) и `.close`. - **Popover** `.kt-ai-popover-anchor > .kt-ai-popover[data-open]` (`data-align="right"`) – якорный интерактивный слой (date-picker, настройки колонок). - **Bulk-bar** `data-floating="true"` – плавающий вариант снизу по центру для длинных таблиц. - **Row actions** `.kt-ai-row .actions` / `.kt-ai-table tr .actions` – тихие действия, видимы на hover/focus-within/selected; на touch видимы всегда. - Активный пункт навигации получает 2px-акцент слева (работает и в icon-rail). Анатомия shell, таблиц, рядов – COMPONENTS.md (перенесено из v1-архива, нормативно). ## Operational Dashboard Contract - Boilerplate задаёт обязательный shell: sidebar, `.kt-ai-topbar`, theme toggle и AI-кнопку Төре. Эти элементы нельзя перерисовывать, заменять самодельными глифами или делать декоративными. Main content проектируется под задачу процесса. - Для рабочих очередей, реестров и консолидации закупок предпочтителен classic app-shell: таблица как главный объект, детали в drawer, короткие workflow-status, одно primary-действие. Custom workspace, матрица, split-view или decision panel используются только когда таблица + drawer не решают основную работу пользователя. - H1/topbar title – короткий рабочий объект, 1-3 слова. Не использовать описание процесса как заголовок. - Subtitle – одна короткая scope-фраза до 90 символов. - KPI показывают рабочее состояние текущего пользователя: новые, требуют решения, риски, ждут документы, просрочено, закрыто сегодня, SLA или сумма риска. ROI, FTE, экономия часов и тенге эффекта не выводятся на пользовательский dashboard по умолчанию. Эти метрики относятся к management/reporting view, паспорту или расчёту эффекта проекта. Исключение – операционный экран консолидации, где пользователю нужны рабочие числа для решения: сколько ТС обработано, сколько имеют потенциал консолидации, какой предварительный потенциал экономии в тенге. - Search, theme toggle, AI button and visible primary actions must work in the prototype when shown. Search inputs are empty by default and must not be prefilled with arbitrary examples. - Primary filters – только workflow-status, максимум 4 пункта плюс `Все`. Confidence, risk type, системы и длинные причины не попадают в default segmented filters. - Workflow `status`, `confidence` и `riskType` моделируются разными полями. - Labels компактные: filter до 2 слов, status до 4 слов, table header до 2 слов; детали и длинные объяснения – в drawer/help. - UI-copy не показывает внутреннюю кухню генерации: `модель вернула`, `fallback`, `не проходит дизайн-систему`, `shell`, `JSON` и похожие формулировки запрещены в пользовательском интерфейсе. - **Голос интерфейса нейтрален и продуктовый.** Запрещены: дисклеймеры прототипа («это прототип на дизайн-системе», «данные иллюстративны»); нравоучения про human-in-the-loop («AI не действует на клиента сам», «решение подтверждает человек», «контрольная точка») — человек-в-контуре показывается контролами (рекомендация + кнопки accept/reject), а не объяснениями; лозунг-лейблы капсом («РЕШЕНИЕ — ЗА ВАМИ») — секции называются нейтральными существительными («Решение»). Любой продукт-специфичный текст (что сделал агент, разбор) живёт в контракте (`scenario.aiSummary`), а не зашит в shell — иначе он протекает в другие продукты. Валидатор ловит эти формулировки (`PREACHY_LANG`). ## Состояния интерактива Единая лестница: default → hover (`-bg-hover` или border-strong) → active/selected (`-bg-active`) → focus-visible (outline `-focus-ring`) → disabled (opacity .4). Hover-переходы `dur-fast`, появления `dur-base`, drawer/modal `dur-slow`. Нажатие кнопки: `scale(.98)` 60ms. ## Движение (motion) Правила — не украшение, а поведение. Каждое имеет причину. - **Длительности по типу:** микро/hover 100–150мс (`dur-fast` 100), обычное появление/смена 150–250мс (`dur-base` 160), overlay/drawer/modal ~240мс (`dur-slow`). Дольше 300мс движение начинает раздражать; короче — пропадает читаемость перехода. - **Появляйся от `scale(.95)`, не от `scale(0)`** (и не от `opacity:0` в одиночку): элемент «подрастает» из своего места, а не возникает из ниоткуда. Уводи так же — до `.95`, не в `0`. - **Отклик на нажатие, не на отпускание:** подсветка/`scale(.98)` на pointer-down мгновенно; коммит — на pointer-up. Лаг убивает ощущение прямоты. - **Переходы прерываемы и обратимы:** закрывающийся drawer можно открыть на полпути. Анимируй от ТЕКУЩЕГО значения (presentation), а не от целевого — иначе «прыжок». - **Вход и выход по одному пути; overlay привязан к источнику:** меню/popover растут из кнопки (`transform-origin` = триггер), drawer уходит туда, откуда пришёл. На реверсе — зеркальный easing (`ease-enter` ↔ `ease-exit`). - **Анимируй только `transform` и `opacity`** (композиторные, без ре-лейаута). Не анимируй `width/height/top/left/box-shadow` — дёргается кадр. - **`prefers-reduced-motion`** обнуляет длительности автоматически (токены + компоненты); оставляем только opacity/цвет, что помогают понять переход. ## Иконки Lucide из локального sprite, монохром через `currentColor`, stroke 1.75. Размеры 16 (база), 14 (плотные ряды), 20 (крупные). Без CDN-шрифтов и CSS-псевдоиконок. Правила и список имён – v1-архив. ## Доступность и QA - Контраст: основной текст ≥ 7:1, muted ≥ 4.5:1, faint только для необязательных подписей. - Фокус видим всегда: глобальный `:focus-visible` в components.css. - `prefers-reduced-motion` поддержан на уровне токенов (обнуляет длительности). - `prefers-contrast: more`: толще фокус-кольцо, границы = `border-strong`, ссылки подчёркнуты, обводка у пилюль. - `prefers-reduced-transparency: reduce`: blur на sticky-топбаре снимается, фон становится плотным (легибельность > эффект). - Чек-лист перед сдачей экрана — единый гейт `CHECKLIST.md` (Definition of Done): обе темы, состояния loading/empty/error, один primary, нет сырых hex, адаптив, паритет, валидатор 0/0. Прогоняется при любом изменении UI, не только при сдаче нового экрана. ## Подключение ```html
``` Для Next.js-прототипов – кит `templates/kt-ai-shadcn` (**внутри папки ДС**, рядом с app-shell — ДС одна самодостаточная папка; переменные совместимы, источник значений – kt-ai-tokens.css; установка – его `templates/kt-ai-shadcn/PROTOTYPING_WORKFLOW.md`). **Два рантайма одного контракта.** HTML app-shell (`templates/kt-ai-app-shell.html`) — демо-рантайм с роутингом разделов: рендерит nav-секции (`view="documents"`, мастер `steps`), баннер-навигацию (`banner.actionNav`), коллекции документов. React-кит — **одноэкранный handoff для разработки**: рендерит главный архетип-экран (queue/dashboard/…) + drawer (включая секцию «Документы» из `_docs`), но НЕ роутит вторичные nav-секции — это намеренно (их реализует разработчик под свой роутер). Поэтому `nav.view`, `steps`, `banner.actionNav` — поведение HTML-рантайма; в React это точки расширения. ## Миграция v1 → v2 1. Заменить подключение `archive/kt_ai_terminal_tokens.css` на пару `kt-ai-tokens.css` + `kt-ai-components.css`. Все старые переменные и классы продолжают работать. 2. Hardcoded-размеры и цвета постепенно переводить на шкалы (`--kt-ai-space-*`, `--kt-ai-text-*`, semantic-цвета). 3. Новые компоненты (кнопки, формы, modal, toast, banner, skeleton, empty) не писать заново – брать из components.css. 4. Паритет тем проверять в showcase.html. ## Ритм отступов (правило близости) `space-*` – сырая шкала для внутренних отступов компонента. **Расстояние МЕЖДУ блоками экрана берётся из отдельной шкалы `stack-*`** – одно значение на роль, а не решение каждого компонента: | Токен | Значение | Когда | |---|---|---| | `--kt-ai-stack-tight` | 12px | внутри группы: подпись ↔ контрол, контрол ↔ контрол в одном ряду | | `--kt-ai-stack-block` | 16px | между элементами одного блока; полоса карточек KPI; панель управления ↔ то, чем она управляет | | `--kt-ai-stack-group` | 24px | **между блоками экрана**: шапка / баннер / KPI / чарт / таблица. Значение по умолчанию | | `--kt-ai-stack-region` | 32px | поля рабочей области, топбар ↔ заголовок | | `--kt-ai-pad-card` | 20px | интерьер карточки/секции | Почему шкала, а не `space-*` напрямую: раньше каждый компонент выбирал отбивку сам, и на одном экране получалось пять разных значений для одного и того же отношения «блок ↔ блок» (8/12/16/20/24). Глаз не читает такую разницу как иерархию – он читает её как небрежность, и экран выглядит захламлённым при формально верных токенах. Ровно так разошлись два рантайма: HTML-шелл давал 16/20, React-кит 24/28. Правило разрешения споров прежнее: если сомневаешься, к какой группе элемент относится визуально – он стоит неправильно. Секционный разрыв (40+, `space-10`) остаётся для смены смысла страницы, а не для соседних блоков одного экрана. ### Одинаковый зазор — не ритм Шкала не означает «поставь `stack-group` на всё». Ровно так экран становится плоским: панель фильтров, её вкладки и карточки списка расходятся на одно и то же расстояние, и глаз не видит ни одной группы — только столбец одинаково далёких полос. Разнобой читается как небрежность, равномерность — как «здесь ничто ни с чем не связано». Обе ошибки одинаково дорогие. **Рецепт экрана — три ступени, не одна:** ``` шапка страницы ← 24 (stack-group): регион системный баннер ← 24 (stack-group): регион ┌ панель управления ← 12 (stack-tight): фильтры и вкладки — ОДНА вещь │ фильтры │ вкладки └ ← 16 (stack-block): панель ближе к тому, чем управляет ┌ содержимое │ KPI · чарт · карточки списка ← 16 между блоками, 12 между однородными карточками └ ``` Выражается стеком, а не своим классом продукта: `