/* ЕДИНСТВЕННОЕ МЕСТО В ПРОЕКТЕ, ГДЕ ЖИВУТ ЦВЕТА.

   Это не соглашение, а правило линтера: hex-цвет в любом другом .css или .njk — ошибка
   `npm run lint` (eslint.config.js, правило elbez/no-hex-color, отрицательные образцы в
   tests/lint/). Причина не в аккуратности: тёмная тема, смена палитры и проверка контраста
   работают только тогда, когда значение одно и лежит в одном месте. Стоит одному #c0392b
   уехать в компонент — и в тёмной теме он останется тем же, а фон под ним поменяется.

   Значения палитры продублированы в server/config/brand.js — знак рисуется в SVG, а SVG не
   читает CSS-переменные. Расхождение ловит tests/brand/tokens-match-brand.test.js: он
   разбирает ЭТОТ файл и сверяет с той таблицей.

   Шрифт — Manrope, лицензия OFL, самохост. Подключены ОБА подмножества, кириллица и латиница
   (плюс -ext), по правилу feedback/webfont-latin-cyrillic-subsets-both.md: если оставить
   только кириллицу, латинские слова («ПУЭ 2.1.21», «PDF», имена вендоров) уедут в системный
   шрифт, и в одной строке буквы будут разной толщины. На Android это видно сразу.
   Файл один и тот же на все начертания: Manrope здесь переменный, ось веса 200–800.

   ЗАГОЛОВОЧНАЯ ГАРНИТУРА подключается строкой ниже и приезжает от задачи логотипа
   (scripts/logo.mjs кладёт файлы и свой лист в assets/fonts/). Здесь её не выбирают и не
   правят: гарнитура — часть знака, а не часть вёрстки, и два исполнителя, выбирающие шрифт
   независимо, гарантированно выберут разный.
   @import обязан стоять ДО любых правил — иначе браузер молча его отбросит. */

@import url("/assets/fonts/unbounded.css");

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/assets/fonts/manrope-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/assets/fonts/manrope-cyrillic-ext.woff2') format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/assets/fonts/manrope-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

@font-face {
  font-family: 'Manrope';
  font-style: normal;
  font-weight: 200 800;
  font-display: swap;
  src: url('/assets/fonts/manrope-latin-ext.woff2') format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}

/* ─── Светлая тема. Она же тема по умолчанию: всё-тёмное забраковано лично на четырёх
       пробах редизайна (memory/alexey-design-taste-croc). ─────────────────────────────── */

:root {
  color-scheme: light dark;

  /* Палитра «Крок» (проба 4, ACTIVE_PALETTE=croc в server/config/brand.js).
     Замеры контраста — tests/brand/contrast.test.js, там же порог 4.5:1 и 3:1. */
  /* ФОН СТРАНИЦЫ — НЕЙТРАЛЬНЫЙ СВЕТЛО-СЕРЫЙ, а не кремовый. Решение 30.07.2026, и оно
     стоило кремового, который стоял здесь до этого.
     Причина ровно одна и она физическая: снимки на страницах перестали быть дуотоном и
     стали цветными, а кадры у нас холодные — сине-зелёный щит, сумеречная ЛЭП. Тёплый
     кремовый рядом с холодным кадром желтит: фон читается несвежим, а снимок — синюшным.
     Два противоположных по температуре больших пятна всегда спорят, кто из них «белый».
     Нейтральный серый этого спора не заводит: он отдаёт роль цвета снимку и кислотной
     кнопке, а сам молчит. Это же значение у эталона (#F4F4F4, docs/design/croc-reference.md)
     — но взято оно не потому, что там так, а потому, что цветное фото требует нейтрального
     поля. Серый в оттенке холодного (не чистый) — чтобы он был в родстве с кадром. */
  --c-bg: #F2F3F4;              /* нейтральный светло-серый фон страницы */
  --c-surface: #FFFFFF;         /* карточка, «пузырь», поле */
  --c-surface-sunken: #E7EBEE;  /* вложенная плашка, шапка таблицы */
  --c-ink: #12251C;             /* основной текст: почти чёрный, но зелёного замеса */
  --c-ink-muted: #4E6157;       /* подписи, вторичное; проверено на 4.5:1 к фону */
  --c-line: #D9DFE4;            /* границы и разделители */
  --c-line-strong: #78838B;     /* граница поля: слабее 3:1 быть не имеет права */

  --c-brand: #007A55;           /* глубокий зелёный. С 29.07.2026 у него ДРУГАЯ РОЛЬ: это
                                   цвет акцента и границ, а не заливка всего подряд. Замер
                                   эталона (docs/design/croc-reference.md) показал, зачем:
                                   там зелёный работает акцентом текста и тинтом 10 %, и
                                   потому звенит. Мы заливали им кнопки и карточки — цвета
                                   было много, а звона ноль.
                                   Тон как у КРОКа (161°), но глубже: сам его хекс запрещён
                                   FORBIDDEN_COLORS, семья цвета разрешена */
  --c-brand-ink: #FFFFFF;       /* текст поверх заливки бренда там, где она осталась */
  --c-brand-hover: #005E41;     /* заливка под курсором и в нажатии */
  --c-brand-hover-ink: #FFFFFF; /* текст поверх неё; отдельный токен не от богатства:
                                   в тёмной теме заливка под курсором СВЕТЛЕЕТ, и белый
                                   текст на ней даёт 2.7:1 — замер поймал это раньше глаза */
  --c-link: #00674A;            /* ссылка на светлом фоне */
  --c-brand-tint: #DCEFE3;      /* тинт: фон блока, шапка карточки */
  --c-brand-tint-ink: #0A4B36;  /* текст поверх тинта */

  /* ─── Главное действие: ТЁМНЫЙ ТЕКСТ НА СВЕТЛОМ КИСЛОТНОМ ────────────────────────────
         Приём снят с эталона живьём, и он же — разбор нашей первой ошибки. Мы сделали
         кнопку тёмным изумрудом с белым текстом: по WCAG корректно (5.36:1) и мертво.
         Белый текст на зелёном ТРЕБУЕТ тёмного зелёного, а тёмный зелёный цветом быть
         перестаёт. Эталон решает наоборот: заливка светлая и звонкая, текст почти чёрный.
         Тогда зелёный остаётся зелёным, а контраст получается не 5, а 10.
         Тон 138° — своя середина между нашим бренд-зелёным (161°) и салатовым эталона
         (107°): это не мята и не чужой фирменный цвет. */
  --c-cta: #3EEA72;             /* заливка главной кнопки; тёмный текст на ней = 10.11:1 */
  --c-cta-ink: #12251C;         /* он же --c-ink: чернила страницы, а не отдельный чёрный */
  --c-cta-hover: #1DD755;       /* глубже под курсором; тёмный текст = 8.34:1 */
  --c-cta-hover-ink: #12251C;

  --c-accent: #FFC53D;          /* тёплое золото: три пятна на экран, не заливка */
  --c-accent-ink: #2E2103;
  --c-outline-number: #3E9C74;  /* обводка гигантских контурных номеров 01–04.
                                   Декоративная: сам номер помечен aria-hidden, а порядок
                                   шага продублирован словами в заголовке. Поэтому порог
                                   3:1 к ней не применяется — но замер её всё равно печатает,
                                   и она его проходит: на первом снимке номера были бледными
                                   призраками, приём КРОКа так не работает.

                                   В ТЁМНОЙ ТЕМЕ ЗНАЧЕНИЕ ЯРЧЕ, И ЭТО НЕ РАССОГЛАСОВАНИЕ.
                                   Было #3E7C61 — по числу 3,20:1 на поверхности, то есть
                                   формально не хуже светлой (3,38:1). На снимке при этом
                                   номера пропадали: обводка 1,5 px на тёмном фоне съедается
                                   сглаживанием, а глаз при низкой абсолютной яркости теряет
                                   тонкую линию — числу это неизвестно. Поднято до #48A47C
                                   (5,17:1), проверено снимком рядом со светлой темой.
                                   ПРАВИЛО: у тонкой линии на тёмном фоне порог выше, чем у
                                   заливки, и решает снимок, а не таблица */

  --c-ok-tint: #DCEFE3;         /* «работает». На зелёном бренде это и есть тинт бренда:
                                   разводить два зелёных ради формальной разницы — пестрота */
  --c-ok-ink: #0A4B36;
  --c-wait-tint: #EFE7D6;       /* «готовим»: приглушённый песок, а не второе золото —
                                   иначе плашка спорит с акцентом на цене */
  --c-wait-ink: #5F4E1F;
  --c-danger-tint: #FBE3E0;     /* ошибка формы */
  --c-danger-ink: #8C1D18;

  --c-shadow: 12 42 32;         /* компоненты тени; собирается в rgb() c альфой */

  /* Здесь стояли два цвета дуотона фотографий (--c-photo-shadow, --c-photo-highlight).
     Их больше нет: 30.07.2026 дуотон снят, снимки показываются цветными
     (components.css, раздел «Фотография»). Цвет, которым больше нечего красить, из файла
     токенов убирается сразу — иначе через месяц им покрасят что-нибудь другое. */

  /* ─── Типографика. ПЕРЕВЁРНУТА 29.07.2026 по замерам эталона.

         Что было и почему это не работало: абзац 400, заголовок 700–800, межстрочный
         заголовка 1,14, h1 вдвое крупнее h2. Получался плакат — тяжёлый, кричащий и
         рыхлый одновременно. У эталона всё наоборот: абзац 300, заголовок 500,
         межстрочный заголовка РОВНО 1,0, а h1 и h2 ОДНОГО КЕГЛЯ (41 px на 1440).
         Иерархия там держится воздухом вокруг заголовка, а не его размером — и это
         прямо по Бирману: расстояние сообщает связь, кегль сообщает только громкость.

         Лёгкие веса дальше 300 не уходят и на мелком не применяются: подписи и
         оговорки набираются 400. Их читают с телефона на улице, часто за пятьдесят, —
         300 на 13 px это уже не «воздушно», а «не разобрать». ─── */
  --font-sans: 'Manrope', system-ui, -apple-system, 'Segoe UI', Roboto, sans-serif;
  /* Заголовочная — Unbounded: широкий геометрический гротеск с кириллицей и лёгкими весами,
     то самое, что у эталона делает гарнитура в начертании Extended. Ставится ТОЛЬКО на
     заголовки, цену и контурные номера: в абзаце широкий гротеск читается вдвое медленнее,
     а страницу нашу читают с телефона в поле.
     Manrope в запасе не для красоты: пока шрифт едет, текст рисуется им, и подмена не
     двигает вёрстку сильнее, чем на пару процентов ширины. */
  --font-display: 'Unbounded', 'Manrope', system-ui, sans-serif;
  --fs-display: clamp(2.2rem, 4.2vw, 3.4rem);   /* заголовок первого экрана: ≈54 px на 1440 */
  --fs-h1: clamp(1.6rem, 2.9vw, 2.55rem);       /* ≈41 px — кегль эталона */
  --fs-h2: clamp(1.6rem, 2.9vw, 2.55rem);       /* ТОТ ЖЕ. Разницу держит воздух, не размер */
  /* ЗАГОЛОВОК, ЧЕЙ ТЕКСТ ПРИХОДИТ ИЗ ДАННЫХ, а не написан в шаблоне: имя товара, текст
     вопроса билета. Отдельная ступень заведена 30.07.2026 по находке на снимке:
     «Электробезопасность, полный доступ, 7 суток» на кегле h2 (41 px) не помещалось
     в карточку ни на 1440, ни на 390 — самое длинное слово шире карточки, и заголовок
     ломался посреди слова. Написанный руками заголовок можно укоротить; пришедший из
     данных — нельзя, значит кегль обязан считаться с тем, что слово в нём может быть
     любой длины. 20,8 px на 390 подобраны так, чтобы «Электробезопасность,» (самое
     длинное имя в каталоге) целиком влезало в карточку на телефоне. */
  --fs-h2-data: clamp(1.3rem, 2vw, 1.75rem);    /* 20,8 px на 390, 28 px на 1440 */
  --fs-h3: 1.1875rem;
  --fs-body: 1.0625rem;
  --fs-small: 0.9375rem;
  --fs-micro: 0.8125rem;
  --fs-number: clamp(3rem, 6vw, 5rem);          /* контурный номер 01–04: был 136 px, и на
                                                   лёгкой типографике это была гиря */
  --lh-tight: 1;         /* заголовок первого экрана: межстрочный эталона, ровно единица */
  --lh-heading: 1.04;    /* h1 и h2 */
  --lh-body: 1.6;
  --tracking-tight: -0.018em;
  --tracking-kicker: 0.1em;
  --w-light: 300;        /* абзац, подводка, длинный текст */
  --w-display: 400;      /* ЗАГОЛОВКИ в заголовочной гарнитуре. Отдельный токен, потому что
                            «вес 500» — это указание про Manrope, а не про физическую
                            толщину штриха: Unbounded на 500 выглядит примерно как Manrope
                            на 700, и заголовок снова становится плакатом. Число подобрано
                            по снимку, а не по таблице весов */
  --w-regular: 400;      /* мелкое: подписи, оговорки, служебное */
  --w-medium: 500;       /* заголовки, кнопки, кикер — ВЕРХНИЙ предел для текста */
  --w-semibold: 600;     /* имя платформы в локапе; больше нигде */
  --w-bold: 700;         /* осталось для крайних случаев вроде знака «+» в аккордеоне */
  --w-black: 800;        /* не используется в разметке; оставлен, чтобы шкала была полной */

  /* ─── Шкала отступов. Шаг 4 px, но именами, а не числами: правило воздуха Бирмана
         («связанное ближе, несвязанное дальше») держится только тогда, когда у «ближе»
         и «дальше» есть имена.
         Верх шкалы поднят: у эталона под шапкой до первого заголовка почти экранная
         высота, у нас там было 150 px. ─── */
  --sp-1: 0.25rem;
  --sp-2: 0.5rem;
  --sp-3: 0.75rem;
  --sp-4: 1rem;
  --sp-5: 1.5rem;
  --sp-6: 2rem;
  --sp-7: 3rem;
  --sp-8: 4rem;
  --sp-9: 6rem;
  --sp-10: 8rem;
  /* Воздух под шапкой до первого заголовка. Считается от высоты экрана, а не от кегля:
     «почти экран» на ноутбуке и «почти экран» на телефоне — разные числа. */
  --sp-hero: clamp(3.5rem, 22vh, 15rem);

  /* ─── Радиусы. Кнопка — 10 px, и это замер, а не вкус: пилюля была ошибкой чтения
         эталона (docs/design/croc-reference.md). Пилюля осталась только там, где она
         и должна быть, — на чипах статуса и на контурной кнопке шапки. ─── */
  --r-sm: 0.625rem;   /* 10 px — кнопка, залитое слово, код */
  --r-md: 1.25rem;    /* 20 px */
  --r-lg: 1.5rem;     /* 24 px */
  --r-xl: 2rem;       /* 32 px */
  --r-band: 3.375rem; /* 54 px — нижний край блока во всю ширину */
  --r-pill: 999rem;
  --r-round: 50%;     /* медальон */

  /* Растворение края у полосы, которая прокручивается вбок. Приём «здесь есть продолжение»:
     чёрный и прозрачный в маске — не цвета, а непрозрачность (маска берёт из градиента
     только альфу), поэтому он одинаково работает в обеих темах и поверх размытого фона.
     Ширина 3,5rem подобрана снимком: при 2rem растворялись две последние буквы, и это
     можно было принять за сглаживание шрифта.

     СЕЙЧАС НЕ ПРИМЕНЁН НИГДЕ, и это осознанно. Единственным его местом было меню в шапке
     на телефоне; 31.07.2026 меню стало раскрывающимся списком, и прокрутки вбок в портале
     не осталось ни одной. Значение оставлено готовым: приём проверен и подобран, а место
     для него появится с первой же таблицей или лентой карточек, которая поедет вбок.
     Если такое место не появится до конца работ по порталу — удалить вместе с этим
     комментарием, а не хранить вечно. */
  --mask-scroll-edge: linear-gradient(to right, black calc(100% - 3.5rem), transparent);

  /* ─── Тени. Мягкие, без офсет-теней с острым краем — они забракованы. ─── */
  --shadow-soft: 0 2px 8px rgb(var(--c-shadow) / 0.06);
  --shadow-card: 0 12px 32px rgb(var(--c-shadow) / 0.09);
  --shadow-float: 0 24px 60px rgb(var(--c-shadow) / 0.16);

  --measure: 38rem;      /* предел строки текста */
  --page-max: 76rem;     /* предел ширины полосы */
  --tap: 2.75rem;        /* минимальная цель нажатия: палец, а не курсор */
  --motion: 160ms;
}

/* Телефон: воздух под шапкой урезан. «Почти экран» на ноутбуке — это красиво, на телефоне
   это четверть экрана до первой буквы, и человек в поле листает вниз, не поняв, куда попал
   (Крайг, первый вопрос: «что это за место»). Считается всё так же от высоты окна, просто
   доля меньше.

   УРЕЗАН ЕЩЁ РАЗ 09.08.2026, и на этот раз причина не в красоте. В шапке появилось поле
   поиска — на телефоне оно занимает свою строку, — а первый экран главной теперь обязан
   показать заголовок И поле «найти вопрос»: поиск это первый шаг механики продукта, и
   человек, который его не увидел, не начал. Замер снимком 390×844: при 12vh (101 px)
   кнопка «Найти вопрос» уходила за нижнюю кромку. */
@media (max-width: 47.99rem) {
  :root { --sp-hero: clamp(1rem, 4vh, 2.5rem); }
}

/* ─── Тёмная тема. Два блока с одинаковыми значениями — цена отказа от препроцессора:
       первый ловит системную настройку, второй — явный выбор тумблером, и он обязан
       побеждать. Расхождение между блоками ловит tests/brand/tokens-match-brand.test.js. ─── */

@media (prefers-color-scheme: dark) {
  :root:not([data-theme='light']) {
    --c-bg: #0E1A15;
    --c-surface: #16261F;
    --c-surface-sunken: #121F19;
    --c-ink: #EAF2EC;
    --c-ink-muted: #9FB3A8;
    --c-line: #26362E;
    --c-line-strong: #7C948A;
    --c-brand: #0E7F58;
    --c-brand-ink: #FFFFFF;
    --c-brand-hover: #2FBB7E;
    --c-brand-hover-ink: #05241A;
    --c-link: #7FDCB0;
    --c-brand-tint: #123529;
    --c-brand-tint-ink: #8FE2B9;
    --c-cta: #3EEA72;
    --c-cta-ink: #08170F;
    --c-cta-hover: #6FF6A1;
    --c-cta-hover-ink: #08170F;
    --c-accent: #FFC53D;
    --c-accent-ink: #2E2103;
    --c-outline-number: #48A47C;
    --c-ok-tint: #123529;
    --c-ok-ink: #8FE2B9;
    --c-wait-tint: #332C16;
    --c-wait-ink: #E8D3A0;
    --c-danger-tint: #40191A;
    --c-danger-ink: #FCB3AD;
    --c-shadow: 0 0 0;
  }
}

:root[data-theme='dark'] {
  --c-bg: #0E1A15;
  --c-surface: #16261F;
  --c-surface-sunken: #121F19;
  --c-ink: #EAF2EC;
  --c-ink-muted: #9FB3A8;
  --c-line: #26362E;
  --c-line-strong: #7C948A;
  --c-brand: #0E7F58;
  --c-brand-ink: #FFFFFF;
  --c-brand-hover: #2FBB7E;
  --c-brand-hover-ink: #05241A;
  --c-link: #7FDCB0;
  --c-brand-tint: #123529;
  --c-brand-tint-ink: #8FE2B9;
  --c-cta: #3EEA72;
  --c-cta-ink: #08170F;
  --c-cta-hover: #6FF6A1;
  --c-cta-hover-ink: #08170F;
  --c-accent: #FFC53D;
  --c-accent-ink: #2E2103;
  --c-outline-number: #48A47C;
  --c-ok-tint: #123529;
  --c-ok-ink: #8FE2B9;
  --c-wait-tint: #332C16;
  --c-wait-ink: #E8D3A0;
  --c-danger-tint: #40191A;
  --c-danger-ink: #FCB3AD;
  --c-shadow: 0 0 0;
}

/* Тумблер стоит в теме «тёмная», а система говорит «светлая» — тогда color-scheme обязан
   переключиться следом, иначе браузер нарисует свои поля и полосы прокрутки светлыми. */
:root[data-theme='dark'] { color-scheme: dark; }
:root[data-theme='light'] { color-scheme: light; }
