/* СГЕНЕРИРОВАНО sitegen.tokens.fixed_css() — не править руками.
 * Правки затираются следующей сборкой: python site/build.py
 * Источник: src/sitegen/tokens.py. Расхождение роняет
 * tests/site/test_tokens_borrowed.py. */

:root {
  --space-1: 4px;
  --space-2: 6px;
  --space-3: 10px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 36px;
  --space-7: 54px;
  --font-size-sm: 14px;
  --font-size-base: 16px;
  --font-size-lg: 20px;
  --font-size-xl: 28px;
  --font-size-display: 40px;
  --leading-tight: 1.15;
  --leading-normal: 1.5;
  --weight-regular: 400;
  --weight-medium: 500;
  --weight-bold: 700;
  --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial,
    sans-serif;
  --radius-sm: 6px;
  --radius-md: 10px;
  --radius-lg: 16px;
  --radius-xl: 28px;
  --shadow-sm: 0 1px 2px rgba(15, 15, 15, 0.08), 0 1px 1px rgba(15, 15, 15, 0.04);
  --shadow-md: 0 4px 10px rgba(15, 15, 15, 0.10), 0 2px 4px rgba(15, 15, 15, 0.06);
  --shadow-lg: 0 16px 32px rgba(15, 15, 15, 0.14), 0 4px 10px rgba(15, 15, 15, 0.08);
  --duration-fast: 120ms;
  --duration-base: 200ms;
  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);
  --ease-out: cubic-bezier(0, 0, 0.2, 1);
}

*, *::before, *::after {
  box-sizing: border-box;
}

body {
  margin: 0;
  font-family: var(--font-sans);
  font-size: var(--font-size-base);
  line-height: var(--leading-normal);
  font-weight: var(--weight-regular);
  color: var(--color-fg);
  background: var(--color-bg);
  -webkit-font-smoothing: antialiased;
}

h1, h2, h3 {
  font-weight: var(--weight-bold);
  line-height: var(--leading-tight);
  text-wrap: balance;
}

h1 {
  font-size: var(--font-size-xl);
}

h2 {
  font-size: var(--font-size-lg);
}

h3 {
  font-size: var(--font-size-base);
}

p {
  text-wrap: pretty;
}

small {
  font-size: var(--font-size-sm);
}

/* Цены, рейтинги, счётчики (§6.1) — цифры не должны "прыгать" по ширине
   при смене значения между карточками одного ряда. */
.tabular-nums {
  font-variant-numeric: tabular-nums;
}

/* Крупная сигнатурная цифра (§6.3) — например, рейтинг на первом экране
   блока репутации. */
.font-display {
  font-size: var(--font-size-display);
  line-height: var(--leading-tight);
  font-weight: var(--weight-bold);
}

img {
  outline: 1px solid rgba(0, 0, 0, .1);
  outline-offset: -1px;
}

/* Состояния интерактивных элементов (2.4.7, §7.4). Свойства перечислены
   поимённо через transition-property — нигде в фиксированном слое нет
   значения "all" у перехода: оно анимировало бы и то, что меняться не
   должно. */
a, button, [role="button"], .btn {
  color: var(--color-accent);
  transition-property: color, background-color, border-color, box-shadow, opacity, transform;
  transition-duration: var(--duration-fast);
  transition-timing-function: var(--ease-standard);
}

a:hover, button:hover, [role="button"]:hover, .btn:hover {
  opacity: 0.85;
}

a:active, button:active, [role="button"]:active, .btn:active {
  transform: scale(0.98);
  transition-timing-function: var(--ease-out);
}

a:focus-visible, button:focus-visible, [role="button"]:focus-visible, .btn:focus-visible {
  outline: 3px solid var(--color-accent);
  outline-offset: 2px;
}

/* Зона нажатия >= 44x44 px (2.5.5) через псевдоэлемент — расширяет
   КЛИКАБЕЛЬНУЮ область, не визуальный размер элемента (маленькая иконка
   остаётся маленькой на вид). `::after` центрируется на элементе через
   translate(-50%, -50%): для любого элемента визуально МЕНЬШЕ 44px
   `min-width`/`min-height` поднимают его ::after ровно до 44x44,
   независимо от того, насколько мал сам элемент.

   ПРАВИЛЬНАЯ АРИФМЕТИКА НЕПЕРЕСЕЧЕНИЯ (предыдущая версия этого
   комментария называла `--space-5`/24px достаточным зазором — это было
   неверно, исправлено по ревью). Две зоны нажатия по 44px пересекаются,
   когда расстояние между их ЦЕНТРАМИ меньше суммы половин, то есть
   меньше 22+22=44px. При типичной раскладке с зазором `gap` между
   видимыми краями соседей центр-расстояние = gap + (s1+s2)/2, откуда
   условие непересечения — `gap >= 44px - меньший из двух видимых
   размеров` (взят МЕНЬШИЙ, а не средний размер — заведомо консервативная
   оценка, безопасная для любой пары, не только для равных). Для пары
   иконок по 16px это требует `gap >= 28px` — больше, чем `--space-5`
   (24px), и именно поэтому прежняя формулировка была неверна.

   НИ ОДИН ТОКЕН МЕНЬШЕ 44px не гарантирует непересечение универсально —
   для достаточно мелкой иконки формула всегда потребует зазор, которого
   у мелкого токена просто нет. `--space-7` (54px, см. :51) — единственная
   ступень шкалы, которая гарантирует зазор при ЛЮБОМ видимом размере
   соседей вплоть до вырожденного нуля (44 - 0 = 44 <= 54, с запасом
   10px); `--space-6` (36px) этому не удовлетворяет даже в лучшем случае
   (36 < 44). Задача 8 обязана разносить соседние `.hit-area` минимум на
   `--space-7` по видимым краям (`gap: var(--space-7)` или эквивалент),
   если хотя бы один из элементов пары визуально меньше 44px; для пары
   элементов, уже больших 44px, вопрос не возникает — расширения не
   происходит вовсе. */
.hit-area {
  position: relative;
}

.hit-area::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: max(44px, 100%);
  height: max(44px, 100%);
  min-width: 44px;
  min-height: 44px;
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { transition-duration: 0.01ms !important; }
}

