/* ==========================================================================
   TOKENS — copied verbatim from 04-visual-system.md and 05-motion.md
   (css/tokens.css is generated by src-final/build.mjs from the spec blocks;
   do not edit by hand, do not rename or round values. Component styles: style.css)
   ========================================================================== */

:root {
  /* ============ ЦВЕТ: фон и поверхности ============ */
  --ink:            #0A0C10;  /* фон страницы (войд) */
  --surface:        #14171D;  /* поверхность 1 — карточки, панели */
  --elevated:       #1C2028;  /* поверхность 2 — приподнятое, hover-строки */
  --hairline:       #2A2F38;  /* границы, разделители, статичные ленты */
  --hairline-soft:  #21252D;  /* ещё тише — внутренние делители таблиц */

  /* ============ ЦВЕТ: текст ============ */
  --text-hi:        #EAEDF2;  /* основной */
  --text-mid:       #9AA3B2;  /* приглушённый (вторичный текст, моно-лейблы) */
  --text-low:       #5E6675;  /* декоративный / disabled / крупная мета ТОЛЬКО */
  --text-inv:       #0A0C10;  /* инверсный: текст на amber-CTA и на светлых плашках */

  /* ============ ЦВЕТ: семантика CI (ДАННЫЕ, не украшение) ============ */
  --pass:           #3DE08A;  /* CI pass — зелёный прогон */
  --fail:           #FF5A54;  /* CI fail — красный прогон */

  /* ============ ЦВЕТ: FlakeKill (единственный брендовый акцент) ============ */
  --amber:          #F5A623;  /* карантин + primary CTA (метка вмешательства) */
  --amber-hover:    #FFB53D;  /* CTA hover */
  --amber-active:   #D98F17;  /* CTA active/pressed */

  /* ============ ЦВЕТ: состояния формы (Connect) ============ */
  --state-error:    #FF5A54;  /* = fail (ошибка авторизации) */
  --state-error-bg: rgba(255,90,84,0.10);
  --state-warn:     #F5A623;  /* = amber (внимание/лимит); не путать с CTA-ролью визуально */
  --state-ok:       #3DE08A;  /* = pass (успех выражается сменой экрана, не зелёной кнопкой) */

  /* ============ RUN-CELL: заливки/края по состоянию ============ */
  /* Регистр АТМОСФЕРЫ, ленты-разделители (на --field-mid-opacity). Поля (hero, фон финальной CTA, полоса Connect) окрашены иначе: --pass/--fail на --field-body с непрозрачностью слоя (Спецификация медиа, п. 2) */
  --cell-pass-fill: rgba(61,224,138,0.16);
  --cell-pass-edge: rgba(61,224,138,0.55);
  --cell-fail-fill: rgba(255,90,84,0.18);
  --cell-fail-edge: rgba(255,90,84,0.60);
  /* Регистр ДАННЫХ (объекты продукта): лента карточки hero, строки демо, история дашборда, ленты шагов How it works */
  --cell-pass-data:      rgba(61,224,138,0.48);  /* ≥ 3:1 к ink / surface / elevated */
  --cell-pass-data-edge: rgba(61,224,138,0.80);
  --cell-fail-data:      rgba(255,90,84,0.68);   /* ≥ 3:1 к ink / surface / elevated */
  --cell-fail-data-edge: rgba(255,90,84,0.80);
  /* Текущий (последний) прогон строки данных — в обоих регистрах один */
  --cell-pass-lit:  #3DE08A;
  --cell-fail-lit:  #FF5A54;
  --cell-quar-fill: rgba(245,166,35,0.18);
  --cell-quar-edge: rgba(245,166,35,0.60); /* также край изолированного прогона (регистр «после») */
  --cell-empty-edge: #2A2F38;             /* пустой amber-слот: пунктир hairline */

  /* ============ ГЛУБИНА поля (слоистость, не плоское мигание) ============ */
  --field-far-opacity:  0.20;   /* дальний слой ячеек */
  --field-mid-opacity:  0.48;   /* средний слой; до него поднимается вспыхнувшая ячейка mid */
  --field-near-opacity: 1.00;   /* передний слой (карточка/демо) */
  --field-rest:         0.5;    /* доля непрозрачности слоя в покое: far 0.10, mid 0.24 */
  --field-body:         #0E1014; /* тело ячейки поля: ink на 13% к hairline */
  --field-far-cell:     clamp(16px, 2.1vw, 24px);  /* ячейка far-слоя */
  --field-mid-cell:     calc(1.5 * var(--field-far-cell) + 2px);  /* 26–38: шаг mid = 1.5 × шаг far; крупнее far = ближе */
  --field-mid-step:     calc(var(--field-mid-cell) + var(--cell-gap));  /* шаг решётки mid: 38.25 на 1024, 42 с 1143 */
  --field-mid-shift:    calc(var(--field-mid-step) / 2);  /* сдвиг решётки mid по x и y: зазоры слоёв не совпадают */
  --field-far-saturate: 0.55;   /* far приглушён по насыщенности на 45% */
  --field-band-h:       clamp(96px, 30vw, 148px);  /* высота полосы поля hero на <1024 */
  --glow-pass:  0 0 14px -3px rgba(61,224,138,0.55);
  --glow-fail:  0 0 14px -3px rgba(255,90,84,0.55);
  --glow-amber: 0 0 18px -2px rgba(245,166,35,0.50);
  --vignette:   radial-gradient(55% 75% at 50% 42%,
                  transparent 0%, transparent 45%, rgba(10,12,16,0.88) 100%);  /* радиусы: 55% ширины, 75% высоты */

  /* ============ ТИПОГРАФИКА: семейства ============ */
  --font-display: "Clash Display", "Space Grotesk", "Helvetica Neue", Arial, sans-serif;
  --font-body:    "Geist Sans", "Helvetica Neue", Arial, sans-serif;
  --font-mono:    "JetBrains Mono", ui-monospace, "SFMono-Regular", Menlo, monospace;

  /* веса */
  --fw-body:      400;
  --fw-body-med:  500;
  --fw-body-semi: 600;
  --fw-mono:      400;
  --fw-mono-med:  500;
  --fw-mono-bold: 700;
  --fw-display:   600;   /* Clash Display Semibold — базовый дисплей */
  --fw-display-b: 700;   /* Bold — hero H1 */

  /* ============ ТИПОГРАФИКА: шкала (clamp mobile→desktop) ============ */
  /* формат: размер / line-height / letter-spacing */
  --fs-display: clamp(3rem, 0.4rem + 8.4vw, 6.5rem);    /* 48 → 104  hero (92 на 1024, 104 с ~1162) */
  --lh-display: 0.96;   --ls-display: -0.02em;

  --fs-h2:      clamp(1.875rem, 0.9rem + 3.25vw, 3.5rem);/* 30 → 56   секции (30 до 480, 35 на 640, 48 на 1024, 56 с 1280) */
  --lh-h2:      1.02;   --ls-h2: -0.015em;

  --ws-display: 0.1em;  /* word-spacing H1 и H2: пробел не съедается отрицательным трекингом */
  --ls-acronym: 0.02em; /* `CI` в H1/H2 — без отрицательного трекинга */

  --fs-h3:      clamp(1.5rem, 1.25rem + 1.1vw, 1.75rem);/* 24 → 28 */
  --lh-h3:      1.14;   --ls-h3: -0.01em;

  --fs-h4:      clamp(1.25rem, 1.1rem + 0.6vw, 1.375rem);/* 20 → 22 */
  --lh-h4:      1.22;   --ls-h4: -0.005em;

  --fs-body-lg: 1.1875rem;  --lh-body-lg: 1.55; --ls-body-lg: 0;   /* 19  лид */
  --fs-body:    1.0625rem;  --lh-body: 1.6;     --ls-body: 0;      /* 17  корпус */
  --fs-small:   0.875rem;   --lh-small: 1.5;    --ls-small: 0;     /* 14 */

  --fs-mono:    0.9375rem;  --lh-mono: 1.5;     --ls-mono: 0;      /* 15  данные */
  --fs-mono-sm: 0.8125rem;  --lh-mono-sm: 1.45; --ls-mono-sm: 0.01em; /* 13 */
  --fs-label:   0.75rem;    --lh-label: 1.3;    --ls-label: 0.08em;/* 12  UPPERCASE */

  /* ============ ПРОСТРАНСТВО (одна система, 4px-база) ============ */
  --space-1: 0.25rem;   /* 4  */
  --space-2: 0.5rem;    /* 8  */
  --space-3: 0.75rem;   /* 12 */
  --space-4: 1rem;      /* 16 */
  --space-5: 1.5rem;    /* 24  = базовая run-cell */
  --space-6: 2rem;      /* 32 */
  --space-7: 3rem;      /* 48 */
  --space-8: 4rem;      /* 64  = поле desktop */
  --space-9: 6rem;      /* 96 */
  --space-10: 8rem;     /* 128 */
  --space-11: 10rem;    /* 160 */

  /* вертикальный ритм секций (край→край блока) */
  --section-y: clamp(4rem, 2rem + 6vw, 10rem);   /* 64 → 160 */

  /* ============ RUN-CELL модуль ============ */
  --cell-size: 1.5rem;   /* 24 desktop (переопределяется на mobile → 16) */
  --cell-gap:  0.25rem;  /* 4  зазор между ячейками */
  --cell-radius: 2px;

  /* ============ LAYOUT ============ */
  --content-max: 1280px;
  --measure:     68ch;   /* максимальная ширина колонки текста */
  --pad-inline:  clamp(1.25rem, 0.5rem + 3.5vw, 4rem);  /* 20 → 64 */
  --grid-gutter: clamp(1rem, 0.5rem + 1.5vw, 1.5rem);   /* 16 → 24 */

  /* ============ РАДИУСЫ ============ */
  --radius-cell:   2px;
  --radius-button: 6px;
  --radius-card:   8px;
  --radius-panel:  10px;

  /* ============ ГРАНИЦЫ ============ */
  --border-hair:  1px solid var(--hairline);
  --border-soft:  1px solid var(--hairline-soft);
  --border-dash:  1px dashed var(--cell-empty-edge);

  /* ============ ТЕНИ (минимальны: глубина = elevation + hairline, не drop-shadow) ============ */
  --shadow-none:  none;
  --shadow-card:  0 1px 0 0 rgba(0,0,0,0.4), 0 8px 24px -12px rgba(0,0,0,0.6);
  --shadow-lift:  0 12px 40px -16px rgba(0,0,0,0.7);

  /* ============ FOCUS (проектируется явно) ============ */
  --focus-ring:      var(--amber);      /* кольцо на тёмных/нейтральных элементах */
  --focus-on-amber:  var(--text-hi);    /* кольцо на amber-плашке (amber на amber невидим) */
  --focus-width:     2px;
  --focus-offset:    2px;

  /* ============ Z-ИНДЕКСЫ ============ */
  --z-base:    0;
  --z-field:   1;    /* фоновое поле под контентом */
  --z-content: 2;
  --z-sticky:  100;  /* мобильный липкий CTA-бар */
  --z-header:  200;
  --z-menu:    300;  /* мобильное меню */
  --z-tooltip: 500;  /* run-cell tooltip */

  /* ============ ДЛИТЕЛЬНОСТИ (заглушки; реальный тайминг — у моушен-дизайнера) ============ */
  --dur-fast:  120ms;
  --dur-base:  200ms;
  --dur-slow:  360ms;
  --ease-std:  cubic-bezier(0.2, 0, 0, 1);
  --ease-out:  cubic-bezier(0.16, 1, 0.3, 1);
}

/* Run-cell на мобильном: база 16px */
@media (max-width: 639px) {
  :root { --cell-size: 1rem; }  /* 16 */
}

/* Reduced motion: мерцание стынет, паттерн держится статикой (см. Live Demo) */
@media (prefers-reduced-motion: reduce) {
  :root { --dur-fast: 0ms; --dur-base: 0ms; --dur-slow: 0ms; }
}

/* ==========================================================================
   MOTION TOKENS — copied verbatim from 05-motion.md
   ========================================================================== */

:root {
  /* ============ ДЛИТЕЛЬНОСТИ ============ */
  --motion-micro:   120ms;  /* = --dur-fast. Hover, focus, active, tooltip */
  --motion-short:   200ms;  /* = --dur-base. Локальные смены состояния:
                                аккордеон, hover-строка, cross-fade ячейки */
  --motion-medium:  380ms;  /* появление секции/шага/панели одним блоком */
  --motion-long:    560ms;  /* ТОЛЬКО экстракция карантина — единственное
                                движение, заслуживающее паузы на себя;
                                короче — жест теряется, не читается как акт */

  /* ============ EASING ============ */
  --ease-exit:    cubic-bezier(0.4, 0, 1, 1);    /* уход — ускоряется */
  --ease-enter:   cubic-bezier(0.16, 1, 0.3, 1); /* = --ease-out. приход —
                                                     замедляется к концу */
  --ease-inout:   cubic-bezier(0.2, 0, 0, 1);    /* = --ease-std. смена
                                                     состояния на месте */
  --ease-extract: cubic-bezier(0.65, 0, 0.35, 1); /* ФИРМЕННАЯ. механический,
                                безоткатный выброс — для экстракции карантина
                                и её эха в шаге 3. Не bounce, не overshoot:
                                характер бренда — точный, не игривый */
  --ease-afterglow: cubic-bezier(0.33, 0, 0.67, 1); /* ТОЛЬКО послесвечение
                                mid-слоя поля hero. Симметричная: яркость
                                держится, потом уходит и тает. С --ease-enter
                                на затухании «светящейся» (≥5% пика) части
                                остаётся 42% длительности и порог доли вспышек
                                не держится — расчёт в «Поле hero (#1)» */

  /* ============ СТАГГЕР ============ */
  --stagger-cell: 60ms;   /* между ячейками при последовательном
                              «сканировании» (Analyzing, Authorize) */
  --stagger-step: 80ms;   /* между шагами How It Works при появлении */
  --delay-none:   0ms;    /* дефолт — задержки нет, если не указано иное */

  /* ============ ЭКСТРАКЦИЯ КАРАНТИНА (#9) ============
     Длительность и кривая полёта — токены 05 (норма 02/04: в px не задаются).
     Расстояние не токен: его считает скрипт из геометрии (FLIP). */
  --extract-fly:          var(--motion-long);   /* 560ms: полёт ряда лжеца */
  --extract-fly-ease:     var(--ease-extract);
  --extract-trace:        var(--motion-short);  /* 200ms: след «изъят» на месте */
  --extract-glow-delay:   calc(var(--motion-long) - var(--motion-short));
                                                /* 360ms: amber-свечение в
                                                   полосе — на последних 200ms
                                                   полёта */
  --extract-result-delay: var(--motion-long);   /* 560ms: GREEN — после
                                                   конца полёта */

  /* ============ ПОЛЕ HERO (#1, canvas 2D) ============
     Единственный источник чисел. field.js читает длительности отсюда
     (getComputedStyle), кривые держит константами, совпадающими с токенами
     выше (расхождение — дефект). */
  --field-tick-min:    1200ms;  /* интервал между сменами состояния живой */
  --field-tick-max:    2400ms;  /* ячейки; значение на ячейку — по сиду */
  --field-fill-fade:   var(--motion-short);  /* 200ms: кроссфейд заливки */
  --field-attack:      60ms;    /* mid: рост свечения 0→1 */
  --field-peak:        80ms;    /* mid: свечение держится на максимуме */
  --field-decay-min:   600ms;   /* mid: затухание свечения; значение */
  --field-decay-max:   900ms;   /* на ячейку — по сиду */
  --field-reveal:      var(--motion-medium); /* 380ms: проявление canvas */
}

/* ==========================================================================
   REDUCED MOTION — copied verbatim from 05-motion.md
   ========================================================================== */

@media (prefers-reduced-motion: reduce) {
  :root {
    --motion-micro:  1ms;
    --motion-short:  1ms;
    --motion-medium: 1ms;
    --motion-long:   1ms;
  }

  /* Глобальный рубильник: любые keyframe-циклы и переходы схлопываются */
  *,
  *::before,
  *::after {
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 1ms !important;
    scroll-behavior: auto !important;
  }

  /* Перемещения и параллакс — отключаются полностью:
     transform больше не участвует ни в одном переходе движения */
  .field-layer,          /* #1 постер поля hero (DOM) */
  .cell-lit,              /* #2 текущий прогон */
  .demo-grid__row,        /* #7, #9 ряд лжеца и мерцание */
  .quarantine-track,      /* #9 */
  .demo-row__trace,       /* #9 след «изъят» */
  .echo-cell,             /* #12 эхо шага 3 */
  .step-reveal,           /* #11 */
  .dashboard-panel,       /* #15 */
  .fix-first-flag,        /* #17 */
  .plan-card,             /* #18 */
  .provider-card__radio,  /* #20 */
  .nav-underline,         /* #24 */
  .accordion-glyph        /* #14 */
  {
    transform: none !important;
    transition-property: opacity !important;
    transition-duration: 80ms !important; /* «мгновенное появление» ≤100ms */
  }

  /* Автоплей и бесконечные циклы — останавливаются на статичном,
     но осмысленном кадре (не пустом) */
  .field-layer,           /* #1 постер поля hero (DOM) */
  .cell-lit,
  .demo-grid,
  .authorize-progress /* #21 */
  {
    animation-play-state: paused !important;
  }

  /* #1 Поле hero: постер с выключенным мерцанием — единственное состояние.
     Canvas скрыт и постер показан на уровне CSS, не дожидаясь скрипта: это же и «смена
     предпочтения на лету» (JS в это время останавливает цикл).
     Модуль при reduce не загружается вовсе (условие в загрузчике). */
  .hero-field > canvas {
    display: none !important;
  }
  .hero-field[data-poster="off"] .field-layer {
    visibility: visible !important;
  }
  .hero-field .field-layer .cell {
    animation: none !important;   /* постер: мерцание выключено */
  }

  /* Контент, появлявшийся по скроллу, — виден сразу */
  [data-reveal],
  .step-reveal,
  .dashboard-panel,
  .fix-first-flag {
    opacity: 1 !important;
    transform: none !important;
  }

  /* Экстракция карантина (#9): мгновенная смена состояния, без «перелёта».
     Клонов полёта нет; ряд лжеца сразу в amber-зоне, на его месте «изъят»,
     оставшиеся строки `● PASS` и неподвижны, строка результата GREEN */
  .demo-fly {
    display: none !important;
  }
  .quarantine-track[data-state="extracted"],
  .demo-row__trace,
  .quarantine-glow,          /* свечение и сплошная рамка зоны */
  .quarantine-final,
  .ghost-cover,              /* призрак зоны: сразу в конечном состоянии */
  .ghost-keep,
  .demo-act__amber,          /* кнопка Quarantined — мгновенно */
  .demo-result__green {
    transition: none !important;
  }

  /* #5 Липкая панель: показ/скрытие по зонам остаётся, но без анимации.
     transform не используется: скрытое состояние держат opacity и visibility,
     переключаются мгновенно (без отложенного visibility) */
  .cta-sticky-bar,
  .site-header__cta {        /* CTA шапки на mobile: переключается в том же кадре, без задержки возврата */
    transform: none !important;
    transition: none !important;
  }

  /* #25: развязка на <640 при reduce — scrollIntoView({behavior:'auto'}) в
     скрипте (CSS scroll-behavior: auto выше); плавной прокрутки нет */

  /* Analyzing/Authorize: прогресс остаётся видимым текстом-счётчиком,
     ячейки переключаются без кроссфейда */
  .scan-cell {
    transition: none !important;
  }

  /* Обратная связь на действие остаётся, но без движения —
     hover/focus/active меняют только цвет/границу мгновенно */
  button, a, [role="button"], input[type="radio"] {
    transition-property: background-color, border-color, color, opacity !important;
    transition-duration: 80ms !important;
  }
}
