/* ============================================================ * KT AI Components v2.1 * Требует kt-ai-tokens.css. Только semantic/component токены, * никаких сырых hex. Имена классов v1 сохранены. * Слой @layer kt-components: продуктовый CSS объявляйте в слое * выше (@layer product) или вне слоёв – он выиграет каскад. * Канон: docs/DESIGN.md · Галерея: showcase.html * ============================================================ */ @layer kt-components { /* border-box для ВСЕХ компонентов ДС, где бы они ни жили. Компоненты вроде .kt-ai-input объявлены как width:100% + padding + border: в content-box они вылезают из контейнера (замерено: 326px в контейнере 300px). Раньше сброс жил только в HTML app-shell, поэтому баг проявлялся ровно там, где ДС вендорят в чужой проект — в основном сценарии передачи разработчикам. Селектор бьёт только по .kt-ai-*, чтобы не трогать вёрстку хост-приложения. */ [class*="kt-ai-"], [class*="kt-ai-"]::before, [class*="kt-ai-"]::after { box-sizing: border-box; } /* Сброс UA-хрома для интерактивных компонентов ДС. Браузер не наследует font-family для button/input/select/textarea и рисует кнопкам свою серую заливку. В HTML app-shell это гасил глобальный сброс, поэтому при вендоринге ДС в чужой проект компоненты приезжали сломанными: .kt-ai-tab — с серым UA-фоном, .kt-ai-filter-chip/.seg/.page-btn — в Arial. :where() даёт НУЛЕВУЮ специфичность — любое правило компонента ниже победит. */ :where(button[class*="kt-ai-"], input[class*="kt-ai-"], select[class*="kt-ai-"], textarea[class*="kt-ai-"]) { font-family: var(--kt-ai-font-sans); font-size: var(--kt-ai-text-sm); color: inherit; } :where(button[class*="kt-ai-"]) { -webkit-appearance: none; appearance: none; background: none; border: none; cursor: pointer; } /* ---------- База ---------- */ .kt-ai-app, .kt-ai-shell { background: var(--kt-ai-bg); color: var(--kt-ai-fg); font-family: var(--kt-ai-font-sans); font-size: var(--kt-ai-text-sm); line-height: var(--kt-ai-leading-normal); -webkit-font-smoothing: antialiased; } .kt-ai-shell { min-height: 100dvh; display: grid; grid-template-columns: var(--kt-ai-sidebar-width) minmax(0, 1fr); } .kt-ai-sidebar { background: var(--kt-ai-bg-soft); border-right: 1px solid var(--kt-ai-divider); color: var(--kt-ai-fg-muted); position: sticky; top: 0; align-self: start; height: 100dvh; overflow-y: auto; } .kt-ai-main { min-width: 0; background: var(--kt-ai-bg); } .kt-ai-work-column { max-width: var(--kt-ai-content-max); margin: 0 auto; padding: var(--kt-ai-space-12) var(--kt-ai-space-8) var(--kt-ai-space-11); } .kt-ai-work-column-wide { max-width: var(--kt-ai-content-wide); margin: 0 auto; padding: var(--kt-ai-space-8); } .kt-ai-work-column-table { max-width: var(--kt-ai-content-table); margin: 0 auto; padding: var(--kt-ai-space-11) var(--kt-ai-space-8); } /* Скроллбары */ .kt-ai-app ::-webkit-scrollbar, .kt-ai-shell ::-webkit-scrollbar { width: 8px; height: 8px; } .kt-ai-app ::-webkit-scrollbar-thumb, .kt-ai-shell ::-webkit-scrollbar-thumb { background: var(--kt-ai-border-strong); border-radius: var(--kt-ai-radius-md); } .kt-ai-app ::-webkit-scrollbar-track, .kt-ai-shell ::-webkit-scrollbar-track { background: transparent; } /* Фокус: единый видимый стиль для всего интерактива */ .kt-ai-app :focus-visible, .kt-ai-shell :focus-visible { outline: 2px solid var(--kt-ai-focus-ring); outline-offset: 1px; } /* ---------- Типографика ---------- */ .kt-ai-h1 { font-size: var(--kt-ai-text-2xl); font-weight: var(--kt-ai-weight-bold); line-height: var(--kt-ai-leading-tight); letter-spacing: -.02em; } .kt-ai-h2 { font-size: var(--kt-ai-text-lg); font-weight: var(--kt-ai-weight-semibold); line-height: var(--kt-ai-leading-tight); letter-spacing: -.01em; } .kt-ai-h3 { font-size: var(--kt-ai-text-md); font-weight: var(--kt-ai-weight-semibold); } /* Капс оставляем — узнаваемый eyebrow-паттерн. Но капс мелким кеглем это худший случай для чтения, и он не имеет права быть ещё и самым тусклым текстом системы: 11px + .8px разрядки + faint. Кегль на ступень выше, разрядка меньше (на 12px .8px избыточна), цвет — muted. */ .kt-ai-label { font-family: var(--kt-ai-font-mono); font-size: var(--kt-ai-text-xs); font-weight: var(--kt-ai-weight-semibold); text-transform: uppercase; letter-spacing: .5px; color: var(--kt-ai-fg-muted); } .kt-ai-meta { font-size: var(--kt-ai-text-xs); color: var(--kt-ai-fg-muted); } .kt-ai-num { font-family: var(--kt-ai-font-sans); font-variant-numeric: tabular-nums; } .kt-ai-link { color: var(--kt-ai-link); text-decoration: none; } .kt-ai-link:hover { text-decoration: underline; } /* ---------- Иконки ---------- */ .kt-icon { width: 16px; height: 16px; display: inline-block; flex: 0 0 16px; color: currentColor; fill: none; stroke: currentColor; stroke-width: 1.75; stroke-linecap: round; stroke-linejoin: round; vertical-align: -2px; } .kt-icon-sm { width: 14px; height: 14px; flex-basis: 14px; } .kt-icon-lg { width: 20px; height: 20px; flex-basis: 20px; } /* ---------- Кнопки ---------- */ .kt-ai-btn { display: inline-flex; align-items: center; justify-content: center; gap: var(--kt-ai-space-3); height: var(--kt-ai-control-h-md); padding: 0 var(--kt-ai-space-5); border-radius: var(--kt-ai-radius-xl); border: 1px solid var(--kt-ai-border-strong); background: var(--kt-ai-bg-elevated); box-shadow: var(--kt-ai-shadow-sm); color: var(--kt-ai-fg); font-family: var(--kt-ai-font-sans); font-size: var(--kt-ai-text-sm); font-weight: var(--kt-ai-weight-medium); cursor: pointer; white-space: nowrap; transition: background var(--kt-ai-dur-fast) var(--kt-ai-ease-standard), border-color var(--kt-ai-dur-fast) var(--kt-ai-ease-standard), transform 60ms var(--kt-ai-ease-standard); } /* hover = тонирующий слой bg-hover поверх поверхности: в dark светлеет, в light темнеет */ .kt-ai-btn:hover { background-image: linear-gradient(var(--kt-ai-bg-hover), var(--kt-ai-bg-hover)); } .kt-ai-btn:active { transform: scale(.98); } .kt-ai-btn:disabled { opacity: .4; cursor: default; transform: none; background-image: none; } .kt-ai-btn[data-variant="primary"] { background: var(--kt-ai-primary); border-color: var(--kt-ai-primary); color: var(--kt-ai-fg-on-fill); font-weight: var(--kt-ai-weight-semibold); box-shadow: inset 0 1px 0 var(--kt-ai-inset-highlight); } .kt-ai-btn[data-variant="primary"]:hover { background: var(--kt-ai-primary-hover); border-color: var(--kt-ai-primary-hover); } .kt-ai-btn[data-variant="ghost"] { border-color: transparent; background: transparent; box-shadow: none; color: var(--kt-ai-fg-muted); } .kt-ai-btn[data-variant="ghost"]:hover { color: var(--kt-ai-fg); background: var(--kt-ai-bg-hover); } .kt-ai-btn[data-variant="danger"] { background: transparent; box-shadow: none; border-color: var(--kt-ai-danger); color: var(--kt-ai-danger); } .kt-ai-btn[data-variant="danger"]:hover { background: var(--kt-ai-danger); color: var(--kt-ai-fg-on-fill); } .kt-ai-btn[data-size="sm"] { height: var(--kt-ai-control-h-sm); padding: 0 var(--kt-ai-space-4); font-size: var(--kt-ai-text-xs); border-radius: var(--kt-ai-radius-lg); } .kt-ai-btn[data-size="lg"] { height: var(--kt-ai-control-h-lg); padding: 0 var(--kt-ai-space-7); font-size: var(--kt-ai-text-md); border-radius: var(--kt-ai-radius-xl); } .kt-ai-icon-button { display: inline-flex; align-items: center; justify-content: center; width: var(--kt-ai-control-h-md); height: var(--kt-ai-control-h-md); border-radius: var(--kt-ai-radius-lg); border: none; background: transparent; color: var(--kt-ai-fg-muted); cursor: pointer; transition: background var(--kt-ai-dur-fast) var(--kt-ai-ease-standard), color var(--kt-ai-dur-fast) var(--kt-ai-ease-standard); } .kt-ai-icon-button:hover, .kt-ai-icon-button[data-active="true"] { background: var(--kt-ai-bg-hover); color: var(--kt-ai-fg); } /* ---------- Формы ---------- */ .kt-ai-field { display: flex; flex-direction: column; gap: var(--kt-ai-space-2); margin-bottom: var(--kt-ai-space-5); } /* Подпись поля. Две формы записи, и обе законны:
с