/* ============================================================
   Fayro — сайт. Палитра владельца «Hybrid Champagne Dark»
   (2026-07-10): единственная тема — тёмная; светлой на сайте нет.
   Золото ≤ 10–12% интерфейса, без чистого чёрного на больших
   поверхностях, молочно-белый текст, спокойный премиум.
   Шрифт: Cera Pro — боевые файлы, лицензия TypeMates #260404
   (Web 10k pageviews/мес; статические 400/500/700, вес 600 в
   правилах ниже браузер отдаёт ближайшему — Bold 700).
   Montserrat — фолбэк.
   ============================================================ */

@font-face {
  font-family: "Cera Pro";
  src: url("fonts/cera-pro/Cera-Pro-Regular.woff2") format("woff2"),
       url("fonts/cera-pro/Cera-Pro-Regular.woff") format("woff");
  font-weight: 400;
  font-display: swap;
}

@font-face {
  font-family: "Cera Pro";
  src: url("fonts/cera-pro/Cera-Pro-Medium.woff2") format("woff2"),
       url("fonts/cera-pro/Cera-Pro-Medium.woff") format("woff");
  font-weight: 500;
  font-display: swap;
}

@font-face {
  font-family: "Cera Pro";
  src: url("fonts/cera-pro/Cera-Pro-Bold.woff2") format("woff2"),
       url("fonts/cera-pro/Cera-Pro-Bold.woff") format("woff");
  font-weight: 700;
  font-display: swap;
}

@font-face {
  font-family: "Montserrat";
  src: url("fonts/Montserrat-Variable.ttf") format("truetype-variations"),
       url("fonts/Montserrat-Variable.ttf") format("truetype");
  font-weight: 100 900;
  font-display: swap;
}

/* ---------- утилиты ---------- */

/* Только для скринридеров: читается вслух, но визуально скрыт и не
   влияет на раскладку (position:absolute убирает из потока и сетки). */
.sr-only {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ★ Ссылка «Перейти к содержимому» (SITE-AWARDS-1): вне экрана, пока не
   получила фокус. Первая остановка Tab на каждой странице. Стиль кнопки —
   тот же язык, что у .btn-primary, только компактнее. */
.skip-link {
  position: absolute;
  left: 16px;
  top: -100px;
  z-index: 100;
  padding: 12px 20px;
  border-radius: 12px;
  background: var(--grad-cta);
  color: var(--on-gold);
  font-size: var(--fs-sm);
  font-weight: var(--display-weight);
  text-decoration: none;
  transition: top 0.18s ease;
}

.skip-link:focus-visible { top: 12px; }

@media (prefers-reduced-motion: reduce) {
  .skip-link { transition: none; }
}

/* Спрятанный 0×0 svg с золотыми градиентами сцены «В-кино».
   Стиль перенесён из инлайна ради строгого CSP (style-src 'self'). */
.cine-defs { position: absolute; }

/* ---------- токены: Hybrid Champagne Dark ---------- */

:root {
  --bg: #080808;            /* основной фон */
  /* SITE-AWARDS-1 (2026-08-05): было #101110 — единственный фон продукта,
     который ЗЕЛЕНИЛ (G на единицу выше R и B) на золотом бренде. Приведён к
     той же тёплости, что у --surface #171716 (R=G>B): теперь лестница фонов
     08/08/08 → 17/17/16 → 23/23/22 идёт в одном направлении по цвету, а не
     виляет из зелени в тепло. Яркость сохранена (16,17,16 → 17,17,16), так
     что ни один замер контраста не сдвигается. */
  --bg-soft: #111110;       /* дополнительный фон */
  --surface: #171716;       /* карточки и поля */
  --header: #1a1a1a;        /* навигационная панель */
  --warm-backing: #38342b;  /* тёплая золотистая подложка */
  /* Дно тёплой зоны «Безопасность» и её кромка. Оба жили хардкодом в правиле
     .security (#14120e и rgba(187,152,95,0.28)); вынесены в токены слоем
     SITE-AWARDS-1 — это ЕДИНСТВЕННАЯ разделительная линия сайта (канон швов
     у .how), и у неё должно быть имя. */
  --bg-warm: #14120e;       /* дно тёплой зоны */
  --line: #3a3937;          /* обычные границы */
  /* VISUAL-POLISH-1: кромка ИНТЕРАКТИВНЫХ контролов. --line остаётся штатной
     волосяной линией декора и разделителей (24 использования, токен не тронут),
     но как ГРАНИЦА КОМПОНЕНТА он вдвое ниже порога 3.0 (WCAG 2.2 §1.4.11):
     1.74:1 к --bg, 1.64:1 к --bg-soft, 1.56:1 к --surface. #6F6B64 — ступень
     t66 общей текстовой шкалы (та же в lib/theme/app_theme.dart и
     admin/styles.css: --t65 #77736B / --t66 #6F6B64 / --t7 #605D55): самая
     ТИХАЯ ступень лестницы, которая проходит порог на всех трёх фонах сайта
     (t7 даёт 2.73:1 на --surface и не проходит). Роль отдельная от текста:
     красить рамку текстовым токеном — смешивать роли. */
  --line-control: #6f6b64;  /* границы кнопок, полей, переключателей */

  --ink: #f4f3f3;           /* основной текст (молочный) */
  --muted: #bdb5ad;         /* вторичный текст */
  /* VISUAL-POLISH-1: ВТОРАЯ ступень текстовой лестницы, которой у сайта не
     было. Лестница сайта --ink / --muted / --faint = t1 / t3 / t6 приложений;
     ступень t2 #D2CEC2 (app_theme.dart, admin/styles.css --t2) отсутствовала,
     и там, где она понадобилась, сайт изобрёл off-ladder #D0CBC6
     (.levels-note-common). Объявляем канон и применяем ровно там. Остальные
     роли --muted НЕ переводим: они держат 8.6–9.9:1 на всех фонах, порога не
     нарушают, и подъём осветлил бы весь корпус текста без выигрыша по числу. */
  --ink-2: #d2cec2;         /* вторичный текст на ступень выше (== t2) */
  /* VISUAL-POLISH-1: было #847e78 — на карточке (--surface) давало 4.47:1,
     недобор 0.03 до порога AA. Новое значение закрывает все три фона сайта. */
  --faint: #888279;         /* приглушённый текст */
  --on-gold: #11110f;       /* текст на золотых кнопках */

  /* VISUAL-POLISH-1: статусы формы партнёра были самодельными (#e8a9a0 /
     #a8c8a0) и почти совпадали с каноном приложений, но не равнялись ему —
     сведены к общим значениям (danger/okFg тёмных палитр клиента, кабинета и
     админки) и объявлены токенами, чтобы следующая правка их не расщепила. */
  --danger: #ecaba5;        /* ошибка (канон приложений) */
  --ok: #a9ddb6;            /* успех (канон приложений) */

  --gold: #c6a669;          /* основное шампанское золото */
  --gold-accent: #d3a865;   /* акцентное золото */
  --gold-light: #e9c479;    /* светлое золото */
  --gold-glint: #f2dd8d;    /* золотой блик */
  --gold-dark: #907141;     /* тёмное золото */
  --gold-border: #bb985f;   /* золотая граница */
  --gold-glow: rgba(211, 168, 101, 0.16); /* золотое свечение */

  --grad-cta: linear-gradient(135deg, #bb985f 0%, #d3a865 55%, #f2dd8d 100%);
  --grad-frame: linear-gradient(135deg, #907141 0%, #c6a669 50%, #e9c479 100%);
  /* Градиент ЗНАКА в лого (владелец 2026-07-23: знак в шапке выцветал —
     на 28px из grad-frame видна только светлая середина). Глубже и
     насыщеннее, из тех же токенов: тёмное основание, светлое — только блик. */
  --grad-mark: linear-gradient(135deg, var(--gold-dark) 0%, var(--gold-border) 38%, var(--gold-accent) 68%, var(--gold-glint) 100%);

  /* ★ ТИПОГРАФИЧЕСКАЯ ШКАЛА (SITE-AWARDS-1, 2026-08-05).
     Аудит насчитал на главной 34 живых сочетания кегль/начертание и шесть
     отдельных размеров в диапазоне 15.2–16.0 px (15.2 / 15.36 / 15.5 / 15.52 /
     15.68 / 16.0) — их не различить глазом, но каждый требовал своего правила.
     Источник дрейфа — самостоятельные clamp() с vw в каждой секции: близкие,
     но неравные значения.
     Теперь ступеней ДЕСЯТЬ, и между соседями не меньше 2 px на 1440:
        13 · 16 · 18 · 20 · 24 · 32 · 48 · 66 · 80 · 200
     Кегль H1 хиро (80) живёт своей формулой — он привязан к ширине колонки,
     см. .hero h1. Остальное набирается только этими токенами.
     Роли: xs — сноски и капс-кикеры; sm — ссылки, кнопки, весь корпус
     вторичного текста; base — основной текст; md — лид-абзацы, вопросы FAQ,
     крупные кнопки; lg — H3; xl — заголовок второго порядка; price — цена
     уровня; title — заголовки секций; mega — гигантская цифра. */
  --fs-xs: 0.8125rem;                                        /* 13 */
  --fs-sm: 1rem;                                             /* 16 */
  --fs-base: 1.125rem;                                       /* 18 */
  --fs-md: clamp(1.125rem, 0.29vw + 1.05rem, 1.25rem);       /* 18 → 20 */
  --fs-lg: clamp(1.25rem, 0.6vw + 1.05rem, 1.5rem);          /* 20 → 24 */
  --fs-xl: clamp(1.5rem, 1.1vw + 1.2rem, 2rem);              /* 24 → 32 */
  --fs-price: clamp(2.5rem, 2.2vw + 1.1rem, 3rem);           /* 40 → 48 */
  /* Опорные точки Платы (66 на 1440, 56 на 1024, 40 на телефоне) сохранены. */
  --fs-title: clamp(2rem, 3.6vw, 3.3rem);                    /* 32 → 52.8 — шкала v2 (statement) */
  --fs-mega: clamp(6rem, 15vw, 12.5rem);                     /* 96 → 200 */

  --font-display: "Cera Pro", "Montserrat", system-ui, sans-serif;
  /* «Вид шрифта» по Плате (полный аудит 2026-07-31): у них ВСЕ заголовки —
     один вес 520 и трекинг −0.0125em (замер: 80/520/−1px, 66/520/−1px,
     24/520/−0.4px). У нас заголовки шли Bold 700 с трекингом −0.02em —
     тяжелее и плотнее их при том же кегле. Cera Pro статическая: 520 у неё
     нет, ближайшее — Medium 500. Гарнитуру их взять нельзя (rothornFont —
     фирменный шрифт Платы), сводим вес, трекинг и интерлиньяж. */
  /* HEADER-V2-STYLE-3 (владелец 25.08: «тексты жирнее, чем в v2 — перенеси
     весь стиль»): дисплейный вес 500 → 400 и трекинг v2. */
  --display-weight: 400;
  --display-tracking: -0.02em;

  --radius: 14px;
  --radius-lg: 26px;
  /* Длина растворения фона на стыке секций — см. канон швов у .how.
     40 px: короче начинает читаться полосой, длиннее — «выцветает» верх
     секции и заметен на коротких блоках вроде .benefits. */
  --seam: 40px;
  /* Где останавливается прокрутка по якорю. Шапка fixed: 65 px на ≥1240 и
     59 px ниже (замер SITE-AWARDS-1), плюс 25 px воздуха — иначе заголовок
     садится вплотную к панели. Применяется ОДНИМ правилом
     `html { scroll-padding-top }`, поэтому новый якорь получает отступ сам,
     без отдельного scroll-margin (до этого слоя пять якорей из семи —
     #top, #how, #app, #security, #faq — не имели его вовсе и уезжали
     под шапку, а #levels и #partners стояли на 64 px, то есть на пиксель
     МЕНЬШЕ шапки и вовсе без воздуха). */
  --anchor-offset: 90px;
  /* Сетка по замерам bancoplata.mx (1440px): контейнер 1300, бока до 70 */
  --container: 1300px;
}

/* ---------- база ---------- */

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
  /* Единственное место, где живёт отступ якорей — см. --anchor-offset. */
  scroll-padding-top: var(--anchor-offset);
}

/* Страховка от горизонтального переполнения: любой случайно вылезший за
   вьюпорт элемент не должен ужимать страницу на iOS (shrink-to-fit) и
   давать боковой скролл. Именно clip, НЕ hidden: hidden создаёт скролл-
   контейнер и ломает position: sticky (card-rise, сцена «В-кино»). */
html { overflow-x: clip; }

body {
  margin: 0;
  font-family: "Cera Pro", "Montserrat", system-ui, -apple-system, "Segoe UI", Roboto, sans-serif;
  font-size: var(--fs-base);
  line-height: 1.6;
  color: var(--ink);
  background: var(--bg);
  /* HEADER-V2-STYLE-4 (замер 25.08): при полностью совпадающих
     шрифте/кегле/весе/трекинге боевой текст выглядел жирнее v2 — субпиксельный
     рендер macOS (auto) утолщает светлый текст на тёмном. v2 живёт на
     antialiased — переносим рендеринг, а не цифры. */
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

img, video { max-width: 100%; display: block; }

h1, h2, h3, p, ul, ol, dl, dd { margin: 0; }

/* ★ SITE-AWARDS-1 (2026-08-05): вес заголовков задан ОДИН раз. Браузерный
   дефолт для h1–h3 — bold (700), а Cera Pro статическая: 700 у неё живёт
   отдельным файлом 57 КБ. На главной весь видимый текст набран 400/500, и
   единственным носителем 700 оставался СКРЫТЫЙ sr-only заголовок «Преимущества
   клуба Fayro» — ради него грузился целый начертательный файл. Заголовки без
   собственного правила теперь берут общий вес темы. */
h1, h2, h3 { font-weight: var(--display-weight); }

::selection { background: var(--gold-glow); }

:focus-visible {
  outline: 2px solid var(--gold);
  outline-offset: 2px;
}

/* Сетка снята с bancoplata.mx замерами 2026-07-31 (запрос владельца «подгони
   как у Платы»): у них поля от края = 92 → 40 → 20 по лесенке, а на широких
   экранах поля дают ЦЕНТРИРОВАНИЕ контейнера 1300, а не его внутренний
   padding. У нас padding clamp(24,5vw,70) съедался ВНУТРИ тех же 1300 —
   на 1440 полезная ширина была 1160 против их 1300, отсюда ощущение
   «сайт обрезан по бокам». Поля теперь: ≥1440 — (100vw−1300)/2 (70 и
   больше), 1201–1439 — 92, 768–1200 — 40, <768 — 20. */
.container {
  max-width: var(--container);
  margin-inline: auto;
  padding-inline: 0;
}

/* max-width на каждой ступени поднят на величину полей: контейнер остаётся
   border-box (иначе grid-секции вылезают за вьюпорт на узких экранах —
   поймано на 390), но ограничивает КОНТЕНТ теми же 1300, а поля живут
   сверх него. Это и даёт цифры Платы: 92 / 40 / 20. */
@media (max-width: 1439px) {
  .container {
    max-width: calc(var(--container) + 184px);
    padding-inline: 92px;
  }
}

@media (max-width: 1200px) {
  .container {
    max-width: calc(var(--container) + 80px);
    padding-inline: 40px;
  }
}

@media (max-width: 767px) {
  .container {
    max-width: calc(var(--container) + 40px);
    padding-inline: 20px;
  }
}

/* Ритм секций по Плате: типовые ~96px сверху и снизу. */
section { padding-block: clamp(72px, 8vw, 96px); }

.section-title {
  font-family: var(--font-display);
  /* Та же калибровка по Плате, но плавно: их 66 на 1440 и 56 на 1024 —
     опорные точки прямой, пол 2.5rem даёт их 40 на телефоне. Прежний clamp
     был положе и проваливался до 35 уже на 768. */
  font-size: var(--fs-title);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  /* 1.1 — их интерлиньяж заголовков (72.6 при кегле 66). */
  line-height: 1.22;
}

.section-sub {
  margin-top: 18px;
  max-width: 640px;
  color: var(--muted);
  /* Лид-абзац: у Платы 20 → 18 → 16 ступенями; здесь та же вилка плавно
     (20 на 1440, 18 на 1024, 16 на телефоне). Парный стиль — .hero-sub. */
  font-size: var(--fs-md);
}

/* ---------- слоты под будущие ассеты ---------- */

/* Иконки выгод — «парящие» золотые объекты без плитки (фон вырезан;
   приём Plata: фон иконки = фон сайта). */
.benefit-icon {
  width: 80px;
  height: 80px;
}

.benefit-icon img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
  filter: drop-shadow(0 12px 20px rgba(0, 0, 0, 0.45));
}

/* ---------- кнопки и бейджи ---------- */

/* Язык кнопок (вердикт владельца 2026-07-11): ДЕЙСТВИЯ — прямоугольник
   r12 (как у Платы), ПИЛЮЛИ остаются меткам и чипам (.badge, стор-бейджи,
   пилюли уровней в мокапах). */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 13px 26px;
  /* VISUAL-POLISH-1: рамка кнопки была той же волосяной линией, что и
     разделители (--line, 1.74:1 к --bg и 1.56:1 к --surface), поэтому кнопка
     как ОБЪЕКТ не отделялась от фона — текст внутри читался, а кнопка нет.
     Порог границ компонентов 3.0. Живые носители этой рамки: «Стать
     партнёром» (.btn-ghost.btn-lg на --bg) и «+ Добавить точку» /
     «+ Прикрепить фото» (.pform-add на --surface); у «Выбрать Silver» и
     «Выбрать Platinum» рамку перебивает --tier-accent-border (зеркало
     металла, трогать в одиночку нельзя). Взят --line-control #6F6B64 =
     3.78:1 к --bg и 3.39:1 к --surface: тихая волосяная линия, прошедшая
     порог. Текстовым --faint (5.26:1) рамку не красим — это роль текста, и
     1px-кромка в яркости тихого текста читается как заливка. --line не тронут. */
  border: 1px solid var(--line-control);
  border-radius: 12px;
  font-family: inherit;
  font-size: var(--fs-sm);
  /* Вес кнопок по Плате: у них 480 в шапке и 520 на крупных — весь сайт
     живёт в узком диапазоне 420–560, жирного начертания нет нигде.
     Наши 600 рендерились Bold 700; Medium 500 — ближайшее к их 480/520. */
  font-weight: 500;
  line-height: 1.2;
  text-decoration: none;
  color: var(--ink);
  background: transparent;
  transition: border-color 0.15s ease, filter 0.15s ease, transform 0.15s ease;
}

.btn:hover { border-color: var(--gold-border); }

/* тап-фидбек (реф — мобильная Плата): кнопка мягко поджимается под пальцем */
.btn:active { transform: scale(0.97); }

.btn-primary {
  background: var(--grad-cta);
  border: none;
  color: var(--on-gold);
}

.btn-primary:hover { filter: brightness(1.06); }

/* Деструктивное действие (DELETE-ACCOUNT-WEB-1). Золотая заливка здесь была бы
   ошибкой смысла: золото в этой системе — приглашение действовать, а «Удалить
   аккаунт» приглашать не должно. Рецепт взят у danger-кнопки приложения
   (подложка + кромка + текст того же тона) и совпадает с .pform-error этого
   листа, чтобы предупреждение и его кнопка выглядели одной семьёй.
   Заливка перебивает базовую рамку .btn, поэтому объявляется и border. */
.btn-danger {
  background: rgba(140, 55, 45, 0.18);
  border: 1px solid rgba(190, 90, 76, 0.35);
  color: var(--danger);
}

.btn-danger:hover {
  background: rgba(140, 55, 45, 0.26);
  border-color: rgba(190, 90, 76, 0.6);
}

/* Крупная кнопка у Платы скруглена сильнее шапочной: r16 при высоте 64
   (шапочная r12 — у нас совпадает и не трогается). */
.btn-lg { padding: 20px 52px; font-size: var(--fs-md); border-radius: 16px; }

/* ★ CTA ШАПКИ — ПИЛЮЛЯ «Book a call» РЕФА orionix.framer.website (владелец
   2026-08-25, «нашу кнопку тоже сделай как у них»): их замер — r100, высота
   40, паддинг 10×20, кегль 14/500, сплошная контрастная плашка без рамки,
   всегда залитая. Снято этим словом: форма C2 (r12, вердикт 2026-07-11) и
   повадка «призрак → заливка на скролле» (2026-07-11) — вместе с ::before-
   слоем и правилами .scrolled. Контраст у них держит чёрная плашка на
   светлой шапке; на нашей тёмной ту же роль играет золото CTA (--grad-cta,
   заливка и текст --on-gold приходят классом btn-primary) — самое
   контрастное пятно шапки. Ховер — подмена подписи (.cta-slide, правило у
   кнопок уровней) и поджатие 0.98. */
.header-cta {
  /* HEADER-V2-STYLE-1 (владелец 25.08): пилюля шапки перенесена с v2 «как
     есть» — контурная, капительная с трекингом, на ховере заливается золотом.
     Прежняя залитая пилюля по замеру Book a call (751/754) снята этим словом. */
  padding: 11px 22px;
  border-radius: 999px;
  background: transparent;
  border-color: currentColor;
  color: var(--ink);
  font-size: 0.83rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  line-height: 1.6;
  transition: background-color 0.3s ease, color 0.3s ease, border-color 0.3s ease;
}

.header-cta:hover {
  background: var(--gold-light);
  border-color: var(--gold-light);
  color: var(--on-gold);
}

.badge {
  display: inline-flex;
  align-items: center;
  padding: 7px 14px;
  border-radius: 999px;
  background: var(--gold-glow);
  border: 1px solid rgba(187, 152, 95, 0.45);
  color: var(--gold-light);
  font-size: var(--fs-xs);
}

/* ---------- шапка ---------- */

/* Хедер: на первом экране полностью прозрачный (как у Plata), но при
   скролле наплывает тёмное стекло — вариант, выбранный владельцем
   (у самой Платы фон не появляется никогда; наш .scrolled оставлен
   осознанно, чтобы меню не смешивалось с контентом). */
.site-header {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  z-index: 20;
  background: transparent;
  border-bottom: 1px solid transparent;
  transition: background 0.35s ease, border-color 0.35s ease;
}

/* Подложка с первого пикселя — для страниц без скролл-скрипта (partner.html:
   там инлайн-JS только один, форма, и его правка тянет пересчёт CSP-хэша). */
.site-header.scrolled,
.site-header-solid {
  background: rgba(8, 8, 8, 0.78);
  backdrop-filter: blur(14px);
  -webkit-backdrop-filter: blur(14px);
  border-bottom-color: var(--line);
}

.header-inner {
  display: flex;
  align-items: center;
  gap: clamp(20px, 4vw, 48px);
  /* HEADER-V2-STYLE-1 (владелец 25.08: «стиль верхнего бара v2 накатить»):
     высота, типографика ссылок, компактный логотип и контурная CTA-пилюля
     перенесены с website-v2. Довод по замеру CDP (25.08 вечер): шапка v2 —
     ПОЛНОШИРИННАЯ с полями clamp(20,4.5vw,64), не контейнер 1300. */
  min-height: 72px;
}

.site-header .container {
  max-width: none;
  padding-inline: clamp(20px, 4.5vw, 64px);
}

.logo {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  text-decoration: none;
  color: var(--ink);
}

/* Размер логотипа сведён с Платой (их видимая графика 140×48 при шапке 64;
   у нас было 118×32 — знак и слово читались мельче их). Знак и кегль слова
   подняты одной пропорцией; на телефоне остаётся прежний размер — там бар
   делится с CTA и бургером. */
.logo-mark {
  width: 25px;
  height: 26px;
  background: var(--grad-mark);
  -webkit-mask: url("assets/fayro-mark.svg") no-repeat center / contain;
  mask: url("assets/fayro-mark.svg") no-repeat center / contain;
}

.logo-word {
  /* v2 и канон бренда: слово — Cera Pro Medium 500, компактный кегль. */
  font-weight: 500;
  letter-spacing: 0.22em;
  font-size: 1rem;
  line-height: 1;
}

.site-nav {
  display: flex;
  gap: clamp(16px, 2.6vw, 34px);
  /* v2-макет: ряд пунктов прижат вправо к CTA (платовское центрирование
     по экрану снято тем же словом владельца). */
  margin-left: auto;
}

/* Платовский шаг 40 на широких снят (HEADER-V2-STYLE-1): v2 держит 34. */
@media (min-width: 1300px) {
  .site-nav { gap: clamp(16px, 2.6vw, 34px); }
}

/* Платовское абсолютное центрирование ряда снято 25.08 (HEADER-V2-STYLE-1):
   v2-макет держит пункты справа, у кнопки. */

.site-nav a {
  text-decoration: none;
  /* Типографика v2: тонкие капительные пункты с трекингом. */
  color: var(--ink);
  opacity: 0.82;
  font-size: 0.83rem;
  font-weight: 500;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  transition: opacity 0.25s ease;
  line-height: 1.6;
  /* «Как это работает» рвалось на две строки и распирало шапку задолго до
     бургер-брейкпоинта (видно на 1000 px ещё до пункта «Партнёрам»). */
  white-space: nowrap;
}

/* Компактного «сжатого ряда» больше нет: замер Платы 2026-07-31 показал, что
   у них пункты живут только с 1241 (на 1240 уже бургер) — мы приведены к той
   же границе, поэтому диапазон, ради которого ряд ужимался, теперь бургерный. */

.site-nav a:hover { opacity: 1; }

/* Одиночная ссылка возврата (partner.html): живёт вне .site-nav, чтобы её не
   забирала мобильная шторка-бургер. margin-left:auto прижимает вправо —
   у .site-nav там margin-inline:auto под макет «лого — меню — CTA». */
.header-back {
  margin-left: auto;
  text-decoration: none;
  color: var(--ink);
  opacity: 0.82;
  font-size: 0.83rem;
  font-weight: 500;
  /* TYPE-TRACKING-1 (31.08): разрядка снята — канон и основание в баннере
     website/v2-pages.css. ЭТО ЕДИНСТВЕННОЕ правило styles.css, попавшее в
     слой: остальные его роли с трекингом рисуются только на архивной
     первой главной (website/index.html), которая на бой не выкладывается.
     .logo-word свои 0.22em сохраняет — это словесный знак. */
  letter-spacing: normal;
  text-transform: uppercase;
  transition: opacity 0.15s ease;
}

.header-back:hover { opacity: 1; }

.nav-toggle {
  display: none;
  flex-direction: column;
  /* gap 5 + полоска 2 дают межцентровое расстояние 7 px — ровно на него
     опираются transform'ы креста ниже (.is-open translateY(7px)). Не менять
     врозь: gap и 7 px — одно число, названное дважды. */
  gap: 5px;
  /* Цель касания 44×44 вместо прежних 38×40 (замер headless на 375). Коробка
     задана размером, а не паддингом: паддинг пришлось бы пересчитывать при
     каждой правке полосок, а бургер — главная навигация телефона, её размер
     обязан держаться сам. box-sizing: border-box глобальный, рамка внутри. */
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  padding: 0;
  /* VISUAL-POLISH-1: та же роль, что у .btn — кромка интерактивного контрола
     (кнопка мобильного меню), а не разделитель. */
  border: 1px solid var(--line-control);
  border-radius: 10px;
  background: transparent;
  cursor: pointer;
}

.nav-toggle span {
  width: 18px;
  height: 2px;
  background: var(--ink);
  transition:
    transform 0.32s cubic-bezier(0.22, 1, 0.36, 1),
    opacity 0.2s ease;
}

/* полоски ↔ крест (класс ставит JS вместе с открытием меню) */
.nav-toggle.is-open span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle.is-open span:nth-child(2) { opacity: 0; transform: scaleX(0.4); }
.nav-toggle.is-open span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* ---------- хиро ---------- */

/* Хиро на полный экран, как у Plata (хедер прозрачный поверх). */
.hero {
  min-height: 900px;
  display: flex;
  align-items: center;
  padding-block: 140px clamp(48px, 7vw, 88px);
}

/* Пропорция колонок держит ЗАГОЛОВОК в трёх строках — это его форма, и она
   важнее пары процентов ширины у сцены. Замер 1512 dp: 1.15fr давало
   текстовой колонке 665 px и разбивало заголовок на пять строк, 1.3fr → 703
   и четыре, 1.35fr → 715 и ровно три. Карта от сужения своей колонки не
   пострадала — её размер задаёт --card-zoom, а не ширина сцены. */
.hero-grid {
  width: 100%;
  display: grid;
  grid-template-columns: 1.35fr 1fr;
  gap: clamp(28px, 4vw, 56px);
  align-items: center;
}

.hero-copy { position: relative; }

/* Маркер верхней кромки контента хиро (см. index.html): триггер стекла
   шапки. Вне потока и без reveal-трансформа — чистая линия отсчёта. */
.hdr-sentinel {
  position: absolute;
  top: 0;
  left: 0;
  width: 1px;
  height: 1px;
  pointer-events: none;
}

.hero h1 {
  margin-top: 22px;
  font-family: var(--font-display);
  /* Плавная шкала, КАЛИБРОВАННАЯ по Плате (решение владельца 2026-07-31:
     «может, clamp вернём, оставив всё остальное — мне нравилась плавность»).
     Их ступени 80/66/56/40 остаются опорными точками, но кегль идёт между
     ними без скачков: прямая проведена через их значения на 1440 (80),
     1200 (66) и 1024 (56), концы прижаты потолком 5rem и полом 2.5rem —
     на телефоне ровно их 40. Прежний clamp имел потолок 64: подняли
     именно потолок и наклон, а не характер шкалы. */
  /* ★ SITE-AWARDS-1 (2026-08-05): к прямой Платы добавлен ПОТОЛОК ПО КОЛОНКЕ.
     Замер по 26 ширинам показал, что заголовок рвётся там, где кегль растёт
     быстрее, чем колонка: 320/360/375 давали ПЯТЬ строк (первая — одно слово
     «Одна», 97 px из 280), 390 — четыре. Причина: пол 2.5rem = 40 px держится
     до 746 px ширины, а колонка на 320 всего 280 px.
     Самая длинная строка заголовка = 8.8 × кегль (замер на 1440: 704 при 80).
     Значит кегль, при котором строк ровно три, = колонка / 8.8; делитель 8.9
     берём ради 1 % запаса на метрику фолбэк-шрифта. Колонка на мобиле =
     100vw − 40 (поля контейнера 20+20), отсюда 11.24vw − 0.281rem.
     min() применяет этот потолок только там, где он ниже прямой Платы
     (до 393 px), поэтому на всех прочих ширинах шкала не изменилась. */
  font-size: clamp(1.9rem, 4.8vw, 4.4rem); /* шкала h1 v2 */
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  line-height: 1.12;
}

/* ★ Провал 1201–1439 (SITE-AWARDS-1): ЧЕТЫРЕ строки на всех ноутбучных
   ширинах — 1201, 1240, 1280, 1366, 1400, 1439 — при трёх на 1180 и на 1440.
   Дело не в заголовке: в этом диапазоне контейнер отдаёт по 92 px полей
   против 40 на 1200 (сетка «как у Платы», .container выше), и колонка хиро
   СУЖАЕТСЯ при росте окна — 616 px на 1200 против 557 на 1201. Кегль же по
   общей прямой продолжает расти (66.2 → 66.3) и перестаёт помещаться.
   Кегль обязан следовать за колонкой, поэтому здесь у него своя прямая,
   выведенная из той же ширины: колонка = (0.96·100vw − 184 − gap) × 0.5745,
   кегль = колонка / 9.0. Ступенька кегля на 1200/1201 и на 1439/1440 — это
   ровно ступеньки самой сетки, других разрывов формула не вносит.
   Немонотонность полей (40 → 92 → 70 при росте ширины) — вопрос к сетке,
   вынесен владельцу отдельно; здесь она только компенсируется. */
@media (min-width: 1201px) and (max-width: 1439px) {
  .hero h1 { font-size: clamp(1.9rem, 4.8vw, 4.4rem); }
}

.hero-sub {
  margin-top: 22px;
  max-width: 560px;
  color: var(--muted);
  /* Та же вилка, что у .section-sub: 20 → 18 → 16 без ступеней. */
  font-size: var(--fs-md);
}

.hero-note {
  margin-top: 26px;
  /* Была --faint 0.92rem — цена, главный аргумент хиро, читалась как сноска. */
  color: var(--muted);
  font-size: var(--fs-sm);
}

.hero-visual { min-height: clamp(320px, 34vw, 440px); }

/* сцена с вращающейся картой: фон ролика совпадает с фоном сайта,
   поэтому без рамок и свечения — карта просто парит в странице.
   Пропорция 6:5 (была 16:10) — карте нужно больше высоты после укрупнения
   ниже; при этом сцена остаётся ниже текстовой колонки хиро, и высота
   секции не меняется.

   ★ ПРАВАЯ КРОМКА КАРТЫ = ПРАВОЕ ПОЛЕ КОНТЕЙНЕРА (владелец 2026-08-04:
   «чтобы правая часть карточки была вровень с правой частью кнопки
   „Оформить подписку“»). Сцена правым краем УЖЕ стояла на этом поле, но
   внутри кадра ролика вокруг карты 23,3 % пустоты, поэтому сама карта
   заканчивалась на 110 px левее кнопки и читалась «сдвинутой к центру».
   Одним сдвигом это не лечится: кадр УВЕЛИЧИВАЕТСЯ и съезжает вправо ровно
   на ширину своего пустого поля.

   Геометрия замерена по кадрам ролика (не на глаз): в покое карта занимает
   23,33 %…76,53 % ширины кадра и 19,75 %…100 % высоты; в начале оборота она
   наклонена и правый угол уходит до 79,86 %. Отсюда две переменные:
     --card-zoom     — ширина кадра в долях сцены;
     --card-overhang — запас сцены ЗА линией выравнивания, куда заезжает
                       угол во время оборота (иначе его срезала бы кромка).
   Вынос кадра считается формулой прямо в `right`, поэтому zoom можно менять
   в одиночку — выравнивание пересчитается само:
     right = −(1 − 0,7653) × zoom × ширина_сцены.

   ★ Запас НЕ расширяет сам блок. Первая версия правки давала сцене
   `width: calc(100% + overhang)` с отрицательным margin — и грид пересчитал
   fr-колонки под возросшую ширину: текстовая колонка ужалась 704 → 665 px,
   а заголовок хиро развалился с трёх строк на пять. Поэтому блок остаётся
   ровно шириной колонки, кадр выходит за него, а обрезку делает МАСКА с
   `mask-size: 100% + overhang` (вне маски — прозрачность, `no-repeat`
   обязателен: по умолчанию маска повторяется и обрезки бы не было). */
.hero-card-stage {
  /* 1.6, а не 1.8: при 1.8 карта выходила 549 px — ШИРЕ своей колонки (529),
     поэтому левым краем заезжала к тексту и оставляла зазор 36 px вместо
     здоровых ~100. Правый край у карты фиксирован линией кнопки, так что
     зазор до текста = 585 − ширина карты (замер 1512 dp): 1.6 даёт 488 px и
     зазор 97 px. */
  --card-zoom: 1.6;
  --card-overhang: 44px;
  position: relative;
  background: var(--bg);
  min-height: 0;
  /* 9:8 — карте после укрупнения нужна высота (414 px при 1512 dp), плюс
     воздух сверху, чтобы её кромка не попадала в затухание маски (6 %).
     Сцена всё равно остаётся ниже текстовой колонки, поэтому высота секции
     не меняется. */
  aspect-ratio: 9 / 8;
}

/* Слой обрезки: абсолютный (layout не трогает) и шире сцены ВПРАВО ровно на
   запас. Он и решает обе задачи разом — кадр не создаёт горизонтальной
   прокрутки (overflow: hidden внутри), а угол карты в начале оборота имеет
   куда заехать. Маска живёт здесь же: слева и сверху/снизу растворяет кромки
   кадра в страницу.

   ★ Справа затухание идёт у САМОЙ кромки слоя (последние 10 px), а не с
   линии выравнивания. Первая версия гасила начиная с неё — и съедала
   золотую грань карты вместе со свечением: на живом сайте правые углы
   выглядели обрубленными вертикальной линией (владелец: «посмотри, что ты
   наделал с карточкой»). Между линией выравнивания и кромкой слоя в покое
   пусто — там фон ролика, — поэтому непрозрачная зона там ничему не мешает,
   а угол, заезжающий в запас во время оборота, остаётся целым. */
/* ★ Затухания СЛЕВА и СВЕРХУ сняты 2026-08-05 (item 621, жалоба владельца
   «нет ли обрезов по углам»): они гасили не фон кадра, а саму карту. Замер на
   живой странице: в покое левая кромка карты стоит на 7,21 % ширины слоя при
   растворении 0–8 % — альфа 0,90, кромка притушена; а в начале оборота карта
   наклонена, её левый край уходит на 0,21 % — альфа 0,03, то есть угол
   практически стёрт. Растворение было нужно, чтобы фон ролика не читался
   кромкой на фоне страницы (#080808 против 8,8,6 у ролика). Теперь это решает
   не маска, а lighten: фон ролика опущен в чистый #000 (v6 пересобран из
   4K-мастера), слой получил фон страницы и изоляцию — всё, что темнее фона,
   заменяется фоном, кромки нет по построению. Тот же приём, что у ролика
   секции «Как это работает» (item 618). Снизу растворение ОСТАЁТСЯ: там
   отражение карты, оно ярче фона и lighten его не тронет. */
.hero-card-clip {
  position: absolute;
  inset: 0 calc(-1 * var(--card-overhang)) 0 0;
  overflow: hidden;
  background: var(--bg);
  isolation: isolate;
  -webkit-mask-image:
    linear-gradient(90deg, #000 0%, #000 calc(100% - 10px), transparent 100%),
    linear-gradient(180deg, #000 0%, #000 86%, transparent 99%);
  -webkit-mask-composite: destination-in;
  mask-image:
    linear-gradient(90deg, #000 0%, #000 calc(100% - 10px), transparent 100%),
    linear-gradient(180deg, #000 0%, #000 86%, transparent 99%);
  mask-composite: intersect;
}

/* Запас сцены уходит в правое поле страницы, а с 1200 px оно сжимается со
   106/92 px до 40 px — прежние 44 px вылезли бы за край экрана прокруткой
   (замер 1024: сцена на 4 px шире вьюпорта). Правило обязано стоять ПОСЛЕ
   базового: специфичность у них одинаковая, побеждает последнее. */
@media (max-width: 1200px) {
  .hero-card-stage { --card-overhang: 30px; }
}

.hero-card-video {
  position: absolute;
  /* кадр прижат к низу (карта «стоит» на нижней кромке, как и раньше) и
     вынесен вправо на своё пустое поле; высота — auto, пропорции 16:9
     держит сам файл, поэтому object-fit не нужен */
  bottom: 0;
  /* 0.2347 = 1 − 0,7653: пустое поле справа в кадре ролика (замер по
     кадрам). Кадр выносится на него минус запас слоя обрезки — так правая
     кромка карты садится ровно на линию правого поля контейнера.
     Проценты здесь считаются от ширины .hero-card-clip. */
  right: calc(var(--card-overhang) - 0.2347 * var(--card-zoom) * 100%);
  left: auto;
  top: auto;
  width: calc(var(--card-zoom) * 100%);
  height: auto;
  /* ★ обязательно: глобальный ресет держит `video { max-width: 100% }` и
     МОЛЧА срезал кадр обратно до ширины сцены — увеличение не применялось,
     а карта уезжала вправо от сдвига без роста. */
  max-width: none;
  /* v7 (25.08, Safari-фикс): чёрная точка ролика ПОДНЯТА в файле до фона
     страницы #080808 — стык совпадает по построению в любом браузере
     (Safari не применяет mix-blend-mode к <video>, и лежавший на lighten
     v6 показывал чёрный квадрат с резкой кромкой). lighten оставлен
     страховкой от шумов кодека в браузерах, где он работает. */
  mix-blend-mode: lighten;
}

/* Переход видео → сайт (владелец, 2026-07-10): в ролике карта стоит на
   отражающей поверхности, и отражение упирается в нижнюю кромку кадра —
   на границе блока читалась «ступенька» (низ кадра до rgb(48,37,30) при
   фоне страницы #080808). Поверх видео: тень-подложка под картой (гасит
   яркое ядро отражения и «заземляет» карту) плюс нижняя виньетка до
   точного цвета фона — кромка растворяется в страницу без шва. */
.hero-card-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    radial-gradient(ellipse 46% 10% at 50% 86%,
      rgba(0, 0, 0, 0.60), rgba(0, 0, 0, 0.24) 55%, transparent 78%),
    linear-gradient(180deg,
      transparent 72%, rgba(8, 8, 8, 0.5) 86%, var(--bg) 99%);
}

/* ---------- лента выгод ---------- */

/* Лента выгод по композиции Plata: колонка центрирована, иконка над
   заголовком, много воздуха.
   ★ SITE-AWARDS-1: собственный padding-block 48/96 убран. Ритм секций задаёт
   ОДНО правило `section { padding-block: clamp(72px, 8vw, 96px) }`; частные
   переопределения давали на странице пять разных вертикальных отступов
   (48 / 88 / 96 / 108 / 140) без причины. Осознанных исключений осталось два:
   хиро (первый экран, 140 сверху) и .security (сцена начинается от кромки). */

.benefits-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 48px 24px;
}

.benefit {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.benefit h3 {
  margin-top: 24px;
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  font-weight: var(--display-weight);
  letter-spacing: -0.01em;
}

.benefit p {
  margin-top: 8px;
  color: var(--muted);
  font-size: var(--fs-base);
  line-height: 1.55;
}

/* ---------- карта, поднимающаяся при прокрутке (аналог Plata) ---------- */

.card-rise {
  /* 140vh = вьюпорт + 40vh прокрутки на подъём: владелец (2026-07-10) —
     после выравнивания карты страница должна отпускаться почти сразу,
     без «мёртвой» прокрутки (при 170vh хвост был ~30vh).
     ★ SITE-AWARDS-1 (2026-08-05): 140 → 120vh. Замер аудита: секция 1260 px
     на 1440 при карте 411 px — 604 px хвоста ПОСЛЕ того, как карта
     выровнялась. Прокрутка подъёма 40vh → 20vh; чтобы карта при этом
     успевала доиграть, длина таймлайна в index.html считается теперь не от
     высоты сцены (stageHeight * 0.12), а от самого прогона. */
  height: 120vh;
  padding-block: 0;
  /* фон = фон сайта: карта вырезана и «летит» без своего кадра */
  background: var(--bg);
}

.card-rise-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
  perspective: 1100px;
}

.card-rise-card {
  /* Пропорция по замерам bancoplata.mx (владелец, 2026-07-10): у Plata
     карта в финале ≈41 % ширины вьюпорта, в наклоне ≈59 %; прежние
     min(920px, 78vw) давали 64 % и 97 % — карта давила на страницу. */
  width: min(800px, 44vw);
  will-change: transform;
  transform: rotateX(58deg) translateY(38%) scale(0.92);
}

.card-rise-img {
  width: 100%;
  height: auto;
  /* Фильтр живёт на дочернем слое: Safari может закэшировать тень один
     раз и композить уже готовую карточку при transform родителя. */
  filter: drop-shadow(0 46px 90px rgba(0, 0, 0, 0.65))
    drop-shadow(0 12px 30px rgba(211, 168, 101, 0.10));
}

@media (prefers-reduced-motion: reduce) {
  /* ★ SITE-AWARDS-1: сама ПРОКРУТКА тоже должна перестать анимироваться.
     Видео и появления гасились, а `html { scroll-behavior: smooth }` жил
     дальше — клик по якорю уезжал плавно вопреки системной настройке. */
  html { scroll-behavior: auto; }

  .card-rise { height: auto; padding-block: 48px; }
  .card-rise-card { transform: none !important; }
}

/* ---------- гигантская цифра ---------- */

/* Полоса --bg-soft (.how + .big-number подряд) РАСТВОРЯЕТСЯ в фон страницы
   своими крайними секциями — см. канон швов у .how. Здесь нижняя кромка. */
.big-number {
  background: linear-gradient(0deg, var(--bg) 0, var(--bg-soft) var(--seam));
  text-align: center;
  overflow: clip; /* ореол шире контейнера на узких экранах */
}

.big-number-inner { position: relative; }

/* Золотой ореол за цифрой (V1, вердикт владельца 2026-07-11) */
.big-number-halo {
  position: absolute;
  left: 50%;
  top: 40%;
  transform: translate(-50%, -50%);
  width: min(560px, 90vw);
  height: min(560px, 90vw);
  border-radius: 50%;
  /* GOLD-HYGIENE-1: ореол приглушён 0.13 → 0.06 и сведён к общему золоту
     #D3A865 (стоял на #C6A669 — оттенке, который больше нигде в продукте не
     живёт). Цифру он подсвечивает по-прежнему, но перестаёт красить полсекции. */
  background: radial-gradient(circle, rgba(211, 168, 101, 0.06), transparent 62%);
  filter: blur(30px);
  pointer-events: none;
}

.big-number-kicker {
  position: relative;
  font-size: var(--fs-xs);
  letter-spacing: 0.3em;
  text-transform: uppercase;
  color: var(--faint);
  margin-bottom: 18px;
}

/* По образцу Plata: гигантская цифра белая (решение владельца 2026-07-10),
   масштаб платовский ~200px (V1 2026-07-11); каунтер — tabular-nums,
   чтобы ширина не плясала при набеге. */
.big-number-value {
  position: relative;
  font-family: var(--font-display);
  font-size: var(--fs-mega);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  line-height: 0.95;
  color: var(--ink);
}

.bn-count { font-variant-numeric: tabular-nums; }

/* Отбивка знака процента (SITE-AWARDS-1): &nbsp; при кегле 200 px давал
   просвет шириной с цифру. 0.055em = ~11 px на десктопе и столько же по
   пропорции на телефоне — держится за кегль, а не за метрику пробела. */
.bn-pct { margin-left: 0.055em; }

.big-number-underline {
  width: 84px;
  height: 2px;
  margin: 26px auto 0;
  /* GOLD-HYGIENE-1: полоска 84×2 px под цифрой — чистый орнамент (в разметке
     aria-hidden), а красилась концами CTA-градиента, то есть цветом главной
     кнопки. Переведена на штатную линию сайта. */
  background: var(--line);
  border-radius: 2px;
}

.big-number h2 {
  margin-top: 14px;
  font-family: var(--font-display);
  font-size: var(--fs-xl);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  color: var(--gold-accent);
}

.big-number .section-sub { margin-inline: auto; }

/* ---------- уровни ---------- */

/* scroll-margin-top: 64px убран (SITE-AWARDS-1): отступ якорей теперь общий,
   `html { scroll-padding-top: var(--anchor-offset) }`. Собственный
   scroll-margin складывался бы с ним и уводил заголовок на 154 px. */

/* ★ АНАТОМИЯ И МАТЕРИАЛ БЛОКА СНЯТЫ С РЕФА orionix.framer.website (владелец
   2026-08-25, «сделай вот такого стиля карточки» со скрином). Полный замер
   рефа, карта переноса и что сознательно не перенесено — website/HANDOFF.md,
   слой ORIONIX-PRICING-5; длинные разборы не живут в styles.css — это байты
   первой загрузки (см. шапку admin/test/website-budget.test.js). */

.levels-kicker {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 14px;
  color: var(--muted);
  font-size: var(--fs-xs);
  /* Трекинг капса — тот же, что у .cine-kicker: третьей лестницы не заводим. */
  letter-spacing: 0.14em;
  line-height: 1.4;
  text-transform: uppercase;
}

.levels-kicker-dot {
  width: 6px;
  height: 6px;
  border-radius: 999px;
  background: var(--gold-accent);
}

.levels-grid {
  margin-top: 44px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(18px, 1.7vw, 24px);
}

/* ★ МАТЕРИАЛ РЕФА ПЕРЕНЕСЁН ЧЕСТНО (пятая правка, 2026-08-25). Четыре прошлых
   захода (747–750) перекладывали их анатомию на тёмные карточки — владелец
   откатил все и показал скрин: нравятся ИХ карточки. Поэтому плиты теперь их:
   белая матовая поверхность, тёмный текст, ни рамок, ни металла, ни бликов;
   одна тёмная акцентная. Замер рефа: #fff / #141414, радиус 24 24 48 48,
   паддинг 40, зазор слоёв 32, четырёхслойная тень (кольцо → контакт →
   мягкая → дальняя подушка). Металл рамки уровней с белой плитой невозможен —
   снят вместе с плитой (в приложении AppCardMetals живёт нетронутым). */
.level-card {
  /* Тёплый белый вместо чистого #fff (владелец 25.08: «не бьёт ли по глазам?»,
     сравнение трёх тонов рендером): #fff на #080808 самый колючий и холодный,
     крем #F1ECE2 возвращает тусклость старой QR-плашки; #F8F5F0 остаётся
     «их» белой плитой, но принадлежит шампань-палитре. */
  --card-surface: #f8f5f0;
  --card-ink: #141414;
  --card-muted: #656565;
  --card-sep: rgba(20, 20, 20, 0.3);
  --card-ico: rgba(20, 20, 20, 0.72);
  --card-cta-bg: #141414;
  --card-cta-ink: #f4f3f3;
  --card-ring: rgba(0, 0, 0, 0.04);
  --card-radius: 24px 24px 48px 48px;
  display: flex;
  flex-direction: column;
  gap: clamp(24px, 2vw, 32px);
  padding: clamp(28px, 2.4vw, 40px);
  border-radius: var(--card-radius);
  background: var(--card-surface);
  /* Их лестница теней 1:1; на #080808 она почти не видна, но белой плите
     отделение и не нужно — контраст держит сам материал. */
  box-shadow:
    0 0 0 1px var(--card-ring),
    0 1px 2px rgba(0, 0, 0, 0.08),
    0 4px 6px rgba(0, 0, 0, 0.04),
    0 40px 40px -24px rgba(0, 0, 0, 0.08);
}

/* Акцентная карта рефа — тёмная плита с белой кнопкой; у них это верхний
   тариф (Scale), у нас — Platinum. На нашем тёмном фоне её кромку держит
   светлое кольцо 1px (у рефа кольцо тёмное 4 % — на #080808 оно исчезло бы):
   единственная адаптация материала. */
.level-card-accent {
  --card-surface: #141414;
  --card-ink: #f4f3f3;
  --card-muted: rgba(244, 243, 243, 0.64);
  --card-sep: rgba(244, 243, 243, 0.24);
  --card-ico: rgba(244, 243, 243, 0.75);
  --card-cta-bg: #f8f5f0;
  --card-cta-ink: #141414;
  --card-ring: rgba(255, 255, 255, 0.12);
}

.level-head {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.level-name {
  font-family: var(--font-display);
  font-size: var(--fs-lg);
  /* v2: имена уровней — единственная дисплейная роль на Medium. */
  font-weight: 500;
  letter-spacing: 0.01em;
  color: var(--card-ink);
}

/* Строка «для кого» — слот описания рефа; содержимое не выдумано, это бывшие
   третьи буллеты Gold и Platinum. */
.level-desc {
  color: var(--card-muted);
  font-size: var(--fs-sm);
  line-height: 1.5;
}

/* Реф рисует разделитель svg-путём (stroke 1.5, linecap round,
   dasharray 0.01,6) — то же без svg: точка r0.75 в центре плитки 6×1.5. */
.level-sep {
  display: block;
  height: 1.5px;
  background-image: radial-gradient(circle at 50% 50%, var(--card-sep) 0 0.75px, transparent 0.76px);
  background-size: 6px 1.5px;
  background-repeat: repeat-x;
}

.level-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

/* Иконка + подпись, как у рефа; пункты — основным цветом карты, приглушена
   только иконка. Набор — Lucide (ISC), спрайт в index.html; сторонних
   скриптов и CDN канон сайта не допускает. */
.level-list li {
  display: grid;
  grid-template-columns: 22px 1fr;
  gap: 12px;
  align-items: start;
  color: var(--card-ink);
  font-size: var(--fs-sm);
  line-height: 1.5;
}

/* 1 px = половина разницы между строкой 24 (16 × 1.5) и иконкой 22: иконка
   стоит по центру ПЕРВОЙ строки, даже если подпись перенесётся. */
.level-ico {
  width: 22px;
  height: 22px;
  margin-top: 1px;
  color: var(--card-ico);
}

.level-list + .level-sep { margin-top: auto; }

.level-price {
  display: flex;
  align-items: baseline;
  gap: 8px;
  font-family: var(--font-display);
  letter-spacing: var(--display-tracking);
  line-height: 1.1;
}

/* Кегль цены сведён с рефом: 32 при имени 24 — герой карточки сам тариф. */
.level-price-amount {
  color: var(--card-ink);
  font-size: var(--fs-xl);
  font-weight: var(--display-weight);
  white-space: nowrap;
}

.level-price-period {
  color: var(--card-muted);
  font-size: var(--fs-sm);
  font-weight: 500;
  letter-spacing: 0;
  white-space: nowrap;
}

/* Годовая цена: тот же расчёт, что в FAQ (год = десять месяцев). */
.level-price-year {
  margin-top: 8px;
  color: var(--card-muted);
  font-size: var(--fs-sm);
  letter-spacing: 0;
}

/* ★ КНОПКА РЕФА: плоская сплошная пилюля во всю ширину, самое контрастное
   пятно карточки — тёмная на белой плите, белая на тёмной. Ни рамки, ни
   градиента, ни блика. У них r100 при высоте 48; держим 52 — цель касания
   уже пройдена. Порог WCAG 1.4.11 держит сама заливка. */
.level-cta {
  margin-top: 24px;
  width: 100%;
  min-height: 52px;
  padding: 14px 20px;
  border: none;
  border-radius: 999px;
  background: var(--card-cta-bg);
  color: var(--card-cta-ink);
}

/* Золотое кольцо фокуса на белой плите падает до 2.1:1 — внутри светлых карт
   кольцо тёмное (порог индикатора 3.0); акцентной тёмной хватает золотого. */
.level-card:not(.level-card-accent) :where(a):focus-visible {
  outline-color: var(--card-ink);
}

/* Подмена подписи на ховере (реф): подпись выписана дважды и уезжает вверх
   ровно на свою высоту. По умолчанию подмены НЕТ и дубликат скрыт: `clip`
   режет не только по вертикали, и на узкой колонке он срезал бы хвост слова. */
.cta-slide > span[aria-hidden="true"] { display: none; }

/* Black Platinum: имя топ-уровня — переливающаяся жемчужная лента в буквах,
   ПЕРЕНОС АНИМАЦИИ ИЗ ПРИЛОЖЕНИЯ (lib/widgets/metal_shine_text.dart, владелец
   2026-07-25): та же 5-стопная лента LevelShine.platinum, тот же период 4.5 c
   линейно без пауз, тот же наклон; металл и движение ТОЛЬКО у Platinum — на
   тёмной акцентной плите лента читается как раньше. Лента выписана дважды в
   картинке 200% — визуальный период равен ширине слова, сдвиг за цикл 100% =
   один период, кадр 4.5 c совпадает с нулевым. Без background-clip остаётся
   плоский жемчужный #c9ced6. */
@supports ((background-clip: text) or (-webkit-background-clip: text)) {
  .level-card-platinum .level-name {
    background-image: linear-gradient(
      100deg,
      #8a8f99 0%, #c5cad1 12%, #f4f2ec 25%, #b3b8c1 38%,
      #8a8f99 50%, #c5cad1 62%, #f4f2ec 75%, #b3b8c1 88%, #8a8f99 100%
    );
    background-size: 200% 100%;
    background-position: 0 50%;
    -webkit-background-clip: text;
    background-clip: text;
    color: transparent;
  }

  /* Тикер только при живом движении: канон сайта — покой при reduce. */
  @media (prefers-reduced-motion: no-preference) {
    .level-card-platinum .level-name {
      animation: pearl-flow 4.5s linear infinite;
    }
  }
}

@keyframes pearl-flow {
  from { background-position: 0 50%; }
  to { background-position: 100% 50%; }
}

.levels-note {
  margin-top: 24px;
  text-align: center;
  color: var(--faint);
  font-size: var(--fs-sm);
}

/* --ink-2 == t2 приложений и админки (VISUAL-POLISH-1). */
.levels-note-common {
  color: var(--ink-2);
  font-size: var(--fs-sm);
}

.levels-note-annual { margin-top: 8px; }

/* Пока эквайринга нет, кнопки тарифов не ведут к покупке — строка объясняет,
   когда откроется. Светлее прочих подписей: это не сноска, а ответ на
   «что дальше». */
.levels-note-status { color: var(--muted); }

/* ---------- как это работает ---------- */

/* ★ КАНОН ШВОВ (SITE-AWARDS-1 → SEAM-DISSOLVE-1, 2026-08-05). Аудит нашёл три
   разных способа разделить секции: голая ступенька фона 8 ед. (benefits→how,
   big-number→card-rise), тёплая золотая волосинка (кромки .security) и серая
   волосинка (верх футера). SITE-AWARDS-1 оставил линию тёплой зоне; владелец
   05.08 забраковал и её — «рваная склейка при переходе тона» (замер: ребро во
   всю ширину, скачок 58/44 ед. с волосинкой).

   Правило теперь одно, без исключений: СМЕНА ТОНА НИКОГДА НЕ ВИДНА КАК КРАЙ.
   Ни линий, ни ступенек — сосед доводит свой фон до тона следующей секции
   градиентом высотой --seam, стык совпадает по токену в ноль. Носители:
   .how (верх полосы --bg-soft), .big-number (её низ), .app (спуск к верху
   тёплой зоны), .partners-teaser (выход из её тёплого дна), .site-footer.
   Золото «Безопасности» живёт в содержимом сцены, не в кромках. */
.how { background: linear-gradient(180deg, var(--bg) 0, var(--bg-soft) var(--seam)); }

.how-grid {
  display: grid;
  grid-template-columns: 0.95fr 1.05fr;
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}

.how-visual { min-height: clamp(300px, 30vw, 420px); }

/* Демо приложения в how-секции. Слот квадратный: 4:3-кадр обрезается
   по бокам (там только фон), телефон в слоте на треть крупнее.

   Ролик кладётся на страницу режимом lighten (2026-08-05, жалоба
   владельца на «чёрный квадрат вокруг телефона»). До этого фон ролика
   пытались попасть В фон секции: чёрную точку поднимали на монтаже до
   #101010, постер вышел #10130f — на хорошем экране прямоугольник
   светлее фона читался целой плашкой, и маска по кромке его не лечила
   (растворяла край, а не саму разницу). Теперь наоборот: фон сцены
   ровно #000 (ролик пересобран из мастера без подъёма чёрного, с
   честными тегами bt709/tv), а lighten оставляет из двух слоёв
   светлейший — всё, что темнее фона секции, ЗАМЕНЯЕТСЯ фоном
   страницы. Кромка невозможна по построению: ни промах кодека, ни
   цветовой профиль дисплея её не вернут. Телефон при этом живёт на
   странице так же, как webp-мокапы с альфой в других секциях.

   БЕЗ border-radius и БЕЗ overflow — сознательно (правка того же дня по
   второй жалобе: «четыре чёрных артефакта по углам»). Скруглённый фон +
   прямоугольный кадр = в углах под видео фона НЕТ, и lighten там мешается
   с пустотой, отдавая чистый чёрный кадра: четыре угловые «скобки».
   Chromium прячет это, клипая видео-слой по радиусу, WebKit аппаратный
   слой видео так не клипает — артефакт виден в Safari. Фон подложки
   обязан покрывать ровно ту же площадь, что и кадр, поэтому слот
   прямоугольный; скругление ему больше и не нужно — он невидим.
   overflow не нужен тоже: object-fit: cover режет кадр внутри бокса. */
.how-visual.has-media {
  position: relative;
  padding: 0;
  border: 0;
  aspect-ratio: 1 / 1;
  background: var(--bg-soft);
  /* бленд видео считается от этого фона, а не от всей страницы */
  isolation: isolate;
}

.how-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  mix-blend-mode: lighten;
}

/* Страховка для браузеров без mix-blend-mode: там чёрный кадр лёг бы
   тёмным прямоугольником — гасим слот в фон широким растворением. */
@supports not (mix-blend-mode: lighten) {
  .how-video {
    -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 52%, transparent 92%);
    mask-image: radial-gradient(circle at 50% 50%, #000 52%, transparent 92%);
  }
}

/* Рукотворного шва повтора больше нет (2026-08-25, жалоба владельца «моргает
   и перезапускается»): петля обоих роликов ниже сгиба ЗАПЕЧЕНА в файлы
   бесшовным пинг-понгом, круг крутит сам браузер (loop) — гасить на стыке
   нечего, класс .is-loop-seam и переход прозрачности сняты вместе с
   JS-механикой. */

.steps {
  margin: 36px 0 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 26px;
}

.step {
  display: flex;
  gap: 18px;
  align-items: flex-start;
}

.step-num {
  flex: none;
  display: grid;
  place-items: center;
  width: 40px;
  height: 40px;
  /* GOLD-HYGIENE-1: кромка кружка нейтральная — золотом остаётся цифра.
     Кружков в секции три подряд, и золотые ободки читались как ещё один
     ряд акцентов рядом с золотыми заголовками шагов. */
  border: 1px solid var(--line);
  border-radius: 50%;
  color: var(--gold-light);
  font-weight: var(--display-weight);
}

.step h3 {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: var(--display-weight);
}

.step p {
  margin-top: 4px;
  color: var(--muted);
  font-size: var(--fs-sm);
}

/* ---------- приложение ---------- */

/* Спуск к тёплой зоне: нижние --seam секции доводят фон страницы до
   --bg-soft — верхнего тона .security, стык невидим. Канон швов, см. .how. */
.app {
  background: linear-gradient(0deg, var(--bg-soft) 0, var(--bg) var(--seam));
}

.app-grid {
  display: grid;
  grid-template-columns: 1.05fr 0.95fr;
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}

.app-download {
  margin-top: 34px;
  display: flex;
  align-items: center;
  gap: 24px;
  flex-wrap: wrap;
}

.store-badges {
  display: flex;
  gap: 10px;
  flex-wrap: wrap;
}

/* Ряд текстовых бейджей живёт ТОЛЬКО на узких экранах: на десктопе магазины
   показывает плашка с QR (реф Plata), два набора рядом = тот самый беспорядок. */
.store-badges-mobile { display: none; }

/* Плашка «QR + магазины» — реф Plata (владелец 2026-07-25: «три бейджа
   внизу выглядят беспорядком»). Код и столбик моно-иконок ОС стоят одним
   блоком на общей бумаге, как у Плата; текстовые пилюли на десктопе больше
   не нужны. ТОЛЬКО десктоп: на ≤960 плашка скрыта (своим же телефоном код не
   отсканируешь) — там показываются .store-badges-mobile. Сам рисунок кода
   владельцу нравится: 124 px = 5 px на модуль, не менять. */
.app-qr-card {
  display: inline-flex;
  align-items: stretch;
  /* Поле плашки СОВПАДАЕТ с полем внутри картинки (2 модуля ≈ 10 px): вместе
     они дают тихую зону кода ≥4 модулей, а визуально код заполняет плашку —
     двойного «воздуха» больше нет (владелец 2026-07-25: «пропорция фиговая»). */
  gap: 16px;
  padding: 10px 14px 10px 10px;
  /* Материал карточек уровней (item 753, владелец: «QR тусклый, выбивается
     инородностью»): прежняя кремовая бумага #EFE9DF с тёпло-чёрными модулями
     и золотым кольцом осталась единственным носителем старого языка — теперь
     та же тёплая белая плита и та же лестница теней, что у тарифов. */
  background: #f8f5f0;
  border-radius: 18px;
  box-shadow:
    0 0 0 1px rgba(0, 0, 0, 0.04),
    0 1px 2px rgba(0, 0, 0, 0.08),
    0 4px 6px rgba(0, 0, 0, 0.04),
    0 40px 40px -24px rgba(0, 0, 0, 0.08);
}

.app-qr-code {
  display: block;
  width: 146px;
  height: 146px;
  border-radius: 10px;
}

.app-qr-os {
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  padding: 4px 0;
}

.app-qr-os-icon {
  display: inline-flex;
  /* Одна бумага — одни чернила: плашка перешла на материал карточек уровней
     (#F8F5F0 / #141414, item 753), модули store-qr.svg и иконки ОС — теми же
     чернилами. Прежнее зеркало AppPalette.qrDark (#1A1710, VISUAL-POLISH-1)
     отвязано осознанно: у сайта теперь один материал, а декодеру контраст
     стал только выше. Тишина иконок по-прежнему даётся opacity. */
  color: #141414;
  opacity: 0.82;
}

.app-qr-os-icon svg { width: 24px; height: 24px; }


.store-note {
  margin-top: 12px;
  color: var(--faint);
  font-size: var(--fs-sm);
}

/* Стор-бейджи футера: светлые пилюли с моно-иконкой (инверсия платовских
   чёрных — у нас тёмный фон). Пока НЕ ссылки: приложение не в сторах. */
.store-badge {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  padding: 9px 16px;
  border-radius: 999px;
  background: var(--ink);
  color: #141414;
  font-size: var(--fs-sm);
  font-weight: var(--display-weight);
  text-decoration: none;
  transition: background 0.25s;
}

.store-badge:hover { background: var(--gold-light); }

/* Приложения ещё нет в сторах: бейджи — не ссылки (span), поэтому и выглядеть
   должны как статус, а не как кнопка. Белые пилюли обещали работающую
   загрузку. Снять класс вместе с оборачиванием в <a> к релизу.
   ★ SITE-AWARDS-1: вес снижен до общего 500 — 600 браузер отдавал Bold 700
   (в Cera Pro нет 600), и «статус» набирался жирнее любого текста рядом.
   cursor: default оставлен намеренно: он честно говорит «не кликается», но
   на телефоне курсора нет — за это отвечает подпись .store-soon-label. */
.store-badge.is-soon {
  background: transparent;
  border: 1px solid var(--line);
  color: var(--faint);
  font-weight: var(--display-weight);
  cursor: default;
}

/* Подпись над рядом бейджей: одно «скоро» на три стора вместо трёх повторов
   в самих пилюлях. Тише названий, но крупнее сноски — это статус ряда. */
.store-soon-label {
  margin-bottom: 10px;
  color: var(--muted);
  font-size: var(--fs-xs);
  letter-spacing: 0.12em;
  text-transform: uppercase;
}

/* Подпись ряда в секции «Приложение» живёт по тому же правилу, что и сам
   ряд: на десктопе там QR-плашка, бейджи скрыты — скрыта и подпись. */
.store-soon-label-mobile { display: none; }

.store-badge.is-soon:hover { background: transparent; }

.app-visual {
  min-height: clamp(380px, 36vw, 520px);
  max-width: 320px;
  justify-self: center;
  width: 100%;
}

/* Телефон с реальным экраном приложения: фотореалистичная рамка-айфон
   запечена в webp (реф Plata, решение владельца 2026-07-10); прежняя
   CSS-рамка .phone-mockup удалена вместе с разметкой. Тень — drop-shadow
   по контуру устройства, а не бокса. */
.phone-device {
  display: block;
  width: min(310px, 82vw);
  height: auto;
  margin: 0 auto;
  filter: drop-shadow(0 34px 90px rgba(0, 0, 0, 0.55));
}

/* ЖИВОЙ телефон (2026-08-15): та же рамка, но экран внутри — запись
   приложения. У h264 альфы нет, поэтому кадр приходит прямоугольником с
   ЧЁРНЫМ фоном; растворяем его каноном media-on-dark (item 618, how-секция):
   сцена держит СВОЙ фон и изолирует бленд, видео кладётся lighten — всё, что
   темнее фона секции, заменяется фоном, и кромка невозможна по построению.
   Отсюда же запрет на drop-shadow: у .phone-device тень идёт по контуру
   прозрачного PNG, а у прямоугольного кадра она обвела бы сам прямоугольник.
   Скруглений и overflow у сцены нет сознательно — при lighten подложка
   обязана покрывать ровно ту же площадь, что и кадр (грабля Safari, item 619). */
.phone-stage {
  width: min(310px, 82vw);
  margin: 0 auto;
  background: var(--bg);
  isolation: isolate;
}

/* Круг ролику делает сам браузер (loop); петля запечена в файл бесшовной
   (пинг-понг), стык не требует ничего. */
.phone-live {
  display: block;
  width: 100%;
  height: auto;
  mix-blend-mode: lighten;
}

/* Без mix-blend-mode кадр лёг бы тёмным прямоугольником — гасим края
   растворением (та же страховка, что у .how-video). */
@supports not (mix-blend-mode: lighten) {
  .phone-live {
    -webkit-mask-image: radial-gradient(circle at 50% 50%, #000 60%, transparent 96%);
    mask-image: radial-gradient(circle at 50% 50%, #000 60%, transparent 96%);
  }
}

/* ---------- партнёрам ---------- */

/* Выход из тёплой зоны: дно .security (--bg-warm) растворяется в фон страницы
   верхними --seam этой секции — канон швов, см. .how. */
.partners-teaser {
  background: linear-gradient(180deg, var(--bg-warm) 0, var(--bg) var(--seam));
}

/* Сплит с телефоном-каталогом (решение владельца 2026-07-11):
   прежняя карточка-тизер .partners-inner заменена. Верхний отступ
   вернулся к секционному (ревью 2026-07-11): секция теперь идёт после
   полосы «Безопасность» с её нижней золотой кромкой, а не впритык к app. */
/* scroll-margin убран — отступ якорей общий (см. --anchor-offset).
   padding-block 108/108 убран — ритм секций общий (см. .benefits). */

.partners-grid {
  display: grid;
  grid-template-columns: 0.9fr 1.1fr;
  gap: clamp(32px, 5vw, 72px);
  align-items: center;
}

/* Телефон-каталог СЛЕВА — зеркалит app-сплит (телефон справа); между ними
   полоса «Безопасность», так что зигзаг читается парой, а не метрономом. */
.partners-visual { order: -1; }

.partners-copy .btn { margin-top: 34px; }

.partners-visual {
  max-width: 310px;
  width: 100%;
  justify-self: center;
}

/* ---------- безопасность: тёплая золотистая зона ---------- */

/* Кромки без линий и без ступенек (вердикт владельца 2026-08-05): сверху .app
   доводит фон до --bg-soft, снизу .partners-teaser уводит --bg-warm обратно
   в --bg — тона на стыках совпадают по токену. Канон швов, см. .how. */
.security {
  background: linear-gradient(180deg, var(--bg-soft) 0%, var(--bg-warm) 100%);
}

/* Заливка кругов-узлов сцены «В-кино»: «дырка» в магистрали, чтобы линия не
   просвечивала сквозь узел. Была прибита в SVG атрибутом fill="#101110" —
   мимо токенов и мимо правки фона (SITE-AWARDS-1). Теперь следует фону. */
.cine-node-bg { fill: var(--bg-soft); }

/* «В-кино» (вердикт владельца 2026-07-11 по примеркам security-compare):
   sticky-сцена — скролл ведёт таймлайн пути кода; прогресс и классы
   (is-on/arrived/flat/done) ставит JS в index.html, здесь — геометрия,
   свечения и переходы. Полоса доверия с QR-«пломбой» — в git-истории. */
.security { padding-block: 0 clamp(64px, 8vw, 96px); }

/* ★ SITE-AWARDS-1 (2026-08-05): 240 → 190vh. Прогресс сцены — ДОЛЯ высоты
   (`-r.top / (height − vh)`), поэтому все пороги (заголовок 0.012, импульс
   0.08…0.82, титр 0.88) доезжают пропорционально; сокращается ровно хвост
   после прибытия галочки. Замер до правки: `.security` 2397 px при контенте
   738 — 1546 px пустого хвоста на 1440. */
.cine { height: 190vh; }

.cine-stage {
  position: sticky;
  top: 0;
  height: 100vh;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: clamp(18px, 3.2vh, 40px);
  padding: clamp(64px, 8vh, 100px) 0 clamp(28px, 4vh, 52px);
  overflow: clip;
}

/* виньетка — «плёнка» поверх сцены */
.cine-stage::after {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(ellipse 120% 90% at 50% 46%, transparent 55%, rgba(0, 0, 0, 0.55) 100%);
  /* Рассвет на выходе (SEAM-DISSOLVE-1): к прибытию титра драйвер сцены
     поднимает --cine-out 0→1, затемнение уходит — иначе нижний срез sticky-
     сцены резал виньетку ступенькой на хвосте секции (замер: 5 ед., 1116 px). */
  opacity: calc(1 - var(--cine-out, 0));
}

.cine-head {
  position: relative;
  z-index: 2;
  text-align: center; /* постер над симметричной сценой — кино-жанр */
  opacity: 0;
  transform: translateY(14px);
  transition:
    opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.6s cubic-bezier(0.22, 1, 0.36, 1);
}

.cine-head.is-on { opacity: 1; transform: none; }

.cine-kicker {
  color: var(--gold-light);
  letter-spacing: 0.14em;
  font-size: var(--fs-xs);
  text-transform: uppercase;
  margin-bottom: 14px;
}

.cine-head .section-title {
  max-width: 680px;
  margin: 0 auto;
  font-size: var(--fs-title);
}

.cine-scene { position: relative; z-index: 1; width: 100%; }

.cine-scene svg { display: block; margin: 0 auto; }

/* десктопная горизонтальная сцена */
#cine-svg {
  width: min(1240px, 96vw);
  max-height: 56vh;
  height: auto;
  aspect-ratio: 1240 / 640;
}

/* вертикальная сцена для ≤960 — включается в мобильном медиа-блоке */
#cine-svg-m {
  display: none;
  width: min(360px, 88vw);
  height: auto;
  aspect-ratio: 360 / 860;
}

.cine-cap {
  position: relative;
  z-index: 2;
  text-align: center;
  color: var(--muted);
  font-size: var(--fs-sm);
  opacity: 0;
  transform: translateY(12px);
  transition:
    opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
}

.cine-cap.is-on { opacity: 1; transform: none; }

.cine-cap b { color: var(--gold-light); font-weight: 500; }

.trust-list {
  margin-top: clamp(38px, 5vw, 56px);
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: clamp(28px, 4vw, 56px);
}

.trust-item dt {
  font-family: var(--font-display);
  font-size: var(--fs-md);
  font-weight: var(--display-weight);
}

.trust-item dd {
  margin-top: 5px;
  color: var(--muted);
  font-size: var(--fs-sm);
  max-width: 480px;
}

/* Слои сцены «В-кино»: магистраль, золотой след, узлы с ореолами, импульс.
   Прорисовка линий — stroke-dashoffset из JS; узлы включаются классом is-on. */
.cine-rail { stroke: rgba(244, 243, 243, 0.22); stroke-width: 1.8; }

.cine-trail {
  stroke-width: 2.2;
  filter: drop-shadow(0 0 6px rgba(233, 196, 121, 0.35));
}

.cine-node { opacity: 0.42; transition: opacity 0.55s cubic-bezier(0.22, 1, 0.36, 1); }
.cine-node .halo { opacity: 0; transition: opacity 0.6s cubic-bezier(0.22, 1, 0.36, 1); }
.cine-node.is-on { opacity: 1; }
.cine-node.is-on .halo { opacity: 1; }

.cine-lbl { fill: var(--muted); }
/* Было --faint: подписи узлов сцены не читались на тёмном фоне. */
.cine-lbl2 { fill: var(--muted); }
.cine-node.is-on .cine-lbl { fill: var(--ink); }

/* галочка: прорисовка при прибытии импульса + одноразовая вспышка */
.cine-tick {
  stroke-dasharray: 60;
  stroke-dashoffset: 60;
  transition: stroke-dashoffset 0.55s cubic-bezier(0.22, 1, 0.36, 1) 0.1s;
}

.arrived .cine-tick { stroke-dashoffset: 0; }

.cine-flash { transform-box: fill-box; transform-origin: center; opacity: 0; }

.arrived .cine-flash { animation: cine-flash 1s cubic-bezier(0.22, 1, 0.36, 1) 0.05s; }

@keyframes cine-flash {
  0% { opacity: 0.55; transform: scale(0.6); }
  100% { opacity: 0; transform: scale(1.9); }
}

/* Короткий fade гасит мигание точки при дрожании скролла на кромке узла
   (внутри узлов JS скрывает импульс — владелец 2026-07-23). */
.cine-pulse { opacity: 0; transition: opacity 0.16s linear; }

/* Иконки узлов оживают при касании луча (канон финальной галочки —
   владелец 2026-07-23): содержимое щита прорисовывается (до того узел —
   пустой круг-заготовка, как финальный), сканер даёт одноразовый
   вертикальный скан-блик, оба узла — вспышку по своей форме. Каждый
   новый проход луча (is-on снят и поставлен снова) переигрывает всё.
   Стартовые состояния и переходы — ТОЛЬКО под html.js и no-preference:
   no-JS и reduced-motion видят готовые иконки без анимаций.
   Длины контуров измерены getTotalLength: щит 127.2/24.8 (деск),
   108.6/20.9 (моб) — dasharray с малым запасом. */
@media (prefers-reduced-motion: no-preference) {
  /* px-единицы обязательны: unitless stroke-dash* в CSS Safari применяет,
     но НЕ анимирует переходом (поймано вживую 2026-07-23). */
  .js .cine-shield {
    stroke-dasharray: 128px;
    stroke-dashoffset: 128px;
    transition: stroke-dashoffset 0.5s cubic-bezier(0.22, 1, 0.36, 1) 0.05s;
  }
  .js .cine-shield-tick {
    stroke-dasharray: 26px;
    stroke-dashoffset: 26px;
    transition: stroke-dashoffset 0.35s cubic-bezier(0.22, 1, 0.36, 1) 0.42s;
  }
  .js .cine-shield.m { stroke-dasharray: 110px; stroke-dashoffset: 110px; }
  .js .cine-shield-tick.m { stroke-dasharray: 22px; stroke-dashoffset: 22px; }
  .cine-node.is-on .cine-shield,
  .cine-node.is-on .cine-shield-tick { stroke-dashoffset: 0; }
  .cine-node.is-on .cine-nflash {
    animation: cine-flash 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.05s;
  }
  .cine-node.is-on .cine-scanline { animation: cine-scan 0.7s ease-out 0.15s; }

  /* мобильная сцена: те же приёмы в самоиграющем каскаде .play
     (узел 2 зажигается на 0.75s, узел 3 — на 1.45s) */
  #cine-svg-m.play .cine-shield {
    stroke-dashoffset: 0;
    transition: stroke-dashoffset 0.5s cubic-bezier(0.22, 1, 0.36, 1) 0.8s;
  }
  #cine-svg-m.play .cine-shield-tick {
    stroke-dashoffset: 0;
    transition: stroke-dashoffset 0.35s cubic-bezier(0.22, 1, 0.36, 1) 1.2s;
  }
  #cine-svg-m.play g.cine-node:nth-of-type(2) .cine-nflash {
    animation: cine-flash 0.9s cubic-bezier(0.22, 1, 0.36, 1) 0.85s;
  }
  #cine-svg-m.play g.cine-node:nth-of-type(3) .cine-nflash {
    animation: cine-flash 0.9s cubic-bezier(0.22, 1, 0.36, 1) 1.55s;
  }
  #cine-svg-m.play .cine-scanline { animation: cine-scan-m 0.7s ease-out 1.55s; }
}

/* Покой вспышек/блика дублирован атрибутом opacity="0" в разметке:
   Safari показывал rect-вспышку сканера постоянно видимой (CSS-правило
   игнорировалось), атрибут держит их скрытыми при любом раскладе —
   CSS-анимация приоритетнее атрибута и всё равно проигрывается. */
.cine-nflash { transform-box: fill-box; transform-origin: center; opacity: 0; }

.cine-scanline { opacity: 0; }

.done .cine-nflash,
.done .cine-scanline { animation: none; }

/* Два кейфрейма вместо var(--scan-dx): Safari не резолвит custom
   properties внутри @keyframes. Пробег = ширина рамки минус отступы. */
@keyframes cine-scan {
  0% { opacity: 0; transform: translateX(0); }
  15% { opacity: 0.9; }
  85% { opacity: 0.9; }
  100% { opacity: 0; transform: translateX(76px); }
}

@keyframes cine-scan-m {
  0% { opacity: 0; transform: translateX(0); }
  15% { opacity: 0.9; }
  85% { opacity: 0.9; }
  100% { opacity: 0; transform: translateX(60px); }
}

/* фолбэк ≤960px и reduced-motion: .flat снимает sticky, .done зажигает всё
   (классы ставит JS при загрузке) */
.cine.flat { height: auto; }

.cine.flat .cine-stage {
  position: static;
  height: auto;
  padding: clamp(72px, 10vw, 96px) 0 0;
}

.cine.flat .cine-head,
.cine.flat .cine-cap { opacity: 1; transform: none; }

.cine.flat .cine-scene svg { max-height: none; }

.done .cine-node { opacity: 1; }
.done .cine-node .halo { opacity: 1; }
.done .cine-tick { stroke-dashoffset: 0; transition: none; }
.done .cine-flash { animation: none; }
.done .cine-pulse { display: none; }

/* ---- мобильная вертикальная сцена: самоиграющая хореография ----
   (владелец 2026-07-11: «чтобы красиво прогрузилась — как линия
   проходит»). Дефолт ниже — всё видно (no-JS, reduced-motion);
   стартовые состояния и переходы живут ТОЛЬКО под html.js и
   no-preference; класс .play ставит IO при доскролле до сцены. */
#cine-svg-m .cine-node,
#cine-svg-m .cine-node .halo { opacity: 1; }

@media (prefers-reduced-motion: no-preference) {
  .js #cine-svg-m:not(.play) .cine-node { opacity: 0.35; }
  .js #cine-svg-m:not(.play) .cine-node .halo { opacity: 0; }

  /* длина зигзага (три кубические Безье, посчитано численно) = 487,
     галочки ~46 — с запасом. Менял путь в разметке → пересчитай здесь,
     иначе линия прочертится не полностью или рывком. */
  .js #cine-svg-m .m-trail { stroke-dasharray: 490; stroke-dashoffset: 490; }
  .js #cine-svg-m .m-tick { stroke-dasharray: 48; stroke-dashoffset: 48; }

  /* золотая линия прочерчивается сверху вниз ~1.7с */
  #cine-svg-m.play .m-trail {
    stroke-dashoffset: 0;
    transition: stroke-dashoffset 1.7s cubic-bezier(0.4, 0, 0.2, 1) 0.35s;
  }

  /* узлы зажигаются в момент прохода линии: телефон сразу, щит на ~24%
     пути, сканер на ~66%, галочка в конце + прорисовка галочки */
  #cine-svg-m.play g.cine-node:nth-of-type(1),
  #cine-svg-m.play g.cine-node:nth-of-type(1) .halo { transition-delay: 0.05s; }
  #cine-svg-m.play g.cine-node:nth-of-type(2),
  #cine-svg-m.play g.cine-node:nth-of-type(2) .halo { transition-delay: 0.75s; }
  #cine-svg-m.play g.cine-node:nth-of-type(3),
  #cine-svg-m.play g.cine-node:nth-of-type(3) .halo { transition-delay: 1.45s; }
  #cine-svg-m.play g.cine-node:nth-of-type(4),
  #cine-svg-m.play g.cine-node:nth-of-type(4) .halo { transition-delay: 2.0s; }

  #cine-svg-m.play .m-tick {
    stroke-dashoffset: 0;
    transition: stroke-dashoffset 0.5s cubic-bezier(0.22, 1, 0.36, 1) 2.15s;
  }
}

/* ---------- FAQ ---------- */

/* FAQ — гибрид (вердикт владельца 2026-07-11): десктоп «мастер-деталь»
   (оглавление + липкая панель ответа), ≤860px — эдиториал-аккордеон
   с номерами. Общая типографика: номер тонким золотом при активности. */

.faq-head {
  display: flex;
  justify-content: space-between;
  align-items: flex-end;
  gap: 20px;
  flex-wrap: wrap;
  margin-bottom: 44px;
}

/* Строка «Не нашли ответ? Напишите нам» снята из разметки 2026-07-25 —
   вела в подвал, где контактов больше нет. Стили оставлены: вернуть строку
   одной правкой, когда появится почта на домене или бот. */
.faq-ask { color: var(--faint); font-size: var(--fs-sm); }

.faq-ask a { color: var(--gold-light); text-decoration: none; }

.faq-num {
  font-size: var(--fs-xs);
  letter-spacing: 0.12em;
  color: var(--faint);
  transition: color 0.3s;
}

.faq-q { font-weight: 500; line-height: 1.3; }

/* --- десктоп: мастер-деталь --- */
.faq-md {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: clamp(28px, 4vw, 64px);
  align-items: start;
}

.faq-list { display: grid; }

.faq-item {
  display: grid;
  grid-template-columns: 52px 1fr;
  gap: 14px;
  align-items: baseline;
  padding: 22px 0;
  border: 0;
  border-bottom: 1px solid var(--line);
  background: none;
  text-align: left;
  font: inherit;
  color: var(--muted);
  cursor: pointer;
  transition: color 0.3s, padding-left 0.3s cubic-bezier(0.22, 1, 0.36, 1);
}

.faq-item:first-of-type { border-top: 1px solid var(--line); }

.faq-item .faq-q { font-size: var(--fs-md); }

.faq-item:hover { color: var(--ink); padding-left: 10px; }

/* ★ Селектор состояния ловил `aria-current`, а скрипт мастер-детали ставит
   `aria-selected` (паттерн ARIA tabs; aria-current — про «текущую страницу»,
   и в разметке его нет вовсе). Правило не срабатывало НИКОГДА: замер живого
   DOM давал у всех шести вкладок один и тот же color rgb(189,181,173) и
   .faq-num rgb(136,130,121) — выбранный вопрос ничем не отличался от
   остальных, и клик по списку выглядел мёртвым.
   Одного цвета мало: ховер уже красит текст в --ink, то есть выбранное и
   «под курсором» сливались бы. Материальный признак — золотая рельса слева
   inset-тенью (фон .faq-item прозрачный, поэтому inset виден) плюс тот же
   сдвиг 10 px, что у ховера: выбранная строка остаётся выдвинутой и после
   ухода курсора. */
.faq-item[aria-selected="true"] {
  color: var(--ink);
  padding-left: 10px;
  box-shadow: inset 2px 0 0 var(--gold-light);
}

.faq-item[aria-selected="true"] .faq-num { color: var(--gold-light); }

.faq-panel {
  position: sticky;
  top: 112px; /* шапка 64 + воздух */
  border-left: 1px solid var(--line);
  padding: 8px 0 8px clamp(24px, 3vw, 48px);
  min-height: 280px;
}

.faq-lbl {
  font-size: var(--fs-xs);
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--gold);
}

.faq-panel-q {
  font-size: var(--fs-xl);
  font-weight: 500;
  line-height: 1.2;
  margin: 14px 0 18px;
}

.faq-panel-a { color: var(--muted); max-width: 480px; }

.faq-panel-inner { animation: faq-in 0.5s cubic-bezier(0.22, 1, 0.36, 1) both; }

@keyframes faq-in {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

/* --- аккордеон: единственная разметка вопросов (SITE-AWARDS-1) --- */
/* Раньше здесь стояло display:none, и аккордеон включался медиазапросом
   ≤860. Теперь наоборот: он виден по умолчанию, а прячется только когда
   скрипт построил из него десктопную мастер-деталь (.faq-has-md ниже) —
   иначе без JS десктоп остался бы вообще без вопросов. */

.faq-ed details { border-bottom: 1px solid var(--line); }

.faq-ed details:first-of-type { border-top: 1px solid var(--line); }

.faq-ed summary {
  display: grid;
  grid-template-columns: 44px 1fr 36px;
  align-items: baseline;
  gap: 14px;
  padding: 22px 0;
  cursor: pointer;
  list-style: none;
}

.faq-ed summary::-webkit-details-marker { display: none; }

.faq-ed .faq-q { font-size: var(--fs-md); }

.faq-x {
  justify-self: end;
  align-self: center;
  width: 30px;
  height: 30px;
  border: 1px solid var(--line);
  border-radius: 50%;
  position: relative;
  transition: border-color 0.3s, transform 0.45s cubic-bezier(0.22, 1, 0.36, 1), background 0.3s;
}

.faq-x::before,
.faq-x::after {
  content: "";
  position: absolute;
  inset: 0;
  margin: auto;
  background: var(--gold);
}

.faq-x::before { width: 11px; height: 1.5px; }

.faq-x::after { width: 1.5px; height: 11px; }

.faq-ed details[open] .faq-num { color: var(--gold-light); }

.faq-ed details[open] .faq-x {
  transform: rotate(135deg);
  border-color: var(--gold-border);
  background: rgba(198, 166, 105, 0.08);
}

.faq-ans {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows 0.45s cubic-bezier(0.22, 1, 0.36, 1);
}

.faq-ed details[open] .faq-ans { grid-template-rows: 1fr; }

.faq-ans > div { overflow: hidden; }

.faq-ans p { padding: 0 46px 24px 58px; color: var(--muted); }

/* Свёрнутый ответ вне отрисовки и поиска — см. блок FAQ в index.html.
   Ставится скриптом после анимации закрытия, поэтому она играет целиком. */
.faq-ans.is-folded { content-visibility: hidden; }

/* Аккордеон прячется на десктопе ТОЛЬКО когда мастер-деталь реально
   построена (класс ставит скрипт). Без JS остаётся аккордеон — это
   единственная разметка вопросов, спрятать её было бы нечем заменить. */
@media (min-width: 861px) {
  .faq-has-md .faq-ed { display: none; }
}

@media (max-width: 860px) {
  .faq-md { display: none; }
  .faq-ed { display: block; }
}

@media (prefers-reduced-motion: reduce) {
  .faq-panel-inner { animation: none; }
  .faq-ans { transition: none; }
}

/* ---------- страница 404 (SITE-AWARDS-1, 2026-08-05) ---------- */

/* До этого слоя несуществующий адрес отдавал дефолтную страницу nginx —
   162 байта белым по белому с версией сервера. Своя страница в теме сайта
   и с двумя выходами: на главную и в поддержку. */
/* grid, а не flex: flex-элементом .container не растягивался и вставал по
   ширине содержимого — текст «плавал» в середине вместо левого поля. */
.err-page {
  min-height: 70vh;
  display: grid;
  align-content: center;
  padding-block: clamp(96px, 14vh, 180px);
}

/* width: 100% обязателен. .err-wrap — это сам .container, а у него
   margin-inline: auto; в grid такой элемент не растягивается (auto-маржи
   отменяют stretch) и встаёт по ширине содержимого — текст «плавал» в
   середине экрана вместо левого поля страницы. Ширину строки держит
   .section-sub (640), ограничивать контейнер не нужно. */
.err-wrap { width: 100%; }

/* Код ошибки — крупная тихая цифра тем же приёмом, что «−20 %» на главной:
   набирается дисплейным начертанием, но живёт как фон, а не как заголовок. */
.err-code {
  font-family: var(--font-display);
  font-size: var(--fs-mega);
  font-weight: var(--display-weight);
  letter-spacing: var(--display-tracking);
  line-height: 0.9;
  color: var(--surface);
  margin-bottom: 8px;
}

.err-actions {
  margin-top: 34px;
  display: flex;
  gap: 14px;
  flex-wrap: wrap;
}

/* ---------- футер ---------- */

/* Верхняя кромка футера была ЕДИНСТВЕННОЙ серой волосинкой страницы среди
   золотых (замер аудита: (58,57,55) на y=9033 при (63,54,37) у .security).
   Линию сняли, переход — общий канон швов (см. .how): фон растворяется. */
.site-footer {
  /* Простор Платы: футер дышит как полноценный экран (фикс 2026-07-11) */
  padding-block: clamp(84px, 10vw, 140px) 40px;
  background: linear-gradient(180deg, var(--bg) 0, var(--bg-soft) var(--seam));
}

/* Футер по рефу Плата: крупный логотип строкой, затем колонки ссылок
   и блок приложения (QR + сторы) справа. */
.footer-head { margin-bottom: clamp(48px, 7vw, 88px); }

.footer-logo .logo-mark {
  width: 40px;
  height: 46px;
}

.footer-logo .logo-word { font-size: var(--fs-lg); }

/* ★ SITE-AWARDS-1 (2026-08-05): четыре РАВНЫЕ колонки. Было
   `repeat(3, 1fr) auto` — четвёртая (приложение) ужималась по содержимому
   до 140 px против ~330 у соседей, и ряд читался как «три колонки и хвост». */
.footer-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: clamp(28px, 4vw, 56px);
}

/* Заголовок колонки: светлее и плотнее ссылок под ним — только этим он от
   них и отличается, отдельного кегля роль не требует. */
.footer-col-title {
  color: var(--ink);
  font-size: var(--fs-sm);
  margin-bottom: 4px;
}

.footer-col {
  display: grid;
  gap: 12px;
  align-content: start;
  color: var(--muted);
  font-size: var(--fs-sm);
}

.footer-col a {
  text-decoration: none;
  color: var(--muted);
}

.footer-col a:hover { color: var(--gold-light); }

.footer-soon { color: var(--faint); }

/* QR слева, столбик бейджей справа — как у Платы (фикс 2026-07-11) */
/* Ряд в столбик: flex-строка осталась от пары «QR-плашка + бейджи», а плашку
   сняли ещё 2026-07-25 — с подписью «Скоро в сторах» (SITE-AWARDS-1) строка
   ставила её СБОКУ от бейджей вместо «над». */
.footer-app { align-self: start; }

.footer-stores {
  display: grid;
  gap: 8px;
  justify-items: start;
}

.footer-desc {
  margin-top: 12px;
  color: var(--muted);
  font-size: var(--fs-sm);
  max-width: 300px;
}

.footer-contacts {
  display: grid;
  gap: 10px;
  align-content: start;
  color: var(--muted);
  font-size: var(--fs-sm);
}

/* Кнопки мессенджеров вместо чат-виджета (0 сторонних скриптов):
   line-иконки в манере иконок выгод, ховер — золото.
   .is-pending скрывает блок, пока владелец не дал номер/username. */
.messenger-buttons {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 10px;
  margin-top: 6px;
}

.btn-messenger {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  padding: 10px 18px;
  /* VISUAL-POLISH-1: кнопки мессенджеров — те же «призрачные» кнопки, что
     .btn, и роль кромки у них та же (сейчас блок скрыт .is-pending до номеров
     владельца — правим до выхода в эфир, а не после). */
  border: 1px solid var(--line-control);
  border-radius: 12px; /* действия = r12 (единый язык кнопок) */
  color: var(--ink);
  text-decoration: none;
  transition: border-color 0.25s, color 0.25s;
}

.btn-messenger:hover {
  border-color: var(--gold);
  color: var(--gold-light);
}

/* Соцсети (Instagram/TikTok/YouTube — решение владельца 2026-07-11):
   line-иконки в манере сайта, ряд по правому краю; слева позже встанут
   телефон/почта (реф Плата). */
/* Соцсети живут в колонке «Помощь» (SITE-AWARDS-1) — прежний отдельный ряд
   .footer-social-row снят вместе с ~200 px пустоты, которую он держал. */
.footer-social {
  display: flex;
  gap: 8px;
  margin-top: 4px;
  /* цель клика 40 px, а сама иконка 24 — визуально ряд должен начинаться
     от края колонки, а не от паддинга первой ссылки */
  margin-left: -10px;
}

/* Цель клика 40×40 при иконке 24×24: минимум WCAG 2.2 §2.5.8 — 24×24,
   и он должен считаться по ССЫЛКЕ, а не по рисунку внутри неё. */
.footer-social a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  border-radius: 12px;
  color: var(--muted);
  transition: color 0.25s;
}

.footer-social a:hover { color: var(--gold-light); }

.footer-social svg { display: block; }

/* Универсальное скрытие заготовок, ждущих данных владельца
   (кнопки мессенджеров, соцсети): вписать данные и снять класс. */
.is-pending { display: none !important; }

.footer-bottom {
  margin-top: clamp(28px, 3.5vw, 44px);
  padding-top: 26px;
  border-top: 1px solid var(--line);
  display: flex;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  color: var(--faint);
  font-size: var(--fs-xs);
}

/* Юр-пометка Meta под иконку Instagram соцряда (SOCIAL-IG-1): своя строка
   на всю ширину ряда, тише копирайта; цвет наследует --faint ряда. */
.footer-legal-note {
  flex-basis: 100%;
  font-size: var(--fs-xs);
}

/* ---------- моушн: скролл-появления (слой 5) ---------- */

/* Скрытие стартового состояния — только при работающем JS (класс .js
   вешает инлайн-скрипт в <head> до первой отрисовки, флэша нет; без JS
   всё видно сразу). Появление один раз; после завершения перехода JS
   снимает классы, чтобы transition не тормозил ховеры карточек. */
.js .reveal {
  opacity: 0;
  transform: translateY(26px);
}

.js .reveal.is-in {
  opacity: 1;
  transform: translateY(0);
  transition:
    opacity 0.7s cubic-bezier(0.22, 1, 0.36, 1),
    transform 0.7s cubic-bezier(0.22, 1, 0.36, 1);
  transition-delay: var(--rd, 0s);
}

@media (prefers-reduced-motion: reduce) {
  .js .reveal { opacity: 1; transform: none; }
}

/* ★ КАРТОЧКА НА ХОВЕРЕ НЕ ДВИГАЕТСЯ (замер рефа, владелец 2026-08-24):
   наведение не меняет ни transform, ни тень, ни заливку — реагирует только
   кнопка: слегка поджимается (0.98, заметно глазу, не ломает ряд), при
   нажатии .btn:active даёт 0.97. То же — у пилюли шапки. */
.level-cta:hover { transform: scale(0.98); }

/* Подмена подписи включается только там, где есть настоящий указатель,
   хватает ширины на подпись в одну строку и разрешено движение. 1.4em, а не
   строка кнопки 1.2: на 1.2 нижняя кромка clip срезает кириллические
   выносные. */
@media (hover: hover) and (pointer: fine) and (min-width: 1001px) and (prefers-reduced-motion: no-preference) {
  .cta-slide {
    display: block;
    overflow: clip;
    height: 1.4em;
  }

  .cta-slide > span,
  .cta-slide > span[aria-hidden="true"] {
    display: block;
    height: 1.4em;
    line-height: 1.4;
    transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
  }

  .level-cta:hover .cta-slide > span { transform: translateY(-1.4em); }

  /* Слайд подписи вернулся в пилюлю шапки (владелец 25.08: «верни анимацию,
     когда текст крутился»), высота строки — v2-шные 1.6em. */
  .header-cta .cta-slide { display: block; overflow: clip; height: 1.6em; }
  .header-cta .cta-slide > span,
  .header-cta .cta-slide > span[aria-hidden="true"] {
    display: block;
    height: 1.6em;
    line-height: 1.6;
    transition: transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
  }
  .header-cta:hover .cta-slide > span { transform: translateY(-1.6em); }
}

/* ---------- адаптив ---------- */

/* Шапка уходит в бургер на 1240 — ровно как у Платы (замер: на 1280 у них
   ряд из шести пунктов, на 1240 уже кнопка меню). Секции ниже по-прежнему
   перестраиваются на 960: бургер раньше остальной вёрстки — это их же
   поведение, ряд пунктов требует больше места, чем колонки контента. */
@media (max-width: 1240px) {
  .header-inner { min-height: 58px; }

  /* Мобильное меню: вместо резкого display-переключения — шторка
     с фейдом и стаггером ссылок (фидбэк владельца 2026-07-11
     «открывается резко»). visibility с задержкой прячет меню ПОСЛЕ
     анимации закрытия; display больше не трогаем. */
  .site-nav {
    position: absolute;
    top: 58px;
    left: 0;
    right: 0;
    display: flex;
    flex-direction: column;
    gap: 0;
    padding: 8px 24px 16px;
    background: var(--header);
    border-bottom: 1px solid var(--line);
    opacity: 0;
    transform: translateY(-10px);
    visibility: hidden;
    pointer-events: none;
    transition:
      opacity 0.28s ease,
      transform 0.36s cubic-bezier(0.22, 1, 0.36, 1),
      visibility 0s linear 0.36s;
  }

  .site-nav.is-open {
    opacity: 1;
    transform: none;
    visibility: visible;
    pointer-events: auto;
    transition:
      opacity 0.28s ease,
      transform 0.36s cubic-bezier(0.22, 1, 0.36, 1);
  }

  .site-nav a {
    padding: 12px 0;
    opacity: 0;
    transform: translateY(-6px);
    transition: opacity 0.24s ease, transform 0.3s cubic-bezier(0.22, 1, 0.36, 1);
  }

  .site-nav.is-open a { opacity: 1; transform: none; }

  /* стаггер: ссылки догоняют шторку по одной */
  .site-nav.is-open a:nth-child(1) { transition-delay: 0.05s; }
  .site-nav.is-open a:nth-child(2) { transition-delay: 0.09s; }
  .site-nav.is-open a:nth-child(3) { transition-delay: 0.13s; }
  .site-nav.is-open a:nth-child(4) { transition-delay: 0.17s; }
  .site-nav.is-open a:nth-child(5) { transition-delay: 0.21s; }
  .site-nav.is-open a:nth-child(6) { transition-delay: 0.25s; }

  /* ★ Автомаржа принадлежит КНОПКЕ, а не бургеру. Ниже 1240 меню уходит в
     абсолютную шторку и выпадает из потока, поэтому прежний
     `margin-left: auto` у бургера разносил строку на «логотип · кнопка
     ······ бургер»: замер 768 dp — между кнопкой и бургером 298 px пустоты,
     а от логотипа до кнопки 16 px. Теперь пустота уходит ВЛЕВО, и правая
     группа «кнопка + бургер» стоит единым блоком у поля. */
  .header-cta { margin-left: auto; }
  .nav-toggle { display: flex; }
}

@media (max-width: 960px) {
  /* QR не показываем: посетитель смотрит с того самого телефона, которым
     его пришлось бы сканировать. Вместо плашки — текстовые бейджи, к релизу
     они станут настоящими кнопками загрузки. */
  .app-qr-card { display: none; }
  .store-badges-mobile { display: flex; }
  .store-soon-label-mobile { display: block; }

  .hero {
    min-height: 640px;
    padding-top: 110px;
  }

  .hero-grid,
  .how-grid,
  .app-grid,
  .partners-grid {
    grid-template-columns: 1fr;
  }

  /* ★ Колонка хиро ПЕРЕЛИВАЛАСЬ за правое поле контейнера (замер 375 dp:
     колонка 352 при контентной ширине 335, текст стоял в 3 px от кромки
     экрана против 20 px слева). Причина — дефолт `min-width: auto` у
     грид-элементов: колонка не может стать уже min-content своего
     содержимого. Баг жил до правки карты (проверено откатом стилей),
     лечится штатно — разрешаем элементам ужиматься. */
  .hero-copy,
  .hero-visual { min-width: 0; }

  /* Одна колонка — выравнивать карту по кнопке шапки не по чему: кнопка
     здесь уступает место бургеру, а сцена занимает всю ширину. Кадр снова
     ЦЕНТРИРУЕТСЯ (сдвиг = половина прироста ширины), увеличение остаётся.
     Запас сцены обнулён: карта здесь и так стоит с полем ~39 px, а лишние
     7 % ширины вылезли бы за край экрана горизонтальной прокруткой. */
  .hero-card-stage {
    --card-overhang: 0px;
    /* Одна колонка: сцена шириной во весь контейнер, и квадрат оставлял бы
       над картой 96 px пустоты (замер 375 dp). 6:5 — ровно под её высоту. */
    aspect-ratio: 6 / 5;
    /* Чуть меньше десктопного: запаса за кромкой здесь нет, а при 1.667
       угол карты в начале оборота подходил к краю сцены на 0,8 px —
       любая иная метрика шрифта/масштаба срезала бы его. При 1.58 запас
       ≈ 10 px, размер карты падает всего на 15 px. */
    --card-zoom: 1.58;
  }

  /* Кадр снова ЦЕНТРИРУЕТСЯ: половина прироста ширины с каждой стороны. */
  .hero-card-video {
    right: calc((100% - var(--card-zoom) * 100%) / 2);
  }

  /* мобайл: пункты доверия в столбик; сцена «В-кино» здесь статична
     (.flat/.done ставит JS при загрузке) и ВЕРТИКАЛЬНА — горизонтальный
     svg, ужатый в 375px, давал нечитаемые подписи ~8px (сим-ревью
     2026-07-11); вертикальный собрат зашит финальным состоянием */
  .trust-list { grid-template-columns: 1fr; }

  #cine-svg { display: none; }

  #cine-svg-m { display: block; }

  /* На мобиле титр дублирует подпись узла-галочки, стоящую строкой выше
     («Скидка применена» × 2 подряд — сим-ревью 2026-07-11); на десктопе
     подписи горизонтальной сцены далеко от титра — там он остаётся */
  .cine-cap { display: none; }

  /* мобайл: текст партнёров прежде телефона */
  .partners-visual { order: 0; }

  /* НЕ ставить тут min-height: у стейджа aspect-ratio 16/10, и min-height
     300px давал transferred-ширину 300×1.6 = 480px > экрана — iOS Safari
     ужимал ВСЮ страницу до ~74% («всё съехало влево», фидбэк владельца
     2026-07-11 с iPhone). Высоту держит сам аспект (при 343px ≈ 214px). */
  .hero-visual { min-height: 0; }

  /* Мобайл: длиннее и стабильнее scroll-дистанция, без скачка при сворачивании
     панели Safari. Тень легче, но остаётся визуально близкой к десктопной.
     ★ SITE-AWARDS-1 (2026-08-05): 72vw → 86vw. Замер до правки на 393 dp —
     карта 288×152 в центре экрана 852 px, то есть 18 % его высоты против
     43 % на десктопе: вокруг неё стоял почти пустой экран. 86vw даёт
     338×219 (26 %), полей по 27 px с каждой стороны — карта остаётся
     «парящей», но перестаёт быть точкой. Дальше не поднимаем: карта
     горизонтальная (1600×1038), рост ширины почти не даёт высоты. */
  .card-rise-card { width: min(520px, 86vw); }
  .card-rise-img {
    filter: drop-shadow(0 28px 54px rgba(0, 0, 0, 0.58))
      drop-shadow(0 8px 22px rgba(211, 168, 101, 0.09));
  }

  .how-visual { order: 2; }

  .benefits-grid { grid-template-columns: repeat(2, 1fr); }

  .app-visual { justify-self: start; }

  .footer-grid { grid-template-columns: 1fr; }
}

@media (max-width: 960px) and (prefers-reduced-motion: no-preference) {
  /* ★ SITE-AWARDS-1 (2026-08-05): 160svh → 130svh. Было 1363 px секции на
     карту 182 px (87 % пустоты, 841 из них ниже карты) — полтора экрана
     черноты ради одного подъёма. Таймлайн привязан к прогону (index.html),
     поэтому карта выравнивается ровно к моменту, когда сцена отлипает,
     и мёртвого хвоста не остаётся вовсе.
     Не 110svh, как задавал план слоя: при 110 прогон выходил 85 px на 393 dp
     (10 % экрана) — весь подъём с 58° до 0° проскакивал за один флик и
     читался щелчком, а не движением. 130svh = 256 px прогона (30 % экрана):
     подъём занимает естественный свайп. Замер после: под картой 289 px из
     852 против 312 до правки, при карте, выросшей 152 → 219 px. */
  .card-rise { height: 130vh; height: 130svh; }
  .card-rise-stage { height: 100vh; height: 100svh; }
}

/* ★ Планшетная раскладка рефа (orionix, замер на 820): ряд переносится в
   ДВЕ карточки, третья растягивается на всю ширину. Тремя колонками на 820
   карточка выходит 234 px, и пункты с иконкой (22 + зазор 12) рвутся на
   три строки. */
@media (max-width: 1000px) and (min-width: 800px) {
  .levels-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }

  .levels-grid > :last-child { grid-column: 1 / -1; }
}

/* Ниже 800 колонка уровня выходит уже 216 px, и в неё перестаёт помещаться
   строка цены («399 ₽ / мес» — 154 px при 149 доступных, замер resp.mjs) и
   пункт «QR-карта в приложении» с его неразрывной группой. Здесь и
   начинается одноколоночная лента. */
@media (max-width: 799px) {
  .levels-grid { grid-template-columns: 1fr; }
}

@media (max-width: 560px) {
  /* CTA остаётся в шапке рядом с бургером (реф — мобильная Плата:
     «Obtener» + бургер; правило продажи). Прежний display:none убран,
     кнопка компактная, хвост слова скрыт (.cta-tail в разметке). */
  /* Кегль остаётся мелким (кнопка компактная по рефу), но высота поднята до
     цели касания 44: было 33.6 px — самая частая цель большого пальца на
     сайте и самая мелкая. Держим min-height, а не паддингом: паддинг съезжает
     вместе с кеглем, а 44 — это про палец, а не про букву. Шапка 58 px, так
     что 44 внутри ложатся с воздухом 7 px сверху и снизу. */
  .header-cta {
    padding: 8px 16px;
    min-height: 44px;
    font-size: 0.78rem;
  }

  .cta-tail { display: none; }

  /* Выгоды строками, как у мобильной Платы: иконка слева, текст справа —
     все четыре на один экран вместо двух с центрированными колонками */
  .benefits-grid { grid-template-columns: 1fr; gap: 26px; }

  .benefit {
    display: grid;
    grid-template-columns: 48px 1fr;
    column-gap: 18px;
    align-items: start;
    text-align: left;
  }

  .benefit-icon {
    width: 48px;
    height: 48px;
    grid-row: 1 / span 2;
    margin: 0;
  }

  .benefit h3 { margin-top: 0; font-size: var(--fs-md); }

  .benefit p { grid-column: 2; font-size: var(--fs-sm); }

  .level-card { padding: 28px 24px; --card-radius: 22px 22px 34px 34px; }

  .level-price { margin-top: 18px; }

  .level-list { margin: 26px 0 28px; }

  .levels-note-common { font-size: var(--fs-sm); }

  /* Мобильный воздух: платовские десктоп-отступы на телефоне давали
     чёрные «дыры» между секциями — ужато ~на четверть (ревью 2026-07-11).
     ★ SITE-AWARDS-1: и здесь ритм задаёт одно правило; частные 36/60 у выгод
     и 56/48 у партнёров убраны вслед за десктопными. Исключения те же —
     хиро и .security. */
  section { padding-block: 56px 64px; }

  .hero { padding-block: 96px 40px; }

  .security { padding-block: 0 56px; }

  .cine.flat .cine-stage { padding: 56px 0 0; }

  .site-footer { padding-block: 64px 28px; }

  /* Разгрузка текста на телефонах (фидбэк владельца 2026-07-11). */
  .hero-sub-lead { display: none; }
}


/* ============================================================
   Страница «Стать партнёром» (partner.html, PARTNER-APPLICATIONS-1):
   онлайн-бриф — та же анкета, что и docx-бриф. Канон Hybrid
   Champagne Dark: тёмные поверхности, золото только акцентами.
   ============================================================ */

.pform-hero { padding-block: 120px 26px; }

/* Секция формы прижата к своему хиро (общий section-отступ сверху не нужен). */
.pform-section { padding-block: 0 96px; }

.pform-hero .section-title { text-align: left; }

.pform-hero .section-sub { text-align: left; margin-top: 14px; max-width: 640px; }

/* Кегль хиро главной (до 66px) в узкой колонке брифа рвал заголовок на
   «Станьте партнёром / Fayro»; здесь он соразмерен анкете и встаёт строкой. */
.pform-hero .section-title { font-size: var(--fs-title); }

/* 760 — КОНТЕНТНАЯ ширина колонки. .container добавляет свой
   padding-inline: clamp(24px, 5vw, 70px), поэтому при max-width:760px
   колонка ужималась до 632px на десктопе — перебиваем паддинг и добираем
   его в max-width. Тот же класс носит футер страницы: контент и подпись
   стоят на одной вертикали. */
.pform-wrap {
  max-width: 808px;
  padding-inline: 24px;
}

.pform-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius-lg);
  padding: 30px 32px 32px;
  margin-top: 22px;
}

.pform-card h2 {
  font-size: var(--fs-md);
  font-weight: var(--display-weight);
  letter-spacing: -0.01em;
  display: flex;
  align-items: baseline;
  gap: 12px;
}

.pform-card h2 .pform-num {
  color: var(--gold-accent);
  font-size: var(--fs-sm);
  font-weight: var(--display-weight);
}

.pform-note { margin-top: 6px; font-size: var(--fs-sm); color: var(--faint); line-height: 1.55; }

/* Ссылка внутри текста карточки. Без этого правила <a> в форме приезжает
   синим браузерным дефолтом — на тёмной странице это единственное пятно чужой
   системы. Золото текста, как у остальных ссылок сайта. */
.pform-card a,
.pform-done a {
  color: var(--gold-light);
  text-decoration: underline;
  text-underline-offset: 3px;
}

.pform-card a:hover,
.pform-done a:hover { color: var(--gold-glint); }

/* Главный абзац карточки: то, ради чего карточку читают (DELETE-ACCOUNT-WEB-1 —
   «удаление можно отменить 30 дней»). Тон --muted против --faint у сноски:
   обещание, по которому человек планирует своё время, не может быть набрано
   тише всего на странице. Кегль тот же — ступеней не прибавляем. */
.pform-lead {
  margin-top: 10px;
  font-size: var(--fs-sm);
  color: var(--muted);
  line-height: 1.6;
}

.pform-field { margin-top: 18px; }

.pform-label {
  display: block;
  font-size: var(--fs-sm);
  /* 600 рендерился Bold 700 (статики 600 нет) — v2-рисунок держит 500. */
  font-weight: 500;
  margin-bottom: 8px;
}

/* Пометка обязательного поля (SITE-AWARDS-1). Прежний .opt («· необязательно»)
   снят: помечать нужно обязательные, а не наоборот. Золотом, потому что это
   статус поля, а не декор; aria-hidden — скринридеру про обязательность
   говорит сам атрибут required. */
.pform-label .req { color: var(--gold-accent); }

/* Легенда в начале формы — она и объясняет звёздочку. */
.pform-legend {
  margin-top: 18px;
  color: var(--muted);
  font-size: var(--fs-sm);
}

.pform-legend .req { color: var(--gold-accent); }

/* Строка точки: два поля С МЕТКАМИ и кнопка удаления. Была flex-строка из
   двух голых инпутов — метки в неё не помещались (SITE-AWARDS-1). */
.pform-branch-field { flex: 1 1 0; min-width: 0; }

.pform-branch-field .pform-label { margin-bottom: 6px; }

/* caret-color: единственная «браузерная» поверхность формы, которая до сих
   пор приезжала дефолтом. Интерактив в этой системе золотой — каретка тоже. */
.pform-input,
.pform-textarea {
  width: 100%;
  font-family: inherit;
  font-size: var(--fs-sm);
  color: var(--ink);
  background: var(--bg-soft);
  /* VISUAL-POLISH-1: кромка поля — учебниковый случай §1.4.11: у пустого поля
     она единственный признак «сюда пишут», а давала 1.56:1 к --surface
     карточки (снаружи) и 1.64:1 к своей заливке --bg-soft (внутри) при пороге
     3.0. Заливка, радиус и золотой :focus не меняются. */
  border: 1px solid var(--line-control);
  border-radius: 12px;
  padding: 13px 15px;
  transition: border-color 0.15s ease;
  caret-color: var(--gold-light);
}

/* ★ Кольцо фокуса НЕ гасить. Здесь стоял `outline: none`, и он молча убивал
   глобальное золотое кольцо: то объявлено через `:where(...)` с нулевой
   специфичностью (см. «фокус с клавиатуры» в конце файла), а этот селектор —
   0-2-0, то есть перебивал его без всякого !important. Замер реальными Tab
   в headless Chrome: все контролы страницы получали `outline: solid 2px`,
   и только текстовое поле — `outline: none`; от индикатора оставалась смена
   рамки 1 px (#6F6B64 → #BB985F, 1.96:1). Поля живут на partner/support/
   delete-account — то есть кольца лишались ровно все формы сайта.
   Смена рамки остаётся, но теперь как ДОБАВКА к кольцу, а не вместо него:
   мышь и палец видят только её (кольцо ходит по :focus-visible), клавиатура —
   обе. */
.pform-input:focus,
.pform-textarea:focus {
  border-color: var(--gold-border);
}

.pform-input::placeholder,
.pform-textarea::placeholder { color: var(--faint); }

.pform-textarea { resize: vertical; min-height: 96px; }

/* Короткие поля (скидка в процентах). Классом, а не style-атрибутом:
   CSP style-src 'self' гасит инлайн-стили. */
.pform-input-num { max-width: 160px; }

/* Строка точки: адрес + телефон + снос. Именно flex, а не grid: у первой
   строки кнопки сноса нет, и третья колонка grid-шаблона всё равно съедала
   gap — поля первой точки не доходили до края карточки. */
.pform-branch {
  display: flex;
  gap: 10px;
  margin-top: 16px;
  /* кнопка «×» стоит на линии полей, а не подписей */
  align-items: flex-end;
}

.pform-branch .pf-branch-addr { flex: 1.7 1 0; min-width: 0; }

.pform-branch .pf-branch-phone { flex: 1 1 0; min-width: 0; }

.pform-branch-del {
  /* VISUAL-POLISH-1: кнопка сноса точки — интерактивный контрол; кромка на
     общий токен границ контролов (глиф «×» остаётся тихим --faint). */
  border: 1px solid var(--line-control);
  background: transparent;
  color: var(--faint);
  border-radius: 12px;
  padding: 0 14px;
  font-size: var(--fs-md);
  line-height: 1;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}

.pform-branch-del:hover { border-color: var(--gold-border); color: var(--ink); }

.pform-add {
  margin-top: 12px;
  padding: 10px 18px;
  font-size: var(--fs-sm);
}

/* Honeypot: поле-ловушка вне экрана; человеку не видно и не фокусируется. */
.pform-hp {
  position: absolute;
  left: -9999px;
  top: -9999px;
  width: 1px;
  height: 1px;
  overflow: hidden;
}

/* Согласие с политикой. */
.pform-consent { display: flex; gap: 12px; align-items: flex-start; margin-top: 4px; }

/* ★ SITE-AWARDS-1 (2026-08-05). Чекбокс согласия был ЕДИНСТВЕННЫМ системным
   контролом сайта: `accent-color` красит только отмеченное состояние, а
   пустой чекбокс браузер рисует сам — белая заливка и рамка rgb(118,118,118).
   На тёмной странице это было самое яркое пятно, ярче золотой CTA, и стояло
   оно ровно на согласии по 152-ФЗ.

   Собственная отрисовка: заливка --surface (та же, что у полей формы),
   кромка --line-control (3.39:1 к --surface — порог §1.4.11 = 3.0), галочка
   --gold-light. Отмеченное состояние отличается ДВУМЯ признаками сразу —
   золотой кромкой и галочкой, — чтобы не полагаться на один мелкий штрих.
   24×24 — минимальная цель по WCAG 2.2 §2.5.8 (у прежнего было 19).
   Галочка нарисована бордюрами ::after: CSP img-src 'self' не пропустил бы
   ни data-URI, ни mask-image (память website-security-canon), а отдельный
   SVG-файл ради двух штрихов — лишний запрос.
   Фокус берёт глобальное :focus-visible (золотое кольцо 2 px). */
.pform-consent input[type="checkbox"] {
  flex: none;
  appearance: none;
  -webkit-appearance: none;
  width: 24px;
  height: 24px;
  margin: 1px 0 0;
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line-control);
  border-radius: 7px;
  cursor: pointer;
  transition: border-color 0.15s ease, background-color 0.15s ease;
}

.pform-consent input[type="checkbox"]:hover { border-color: var(--gold-border); }

.pform-consent input[type="checkbox"]:checked { border-color: var(--gold-border); }

.pform-consent input[type="checkbox"]::after {
  content: "";
  position: absolute;
  left: 7px;
  top: 3px;
  width: 6px;
  height: 12px;
  border: solid var(--gold-light);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg) scale(0.6);
  opacity: 0;
  transition: opacity 0.12s ease, transform 0.12s ease;
}

.pform-consent input[type="checkbox"]:checked::after {
  opacity: 1;
  transform: rotate(45deg) scale(1);
}

@media (prefers-reduced-motion: reduce) {
  .pform-consent input[type="checkbox"],
  .pform-consent input[type="checkbox"]::after { transition: none; }
}

.pform-consent label { font-size: var(--fs-sm); line-height: 1.55; color: var(--muted); }

/* Выбор ОДНОГО варианта из закрытого списка (DELETE-ACCOUNT-WEB-1: «почему
   уходите», вопрос необязательный). Отрисовка своя по той же причине, по
   которой она своя у чекбокса согласия выше: системный radio на тёмной
   странице браузер рисует белым, и он становится самым ярким пятном экрана.
   Круг вместо квадрата — чтобы «один из» читалось формой контрола, а не
   только поведением. Цель 24×24 (WCAG 2.2 §2.5.8), отмеченное состояние
   отличается ДВУМЯ признаками сразу: золотой кромкой и золотой точкой. */
.pform-choice { margin-top: 12px; display: grid; gap: 12px; }

.pform-choice-item { display: flex; gap: 12px; align-items: center; }

/* Сноска после группы выбора: 6 px «прилипали» к последнему варианту и
   читались шестым пунктом списка. */
.pform-choice + .pform-note { margin-top: 16px; }

.pform-choice input[type="radio"] {
  flex: none;
  appearance: none;
  -webkit-appearance: none;
  width: 24px;
  height: 24px;
  margin: 0;
  position: relative;
  background: var(--surface);
  border: 1px solid var(--line-control);
  border-radius: 50%;
  cursor: pointer;
  transition: border-color 0.15s ease;
}

.pform-choice input[type="radio"]:hover,
.pform-choice input[type="radio"]:checked { border-color: var(--gold-border); }

.pform-choice input[type="radio"]::after {
  content: "";
  position: absolute;
  left: 50%;
  top: 50%;
  width: 10px;
  height: 10px;
  margin: -5px 0 0 -5px;
  border-radius: 50%;
  background: var(--gold-light);
  opacity: 0;
  transform: scale(0.4);
  transition: opacity 0.12s ease, transform 0.12s ease;
}

.pform-choice input[type="radio"]:checked::after { opacity: 1; transform: scale(1); }

@media (prefers-reduced-motion: reduce) {
  .pform-choice input[type="radio"],
  .pform-choice input[type="radio"]::after { transition: none; }
}

.pform-choice label {
  font-size: var(--fs-sm);
  line-height: 1.55;
  color: var(--muted);
  cursor: pointer;
}

/* Кнопка-ссылка внутри формы: раскрытие политики в форме поддержки и
   «Прислать код ещё раз» на странице удаления (DELETE-ACCOUNT-WEB-1) — одно
   поведение, один вид. */
.pform-consent button,
.pform-resend {
  background: none;
  border: none;
  padding: 0;
  font: inherit;
  color: var(--gold-light);
  cursor: pointer;
  text-decoration: underline;
  text-underline-offset: 3px;
  /* У <button> браузерный text-align:center — при переносе на две строки
     (узкий экран) текст ссылки центрировался и рвал левый край абзаца. */
  text-align: left;
}

.pform-policy {
  margin-top: 14px;
  max-height: 300px;
  overflow-y: auto;
  background: var(--bg-soft);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 16px 18px;
  font-size: var(--fs-sm);
  line-height: 1.6;
  color: var(--muted);
  white-space: pre-wrap;
}

/* Сообщения формы. */
.pform-error {
  margin-top: 14px;
  padding: 12px 15px;
  border-radius: 12px;
  font-size: var(--fs-sm);
  line-height: 1.5;
  color: var(--danger);
  background: rgba(140, 55, 45, 0.18);
  border: 1px solid rgba(190, 90, 76, 0.35);
}

.pform-submit-row { margin-top: 26px; display: flex; align-items: center; gap: 16px; flex-wrap: wrap; }

.pform-submit-row .pform-hint { font-size: var(--fs-xs); color: var(--faint); }

.pform-submit[disabled] { opacity: 0.55; pointer-events: none; }

/* Смена шага формы — движение, а не телепорт (канон анимации: мгновенная
   подмена блока читается сбоем). 240 мс той же кривой, что у остальных
   переходов сайта; при prefers-reduced-motion блок просто появляется. */
@keyframes pform-step-in {
  from { opacity: 0; transform: translateY(14px); }
  to { opacity: 1; transform: none; }
}

.pform-step-in { animation: pform-step-in 0.24s cubic-bezier(0.22, 1, 0.36, 1) both; }

@media (prefers-reduced-motion: reduce) {
  .pform-step-in { animation: none; }
}

/* Исчерпанная попытка повтора: кнопка остаётся на месте (иначе строка прыгает),
   но гаснет и перестаёт нажиматься — рядом идёт отсчёт в .pform-hint. */
.pform-resend[disabled] { opacity: 0.5; pointer-events: none; text-decoration: none; }

/* MICRO-MOTION-1: тряска блока ошибки. Класс перевешивает скрипт формы на
   КАЖДЫЙ показ (remove → reflow → add), поэтому повторная ошибка дёргает уже
   видимый блок заново. Затухающая синусоида ±6 px, 420 мс. */
@keyframes pform-shake {
  10%, 90% { transform: translateX(-1px); }
  20%, 80% { transform: translateX(3px); }
  30%, 50%, 70% { transform: translateX(-6px); }
  40%, 60% { transform: translateX(6px); }
}

.pform-shake { animation: pform-shake 0.42s cubic-bezier(0.36, 0.07, 0.19, 0.97) both; }

@media (prefers-reduced-motion: reduce) {
  .pform-shake { animation: none; }
}

/* Экран «спасибо». */
.pform-done {
  background: var(--surface);
  border: 1px solid var(--gold-border);
  border-radius: var(--radius-lg);
  padding: 38px 34px;
  margin-top: 26px;
}

/* MICRO-MOTION-1: экран «спасибо» въезжает тем же движением, что смена шага
   (телепорты запрещены), а галочка над заголовком рисуется штрихом: сперва
   золотое кольцо, следом сам знак. Анимации стартуют в момент снятия
   [hidden] (display:none → block перезапускает CSS-анимацию). Золото — канон
   GOLD-HYGIENE: «заявка отправлена» — это статус. */
.pform-done:not([hidden]) { animation: pform-step-in 0.3s cubic-bezier(0.22, 1, 0.36, 1) both; }

.pform-done-check { display: block; margin-bottom: 18px; }

.pform-done-check circle {
  stroke: var(--gold-border);
  stroke-width: 2;
  /* Длина окружности r=25: 2π·25 ≈ 157.1 — от неё пляшет прорисовка. */
  stroke-dasharray: 158;
  stroke-dashoffset: 158;
  transform: rotate(-90deg);
  transform-origin: 50% 50%;
  animation: pform-check-draw 0.5s cubic-bezier(0.22, 1, 0.36, 1) 0.1s forwards;
}

.pform-done-check path {
  stroke: var(--gold-glint);
  stroke-width: 2.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  /* Длина ломаной M17 29.5 → 25 37.5 → 39 21 ≈ 32.9. */
  stroke-dasharray: 34;
  stroke-dashoffset: 34;
  animation: pform-check-draw 0.32s cubic-bezier(0.22, 1, 0.36, 1) 0.45s forwards;
}

@keyframes pform-check-draw { to { stroke-dashoffset: 0; } }

@media (prefers-reduced-motion: reduce) {
  .pform-done:not([hidden]) { animation: none; }

  .pform-done-check circle,
  .pform-done-check path { animation: none; stroke-dashoffset: 0; }
}

.pform-done h2 { font-size: var(--fs-lg); font-weight: var(--display-weight); }

.pform-done p { margin-top: 12px; color: var(--muted); line-height: 1.6; }

.pform-done .btn { margin-top: 20px; }

/* Селектор двойной: .pform-done p (margin-top:12px) специфичнее одиночного
   класса и перебивал бы отступ. */
.pform-done .pform-done-id { margin-top: 14px; }

/* Шаг фото на экране «спасибо» (PHOTO-BRIEF-1): до 3 файлов по одноразовому
   токену; строки статусов — тем же тихим тоном, что и pform-note. */
.pform-photos {
  margin-top: 28px;
  padding-top: 24px;
  /* GOLD-HYGIENE-1: разделитель блока — обычная линия; золото на служебной
     кромке ничего не сообщает. */
  border-top: 1px solid var(--line);
}

.pform-photos h3 { font-size: var(--fs-md); font-weight: var(--display-weight); }

.pform-photo-row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 14px;
  margin-top: 12px;
  padding: 11px 15px;
  /* GOLD-HYGIENE-1: строк-файлов до трёх подряд — золотые рамки складывались
     в золотую лесенку; рамка нейтральная, статус несёт текст. */
  border: 1px solid var(--line);
  border-radius: 12px;
  font-size: var(--fs-sm);
}

.pform-photo-row .pform-photo-name {
  color: var(--muted);
  overflow-wrap: anywhere;
  min-width: 0;
}

.pform-photo-row .pform-photo-status { color: var(--faint); white-space: nowrap; }

.pform-photo-ok .pform-photo-status { color: var(--ok); }

.pform-photo-bad .pform-photo-status { color: var(--danger); white-space: normal; text-align: right; }

.pform-done .pform-photos-done { color: var(--ok); }

/* Футер брифа: страница короткая, простор футера главной (до 140px сверху)
   здесь оставлял пустую яму. Подпись живёт в колонке .pform-wrap, поэтому
   ограничение ширины от макета главной снимаем. */
.pform-footer { padding-block: 48px 28px; }

.pform-footer .footer-desc { max-width: none; margin-top: 0; }

/* Ряд ссылок подвала внутренних страниц (SITE-AWARDS-1). */
.pform-footer-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
  margin-top: 18px;
}

.pform-footer-nav a {
  color: var(--muted);
  font-size: var(--fs-sm);
  text-decoration: none;
  transition: color 0.2s ease;
}

.pform-footer-nav a:hover { color: var(--gold-light); }

.footer-copy {
  margin-top: 22px;
  color: var(--faint);
  font-size: var(--fs-xs);
}

@media (max-width: 640px) {
  .pform-hero { padding-block: 96px 16px; }
  .pform-card { padding: 24px 18px 26px; }
  .pform-branch { flex-wrap: wrap; }
  .pform-branch .pf-branch-addr,
  .pform-branch .pf-branch-phone { flex-basis: 100%; }
  .pform-branch-del { margin-left: auto; padding: 8px 14px; }
}

/* ---------- очень узкие экраны: 320–380 dp ---------- */

/* Шапка физически не помещалась при 320 dp (iPhone SE 1-го поколения,
   складные в закрытом виде): замер — логотип 142 + кнопка 98 + бургер 40
   и два зазора по 24 = 328 px при доступных 280, из-за чего .header-inner
   растягивался и вся страница уезжала горизонтальной прокруткой
   (scrollWidth 372 при вьюпорте 320). Порог 380 px взят с запасом: своим
   содержимым шапка перестаёт помещаться уже при 368.
   Лечим втроём — зазор, слово логотипа и кнопка; знак логотипа, порядок
   элементов и правило «CTA всегда на виду» не трогаем. */
@media (max-width: 380px) {
  .header-inner { gap: 10px; }

  .logo-word {
    font-size: var(--fs-base);
    letter-spacing: 0.2em;
  }

  .header-cta {
    padding: 8px 12px;
    min-height: 44px;
    font-size: 0.78rem;
  }
}

/* ---------- фокус с клавиатуры ---------- */

/* До 2026-08-04 своего стиля фокуса на сайте не было ВООБЩЕ (аудит: 0 правил
   :focus-visible), и клавиатурная навигация шла дефолтным контуром браузера —
   синим в Chrome и почти невидимым поверх тёмного фона в Safari. Ставим своё
   кольцо: золото уровня действия + тёмная подложка вторым слоем, чтобы оно
   читалось и на фоне страницы, и поверх золотой заливки кнопок.
   :focus-visible (а не :focus) — мышь и палец кольца не получают.
   :where() держит нулевую специфичность: любое правило страницы перебивает
   это без !important. */
:where(a, button, summary, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--gold-light);
  outline-offset: 3px;
  box-shadow: 0 0 0 6px rgba(8, 8, 8, 0.75);
}

/* Внутри карточек и FAQ подложка не нужна — кольцо стоит на собственной
   поверхности, лишний ободок только утолщал бы его. */
:where(.level-card, .faq-item) :where(a, button, summary):focus-visible {
  box-shadow: none;
}

/* ---------- перенос строк ---------- */

/* Заголовки: браузер сам уравнивает длины строк вместо «лесенки», где
   последняя строка — одно слово. Раньше форма заголовка держалась только
   пропорцией колонки и ломалась на каждой второй ширине (замер 1280:
   четыре строки против трёх на 1512). Свойство поддерживают Chrome 114+ и
   Safari 17.4+; где его нет — перенос прежний, ничего не ломается. */
:where(h1, h2, h3, .level-name, .faq-q) {
  text-wrap: balance;
}

/* Абзацы: `pretty` не балансирует всю колонку (дорого на длинном тексте),
   но не даёт последней строке остаться одним коротким словом. */
:where(p, li, dd, figcaption) {
  text-wrap: pretty;
}
