/* Стили экранов потока $1.19. Собраны из макетов v3-upload.css, v3-checks.css, v3-payment.css, v3-processing.css, v3-download.css, v3-error.css, v3-overlay.css;
   порядок тот же, что был у подключений на отдельных страницах. Палитра, размеры и
   геометрия сюда не входят — они в base.css, и ни одно правило здесь их не
   переопределяет: это проверяет отдельный сторож. */

/* ── v3-upload.css ── */
/* Экран 1 — загрузка, v3. Подключается после v3-base.css.

   Верх без фотографии: сначала обещание, сразу за ним сам инструмент, и только
   потом работы — все снимки ушли вниз, как и просили. Туфель нет ни здесь, ни в
   витрине. Названий предметов под фото нет: и так видно.

   Повторы вычищены: «без карты и регистрации» названо один раз (в инструменте),
   «никаких списаний» один раз (в финале), блок «у сервисов → у нас» убран целиком —
   он повторял те же четыре факта другими словами. Ни одна формулировка не
   переписана: показаны те же ключи data-i18n, просто не по два раза. */

/* ── обещание ───────────────────────────────────────────────────────────────── */
/* Над заголовком уже стоит строка условий — сверху малое значение, иначе два
   разделителя подряд. Снизу среднее: тон сам отделяет полосу инструмента. */
.hero{padding:var(--s2) var(--gut) var(--s3);text-align:center}
.hero h1{font-size:var(--t5);font-weight:700;line-height:.96;letter-spacing:-.042em;
  max-width:17ch;margin:0 auto;text-wrap:balance}
.w-light{font-weight:400}      /* контраст на крупном — весом, не цветом (ТЗ §2) */
/* Под заголовком воздуха меньше: лид подходит ближе, подстрочник — вплотную к нему. */
.hero-lead{font-size:var(--t3);line-height:1.45;color:var(--muted);max-width:54ch;
  margin:var(--s2) auto 0;text-wrap:pretty}
.hero-sub{margin-top:var(--s1);color:var(--muted)}
/* Ограничение — тише лида: его читают вторым, и оно не должно спорить с обещанием. */
.hero-limit{max-width:54ch;margin:var(--s2) auto 0;color:var(--faint);
  font-size:var(--t2);text-wrap:pretty}

/* ── инструмент: единственная полоса со своим тоном ─────────────────────────── */
/* Шаг снаружи уже дал герой — внутри полосы берём большое значение шкалы,
   иначе два шага сложатся в прежнюю дыру. */
.tool{background:var(--surface);border-block:1px solid var(--border);
  padding:var(--s3) var(--gut) var(--s2)}
.tool .micro{text-align:center}
/* Плитки без рамки у каждой: их делит тон подложки и зазор сетки. */
.mkt{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--s1);margin-top:var(--s3);
  scroll-margin-top:var(--s3)}
@media(min-width:600px){.mkt{grid-template-columns:repeat(3,1fr)}}
@media(min-width:1100px){.mkt{grid-template-columns:repeat(6,1fr)}}
/* Класс btn на плитке — не украшение: app.js слушает «#marketplace-selector .btn».
   Правила ниже перекрывают общую кнопку целиком. */
.mkt .btn{border:1px solid var(--border);font-weight:400}
.mkt-b{position:relative;display:flex;align-items:center;justify-content:center;
  min-height:72px;padding:var(--s2);background:var(--g0);cursor:pointer;overflow:hidden;
  border:1px solid var(--border);border-radius:var(--r);
  transition:background-color .14s ease,border-color .14s ease}
.mkt-b:hover{background:var(--g2);border-color:var(--border-strong)}
/* Выбранная площадка — тон плюс полоса индикатора снизу. Полоса — отдельным
   элементом, а не тенью: теней на сайте ноль (ТЗ §4). */
.mkt-b.active{background:var(--g2)}
.mkt-b.active::after{content:"";position:absolute;left:0;right:0;bottom:0;height:2px;
  background:var(--ind)}
.mkt-n{font-size:var(--t2);font-weight:500}

/* Пунктира нет: пунктир всегда читается дешёво. Сплошная волосяная линия
   и ступень тона, которая поднимается при наведении. */
.dropzone{margin-top:var(--s3);padding:var(--s2) var(--s3);
  border:1px solid var(--border-strong);border-radius:var(--r);background:var(--g0);
  text-align:center;cursor:pointer;
  transition:border-color .14s ease,background-color .14s ease}
.dropzone:hover,.dropzone.hover{border-color:var(--ind);background:var(--g2)}
.dropzone.ready{border-color:var(--ind)}
.dropzone.disabled{cursor:default}
.dropzone.disabled:hover{border-color:var(--border-strong);background:var(--g0)}
.dz-text{display:block;font-size:var(--t2);font-weight:500}
.dz-l{display:block;font-size:var(--t2);color:var(--muted);margin-top:var(--s1)}
#turnstile-box{display:flex;justify-content:center;margin-top:var(--s2)}
#turnstile-box:empty{display:none}   /* пустой — не занимает место, отступы поля равные */
#hp{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);
  opacity:0;pointer-events:none}
.dz-foot{margin-top:var(--s3);text-align:center;color:var(--muted);text-wrap:pretty}

/* ── четыре факта ───────────────────────────────────────────────────────────── */
/* Отступ после полосы инструмента — на месте: тон её отделяет, но воздух всё равно
   нужен, иначе факты липнут к границе. Внутренний отступ полосы при этом уменьшен,
   чтобы стык не был вдвое больше остальных. */
/* Строка условий наверху: все четыре ключа одной строкой, все четыре значения —
   второй строкой под ними, колонка в колонку, во всю ширину лендинга. Линии снизу нет,
   отступы обычные. Узко — просто пары в два столбца, иначе не влезает. */
.facts{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--s3);
  padding:var(--s3) var(--gut) 0}
.facts.top{padding:var(--s2) var(--gut)}
.f-k{display:block;font-size:var(--t2);font-weight:500;color:var(--text);
  margin-bottom:var(--s1)}
.f-v{display:block;color:var(--muted);text-wrap:pretty}
@media(min-width:760px){
  /* Колонки по ширине содержимого, свободное место поровну между ними: первый пункт
     стоит на левом крае содержимого, последний — ровно на правом, промежутки равные.
     Равные доли этого не давали: тексты разной длины, и справа оставалась пустота. */
  .facts{grid-template-columns:repeat(4,auto);justify-content:space-between;
    row-gap:var(--s1);column-gap:var(--s3)}
  .facts > div{display:contents}
  .f-k{grid-row:1;margin-bottom:0;white-space:nowrap}
  .f-v{grid-row:2}
  .facts > div:nth-child(1) .f-k,.facts > div:nth-child(1) .f-v{grid-column:1}
  .facts > div:nth-child(2) .f-k,.facts > div:nth-child(2) .f-v{grid-column:2}
  .facts > div:nth-child(3) .f-k,.facts > div:nth-child(3) .f-v{grid-column:3}
  .facts > div:nth-child(4) .f-k,.facts > div:nth-child(4) .f-v{grid-column:4}
}
/* Широко колонка вмещает значение целиком — переносов нет, строка ровная. */
@media(min-width:1200px){.f-v{white-space:nowrap}}

/* ── правила пригодности: внутри полосы инструмента, сразу под полем ──────────
   Внизу страницы им было нечего делать — это подсказка к выбору файла. */
.guide{margin-top:var(--s3);display:grid;grid-template-columns:1fr;gap:0 var(--s3)}
@media(min-width:860px){.guide{grid-template-columns:repeat(2,1fr)}}
.g-row{display:grid;grid-template-columns:18px minmax(0,1fr);gap:var(--s2);padding:var(--s2) 0;
  border-top:1px solid var(--border)}
/* Маркеры перечня — на читаемой ступени: запрет «✗» должен быть виден так же
   ясно, как «✓», иначе он не работает. --g4 остаётся границам. */
.g-i{font-size:var(--t2);color:var(--muted);line-height:1.5}
.g-i.ok,.g-i.no{color:var(--text)}
.g-t{font-size:var(--t2);font-weight:500;margin-bottom:var(--s1)}
.g-b{color:var(--muted);text-wrap:pretty}

/* ── финал ──────────────────────────────────────────────────────────────────── */
.close{padding:var(--s3) var(--gut) 0;text-align:center}
.close h2{font-size:var(--t4);font-weight:700;letter-spacing:-.02em;line-height:1.1}
.close-note{color:var(--muted);max-width:48ch;margin:var(--s2) auto 0;text-wrap:pretty}
.close .btn{margin-top:0}

/* ── плашка беты ────────────────────────────────────────────────────────────── */
#maint-banner{padding:var(--s2) var(--gut);background:var(--clay-soft);color:var(--text);
  border-bottom:1px solid rgba(204,120,92,.3);font-size:var(--t2);text-align:center}
#maint-banner[hidden]{display:none}

/* ── v3-checks.css ── */
/* Экран проверки — то, что человек видит после загрузки и до оплаты.
   Подключается после type.css и v3-base.css.

   В разметке этого экрана нет: он рождается в app.js внутри узла card-flow.
   Здесь задан только вид. Состояния разложены по соседним файлам, потому что на
   живой странице они не встречаются: v3-checks (идёт), v3-checks-passed (прошло),
   v3-checks-warning (замечания), v3-errors (обрыв).

   Группы стоят плашками в ряд и равной высоты: их проверяют почти одновременно,
   и колонкой во всю ширину экран превращался в портянку. Карточки, которые несут
   решение — замечания, оплата, обрыв, — занимают всю строку: в них кнопки. */

.checks{padding:var(--s2) var(--gut) 0;text-align:center}
.checks h1{font-size:var(--t4);font-weight:700;letter-spacing:-.02em;line-height:1.1}
.checks .sub{color:var(--muted);margin-top:var(--s1)}
/* Честная закачка: реальный процент отправки файла, пишется скриптом (up_progress).
   Цвет основного текста, не muted — пока файл летит, это главная строка экрана
   (просьба владельца 2026-08-10: ярче). */
#up-progress{color:var(--text);font-size:var(--t2);margin-top:var(--s1);
  font-variant-numeric:tabular-nums}

#card-flow{margin-top:var(--s3);padding:0 var(--gut);text-align:left;
  display:grid;grid-template-columns:1fr;gap:var(--s2);align-items:stretch;
  justify-items:stretch}
/* На широком экране все пять групп стоят в одну строку — там ряд заполнен целиком.
   Уже — три и две колонки: последний ряд может быть неполным, но плашки остаются
   одного размера, а экран не вытягивается в портянку. */
@media(min-width:560px){#card-flow{grid-template-columns:repeat(2,1fr)}}
@media(min-width:900px){#card-flow{grid-template-columns:repeat(3,1fr)}}
@media(min-width:1100px){#card-flow{grid-template-columns:repeat(5,1fr)}}
#card-flow .flow-card{padding:var(--s3)}
/* Группы одного размера, даже если в одной три пункта, а в другой пять: высота
   задана по самой полной. Только там, где колонок несколько: в одну колонку равнять
   нечего, и высота там только делала бы пустоту.
   Равнять их с карточкой решения (замечания, оплата) тоже нельзя — та втрое выше. */
@media(min-width:560px){
  #card-flow .flow-card.passed,#card-flow .flow-card.checking{min-height:15rem}
}
#card-flow .flow-card.passed,#card-flow .flow-card.checking{min-height:15rem}
#card-flow .flow-card.warning,#card-flow .flow-card.payment,
#card-flow .flow-card.error,#card-flow .flow-card.foot,
#card-flow .warn-line{grid-column:1/-1}
/* Плашка была растянута на всю ширину, а СОДЕРЖИМОЕ — нет: строки «значок + название +
   подсказка» и кнопки имели ширину по тексту и жались влево, справа оставалась пустыня.
   Владелец описал это как «прибито к левому краю и не по ширине экрана». Растягиваем то,
   что внутри. */
#card-flow .flow-card.warning .fc-check,
#card-flow .flow-card.foot .fc-check{width:100%}
#card-flow .flow-card.warning .fc-check>div,
#card-flow .flow-card.foot .fc-check>div{flex:1 1 auto;min-width:0}
#card-flow .flow-card.warning .fc-btn,
#card-flow .flow-card.foot .fc-btn{width:100%;margin-right:0}
/* Подсказка была ослаблена ТРИЖДЫ: размер 0.85, прозрачность 0.7 и приглушённый цвет из
   base.css. Три ослабления подряд на тёмном фоне — это и есть «нихуя не видно». Осталась
   разница тоном, без размера и прозрачности; имя класса теперь есть, inline-стиля нет. */
#card-flow .fc-tip{display:block;margin-top:2px;color:var(--muted);opacity:1;
  font-size:inherit;text-wrap:pretty}
/* Итог и цена в нижнем блоке. Один стиль со всеми плашками: поля, рамка и скругление
   приходят от .flow-card, здесь только строки. */
#card-flow .flow-card.foot .fc-sum{color:var(--text);text-wrap:pretty}
#card-flow .flow-card.foot .fc-paid{color:var(--muted);margin-top:var(--s1);
  padding-top:var(--s1);border-top:1px solid var(--border);text-wrap:pretty}
#card-flow .fc-title{font-size:var(--t3);margin-bottom:var(--s2)}

/* Последняя карточка успешного пути. Сеть одна, поэтому это кнопка, а не выбор. */
.flow-card.payment .net-card{display:flex;width:100%;margin-top:var(--s2);
  min-height:52px;padding:0 var(--s3)}
.promo-block{margin-top:var(--s3);padding-top:var(--s2);border-top:1px solid var(--border)}
.promo-q{color:var(--muted)}

/* ── v3-payment.css ── */
/* Экран 2 — оплата, v3. Подключается после type.css и v3-base.css.

   Состав из ТЗ §6 и §9.3, состояния из §10.2. Здесь человек ждёт и нервничает,
   поэтому порядок такой: сколько и куда, потом сколько осталось времени, потом
   промокод, и только внизу отмена.

   Две колонки, а не портянка: слева всё, что делают руками — адрес, отсчёт, код;
   справа то, на что смотрят с другого устройства, — QR и кошелёк. На узком экране
   колонки складываются, QR уходит под адрес.

   Сумма — единственное крупное число на экране. Memo снято решением владельца. */

.pay{padding:var(--s3) var(--gut) 0;text-align:center}
.pay-amount{font-size:var(--t5);font-weight:700;line-height:1;letter-spacing:-.04em;
  font-variant-numeric:tabular-nums;margin-top:var(--s2)}
.pay-net{color:var(--muted);margin-top:var(--s1)}
/* «Скопировать сумму» — тихая кнопка под суммой, тем же приёмом, что номер заказа.
   Нужна потому, что в QR провайдера суммы нет: с телефона её набирают руками, а
   опечатка в сумме — это недоплата и повисший заказ. */
.pay-amount-copy{display:inline-block;margin-top:var(--s1);color:var(--muted);
  background:none;border:0;border-bottom:1px dashed var(--border-strong);
  padding:0 2px;cursor:pointer;font-size:var(--t2);font-family:inherit}
.pay-amount-copy:hover{color:var(--text);border-bottom-color:var(--ind)}

/* Колонки одной высоты: начинаются и кончаются на одной линии. */
.pay-grid{display:grid;grid-template-columns:1fr;gap:var(--s3);
  margin-top:var(--s3);text-align:left;align-items:stretch}
@media(min-width:900px){
  /* Правая дорожка узкая и с потолком: код квадратный, и колонка не должна
     разъезжаться шире него, иначе квадрат плавает в пустоте. */
  .pay-grid{grid-template-columns:minmax(0,1fr) minmax(240px,280px)}
}

/* Кнопка оплаты — единственное действие на экране, поэтому во всю ширину колонки и
   заметная. Выключенная (пока сервер не дал ссылку) выглядит выключенной, а не бледной:
   вести ей некуда, и человек не должен по ней стучать. */
#pay-open-btn{display:block;width:100%;padding:var(--s2);font-size:var(--t2)}
#pay-open-btn[disabled]{opacity:.45;cursor:default;pointer-events:none}
.pay-hint{color:var(--muted);margin-top:var(--s1);text-wrap:pretty}

/* Частичная оплата — самый длинный текст на экране и единственный, который надо
   прочитать целиком: человек уже отправил деньги и боится, что потерял их. */
#pay-partial-note{margin:var(--s3) auto 0;text-align:left}

/* Отсчёт тикает раз в секунду — цифры табличные, соседнее не дёргается. */
.pay-state{margin-top:var(--s3)}
.pay-wait{display:inline-flex;align-items:center;gap:var(--s1);color:var(--muted)}
.pay-wait::before{content:"";width:7px;height:7px;flex:0 0 7px;border-radius:50%;
  background:var(--ind)}
/* Подсказка заплатившему. Цветом ТЕКСТА, не приглушённым, и с той же точкой-индикатором,
   что у строки ожидания, — она обязана читаться как живое состояние, а не как сноска.
   Первый заход был серым и ниже отсчёта: владелец её не заметил за семь минут на экране. */
#pay-sent-hint.pay-sent{display:flex;align-items:baseline;gap:var(--s1);
  margin-top:var(--s1);color:var(--text);text-wrap:pretty;
  font-variant-numeric:tabular-nums}
#pay-sent-hint.pay-sent::before{content:"";width:7px;height:7px;flex:0 0 7px;
  border-radius:50%;background:var(--ind);transform:translateY(-1px)}

/* Поле для хеша — спасательный круг: свёрнуто, приглушено, не спорит с кнопкой оплаты. */
.pay-hash{margin-top:var(--s2)}
.pay-hash>summary{color:var(--muted);cursor:pointer;list-style:none}
.pay-hash>summary::-webkit-details-marker{display:none}
.pay-hash>summary::before{content:"?";display:inline-flex;align-items:center;
  justify-content:center;width:16px;height:16px;margin-right:var(--s1);
  border:1px solid var(--border-strong);border-radius:50%;font-size:11px}
.pay-hash>summary:hover{color:var(--text)}
.pay-hash .field{margin-top:var(--s1)}
.pay-hash input{font-variant-numeric:tabular-nums}

.promo{margin-top:var(--s3)}
/* Ряд действий живёт внутри левой колонки и прижат к её низу: обе кнопки ровно по
   ширине левой колонки, под кодом их нет. Правая колонка при этом кончается на той же
   линии — кошелёк прижат к низу своей. */
.pay-left{display:flex;flex-direction:column;min-width:0}
.pay .acts{display:grid;grid-template-columns:repeat(2,1fr);gap:var(--s1);
  margin-top:var(--s3)}
@media(max-width:560px){.pay .acts{grid-template-columns:1fr}}

/* Правая колонка — «как не потерять заказ». Раньше здесь стоял QR; он уехал вместе с
   адресом на страницу провайдера, а место осталось за тем, о чём надо сказать
   ДО оплаты: заказ живёт в этом браузере. Колонка по-прежнему читается сверху вниз и
   кончается на одной линии с левой. */
.pay-aside{display:flex;flex-direction:column;min-width:0}
.pay-keep{display:flex;flex-direction:column;gap:var(--s1);padding:var(--s2);min-width:0;
  background:var(--surface-2);border:1px solid var(--border);border-radius:var(--r)}
.pay-keep-title{font-weight:600}
/* Текст спокойный, приглушённый и НЕ красный: это предупреждение, а не авария. */
.pay-keep-text{color:var(--muted);text-wrap:pretty;margin:0}
/* Второй шаг появляется только по согласию — ссылка и есть ключ от заказа. */
.pay-keep-confirm{display:flex;flex-direction:column;gap:var(--s1);
  margin-top:var(--s1);padding-top:var(--s1);border-top:1px solid var(--border)}
/* Ссылка на заказ — длинная и БЕЗ ЕДИНОГО ПРОБЕЛА. Без разрешения ломаться по любому
   знаку она распирает колонку, а с ней и всю страницу: на 320 точках сетка уезжала до
   785 (поймано стражем приёмки вёрстки). Тот же случай, что был с адресом кошелька. */
.pay-keep-msg{color:var(--text);margin-top:var(--s1);overflow-wrap:anywhere;
  word-break:break-word}
.pay-keep .btn{width:100%;margin-top:var(--s1)}

/* ── v3-processing.css ── */
/* Экран 3 — обработка, v3. Подключается после /type.css и v3-base.css.

   Состав из ТЗ §6, состояния из §10.3. Здесь человек только ждёт, поэтому на
   экране всего два сообщения: сколько прошло и что происходит сейчас.

   Процент — единственное крупное число. Полоса идёт от края до края: это
   состояние всей страницы, а не элемент в колонке. */

.proc{padding:var(--step) var(--gut) 0;text-align:center}
/* Число пишет app.js в текст этого узла, поэтому рисовать его правилом нельзя —
   вышло бы два числа подряд. Цифры табличные: при смене значения ширина не гуляет
   и соседние блоки не дёргаются.
   Плавность самого счёта — на стороне кода: сейчас он идёт шагами по 110 мс к цели,
   которая скачет (bumpProgress с 45 сразу на 60 и 90). Ровным он станет, если вести
   не цель, а само значение — тем же ходом, что полоса ниже. */
.proc-pct{font-size:var(--t5);font-weight:700;line-height:1;letter-spacing:-.04em;
  font-variant-numeric:tabular-nums}
.proc-status{font-size:var(--t3);margin-top:var(--s1)}

/* Три шага в строку. Пройденный и текущий читаются, будущий приглушён —
   разница тоном, без значков и без цвета. */
.steps{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--s2) var(--s3);
  margin-top:var(--s3)}
/* Имя класса задаёт app.js: он переписывает className целиком на «proc-step done»
   или «proc-step active». Своё имя здесь означало бы, что состояние молча не применится. */
.proc-step{display:inline-flex;align-items:center;gap:var(--s1);color:var(--g4)}
.proc-step::before{content:"";width:7px;height:7px;flex:0 0 7px;border-radius:50%;
  background:currentColor}
.proc-step.done{color:var(--muted)}
.proc-step.active{color:var(--text)}
.proc-step.active::before{background:var(--ind)}

/* Полоса во всю ширину — под шагами, вплотную к краям экрана. */
.pbar{height:2px;background:var(--border);margin-top:var(--s3)}
/* Ширину полосы пишет app.js в inline-стиль, поэтому здесь только переход — он и
   сглаживает его шаги. Анимацией ширину задавать нельзя: она перебивает inline-запись,
   и полоса встала бы на месте на всё время работы. */
.pfill{height:100%;background:var(--ind);
  transition:width .6s cubic-bezier(.22,.61,.36,1)}

/* Карточки хода работы. Их строит скрипт — здесь по одному образцу на состояние,
   чтобы вид был задан заранее, а не сочинялся в коде. */
/* Плашками во всю ширину — как на экране проверки. Широкие карточки (оплата, дубликат,
   ошибка) занимают всю строку: у них внутри своя сетка и кнопки. */
/* Сообщение о задержке — единственное, что может добавиться на этом экране. */
.stuck-msg{max-width:54ch;margin:var(--step) auto 0;padding:0 var(--gut);
  color:var(--muted);text-align:center;text-wrap:pretty}

/* ── v3-download.css ── */
/* Экран 4 — скачивание, v3. Подключается после /type.css и v3-base.css.

   Состав из ТЗ §6, состояния из §10.4. Порядок простой: файл готов → забери →
   он скоро исчезнет. Отсчёт до удаления стоит рядом с кнопкой, а не в подвале:
   это единственная причина торопиться.

   Фотографии на экране нет. Готовый файл всегда на чистом белом, и на графите он
   превратился бы в слепящий прямоугольник; в макете вместо него рамка кадра с его
   настоящими пропорциями — app.js подставит туда изображение. */

.dl{padding:var(--s3) var(--gut) 0;text-align:center}

/* Рамка кадра. Подпись лежит ПОД изображением, а не рядом с ним: app.js владеет только
   узлом dl-result-img и соседей не трогает, поэтому сосед остался бы виден рядом с фото. */
.dl-frame{position:relative;max-width:340px;margin:var(--s3) auto 0;aspect-ratio:3/4;
  border:1px solid var(--border-strong);border-radius:var(--r);background:var(--surface);
  display:flex;align-items:center;justify-content:center;overflow:hidden}
.dl-slot{position:absolute;z-index:0}
#dl-result-img{position:relative;z-index:1;max-width:100%;max-height:100%;
  border-radius:var(--r)}
.dl-slot{color:var(--muted);font-size:var(--t2);font-variant-numeric:tabular-nums}

/* Отчёт о проверках. Четыре категории, девятнадцать пунктов — состав из app.js.
   Категории идут колонками и переносятся: на 320 остаётся одна колонка, ничего не
   прячется в боковую прокрутку. */
/* Плашки во всю ширину и равной высоты: сетка тянет их по самой высокой в ряду,
   поэтому категория из четырёх пунктов не выглядит обрубком рядом с категорией из шести. */
#dl-checks-col{display:grid;grid-template-columns:1fr;gap:var(--s2);
  margin:var(--s3) calc(var(--gut)*-1) 0;padding:0 var(--gut);
  text-align:left;align-items:stretch;grid-auto-rows:1fr}
@media(min-width:640px){#dl-checks-col{grid-template-columns:repeat(2,1fr)}}
@media(min-width:1100px){#dl-checks-col{grid-template-columns:repeat(4,1fr)}}
.dl-card{padding:var(--s2);background:var(--surface);border:1px solid var(--border);
  border-radius:var(--r)}
.dl-card-title{display:flex;align-items:center;gap:var(--s1);font-weight:500;
  padding-bottom:var(--s1);border-bottom:1px solid var(--border);margin-bottom:var(--s1)}
.dl-card-icon{display:inline-flex;color:var(--text)}
.dl-card-check{display:flex;align-items:baseline;gap:var(--s1);padding:2px 0;
  color:var(--muted);font-variant-numeric:tabular-nums}
.dc-icon{width:14px;height:14px;flex:0 0 14px;color:var(--text);
  position:relative;top:2px}
/* Замечание — не ошибка: пункт не гаснет и не краснеет целиком, метится только значок. */
.dl-card-check.warn{color:var(--text)}
.dl-card-check.warn .dc-icon{color:var(--ind);top:0;font-weight:500;
  display:inline-flex;align-items:center;justify-content:center}
/* Знак замечания рисует правило: app.js на этом месте отдаёт пустой узел. */
.dl-card-check.warn .dc-icon:empty::before{content:"!"}
/* Подзаголовок с замечаниями — тем же индикатором, что и сами пункты. */
.dl .sub.warn{color:var(--ind)}
/* Значение в скобках — доказательство: «255,255,255» и «все белые» читают в первую
   очередь. Тише названия оно за счёт скобок, а не за счёт тона. */
.dc-det{color:var(--muted)}

/* Отсчёт до автоудаления. Тикает раз в секунду — цифры табличные, соседнее не прыгает. */
/* Тихая серая строка по центру, без err-line: правило сервиса, а не ошибка
   (правка владельца 2026-08-10 — палка сбоку посреди центрированного экрана).
   Без ограничения ширины: на широком экране строка идёт ОДНОЙ строкой (вторая
   просьба той же правки); на телефоне переносится естественно. */
#dl-countdown{margin:var(--s3) 0 0;color:var(--muted);
  font-variant-numeric:tabular-nums}
/* Кнопки — тем же приёмом, что экран оплаты: пара на всю ширину контента,
   на узком складывается в столбец. Узкие 260px терялись под широким отчётом. */
/* Кнопка на экране готового файла ОДНА — «Скачать», и она занимает всю ширину на любом
   экране. Ряд был на две колонки под вторую кнопку («обработать ещё фото»), которую
   убрали 2026-09-09: после неё «Скачать» осталась бы половинной и висела бы слева,
   хотя действие здесь ровно одно — забрать своё. Правило на одну колонку убирает и
   отдельную ветку для узких экранов: она больше ничего не меняет. */
.dl .acts{display:grid;grid-template-columns:1fr;gap:var(--s1);
  margin-top:var(--s3)}
.dl .acts .btn{flex:none;width:100%}

/* ── v3-error.css ── */
/* Экран 5 — ошибка, v3. Подключается после /type.css и v3-base.css.

   Состав из ТЗ §6, варианты из §10.5. У экрана не один вид: главный — неоплаченный
   заказ, с заголовком, телом, подписью и двумя кнопками; короткий — одна строка
   причины и одна кнопка. Вид один, текст подставляется.

   Сигнал даёт вертикальная черта индикатора у заголовка, а не красный экран:
   ошибка здесь бытовая, а не катастрофа. */

.err{padding:var(--step) var(--gut) 0}
.err-body{max-width:54ch;margin-inline:auto;text-align:left}
.err-h{font-size:var(--t4);font-weight:700;letter-spacing:-.02em;line-height:1.15;
  padding-left:var(--s2);border-left:2px solid var(--ind);text-wrap:pretty}
.err-t{color:var(--muted);margin-top:var(--s2);text-wrap:pretty}
.err-sub{color:var(--faint);margin-top:var(--s1);text-wrap:pretty}
.err-pay{margin-top:var(--s3);font-weight:500}
#error-buttons{display:flex;flex-wrap:wrap;gap:var(--s1);margin-top:var(--s2)}
#error-buttons .btn{flex:1 1 200px}

/* ── v3-overlay.css ── */
/* Перекрытия. Подключаются после type.css, v3-base.css и стилей того экрана,
   поверх которого стоят.

   Их два, и они разной природы. Окно отмены — единственное место, где человек
   теряет заказ, поэтому полотно гасится почти в чёрное, а вопрос набран крупно.
   Плашка обслуживания закрывает работу целиком: там гасить нечего, там надо
   объяснить и не пугать.

   Размытия нет ни там, ни там: на служебном сообщении оно читается украшением. */

/* ── окно подтверждения ───────────────────────────────────────────────────── */
#confirm-modal{position:fixed;inset:0;z-index:9999;display:flex;align-items:center;
  justify-content:center;padding:var(--gut);background:rgba(10,9,8,.88)}
.modal-panel{width:100%;max-width:520px;background:var(--surface);
  border:1px solid var(--border-strong);border-top:2px solid var(--ind);
  border-radius:var(--r);padding:var(--s3)}
.modal-q{font-size:var(--t4);font-weight:700;letter-spacing:-.02em;line-height:1.15;
  text-wrap:pretty}
.modal-d{color:var(--muted);margin-top:var(--s2);max-width:46ch;text-wrap:pretty}
.modal-acts{display:flex;flex-wrap:wrap;gap:var(--s1);margin-top:var(--s3)}
.modal-acts .btn{flex:1 1 200px}
/* Необратимое действие помечено чертой индикатора, а не заливкой: заливка сделала бы
   его самым заметным пятном на экране, а по умолчанию человек должен остаться. */
#m-delete-btn{border-left:2px solid var(--ind)}

/* ── перекрытие обслуживания ──────────────────────────────────────────────── */
/* Видимость задаёт app.js через style.display, поэтому здесь display стоит только
   для макета — на живой странице его перебьёт inline-запись. */
#maint-overlay{position:fixed;inset:0;z-index:100000;display:flex;flex-direction:column;
  align-items:center;justify-content:center;text-align:center;padding:var(--gut);
  background:rgba(10,9,8,.96)}
.maint-rule{width:52px;height:2px;background:var(--ind);margin-bottom:var(--s3)}
.maint-t{font-size:var(--t4);font-weight:700;letter-spacing:-.02em}
.maint-s{color:var(--muted);margin-top:var(--s2);max-width:36ch;text-wrap:pretty}

/* ── разметка, которую строит скрипт ─────────────────────────────────────────
   Экраны проверок, оплаты и скачивания рисует app.js, и до переноса он нёс свои цвета:
   синюю галочку, зелёный успех, красную ошибку — палитры канона они не знали. Цвет ушёл
   отсюда: скрипт ставит класс, значение живёт в палитре. Правил здесь два, остальное
   покрыто канонными классами (.field-msg.bad/.ok, .stuck-msg, .dc-det, .sub.warn, а
   иконки берут цвет у состояния своей карточки через currentColor). */
.fc-pay{margin:var(--s2) 0 var(--s1);color:var(--muted)}
/* Полоса промокода липнет к верху — единственное, чем она отличается от промо-полосы,
   чьи цвета и рамку она и переиспользует. */
.gate-banner{position:sticky;top:0;z-index:50;font-weight:500}

/* НОМЕР ЗАКАЗА — тихая строка, а не заголовок. Он нужен человеку ровно в одном случае:
   назвать себя в поддержке. Поэтому приглушённый, моноширинный (чтобы диктовать по
   знакам) и с явным намёком, что по нему можно нажать. */
.ord-line{display:flex;align-items:center;justify-content:center;gap:var(--s1);
  margin-top:var(--s2);color:var(--muted)}
.ord-id{font-family:var(--mono,ui-monospace,monospace);color:var(--text);
  background:none;border:0;border-bottom:1px dashed var(--border-strong);
  padding:0 2px;cursor:pointer;font-size:inherit}
.ord-id:hover{border-bottom-color:var(--ind)}
