/* MainShot — v3, общая основа. Подключается ПЕРВЫМ на каждом экране v3-*.
   Полная переделка вида. Что изменилось против v2 и почему:

   · Ось и симметрия. Фиксированного контейнера по центру нет (ТЗ §4): полосы идут
     во всю ширину, но у всех одни и те же поля, а текст ограничен мерой в знаках
     и стоит по центру этих полей. Симметрия — от равных полей и равных ячеек,
     а не от узкой ленты.
   · Воздух вместо линий. Шаг ритма один (--step), между блоками много пустого,
     волосяные линии остались только там, где правда делят перечень.
   · Глубина — ступенью тона, не тенью. Теней ноль (ТЗ §4).
   · Индикатор — родная терракота, два-три касания на экран. Главная кнопка —
     графитовая плита на ступень светлее фона: страница остаётся тёмной целиком.
   · Крупное против мелкого: шесть размеров с настоящим разрывом, середины нет.

   Двадцать имён переменных, которые потребляют живые правила, определены все:
   те, что не попали в семёрку, стали псевдонимами (ТЗ §2). */

/* Шрифт подключает отдельный лист /type.css — он идёт ПЕРВЫМ, до этого файла:
   Inter из /type/, woff2, четыре насыщенности (400, 500, 600, 700). Здесь @font-face
   нет намеренно: один владелец на одно решение. */

:root{
  /* семь ступеней графита — тёплые, под родной терракотовый знак */
  --g0:#0A0908; --g1:#13100F; --g2:#1D1917; --g3:#332D29;
  --g4:#514840; --g5:#8A837C; --g6:#CFC9C1;
  /* индикатор — один, родной цвет бренда из frontend/base.css */
  --ind:#CC785C;

  /* имена, которые читают живые правила */
  --bg:var(--g0); --surface:var(--g1); --surface-2:var(--g2);
  --border:var(--g3); --border-strong:var(--g4);
  --muted:var(--g5); --faint:var(--g5); --text:var(--g6);
  --clay:var(--ind); --clay-dark:#B25D43; --clay-soft:rgba(204,120,92,.13);
  --amber:var(--ind); --amber-dark:#B25D43; --amber-soft:rgba(204,120,92,.13);
  --danger:var(--ind); --danger-soft:rgba(204,120,92,.13);
  --green:var(--g5); --green-dark:var(--g5); --green-soft:var(--g2); --green-border:var(--g3);
  --sage:var(--g5); --sage-dark:var(--g5); --sage-soft:var(--g2);

  /* шесть размеров, середины нет */
  --t1:11px; --t2:15px; --t3:20px;
  --t4:clamp(26px,2.6vw,34px); --t5:clamp(40px,6.6vw,120px); --t6:clamp(56px,9vw,132px);

  --r:8px;
  --gut:clamp(18px,5vw,132px);   /* поля, равные слева и справа */

  /* Шкала отступов — такая же строгая, как шкала шрифтов: один шаг между полосами
     и три значения внутри полос, с настоящим разрывом. Промежуточных нет: 18 и 20
     рядом больше не встретятся, потому что таких чисел в системе не существует. */
  --step:clamp(68px,11vh,164px);   /* между полосами — единственное значение */
  --s1:8px;                        /* парные строки: значение под ключом */
  --s2:16px;                       /* подписи, строки перечня */
  --s3:32px;                       /* группа от группы */
  --mono:ui-monospace,SFMono-Regular,"SF Mono",Menlo,Consolas,monospace;
}

*{margin:0;padding:0;box-sizing:border-box}
html{-webkit-text-size-adjust:100%}
/* Кнопка ведёт на якорь выбора площадки. Прокрутка плавная — но только если человек
   не просил в системе уменьшить анимацию. */
@media (prefers-reduced-motion:no-preference){html{scroll-behavior:smooth}}
body{background:var(--bg);color:var(--text);font-family:Inter,system-ui,sans-serif;
  font-weight:400;font-size:var(--t2);line-height:1.55;
  min-height:100vh;display:flex;flex-direction:column}
.app{flex:1;display:flex;flex-direction:column}
img{display:block;max-width:100%}
button{font:inherit;color:inherit;background:none;border:0}
a{color:var(--text);text-decoration:none}
a:hover{color:var(--ind)}

/* Шрифт на странице один — Inter. Класс ниже даёт только табличные цифры,
   чтобы числа не прыгали по ширине, без смены начертания. */
.mono{font-variant-numeric:tabular-nums}
/* Надпись словами — обычным начертанием и общим размером текста. Моноширинное
   осталось только на чистых числах: размеры площадок и размер готового файла. */
.micro{display:block;font-size:var(--t2);font-weight:500;color:var(--muted)}
.hidden{display:none!important}
.screen{display:none}
.screen.active{display:block;flex:1 0 auto}
/* Возврат с оплаты: пока restoreOrder не выяснил, какой экран верный, не показываем
   НИ ОДНОГО. Иначе размеченный в html `active` экран загрузки успевает отрисоваться, и
   человек, только что заплативший, видит главную — «заказа нет». Метку ставит app.js
   синхронно (только когда заказ в памяти браузера есть) и снимает в finally. */
html.restoring .screen.active{display:none}

/* ── шапка ──────────────────────────────────────────────────────────────────── */
.hd{display:flex;align-items:center;justify-content:space-between;gap:var(--s2);
  flex-wrap:wrap;padding:var(--s2) var(--gut)}
.hd-logo{display:flex;align-items:center;gap:var(--s1)}
/* Плашка графитовая, буквы костяные — как заголовки на странице. Терракота держит
   волосяную обводку: акцент на месте, но цветным пятном в шапку не лезет. */
.hd-mark{width:26px;height:26px;border-radius:6px;
  background:var(--surface-2);color:var(--text);box-shadow:inset 0 0 0 1px var(--ind);
  font-size:var(--t1);font-weight:700;display:flex;align-items:center;justify-content:center}
.hd-word{font-size:var(--t1);font-weight:500;letter-spacing:.3em;color:var(--muted);
  transition:color .14s ease}
.hd-logo:hover .hd-word{color:var(--text)}
.hd-right{display:flex;align-items:center;gap:var(--s1) var(--s3);flex-wrap:wrap}
.hd-price{font-size:var(--t1);letter-spacing:.06em;color:var(--muted)}
.hd-price b{color:var(--text);font-weight:500}
.hd-bot{font-family:Inter,system-ui,sans-serif;font-size:var(--t2);color:var(--muted)}
.lang{display:flex}
.lang .lang-opt{min-height:48px;display:flex;align-items:center;padding:0 var(--s2);
  font-size:var(--t2);letter-spacing:.06em;color:var(--muted);
  cursor:pointer;user-select:none;transition:color .14s ease}
.lang .lang-opt:hover{color:var(--text)}
.lang .lang-opt.active{color:var(--text)}

/* ── подвал ─────────────────────────────────────────────────────────────────── */
.ft{border-top:1px solid var(--border);margin-top:var(--s3);
  padding:var(--s3) var(--gut);display:flex;flex-wrap:wrap;align-items:center;
  gap:var(--s2) var(--s3)}
.ft-links{display:flex;flex-wrap:wrap;gap:var(--s2) var(--s3)}
.ft-links a{font-size:var(--t2);color:var(--muted);transition:color .14s ease}
.ft-meta,.ft-count{font-size:var(--t2);color:var(--muted)}
.ft-count{margin-left:auto}

/* ── кнопки ─────────────────────────────────────────────────────────────────── */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--s1);
  min-height:48px;padding:var(--s2);border:1px solid var(--border-strong);
  border-radius:var(--r);color:var(--text);font-size:var(--t2);font-weight:500;
  cursor:pointer;text-align:center;transition:border-color .14s ease,color .14s ease}
.btn:hover{border-color:var(--muted)}
/* Главное действие — графитовая плита на ступень светлее фона, с волосяной обводкой.
   Ни костяного пятна, ни цветной заливки: страница остаётся тёмной целиком, кнопку
   держит тон и вес надписи. Под курсором плита поднимается ещё на ступень. */
.btn.primary{background:var(--g3);border-color:var(--muted);color:var(--text)}
.btn.primary:hover{background:var(--g4);border-color:var(--g6);color:var(--text)}
.btn.lg{min-height:56px;padding:var(--s2) var(--s3);font-size:var(--t2)}
.btn.disabled,.btn:disabled{opacity:.45;cursor:default}

/* ── появление: только на загрузке страницы, по времени ───────────────────────
   Привязку к прокрутке (`animation-timeline: view()`) убрал: там, где таймлайн не
   пересчитывается, секции залипают в первом кадре и половина страницы просто
   не видна. Видимость содержимого не должна зависеть от анимации — поэтому
   двигается только герой, один раз, по обычному таймеру. */
@keyframes rise{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}
/* Одно собранное появление на загрузке: заголовок, лид, условие и инструмент выходят
   в очередь, а не все сразу. Всё по обычному таймеру — к прокрутке ничего не привязано,
   поэтому видимость содержимого ни от чего не зависит. */
@media (prefers-reduced-motion:no-preference){
  .hero h1,.hero-lead,.hero-sub,.tool{animation:rise .55s ease-out both}
  .hero-lead{animation-delay:.08s}
  .hero-sub{animation-delay:.16s}
  .tool{animation-delay:.24s}
}

/* ── плашки сверху страницы: одна геометрия на три случая ─────────────────────
   Промо-остаток (9.2), обслуживание (9.4) и гейт-плашка (10.7). Разный смысл —
   разный тон подложки, но полоса, отступы и выравнивание общие: три разные
   геометрии наверху читались бы как три разных сайта.
   Место — самая первая строка, над шапкой. */
.topbar{padding:var(--s2) var(--gut);text-align:center;font-size:var(--t2);
  border-bottom:1px solid var(--border)}
.topbar[hidden]{display:none}
/* Число в счётчике внизу: сосед подписи, поэтому свой класс. Табличные цифры —
   чтобы строка не дёргалась, когда счётчик растёт. */
.ft-num{font-variant-numeric:tabular-nums}
/* Промо: кампания идёт — единственный случай, когда полоса зовёт, а не предупреждает. */
.promo-banner{background:var(--clay-soft);color:var(--text);
  border-bottom-color:rgba(204,120,92,.3)}
.promo-counts{font-weight:500;font-variant-numeric:tabular-nums;color:var(--ind)}
/* Обслуживание: жёлтой полосы с живого сайта здесь нет — на графите она орёт.
   Служебное сообщение говорит тоном подложки, а не цветом. */
#maint-banner{background:var(--surface-2);color:var(--muted)}
/* Гейт: код уже применён, полоса липнет к верху и едет со страницей. */
#gate-banner{position:sticky;top:0;z-index:50;background:var(--surface-2);color:var(--text)}

/* ── состояния без текста (ТЗ §11) ────────────────────────────────────────────
   Один приём на весь сайт: тон подложки отвечает на курсор, обводка индикатора —
   на клавиатуру. Размер элемента не меняется ни в одном состоянии, иначе строка
   прыгает под пальцем. */
:where(a,button,input,[tabindex]):focus-visible{outline:2px solid var(--ind);
  outline-offset:2px;border-radius:var(--r)}
.btn:active,.mkt-b:active{transform:translateY(1px)}
/* Выключено — очевидно бесполезно, но не похоже на ошибку: тон гаснет, цвет не меняется. */
.btn.disabled,.btn:disabled,.dropzone.disabled{opacity:.45;cursor:default}
.btn.disabled:hover,.btn:disabled:hover{border-color:var(--border-strong)}
/* Идёт отправка: повторное нажатие невозможно и видимо невозможно. */
.btn.loading{opacity:.6;pointer-events:none}
.btn.loading::after{content:"";width:12px;height:12px;border-radius:50%;
  border:2px solid var(--muted);border-top-color:transparent;animation:spin .7s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.btn.loading::after{animation:none}}

/* ── поле ввода и его ошибка ──────────────────────────────────────────────────
   Место под сообщение занято всегда: иначе появление ошибки сдвигает всё вниз. */
/* Поле и кнопка делят строку целиком: правый край кнопки совпадает с правым краем
   адреса над ней, левый край поля — с левым. */
.field{display:flex;flex-wrap:wrap;gap:var(--s1);align-items:stretch}
.field .btn{flex:0 0 auto;min-width:140px}
.field input{flex:1 1 60%;min-height:48px;padding:0 var(--s2);
  background:var(--g0);color:var(--text);border:1px solid var(--border-strong);
  border-radius:var(--r);font:inherit;transition:border-color .14s ease}
.field input::placeholder{color:var(--g4)}
.field input:hover{border-color:var(--muted)}
.field input.cc-bad{border-color:var(--ind)}
.field-msg{display:block;min-height:1.55em;margin-top:var(--s1);font-size:var(--t2);
  color:var(--muted)}
.field-msg.bad{color:var(--ind)}
.field-msg.ok{color:var(--text)}

/* ── строка ошибки и предупреждение ───────────────────────────────────────────
   Ошибка — сигнальная, у неё вертикальная черта индикатора. Предупреждение мягче:
   тон подложки, без черты, потому что оно не блокирует действие. */
.err-line{padding-left:var(--s2);border-left:2px solid var(--ind);color:var(--text)}
.warn-line{padding:var(--s2);background:var(--surface-2);border-radius:var(--r);
  color:var(--muted)}

/* ── карточка хода работы ─────────────────────────────────────────────────────
   Один вид, пять состояний значка. Скрипт строит её сам — здесь только вид. */
/* Карточку собирает app.js: внутри всегда заголовок со значком, под ним содержимое.
   Поэтому она блок, а не сетка — сетка развалила бы порядок его узлов. */
.flow-card{padding:var(--s2);background:var(--surface);
  border:1px solid var(--border);border-radius:var(--r)}
.fc-title{display:flex;align-items:center;font-size:var(--t2);font-weight:500}
.fc-body{color:var(--muted);margin-top:var(--s1);text-wrap:pretty}
.fc-acts{display:flex;flex-wrap:wrap;gap:var(--s1);margin-top:var(--s2)}
.fc-acts .btn{min-height:44px;padding:var(--s1) var(--s2)}
.stuck-msg{margin-top:var(--s2);color:var(--muted);text-wrap:pretty}

/* ── общее для экранов потока ─────────────────────────────────────────────────
   Ленты по центру нет: текст держит меру в знаках и стоит по центру общих полей. */
.flow{padding:var(--s3) var(--gut) 0;text-align:center}
.flow h1{font-size:var(--t4);font-weight:700;letter-spacing:-.02em;line-height:1.1}
.flow .sub{color:var(--muted);margin-top:var(--s1)}
.measure{max-width:54ch;margin-inline:auto}
.panel{background:var(--surface);border:1px solid var(--border);border-radius:var(--r);
  padding:var(--s3) var(--s2)}
.acts{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--s1);margin-top:var(--s3)}
.acts .btn{flex:0 1 260px}
.label{display:block;font-size:var(--t2);color:var(--muted);margin-bottom:var(--s1)}

/* ── то, что рождается в app.js ───────────────────────────────────────────────
   Эти узлы страница не содержит: их собирает скрипт своими именами классов.
   Правила здесь — единственное место, где задан их вид. */

/* карточка хода работы: значок состояния стоит внутри заголовка */
.fc-status{display:inline-flex;align-items:center;justify-content:center;
  width:16px;height:16px;flex:0 0 16px;margin-right:var(--s1)}
.fc-status svg{width:16px;height:16px}
/* Пройденная группа читается, текущая тише: разница тоном, без второго цвета. */
.flow-card.passed .fc-status,.flow-card.passed .fc-icon{color:var(--text)}
/* Текущие подпункты — это то, что проверяется прямо сейчас, а не выключенное:
   тон тот же, что у остального текста, а «идёт» показывает крутящийся значок. */
.flow-card.checking .fc-check{color:var(--muted)}
.fc-check{display:flex;align-items:baseline;gap:var(--s1);margin-top:var(--s1);
  color:var(--muted);text-wrap:pretty}
.fc-check strong{color:var(--text);font-weight:500}
/* Подсказка к замечанию. Имени класса у неё нет — app.js отдаёт голый span с inline-стилем
   (font-size:.85em;opacity:.7), поэтому цепляемся за форму: второй span внутри строки.
   Если в коде появится class="fc-tip", правило можно будет упростить. */
.fc-check div > span{display:block;margin-top:2px;color:var(--muted);text-wrap:pretty}
/* Значок замечания — знак, а не картинка: в коде на этом месте стоит пустая строка,
   поэтому его рисует правило, а не разметка. */
.flow-card.warning .fc-check .fc-icon::before{content:"!";color:var(--ind);font-weight:500}
/* Знак в заголовке. getStatusIcon в app.js возвращает для этих состояний пустую строку,
   поэтому знак рисует правило — иначе на живой странице заголовок выйдет без метки. */
.flow-card.warning .fc-status,.flow-card.duplicate .fc-status,
.flow-card.error .fc-status{color:var(--ind);font-weight:500}
.flow-card.warning .fc-status:empty::before,
.flow-card.duplicate .fc-status:empty::before,
.flow-card.error .fc-status:empty::before{content:"!"}
.fc-icon{display:inline-flex;align-items:center;justify-content:center;
  width:14px;height:14px;flex:0 0 14px;position:relative;top:2px;color:var(--text)}
.fc-icon svg{width:14px;height:14px}
.fc-btn{display:inline-flex;align-items:center;justify-content:center;min-height:44px;
  padding:var(--s1) var(--s2);margin-top:var(--s1);margin-right:var(--s1);
  border:1px solid var(--border-strong);border-radius:var(--r);background:none;
  color:var(--text);font:inherit;font-weight:500;cursor:pointer;
  transition:border-color .14s ease}
.fc-btn:hover{border-color:var(--muted)}
.fc-btn.primary{background:var(--g3);border-color:var(--muted)}
.fc-btn.primary:hover{background:var(--g4);border-color:var(--g6)}
/* Отмена заказа — единственное необратимое действие: черта индикатора, не заливка. */
.fc-btn.danger{border-left:2px solid var(--ind)}
.fc-spinner{display:inline-block;width:14px;height:14px;border-radius:50%;
  border:2px solid var(--g4);border-top-color:var(--text);animation:spin .7s linear infinite}
@media (prefers-reduced-motion:reduce){.fc-spinner{animation:none}}
/* Широкая карточка: оплата и дубликат несут внутри сетку сетей. */
.flow-card.wide{grid-template-columns:1fr}
.flow-card.wide .fc-title{margin-bottom:var(--s1)}

/* Кнопка оплаты. Сеть одна, поэтому это действие, а не выбор: правила старой сетки
   сетей (.net-coin, .net-chain и коробка на 120px) убраны вместе с ней — на экранах
   их больше нет ни одного. Наведение задаёт .fc-btn.primary, здесь его нет намеренно:
   два правила на одну кнопку спорили бы, и выигрывало бы более длинное. */
.net-card{display:flex;align-items:center;justify-content:center;cursor:pointer}

/* промокод внутри карточки оплаты */
.promo-input-wrap{display:flex;flex-wrap:wrap;gap:var(--s1);margin-top:var(--s1)}
.promo-input-wrap input{flex:1 1 180px;min-height:48px;padding:0 var(--s2);
  background:var(--g0);color:var(--text);border:1px solid var(--border-strong);
  border-radius:var(--r);font:inherit}
.promo-input-wrap input::placeholder{color:var(--g4)}
.promo-input-wrap button{min-height:48px;padding:0 var(--s2);border:1px solid var(--border-strong);
  border-radius:var(--r);background:none;color:var(--text);font:inherit;font-weight:500;
  cursor:pointer;transition:border-color .14s ease}
.promo-input-wrap button:hover{border-color:var(--muted)}
.promo-result{display:block;min-height:1.55em;margin-top:var(--s1);color:var(--muted)}

/* Отсчёт на исходе. Индикатор — единственная разница: размер и место не меняются,
   иначе строка дёргается ровно в тот момент, когда на неё смотрят. */
.urgent{color:var(--ind)}
