/* tokens.css — фундамент дизайн-системы сборки.
 *
 * Зачем: раньше каждый сайт собирался «на глаз» — отсюда 6 разных радиусов,
 * padding 134px во всех секциях подряд и заголовок всего в 3.4 раза крупнее текста.
 * Здесь правильное решение сделано ДЕФОЛТОМ: подключил — и шкалы уже верные.
 *
 * Правило: в компонентах не бывает захардкоженных цветов, размеров и радиусов.
 * Только var(). Если нужного токена нет — добавь его сюда, а не пиши число в месте.
 *
 * Палитру и шрифты задаёт файл проекта (brand.css), он переопределяет
 * --color-* и --font-*. Здесь только нейтральный дефолт, чтобы кит работал сразу.
 */

:root {
  /* ============ ТИПОГРАФИКА ============
     Шкала строится не «шагами по 4px», а мультипликативно, с крупным дисплейным
     верхом. Именно разрыв между --text-hero и --text-body создаёт то самое
     ощущение иерархии, которого не было. Целевой контраст hero/body: 7-9x. */
  --font-display: "Times New Roman", serif;  /* переопределить в brand.css */
  --font-text: system-ui, sans-serif;        /* переопределить в brand.css */
  --font-mono: ui-monospace, "Cascadia Code", "SF Mono", Menlo, monospace;

  /* Два ограничителя сразу, оба поставлены по факту провала:
     нижняя граница 5rem — потому что на телефоне заголовок в 4rem давал контраст
     3.44x при пороге 3.5x, то есть на экране, откуда идёт рекламный трафик,
     h1 почти сливался с абзацем;
     потолок 17vh — потому что без него заголовок в три строки выдавливал
     подзаголовок и кнопки за пределы первого экрана. */
  --text-hero: min(clamp(5rem, 1.2rem + 11.5vw, 11.5rem), 17vh);
  --text-display: clamp(2.75rem, 1.4rem + 5.4vw, 6.5rem); /*  44 → 104px */
  --text-title: clamp(1.9rem, 1.3rem + 2.4vw, 3.25rem);   /*  30 →  52px */
  --text-lead: clamp(1.15rem, 1rem + 0.7vw, 1.5rem);      /*  18 →  24px */
  --text-body: clamp(1.0625rem, 1rem + 0.2vw, 1.1875rem); /*  17 →  19px */
  --text-small: clamp(0.875rem, 0.85rem + 0.1vw, 0.9375rem);
  --text-micro: clamp(0.6875rem, 0.66rem + 0.12vw, 0.78rem);

  /* Крупный текст обязан быть сжат по высоте строки и трекингу, мелкий — наоборот.
     Единая line-height 1.5 на всё — верный признак, что типографику не настраивали. */
  --lh-hero: 0.88;
  --lh-display: 0.95;
  --lh-title: 1.08;
  --lh-body: 1.6;
  --lh-lead: 1.45;

  --track-hero: -0.035em;
  --track-display: -0.025em;
  --track-title: -0.015em;
  --track-body: 0em;
  --track-caps: 0.14em;   /* капс без разрядки читается как ошибка */

  --measure: 62ch;        /* предел ширины абзаца: длиннее — глаз теряет строку */
  --measure-tight: 44ch;

  /* ============ ПРОСТРАНСТВО ============
     Нелинейная шкала: мелкие шаги плотные, крупные — с разгоном. Секции НЕ должны
     все иметь один и тот же отступ: --space-section-sm/md/lg существуют, чтобы
     ритм страницы был живым, а не механическим. */
  --space-3xs: 0.25rem;
  --space-2xs: 0.5rem;
  --space-xs: 0.75rem;
  --space-sm: 1.25rem;
  --space-md: 2rem;
  --space-lg: 3.25rem;
  --space-xl: 5.25rem;
  --space-2xl: 8.5rem;
  --space-3xl: 13.75rem;

  --space-section-sm: clamp(3rem, 2rem + 4vw, 5rem);
  --space-section-md: clamp(4.5rem, 3rem + 7vw, 9rem);
  --space-section-lg: clamp(7rem, 4rem + 12vw, 15rem);

  --gutter: clamp(1.25rem, 0.75rem + 2.4vw, 3.5rem);
  --page-max: 1440px;
  --content-max: 1180px;

  /* ============ РАДИУСЫ ============
     Ровно четыре ступени + пилюля. Никаких 9px рядом с 10px: аудит считает
     соседние значения с разницей <=3px браком, и это правильно. */
  --radius-xs: 2px;
  --radius-sm: 6px;
  --radius-md: 14px;
  --radius-lg: 28px;
  --radius-pill: 999px;

  /* ============ ЦВЕТ ============
     OKLCH: равномерная светлота, поэтому оттенки не «проваливаются» при
     осветлении. Роли, а не названия: bg/surface/text/muted/accent/on-accent.
     Акцент — ОДИН и всегда означает действие. Второй акцент — только со статусом. */
  --color-bg: oklch(98.5% 0.004 100);
  --color-surface: oklch(96% 0.005 100);
  --color-elevated: oklch(100% 0 0);
  --color-text: oklch(18% 0.01 100);
  --color-muted: oklch(52% 0.012 100);
  --color-hairline: oklch(18% 0.01 100 / 0.12);
  --color-accent: oklch(58% 0.19 42);
  --color-accent-hover: oklch(52% 0.2 42);
  --color-on-accent: oklch(99% 0 0);
  --shadow-color: oklch(25% 0.03 100);

  /* ============ СЛОИ ============ */
  --z-base: 0;
  --z-sticky: 10;
  --z-header: 100;
  --z-overlay: 1000;
  --z-grain: 9999;
}

/* Тёмная схема — не «инверсия», а отдельно подобранные значения.
   Чистый #000 не используем: он глушит фактуру и делает края ватными. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --color-bg: oklch(15% 0.012 265);
    --color-surface: oklch(19% 0.014 265);
    --color-elevated: oklch(23% 0.016 265);
    --color-text: oklch(96% 0.006 265);
    --color-muted: oklch(68% 0.014 265);
    --color-hairline: oklch(96% 0.006 265 / 0.14);
    --shadow-color: oklch(4% 0.02 265);
  }
}
:root[data-theme="dark"] {
  --color-bg: oklch(15% 0.012 265);
  --color-surface: oklch(19% 0.014 265);
  --color-elevated: oklch(23% 0.016 265);
  --color-text: oklch(96% 0.006 265);
  --color-muted: oklch(68% 0.014 265);
  --color-hairline: oklch(96% 0.006 265 / 0.14);
  --shadow-color: oklch(4% 0.02 265);
}

/* ============ БАЗА ============ */
*, *::before, *::after { box-sizing: border-box; }
/* clip обязателен и на html: прокруткой заведует корневой элемент, и правило
   на одном body её не убирает (проверено на демо 21.08.2026). */
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; overflow-x: clip; }
@media (prefers-reduced-motion: reduce) { html { scroll-behavior: auto; } }

body {
  margin: 0;
  /* clip, а не hidden: горизонтальные reveal сдвигают блок на 28px вправо, пока он
     скрыт, и страница получает прокрутку вбок ещё до появления контента.
     hidden здесь не годится — он создаёт контекст прокрутки и ломает position: sticky,
     на котором держатся липкие сцены. */
  overflow-x: clip;
  background: var(--color-bg);
  color: var(--color-text);
  font-family: var(--font-text);
  font-size: var(--text-body);
  line-height: var(--lh-body);
  letter-spacing: var(--track-body);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
  font-synthesis-weight: none; /* не давать браузеру подделывать жирность */
}

/* Заголовки получают дисплейные настройки автоматически — чтобы «забыть сжать
   line-height» было невозможно. */
h1, h2, h3 {
  font-family: var(--font-display);
  font-weight: var(--weight-display, 600);
  text-wrap: balance;         /* не оставлять одно слово на последней строке */
  margin: 0 0 var(--space-sm);
  /* На узком экране одно длинное слово в 80px шире вьюпорта и даёт
     горизонтальную прокрутку — проверено на демо («Площадка», 373px при 375px).
     Сначала пробуем перенос по правилам языка, и только если и он не спас —
     рвём слово, чтобы страница не поехала вбок. */
  hyphens: auto;
  overflow-wrap: break-word;
}
h1 { font-size: var(--text-hero); line-height: var(--lh-hero); letter-spacing: var(--track-hero); }
h2 { font-size: var(--text-display); line-height: var(--lh-display); letter-spacing: var(--track-display); }
h3 { font-size: var(--text-title); line-height: var(--lh-title); letter-spacing: var(--track-title); }

p { margin: 0 0 var(--space-sm); max-width: var(--measure); text-wrap: pretty; }
.lead { font-size: var(--text-lead); line-height: var(--lh-lead); max-width: var(--measure-tight); color: var(--color-muted); }

a { color: inherit; text-underline-offset: 0.18em; }
img, video, svg, canvas { display: block; max-width: 100%; height: auto; }
img { background: var(--color-surface); } /* пока грузится — не белая дыра */

/* Цифры в таблицах и метриках не должны «прыгать» при обновлении. */
.num, table, time, [data-count] { font-variant-numeric: tabular-nums; }

/* ============ РАСКЛАДКА ============ */
.page { width: min(100% - var(--gutter) * 2, var(--page-max)); margin-inline: auto; }
.content { width: min(100%, var(--content-max)); }
.stack > * + * { margin-block-start: var(--stack-gap, var(--space-md)); }

/* Полноэкранная полоса внутри ограниченного контейнера — без ломки скролла. */
.bleed {
  width: 100vw;
  margin-inline: calc(50% - 50vw);
  max-width: none;
}

/* Сетка, которая по умолчанию НЕ ровная: главный элемент шире прочих.
   Ровные ряды одинаковых карточек — то, за что аудит снимает 12 баллов. */
.grid-editorial {
  display: grid;
  gap: var(--space-lg) var(--gutter);
  grid-template-columns: repeat(12, 1fr);
}
.grid-editorial > .col-wide { grid-column: span 7; }
.grid-editorial > .col-narrow { grid-column: span 5; }
.grid-editorial > .col-full { grid-column: 1 / -1; }
.grid-editorial > .col-offset { grid-column: 3 / span 8; }
@media (max-width: 860px) {
  .grid-editorial > * { grid-column: 1 / -1 !important; }
}

/* Скрыто визуально, но доступно скринридеру. */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip-path: inset(50%); white-space: nowrap; border: 0;
}
