/* ============================================================================
   Óleńsiz — design tokens
   Философия: Swiss / International Typographic.

   Итерация 3:
   — единая шкала отступов 4/8/12/16/24/32/48/64 и ничего между ними;
   — сетка 12 колонок с одним жёлобом, экраны собираются по ней, а не потоком;
   — фон под музыку стал живым: к цвету обложки добавились медленное течение
     пятен и реакция на бит (см. src/pulse.js).

   Остаётся из итерации 2: только тёмная тема, только десктоп (база 1440×900),
   размеры от высоты вьюпорта — ни один экран не скроллится.

   Обложки альбомов — единственное крупное цветовое пятно, поэтому нейтральная
   шкала намеренно бесцветна.
   ========================================================================= */

:root {
  color-scheme: dark;

  /* --- Нейтральная шкала: холодный slate --------------------------------- */
  --n-000: #000000;
  --n-050: #08090a;
  --n-100: #0e1012;
  --n-150: #16181c;
  --n-200: #1e2126;
  --n-300: #2b2f36;
  --n-400: #454b55;
  --n-500: #6b727d;
  --n-600: #949aa4;
  --n-700: #c2c7ce;
  --n-800: #e4e7ea;
  --n-900: #f6f7f8;
  --n-999: #ffffff;

  /* Единственный акцент. Кислотный лайм читается как сигнал, а не как бренд,
     и почти не встречается на обложках — потому с ними не спорит. */
  --a-400: #b8e600;
  --a-500: #ccff00;
  --a-600: #d9ff4d;

  /* --- Семантика: компоненты используют ТОЛЬКО это ----------------------- */
  --color-bg-primary: var(--n-050);
  --color-bg-secondary: var(--n-100);
  --color-bg-tertiary: var(--n-150);
  --color-bg-elevated: var(--n-200);
  --color-bg-inverse: var(--n-900);

  --color-text-primary: var(--n-900);
  --color-text-secondary: var(--n-600);
  --color-text-tertiary: var(--n-500);
  --color-text-inverse: var(--n-050);
  --color-text-link: var(--a-500);

  /* border-primary рисует форму инпутов, кнопок и списка результатов —
     обязан брать 3:1 к фону (WCAG 1.4.11). border-secondary — только
     декоративные линейки, к ним требования нет. */
  --color-border-primary: #646b75;
  --color-border-secondary: var(--n-300);
  --color-border-strong: var(--n-600);
  --color-border-focus: var(--a-500);

  --color-accent-primary: var(--a-500);
  --color-accent-primary-hover: var(--a-600);
  --color-accent-primary-active: var(--a-400);
  --color-accent-on: var(--n-050);
  --color-accent-secondary: var(--n-800);

  --color-status-success: #4ade80;
  --color-status-warning: #fbbf24;
  --color-status-error: #f87171;
  --color-status-error-strong: #ef4444;
  --color-status-info: var(--n-600);

  --color-surface-overlay: rgba(0, 0, 0, 0.78);

  /* --- Живой фон под музыку -----------------------------------------------
     Значения перезаписываются из JS при проигрывании трека.
     По умолчанию нейтральны — фон не виден. */
  --song-c1: transparent;
  --song-c2: transparent;
  --song-c3: transparent;
  --song-energy: 0;      /* 0..1, общая энергия — для совместимости */
  --song-beat: 0;        /* 0..1, удар: им загорается сам фон */
  --song-voice: 0;       /* 0..1, верхние частоты: ими живут цветные пятна */
  --song-s1: 1;          /* размеры пятен по доле цвета на обложке */
  --song-s2: 1;
  --song-s3: 1;
  --song-opacity: 0;     /* общая видимость слоя */

  /* --- Спейсинг: ОДНА шкала, шаг из ряда 4/8/12/16/24/32/48/64 ------------
     Промежуточных значений нет. Если нужного нет в шкале — значит, нужен
     не новый отступ, а другая композиция. */
  --s-0: 0;
  --s-4: 4px;
  --s-8: 8px;
  --s-12: 12px;
  --s-16: 16px;
  --s-24: 24px;
  --s-32: 32px;
  --s-48: 48px;
  --s-64: 64px;

  /* Вертикальный ритм, сжимающийся вместе с вьюпортом: главный инструмент
     против скролла. Каждое значение — интервал между двумя ступенями шкалы. */
  --gap-v-sm: clamp(8px, 1.2vh, 12px);
  --gap-v-md: clamp(12px, 2.2vh, 24px);
  --gap-v-lg: clamp(16px, 3.4vh, 48px);
  --pad-shell-v: clamp(12px, 2vh, 24px);
  --pad-shell-h: clamp(24px, 3vw, 48px);

  /* --- Сетка ---------------------------------------------------------------
     12 колонок, один жёлоб. Все экраны раскладываются по ней; произвольных
     ширин в компонентах нет. */
  --grid-columns: 12;
  --grid-gutter: clamp(16px, 2vw, 32px);
  --max-width-page: 1400px;
  --max-width-content: 34rem;
  /* Колонка центрального экрана раунда: 7 из 12 колонок при базе 1440. */
  --col-round: min(760px, 100%);
  --col-answer: min(620px, 100%);

  /* --- Типографика --------------------------------------------------------
     Веб-шрифт не грузим: FOIT на первом экране игры дороже идеальной буквы
     «Ә», а системные стеки покрывают казахскую кириллицу везде. */
  --font-family-display: "Helvetica Neue", Inter, "Segoe UI", system-ui,
    -apple-system, "Noto Sans", Arial, sans-serif;
  --font-family-body: var(--font-family-display);
  --font-family-mono: ui-monospace, "SF Mono", "JetBrains Mono", Menlo,
    Consolas, monospace;

  --font-size-xs: 0.6875rem;   /* 11 — микро-лейблы капсом */
  --font-size-sm: 0.8125rem;   /* 13 */
  --font-size-base: 0.9375rem; /* 15 */
  --font-size-md: 1.0625rem;   /* 17 */
  --font-size-lg: clamp(1.05rem, 2.2vh, 1.375rem);
  --font-size-xl: clamp(1.3rem, 3vh, 1.875rem);
  --font-size-2xl: clamp(1.7rem, 4.4vh, 2.75rem);
  --font-size-3xl: clamp(2.2rem, 6.4vh, 4rem);
  --font-size-4xl: clamp(2.8rem, 9vh, 6.5rem);

  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;

  --line-height-tight: 1.02;
  --line-height-snug: 1.2;
  --line-height-normal: 1.45;
  --line-height-relaxed: 1.6;

  --letter-spacing-tighter: -0.04em;
  --letter-spacing-tight: -0.02em;
  --letter-spacing-normal: 0;
  --letter-spacing-wide: 0.08em;
  --letter-spacing-wider: 0.18em;

  /* Swiss: скругления почти нулевые. 2px — уступка рендерингу, не украшение. */
  --border-radius-sm: 0;
  --border-radius-md: 2px;
  --border-radius-lg: 4px;
  --border-radius-full: 999px;

  --border-width-hair: 1px;
  --border-width-rule: 2px;

  --shadow-none: none;
  --shadow-sheet: 0 24px 80px rgba(0, 0, 0, 0.7);
  /* Единственная «объёмная» тень в проекте — под поднятой карточкой финала.
     Там она несёт смысл: показывает, какая карточка выбрана. */
  --shadow-card-lift: 0 32px 64px -12px rgba(0, 0, 0, 0.8),
    0 0 0 1px rgba(255, 255, 255, 0.06);

  /* --- Motion -------------------------------------------------------------- */
  --duration-instant: 60ms;
  --duration-fast: 150ms;
  --duration-normal: 240ms;
  --duration-slow: 400ms;
  --duration-slower: 700ms;

  --easing-default: cubic-bezier(0.4, 0, 0.2, 1);
  --easing-in: cubic-bezier(0.4, 0, 1, 1);
  --easing-out: cubic-bezier(0, 0, 0.2, 1);
  --easing-spring: cubic-bezier(0.16, 1.32, 0.42, 1);

  /* --- Компонентные токены ------------------------------------------------
     Все завязаны на высоту вьюпорта: это и есть механизм «ноль скроллинга». */
  --control-height: clamp(38px, 5vh, 48px);
  --play-button-size: clamp(96px, 18vh, 160px);
  --card-art-radius: var(--border-radius-md);
  --rail-thickness: 3px;
  --final-card-width: clamp(120px, 13vw, 190px);
  --reveal-art-size: clamp(150px, 30vh, 280px);

  /* --- Пороги адаптивной деградации по высоте (см. src/fit.js) ------------
     Не media query по ширине: прятать надо при нехватке ВЫСОТЫ, в том числе
     когда пользователь зумит страницу. */
  --h-threshold-1: 820px;  /* прячем декоративное и подписи-пояснения */
  --h-threshold-2: 720px;  /* прячем счётчик уровней в шапке */
  --h-threshold-3: 640px;  /* прячем подписи под иконками */
  --h-threshold-4: 560px;  /* прячем второй лидерборд */
}

/* ---------------------------------------------------------------------------
   Уважение к prefers-reduced-motion объявлено на уровне токенов, чтобы ни один
   компонент не мог случайно проигнорировать настройку.
   ------------------------------------------------------------------------ */
@media (prefers-reduced-motion: reduce) {
  :root {
    --duration-instant: 1ms;
    --duration-fast: 1ms;
    --duration-normal: 1ms;
    --duration-slow: 1ms;
    --duration-slower: 1ms;
    --easing-spring: linear;
  }
}
