/* ============================================================================
   КОНСТРУКТ · ВИЗУАЛЬНЫЙ ЯЗЫК
   ----------------------------------------------------------------------------
   Один словарь на весь сайт: главную, витрины продуктов, правовой раздел.
   Источник — дизайн-система Образа, packages/brand/src/tokens.css. Значения
   перенесены как есть; КОНСТРУКТ добавляет к ним только геометрию тессеракта
   (см. раздел «Форма» внизу файла).

   Почему словарь один. До этого файла в проекте жили два набора имён: kn-* на
   главной и kp-* на страницах продуктов, с разными значениями одного и того же
   серого. Человек, переходящий с konstrukt.tech на konstrukt.tech/drift, видел
   смену холста — и это читалось как два разных сайта, а не как один.

   Три состояния темы, а не два. В Образе тёмная тема объявлена умолчанием, а
   светлая живёт под [data-theme="light"]; медиазапроса там нет вовсе, потому
   что приложение Образа тему не угадывает — её выбирает вошедший человек. На
   сайте гость не входит, поэтому тема обязана иметь третье состояние «как в
   системе». Отсюда порядок: :root несёт светлую, медиазапрос надевает тёмную
   на всех, кроме тех, кто выбрал светлую руками, а [data-theme='dark'] надевает
   её поверх системы. Ключ выбора — kp-theme, значения auto|light|dark.

   Значения тёмной темы объявлены ОДИН раз (--d-*) и дальше только
   раскладываются по двум состояниям. Так правка цвета остаётся правкой в одном
   месте: продублирован список присваиваний, но не сами цвета.
   ========================================================================== */

:root{
  /* ── Тёмный набор. Здесь он только хранится; надевается ниже ──────────────
   * Серый АХРОМАТИЧЕСКИЙ, R=G=B (решение господина Тимура 13 сентября 2026,
   * перенесено из Образа). Прежние #1a1a1a / #202021 / #232325 несли в себе
   * синеву: экран отдавал холодом и читался «цифровым», а не материальным.
   * Правило на будущее: любой серый в тёмной теме — без подтона. Цвет
   * остаётся только за смыслом. */
  --d-canvas:  #111111;
  --d-surface: #161616;
  --d-raised:  #1b1b1b;
  --d-ink:     #f2f2f2;
  --d-ink-1:   rgba(242,242,242,.78);
  --d-ink-2:   rgba(242,242,242,.56);
  --d-ink-3:   rgba(242,242,242,.45);
  --d-line:    rgba(242,242,242,.12);
  --d-line-2:  rgba(242,242,242,.22);
  --d-hover:   rgba(242,242,242,.05);
  --d-press:   rgba(242,242,242,.09);
  --d-focus:   rgba(242,242,242,.48);
  --d-invert:  #111111;
  --d-low:     0 1px 2px rgba(0,0,0,.30), 0 6px 18px rgba(0,0,0,.16);
  --d-mid:     0 2px 5px rgba(0,0,0,.34), 0 16px 38px rgba(0,0,0,.22);
  --d-high:    0 4px 12px rgba(0,0,0,.42), 0 30px 72px rgba(0,0,0,.30);
  --d-grain-opacity: .20;

  /* ── Светлая тема: действующая по умолчанию ──────────────────────────────
   * Абсолютный белый холст и абсолютно чёрные чернила. Все три уровня
   * поверхности белые намеренно: воздух и глубина делаются расстоянием,
   * прозрачностью, тонкой линией и мягкой тенью, а не серой заливкой.
   * Поэтому прежний --bg-alt #f6f6f7 отменён — подвал и вставки отделяются
   * линией, а не плашкой. */
  --kn-canvas:        #ffffff;
  --kn-surface:       #ffffff;
  --kn-surface-raised:#ffffff;

  --kn-ink:           #000000;
  --kn-ink-primary:   rgba(0,0,0,.78);
  --kn-ink-secondary: rgba(0,0,0,.56);
  /* Третий уровень чернил был .36 — и это единственное место словаря, где
   * цифра не выдерживала проверки глазом. Посчитано по WCAG 2.1 (формула
   * относительной яркости sRGB):
   *     .36 на белом → 2.52:1   — ниже даже порога 3:1 для нетекстовых частей;
   *     .36 на #111  → 3.10:1   — проходит только крупный текст, а им набран
   *                               один заголовок из десяти.
   * .45 даёт 3.35:1 на белом и 4.17:1 на графите. Этого мало для мелкого
   * текста (нужно 4.5:1), поэтому третий уровень оставлен ТОЛЬКО за подписями,
   * которые дублируют смысл: надзаголовки, метки состояния, версты капсом.
   * Всё, что читают ради содержания — шапки таблиц, реквизиты, правовая
   * строка, — переведено на второй уровень (.56 → 4.94:1 и 5.84:1). См.
   * site.css, раздел «чернила второго уровня».
   *
   * Довести третий уровень до 4.5:1 можно — .54 на белом и .48 на графите, —
   * но тогда он сравняется со вторым (.56) и лестница из трёх ступеней
   * схлопнется в две. Это решение вкуса, а не арифметики, и оно за
   * господином Тимуром. */
  --kn-ink-muted:     rgba(0,0,0,.45);
  --kn-ink-invert:    #ffffff;

  --kn-line:          rgba(0,0,0,.12);
  --kn-line-strong:   rgba(0,0,0,.22);
  --kn-state-hover:   rgba(0,0,0,.04);
  --kn-state-pressed: rgba(0,0,0,.08);
  --kn-focus-ring:    rgba(0,0,0,.42);

  --kn-shadow-low:    0 1px 2px rgba(0,0,0,.035), 0 6px 18px rgba(0,0,0,.055);
  --kn-shadow-medium: 0 2px 5px rgba(0,0,0,.045), 0 16px 42px rgba(0,0,0,.075);
  --kn-shadow-high:   0 4px 12px rgba(0,0,0,.06),  0 30px 72px rgba(0,0,0,.12);

  /* ── Полоса содержания ───────────────────────────────────────────────────
   * ОДНА на все публичные поверхности. Шапка, подвал, первый экран и блоки
   * витрины обязаны мерить ширину этим токеном, иначе знак в шапке и заголовок
   * секции начинают стоять на разных вертикалях. Проценты и rem вместе: при
   * зуме оболочка сжимается и растёт заодно с типографикой, а не расползается
   * относительно неё.
   *
   * Отдельно --kn-measure: строка текста шире 75 знаков не читается, поэтому
   * правовые страницы и длинные тексты меряются им, а не полосой. */
  --kn-shell:   min(92%, 104rem);
  --kn-measure: min(92%, 48rem);
  --kn-nav-h:   60px;

  /* ── Типографика ─────────────────────────────────────────────────────────
   * Poppins ведёт заголовки, Manrope — всё остальное. Century Gothic стоит в
   * запасе у display: он был исходным шрифтом знака, и на машине без Poppins
   * пропорции остаются теми же. */
  --font-display: 'Poppins', 'Manrope', 'Century Gothic', CenturyGothic, sans-serif;
  --font-ui:      'Manrope', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
  --font-body:    var(--font-ui);

  --kn-ease:      cubic-bezier(.16,1,.3,1);

  /* ── Зерно ───────────────────────────────────────────────────────────────
   * Общий материал сайта, а не приём одной страницы. Плитка кладётся 1:1
   * (--kn-grain-size), иначе крапина мылится. Маска низкой частоты гуляет
   * плотностью; её период намеренно не кратен периоду зерна, поэтому
   * совпадения не выстраиваются в решётку. */
  --kn-grain-size:      320px 320px;
  --kn-grain-mask-size: 1180px 1180px;
  --kn-grain-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='600' height='600'%3E%3Cfilter id='cl' x='0' y='0' width='100%25' height='100%25' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.0055' numOctaves='4' seed='23' stitchTiles='stitch' result='c'/%3E%3CfeColorMatrix in='c' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='1.7' intercept='-0.32'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='600' height='600' filter='url(%23cl)'/%3E%3C/svg%3E");
  --kn-grain-opacity: .16;
  /* На белом холсте крапина обязана быть тёмной — иначе зерна просто нет. */
  --kn-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='320'%3E%3Cfilter id='grain' x='0' y='0' width='100%25' height='100%25' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.72' numOctaves='1' seed='11' stitchTiles='stitch' result='n'/%3E%3CfeColorMatrix in='n' type='matrix' values='0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='2.7' intercept='-1.45'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='320' height='320' filter='url(%23grain)'/%3E%3C/svg%3E");

  /* ── Форма: подтверждение тессерактом ────────────────────────────────────
   * Здесь КОНСТРУКТ добавляет к языку Образа своё. Знак студии — четырёхмерный
   * куб: прямые рёбра, острые вершины, узлы каркаса. Скруглений в нём нет, и
   * закруглённая карточка спорит со знаком, стоящим на том же экране.
   *
   * Поэтому радиус равен нулю, а глубина набирается не тенью и не заливкой, а
   * толщиной линии: hairline у спокойной поверхности, line-strong у выбранной.
   * Ровно так же в каркасе тессеракта ближнее ребро тяжелее дальнего.
   *
   * --kn-node — размер узла на углу поверхности. Метка тессеракта в мелком
   * масштабе: четыре точки по углам читаются как вершины каркаса. */
  --kn-radius:    0px;
  --kn-radius-sm: 0px;
  --kn-hair:      1px;
  --kn-edge:      2px;
  --kn-node:      3px;
  /* Угол разреза у акцентных поверхностей: 45°, как диагональ ромба, в который
   * тессеракт складывается на первом экране. */
  --kn-bevel:     10px;
}

/* Тёмная по системе — всем, кроме выбравших светлую руками. */
@media (prefers-color-scheme: dark){
  :root:not([data-theme='light']){
    --kn-canvas:        var(--d-canvas);
    --kn-surface:       var(--d-surface);
    --kn-surface-raised:var(--d-raised);
    --kn-ink:           var(--d-ink);
    --kn-ink-primary:   var(--d-ink-1);
    --kn-ink-secondary: var(--d-ink-2);
    --kn-ink-muted:     var(--d-ink-3);
    --kn-ink-invert:    var(--d-invert);
    --kn-line:          var(--d-line);
    --kn-line-strong:   var(--d-line-2);
    --kn-state-hover:   var(--d-hover);
    --kn-state-pressed: var(--d-press);
    --kn-focus-ring:    var(--d-focus);
    --kn-shadow-low:    var(--d-low);
    --kn-shadow-medium: var(--d-mid);
    --kn-shadow-high:   var(--d-high);
    --kn-grain-opacity: var(--d-grain-opacity);
    /* На графите крапина светлая. */
    --kn-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='320'%3E%3Cfilter id='grain' x='0' y='0' width='100%25' height='100%25' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.72' numOctaves='1' seed='11' stitchTiles='stitch' result='n'/%3E%3CfeColorMatrix in='n' type='matrix' values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='2.7' intercept='-1.45'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='320' height='320' filter='url(%23grain)'/%3E%3C/svg%3E");
  }
}

/* Тёмная выбрана руками — поверх системы. */
:root[data-theme='dark']{
  --kn-canvas:        var(--d-canvas);
  --kn-surface:       var(--d-surface);
  --kn-surface-raised:var(--d-raised);
  --kn-ink:           var(--d-ink);
  --kn-ink-primary:   var(--d-ink-1);
  --kn-ink-secondary: var(--d-ink-2);
  --kn-ink-muted:     var(--d-ink-3);
  --kn-ink-invert:    var(--d-invert);
  --kn-line:          var(--d-line);
  --kn-line-strong:   var(--d-line-2);
  --kn-state-hover:   var(--d-hover);
  --kn-state-pressed: var(--d-press);
  --kn-focus-ring:    var(--d-focus);
  --kn-shadow-low:    var(--d-low);
  --kn-shadow-medium: var(--d-mid);
  --kn-shadow-high:   var(--d-high);
  --kn-grain-opacity: var(--d-grain-opacity);
  --kn-grain: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='320' height='320'%3E%3Cfilter id='grain' x='0' y='0' width='100%25' height='100%25' color-interpolation-filters='sRGB'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.72' numOctaves='1' seed='11' stitchTiles='stitch' result='n'/%3E%3CfeColorMatrix in='n' type='matrix' values='0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 1 0 0 0 0'/%3E%3CfeComponentTransfer%3E%3CfeFuncA type='linear' slope='2.7' intercept='-1.45'/%3E%3C/feComponentTransfer%3E%3C/filter%3E%3Crect width='320' height='320' filter='url(%23grain)'/%3E%3C/svg%3E");
}

/* ============================================================================
   СОВМЕСТИМЫЕ ИМЕНА
   ----------------------------------------------------------------------------
   В проекте уже написаны тысячи строк на двух прежних словарях: --fg/--border/
   --surface на сайте и --ink/--line/--bg-card в приложениях. Переписывать их
   разом — это одна большая правка, которую нечем проверить. Поэтому старые
   имена остаются и указывают на новые.

   В НОВЫХ компонентах их использовать нельзя: пишется --kn-*.
   ========================================================================== */
:root{
  --bg:             var(--kn-canvas);
  --bg-alt:         var(--kn-canvas);   /* серой подложки больше нет */
  --surface:        var(--kn-surface);
  --border:         var(--kn-line);
  --border-strong:  var(--kn-line-strong);
  --fill:           var(--kn-state-hover);
  --fill-2:         var(--kn-state-pressed);
  --fg:             var(--kn-ink);
  --muted:          var(--kn-ink-secondary);
  --faint:          var(--kn-ink-muted);
  --invert-fg:      var(--kn-ink-invert);
  --sheen:          var(--kn-state-pressed);
  --shadow:         var(--kn-shadow-low);
  --shadow-hover:   var(--kn-shadow-medium);
  --shadow-soft:    var(--kn-shadow-low);

  --ink:         var(--kn-ink);
  --ink-dim:     var(--kn-ink-secondary);
  --ink-faint:   var(--kn-ink-muted);
  --line:        var(--kn-line);
  --line-bright: var(--kn-line-strong);
  --bg-card:     var(--kn-surface);

  --radius:      var(--kn-radius);
  --radius-sm:   var(--kn-radius-sm);
  --radius-pill: var(--kn-radius);
  --shell:       var(--kn-shell);
  --maxw:        var(--kn-measure);
  --nav-h:       var(--kn-nav-h);
  --ease:        var(--kn-ease);

  --grain:         var(--kn-grain);
  --grain-size:    var(--kn-grain-size);
  --grain-opacity: var(--kn-grain-opacity);

  /* Два имени из слоёв главной: --bg-soft держал серую подложку (#f6f6f7 на
   * светлой, #202021 на тёмной), --invert-bg — вывернутый фон. Подложки в
   * языке Образа больше нет, поэтому --bg-soft равен холсту: вставка
   * отделяется линией. --invert-bg остаётся вывернутым и берёт чернила. */
  --bg-soft:   var(--kn-canvas);
  --invert-bg: var(--kn-ink);
}
