/* Кабинет клиента.
   Тот же словарь, что у служебного интерфейса (PRODUCT.md): спокойно, точно,
   цифры — главное на странице; цвет — для состояния и главного действия.
   Монохромно, как дашборд Vercel: Geist, линии 1px. Светлая тема по
   умолчанию, тёмная — по настройке системы. Один файл, встроен в бинарник,
   без сборки и CDN: строгая CSP выполнима. */

/* Geist и Geist Mono (Vercel, SIL OFL 1.1 — fonts/OFL.txt): переменные,
   один файл на начертание, вес 100–900. Свои файлы, без CDN: CSP. */
@font-face {
  font-family: "Geist";
  src: url("fonts/Geist-Variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}
@font-face {
  font-family: "Geist Mono";
  src: url("fonts/GeistMono-Variable.woff2") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  color-scheme: light dark;

  /* Нейтральные — без оттенка (chroma 0), как у дашборда Vercel; те же
     значения, что у служебного интерфейса (DESIGN.md, «Color tokens»). */
  --bg: oklch(0.985 0 0);          /* #fafafa */
  --surface: oklch(1 0 0);         /* #ffffff */
  --surface-2: oklch(0.982 0 0);   /* #f9f9f9 */
  --side: oklch(0.975 0 0);        /* #f7f7f7 */
  --hover: oklch(0.96 0 0);        /* #f2f2f2 */
  --line: oklch(0.93 0 0);         /* #e8e8e8 */
  --line-strong: oklch(0.85 0 0);  /* #cecece */

  --text: oklch(0.205 0 0);        /* #171717 */
  --text-2: oklch(0.39 0 0);       /* #454545 */
  --muted: oklch(0.51 0 0);        /* #666666 — не ниже 4,97:1 на любом нейтральном */

  /* Главное действие — чернилами; ссылки — чернилами с подчёркиванием;
     синий — только кольцо фокуса. */
  --accent: oklch(0.205 0 0);
  --accent-hover: oklch(0.32 0 0);
  --accent-ink: oklch(0.99 0 0);
  --accent-soft: oklch(0.95 0 0);
  --link: oklch(0.205 0 0);
  --focus: oklch(0.56 0.2 258);    /* #0e6ee6 */

  --ok: oklch(0.47 0.12 150);      /* #146d34 */
  --ok-soft: oklch(0.965 0.035 150);
  --warn: oklch(0.5 0.11 65);      /* #8d5406 */
  --warn-soft: oklch(0.965 0.045 85);
  --bad: oklch(0.51 0.18 27);      /* #b72725 */
  --bad-soft: oklch(0.962 0.022 27);

  /* Графики (DESIGN.md, «Charts») — те же роли, что в служебном интерфейсе. */
  --viz-1: #2a78d6;
  --viz-2: #eb6834;
  --viz-3: #1baf7a;
  /* Порядковая шкала (уровни, приоритеты): один тон, от ступени у
     поверхности к дальней — самое тяжёлое в --viz-o3 (validate_palette.js
     --ordinal на #ffffff — PASS). */
  --viz-o1: #86b6ef;
  --viz-o2: #3987e5;
  --viz-o3: #1c5cab;
  /* «Работает» на таймлайне — спокойная ступень --ok (33 % на поверхности):
     громкими остаются сбои (DESIGN.md, «Charts»). */
  --viz-ok-quiet: #b1cfbc;
  --viz-ink: var(--text);
  --viz-ctx: oklch(0.8 0 0);       /* #bebebe: ΔE ≥ 15 к бирюзовому (сомы рядом с BTC) */
  /* Нейтральное состояние (Tone Neutral, «не настроен» на таймлайне) — серый
     темнее контекста: светлый --viz-ctx почти сливается со спокойным
     «работает» (ΔE 4,9), этот — 11,6 (DESIGN.md, «Charts»). */
  --viz-none: oklch(0.72 0 0);     /* #a4a4a4 */
  --viz-grid: oklch(0.94 0 0);
  --viz-axis: var(--line-strong);
  --viz-label: var(--muted);
  --viz-surface: var(--surface);
  --viz-track: oklch(0.93 0 0);
  --viz-band: oklch(0.205 0 0 / 0.05);
  --viz-cross: var(--line-strong);
  --viz-rule: var(--text-2);
  --viz-wash: 0.1;
  --viz-on-2: oklch(0.145 0 0);
  --viz-on-3: oklch(0.145 0 0);
  --viz-on-ctx: oklch(0.145 0 0);
  --viz-on-ink: oklch(1 0 0);

  --radius: 8px;
  --r-sm: 6px;
  --font: "Geist", -apple-system, BlinkMacSystemFont, "Segoe UI Variable Text", "Segoe UI", Roboto,
    "Noto Sans", "Helvetica Neue", Arial, sans-serif;
  --mono: "Geist Mono", ui-monospace, "SF Mono", SFMono-Regular, Menlo, Consolas, monospace;

  --side-w: 240px;
  --z-menu: 20;
  --ease: cubic-bezier(0.22, 1, 0.36, 1);
  --t: 160ms;
}

/* Тёмная — фон чёрный, поверхность почти чёрная, без неона: это не биржа.
   Только на экране: подтверждение сделки печатается светлым. */
@media screen and (prefers-color-scheme: dark) {
  :root {
    --bg: oklch(0 0 0);              /* #000000 */
    --surface: oklch(0.145 0 0);     /* #0a0a0a */
    --surface-2: oklch(0.175 0 0);   /* #101010 */
    --side: oklch(0.11 0 0);         /* #040404 */
    --hover: oklch(0.22 0 0);        /* #1b1b1b */
    --line: oklch(0.27 0 0);         /* #262626 */
    --line-strong: oklch(0.36 0 0);  /* #3d3d3d */

    --text: oklch(0.95 0 0);         /* #eeeeee */
    --text-2: oklch(0.82 0 0);       /* #c4c4c4 */
    --muted: oklch(0.71 0 0);        /* #a1a1a1 */

    --accent: oklch(0.95 0 0);
    --accent-hover: oklch(0.85 0 0);
    --accent-ink: oklch(0.145 0 0);
    --accent-soft: oklch(0.24 0 0);
    --link: oklch(0.95 0 0);
    --focus: oklch(0.66 0.17 258);   /* #4a91f8 */

    --ok: oklch(0.78 0.15 150);      /* #67d283 */
    --ok-soft: oklch(0.24 0.05 150);
    --warn: oklch(0.82 0.13 80);     /* #f0ba59 */
    --warn-soft: oklch(0.25 0.05 75);
    --bad: oklch(0.72 0.17 25);      /* #fd736d */
    --bad-soft: oklch(0.25 0.06 25);

    --viz-1: #3987e5;
    --viz-2: #d95926;
    --viz-3: #199e70;
    --viz-o1: #1c5cab;              /* в тёмной шкала идёт от тёмного к светлому */
    --viz-o2: #3987e5;
    --viz-o3: #86b6ef;
    --viz-ok-quiet: #26462e;        /* --ok 30 % на #0a0a0a */
    --viz-ctx: oklch(0.45 0 0);
    --viz-none: oklch(0.45 0 0);     /* #555555 */
    --viz-grid: oklch(0.22 0 0);
    --viz-track: oklch(0.25 0 0);
    --viz-band: oklch(0.95 0 0 / 0.06);
    --viz-on-ctx: oklch(1 0 0);
    --viz-on-ink: oklch(0.145 0 0);
  }
}

* { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }

/* Атрибут hidden сильнее display у кнопок и блоков: скрипт прячет — значит скрыто. */
[hidden] { display: none !important; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--text);
  font: 15px/1.55 var(--font);
  -webkit-font-smoothing: antialiased;
}

/* Ссылка — чернилами; узнаётся по подчёркиванию, а не по цвету. */
a { color: var(--link); text-underline-offset: 0.2em; text-decoration-thickness: 1px; text-decoration-color: color-mix(in oklch, currentColor 40%, transparent); }
a:hover { color: var(--accent-hover); text-decoration-color: currentColor; }

:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--r-sm); }

::selection { background: var(--accent-soft); color: var(--text); }

h1, h2, h3 { text-wrap: balance; color: var(--text); }
h1 { font-size: 23px; line-height: 1.25; font-weight: 640; letter-spacing: -0.02em; margin: 0 0 6px; }
h2 { font-size: 17px; line-height: 1.3; font-weight: 620; letter-spacing: -0.01em; margin: 0 0 10px; }
h3 { font-size: 15px; font-weight: 620; margin: 0 0 8px; }
p { margin: 8px 0; text-wrap: pretty; }
.wrap > p, .wrap > section > p { max-width: 82ch; }

code {
  font-family: var(--mono); font-size: 13.5px;
  background: var(--surface-2); border: 1px solid var(--line);
  border-radius: 4px; padding: 0 5px;
  overflow-wrap: anywhere;
}
/* Адрес кошелька или хеш транзакции — моноширинно, переносится в любом месте. */
.addr { font-family: var(--mono); font-size: 13px; overflow-wrap: anywhere; }

.muted { color: var(--muted); }
.small { font-size: 13px; }
.hint { color: var(--muted); font-size: 13.5px; margin: 8px 0 0; max-width: 72ch; }
/* Подпись над значением: обычный текст, а не капс с разрядкой. */
.eyebrow { font-size: 13px; color: var(--muted); margin-bottom: 4px; }
.num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* ── Каркас ────────────────────────────────────────────────────────── */

.side-toggle { display: none; }

body:has(> .side) {
  display: grid;
  grid-template-columns: var(--side-w) minmax(0, 1fr);
  grid-template-rows: auto 1fr auto;
  grid-template-areas: "side banners" "side main" "side foot";
}

/* Меню закреплено во всю высоту окна: название и «Выйти» на месте, список
   разделов между ними прокручивается сам, не сдвигая страницу. Высота —
   видимая часть окна (dvh): в мобильном Safari 100vh выше неё, и «Выйти»
   ушло бы под панель браузера. */
.side {
  grid-area: side;
  position: sticky; top: 0;
  height: 100vh; height: 100dvh;
  display: flex; flex-direction: column;
  background: var(--side);
  border-right: 1px solid var(--line);
  overflow: hidden;
}
.side-head { flex: none; padding: 18px 20px 12px; }
.brand { font-size: 16px; font-weight: 680; letter-spacing: -0.01em; color: var(--text); text-decoration: none; }
.brand:hover { color: var(--text); }
.side-menu-btn { display: none; }

.side-nav {
  flex: 1; min-height: 0;
  padding: 2px 10px 16px;
  overflow-y: auto;
  overscroll-behavior: contain;
  scrollbar-width: thin;
  scroll-padding-top: 8px;
}
.side-nav a {
  display: block;
  padding: 5px 10px;
  margin: 1px 0;
  border-radius: var(--r-sm);
  color: var(--text-2);
  text-decoration: none;
  font-size: 14px; line-height: 20px;
  transition: background-color var(--t) var(--ease), color var(--t) var(--ease);
}
.side-nav a:hover { background: var(--hover); color: var(--text); }
.side-nav a[aria-current] {
  background: var(--surface);
  color: var(--text);
  font-weight: 600;
  box-shadow: inset 0 0 0 1px var(--line);
}
/* Раздел меню всегда раскрыт: над ссылками — приглушённая подпись обычным
   текстом, без стрелки и сворачивания. В невысоком окне начальная прокрутка
   ставит наверх раздел текущей страницы — подпись целиком, под ней ссылку
   (scroll-initial-target; где не поддерживается — список сверху). */
.side-group + .side-group { margin-top: 12px; }
.side-nav .side-group:has(a[aria-current]) { scroll-initial-target: nearest; scroll-snap-align: start; }
.side-label { margin: 0; padding: 4px 10px 2px; font-size: 12.5px; line-height: 18px; font-weight: 500; color: var(--muted); }
.side-group ul { list-style: none; margin: 0; padding: 0; }

.side-me {
  flex: none;
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 12px 20px 14px;
  border-top: 1px solid var(--line);
  font-size: 13px;
}
.me-name { color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.wrap {
  grid-area: main;
  width: 100%;
  max-width: 820px;
  padding: 32px 40px 64px;
  display: flex; flex-direction: column; gap: 28px;
}
.centered { min-height: 88vh; display: flex; align-items: center; justify-content: center; padding: 24px 16px; }
.auth { width: 100%; max-width: 400px; }
.auth h1 { margin-bottom: 14px; }

.foot {
  grid-area: foot;
  display: flex; flex-wrap: wrap; gap: 4px 18px;
  padding: 16px 40px 20px;
  border-top: 1px solid var(--line);
  font-size: 12.5px; color: var(--muted);
}
body:not(:has(> .side)) .foot { justify-content: center; border-top: 0; }

/* Приостановленные услуги — над каждой страницей (документ 18, п. 5.5). */
.banners { grid-area: banners; display: flex; flex-direction: column; gap: 6px; padding: 16px 40px 0; max-width: 820px; }
.banner {
  margin: 0; padding: 10px 14px;
  font-size: 14px;
  color: var(--warn); background: var(--warn-soft);
  border: 1px solid color-mix(in oklch, var(--warn) 35%, transparent);
  border-radius: var(--r-sm);
}

/* ── Блоки ─────────────────────────────────────────────────────────── */

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  padding: 24px;
}
.card > :first-child { margin-top: 0; }
/* Скрытые поля формы идут первыми и не рисуются: первое видимое поле
   начинается у края карточки, а не на 16 px ниже. */
.card > :nth-child(1 of :not(input[type="hidden"])) { margin-top: 0; }
.card > :last-child { margin-bottom: 0; }

.account {
  display: flex; justify-content: space-between; align-items: flex-start; flex-wrap: wrap; gap: 16px;
  padding: 20px 22px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
.account-no { font-family: var(--mono); font-size: 21px; letter-spacing: 0.01em; font-variant-numeric: tabular-nums; }

.status {
  display: inline-flex; align-items: center;
  padding: 3px 10px;
  font-size: 13px; font-weight: 550;
  white-space: nowrap;
  color: var(--text-2);
  background: var(--surface-2);
  border: 1px solid var(--line);
  border-radius: 999px;
}
.status-ok { color: var(--ok); background: var(--ok-soft); border-color: color-mix(in oklch, var(--ok) 30%, transparent); }
.status-wait { color: var(--warn); background: var(--warn-soft); border-color: color-mix(in oklch, var(--warn) 30%, transparent); }
.status-bad { color: var(--bad); background: var(--bad-soft); border-color: color-mix(in oklch, var(--bad) 30%, transparent); }
.status-muted { color: var(--muted); }

/* ── Таблицы ───────────────────────────────────────────────────────── */

table.balances {
  width: 100%;
  border-collapse: separate; border-spacing: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.balances th, .balances td { padding: 11px 16px; text-align: left; border-bottom: 1px solid var(--line); }
.balances thead th { font-size: 12.5px; font-weight: 600; color: var(--muted); background: var(--surface-2); }
.balances tbody tr:last-child td { border-bottom: 0; }
.balances .num { text-align: right; font-variant-numeric: tabular-nums; }
.balances td.num { font-family: var(--mono); font-size: 14px; }
.balances td.num .status { font-family: var(--font); }
/* Каждая таблица — в обёртке <div class="scroll-x">: на узком экране
   прокручивается вбок обёртка, а таблица остаётся таблицей во всю ширину —
   рамка, шапка и строки одной длины (display: block у самой таблицы сжимал
   строки по содержимому, а рамка оставалась во всю ширину). */
.chart-data .scroll-x { margin: 8px 0 4px; }

/* ── Формы ─────────────────────────────────────────────────────────── */

label { display: block; font-size: 14px; font-weight: 500; color: var(--text-2); margin: 16px 0 6px; }
input, select, textarea {
  width: 100%;
  min-height: 42px;
  padding: 9px 12px;
  font: inherit; font-size: 15px;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  transition: border-color var(--t) var(--ease), box-shadow var(--t) var(--ease);
}
input[type="checkbox"], input[type="radio"] { width: 18px; height: 18px; min-height: 0; accent-color: var(--accent); }
/* Флажок или вариант с подписью — в строку, обычным весом. */
label:has(> input[type="checkbox"]), label:has(> input[type="radio"]) {
  display: flex; align-items: center; gap: 10px;
  margin: 10px 0 0;
  font-weight: 400; color: var(--text);
}
label:has(> input[type="checkbox"]) > input, label:has(> input[type="radio"]) > input { flex: none; }
input:hover, select:hover, textarea:hover { border-color: color-mix(in oklch, var(--line-strong) 60%, var(--text)); }
input:focus-visible, select:focus-visible, textarea:focus-visible {
  outline: none;
  border-color: var(--focus);
  box-shadow: 0 0 0 3px color-mix(in oklch, var(--focus) 22%, transparent);
}
input::placeholder { color: var(--muted); }

/* Группа вариантов под общей подписью, без своей рамки; legend — как подпись
   поля. */
fieldset { min-width: 0; margin: 16px 0 0; padding: 0; border: 0; }
legend { padding: 0; margin-bottom: 6px; font-size: 14px; font-weight: 500; color: var(--text-2); }
fieldset > label:has(> input[type="radio"]):first-of-type { margin-top: 4px; }

/* Ошибка у поля: под ним, словами; рамка поля — тоном отказа. */
.field-error { margin: 6px 0 0; font-size: 13.5px; color: var(--bad); max-width: 72ch; }
input[aria-invalid="true"], select[aria-invalid="true"], textarea[aria-invalid="true"] { border-color: var(--bad); }

.row { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }
@media (max-width: 520px) { .row { grid-template-columns: 1fr; } }

/* Группа вариантов под общей подписью: своей рамки нет, legend — как подпись
   поля. Варианты видны все сразу, на телефоне тоже. */
fieldset { min-width: 0; margin: 16px 0 0; padding: 0; border: 0; }
legend { padding: 0; margin-bottom: 2px; font-size: 14px; font-weight: 500; color: var(--text-2); max-width: 82ch; }
fieldset fieldset { margin-top: 12px; }
fieldset > details.more { margin-top: 6px; max-width: 82ch; }
fieldset > details.more p { margin: 6px 0 0; }

/* Ошибка у своего поля — словом под ним; рамка поля только повторяет. */
.field-error { margin: 6px 0 0; font-size: 13px; color: var(--bad); max-width: 82ch; }
input[aria-invalid="true"]:not([type="checkbox"]):not([type="radio"]), select[aria-invalid="true"], textarea[aria-invalid="true"] { border-color: var(--bad); }

/* Уточнение к ответу «Да» о ПДЛ: скрыто, пока «Да» не отмечено. Без :has()
   правило не применяется, и уточнение просто видно всегда. */
.pep:has(input[name="pep"][value="yes"]:not(:checked)) .pep-more { display: none; }

button, .as-button {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  min-height: 42px;
  padding: 9px 18px;
  font: inherit; font-size: 15px; font-weight: 600;
  color: var(--text);
  background: var(--surface);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  cursor: pointer;
  text-decoration: none;
  transition: background-color var(--t) var(--ease), border-color var(--t) var(--ease);
}
button:hover, .as-button:hover { background: var(--hover); color: var(--text); }
button:disabled { opacity: 0.5; cursor: not-allowed; }

button.primary, .primary.as-button {
  margin-top: 20px;
  color: var(--accent-ink);
  background: var(--accent);
  border-color: var(--accent);
}
button.primary:hover, .primary.as-button:hover { background: var(--accent-hover); border-color: var(--accent-hover); color: var(--accent-ink); }

button.link {
  min-height: 0; padding: 0;
  background: none; border: 0;
  color: var(--link); font-weight: 500; font-size: inherit;
  text-decoration: underline; text-underline-offset: 0.18em;
}
button.link:hover { background: none; color: var(--accent-hover); }

.kyc-form { margin-top: 8px; }

/* Маленькая форма в ячейке таблицы. */
.inline { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 0; }
.inline label, .inline label:has(> input) { margin: 0; }
.inline input:not([type="checkbox"]):not([type="radio"]), .inline select { width: auto; min-width: 0; min-height: 34px; padding: 5px 10px; font-size: 14px; }
.inline button { min-height: 34px; padding: 5px 12px; font-size: 14px; }
.inline button.primary { margin-top: 0; }
.inline .actions { margin-top: 0; }

.lead { margin: -2px 0 0; color: var(--text-2); max-width: 82ch; overflow-wrap: anywhere; }
.actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-top: 20px; }
.actions button.primary, .actions .primary.as-button { margin-top: 0; }

/* Соседние страницы раздела — строка вкладок. */
.subnav { display: flex; flex-wrap: wrap; gap: 2px; border-bottom: 1px solid var(--line); }
.subnav a {
  padding: 8px 12px 9px;
  color: var(--text-2); text-decoration: none; font-size: 14px;
  border-bottom: 2px solid transparent; margin-bottom: -1px;
}
.subnav a:hover { color: var(--text); border-bottom-color: var(--line-strong); }
.subnav a[aria-current] { color: var(--text); font-weight: 600; border-bottom-color: var(--accent); }

/* Свойства одного объекта: поле — значение. */
.kv {
  display: grid; grid-template-columns: minmax(130px, max-content) 1fr; gap: 8px 24px;
  margin: 0; padding: 16px 20px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
}
.kv dt { color: var(--muted); font-size: 14px; }
.kv dd { margin: 0; min-width: 0; overflow-wrap: anywhere; }
.kv dd.num { text-align: left; }
@media (max-width: 520px) { .kv { grid-template-columns: 1fr; gap: 2px; } .kv dd { margin-bottom: 8px; } }

/* Пустой список объясняет, что будет дальше. */
.empty {
  margin: 0; padding: 18px 20px;
  color: var(--text-2);
  border: 1px dashed var(--line-strong); border-radius: var(--radius);
}

/* Несколько блоков подряд внутри одной секции: секции разносит gap у .wrap,
   а карточки, таблицы и списки внутри секции — этот отступ. */
section > * + :is(.card, .kv, .empty, .callout, .scroll-x, .checklist, .chart, .stats, .meter) { margin-top: 12px; }

/* ── Подключение: чек-лист шагов ───────────────────────────────────── */

/* Путь клиента к первой операции (документ 23, п. 4.3) — один компонент
   (templates/journey.html) на «Счёте», в профиле и в блоке «Подключение»
   других страниц: карточка .checklist, сверху «Шаг N из M» и одна сплошная
   полоса выполненного, ниже строки шагов. Строка — значок, название и
   состояние словом; текущий шаг (aria-current="step") открыт в своей
   строке: пояснение, «ещё N», кнопка. Выполненные приглушены. Значок и тон
   только повторяют слово: зелёный — выполнено, янтарный — ждёт Оператора,
   «Пока недоступно» — нейтрально, с пояснением под названием. */
.checklist {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
/* «Шаг N из M» слева, «Выполнено K из M» — над концом полосы справа: число
   рядом с тем, что оно заполняет. Не помещаются в строку — счёт уходит
   под шаг. */
.checklist-head {
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0 12px;
  padding: 14px 16px 16px;
}
.checklist-head p { flex: 1 1 auto; margin: 0 0 10px; font-size: 14px; font-weight: 560; color: var(--text); }
.checklist-count { margin: 0 0 10px; font-size: 13px; color: var(--muted); white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Одна полоса — доля выполненных шагов: <progress>, без скрипта и без
   style-атрибута. Заполнение — тоном «готово», дорожка — линией. */
.checklist-bar {
  -webkit-appearance: none; appearance: none;
  display: block; flex: 0 0 100%; width: 100%; height: 4px;
  border: 0; border-radius: 2px;
  background: var(--line);
  color: var(--ok);
  overflow: hidden;
}
.checklist-bar::-webkit-progress-bar { background: var(--line); border-radius: 2px; }
.checklist-bar::-webkit-progress-value { background: var(--ok); border-radius: 2px; }
.checklist-bar::-moz-progress-bar { background: var(--ok); border-radius: 2px; }

.stepper { list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
/* Список без шапки (действия «Идентификации») — линия карточки над ним уже есть. */
.checklist > .stepper:first-child { border-top: 0; }
.stepper > li {
  display: grid; grid-template-columns: 20px minmax(0, 1fr); column-gap: 12px;
  padding: 12px 16px;
}
.stepper > li + li { border-top: 1px solid var(--line); }
.step-mark { grid-column: 1; grid-row: 1; display: block; margin-top: 1px; overflow: visible; }
/* Название и состояние — в строку; не помещаются — состояние уходит под
   название. Подписи переносятся только по словам, без переноса по слогам
   («Идентифика-ция»). */
.stepper-head {
  grid-column: 2; min-width: 0;
  display: flex; flex-wrap: wrap; align-items: baseline; justify-content: space-between; gap: 0 12px;
}
.stepper-name { font-size: 15px; line-height: 22px; font-weight: 450; color: var(--text-2); overflow-wrap: break-word; hyphens: manual; }
.stepper-state { font-size: 13px; line-height: 22px; color: var(--muted); white-space: nowrap; }
.stepper-body { grid-column: 2; min-width: 0; margin-top: 2px; font-size: 14px; color: var(--text-2); }
.stepper-body > p { margin: 0; max-width: 72ch; }
.stepper-body > .actions { margin-top: 12px; }

/* Текущий шаг — название чернилами и жирнее, значок — кольцо с точкой;
   выполненные — тише всех; ждёт Оператора — состояние тоном «ждёт». */
.stepper > li[aria-current="step"] .stepper-name { color: var(--text); font-weight: 600; }
.stepper > li[aria-current="step"] .stepper-state { color: var(--text-2); }
.stepper > li.step-done .stepper-name { color: var(--muted); }
.stepper > li.step-wait .stepper-state { color: var(--warn); }
.stepper > li.step-off .stepper-body { color: var(--muted); }

/* Значки (journey.html, «stepmark»): линии 1,5 px; цвет — токенами
   состояний, классом, а не атрибутом. */
.step-mark :is(circle, path) { fill: none; stroke-width: 1.5; stroke-linecap: round; stroke-linejoin: round; }
.step-mark .m-ring { stroke: var(--line-strong); }
.step-mark .m-hand { stroke: var(--muted); }
.step-mark .m-dot { display: none; fill: var(--accent); stroke: none; }
.step-mark .m-fill { fill: var(--ok-soft); stroke: none; }
.step-mark .m-tick { stroke: var(--ok); stroke-width: 1.75; }
.step-wait .step-mark :is(.m-ring, .m-hand) { stroke: var(--warn); }
.step-off .step-mark .m-ring, .step-end .step-mark .m-ring { stroke-dasharray: 2.6 2.4; }
[aria-current="step"] > .step-mark .m-ring { stroke-width: 2; }
.step-todo[aria-current="step"] .step-mark .m-ring { stroke: var(--accent); }
.step-todo[aria-current="step"] .step-mark .m-dot { display: inline; }

@media (max-width: 520px) {
  .checklist-head { padding: 12px 14px 14px; }
  .stepper > li { padding: 12px 14px; }
}
/* Принудительные цвета: полоса — системная, значки — системным цветом
   текста; слово состояния рядом всегда. Залитый круг отметки «выполнено» —
   кольцом: заливка и галочка одного системного цвета слились бы. */
@media (forced-colors: active) {
  .checklist-bar { -webkit-appearance: auto; appearance: auto; }
  .step-mark :is(.m-ring, .m-hand, .m-tick) { stroke: CanvasText; }
  .step-mark .m-dot { fill: CanvasText; }
  .step-mark .m-fill { fill: none; stroke: CanvasText; stroke-width: 1.5; }
}


/* «ещё N»: остальные строки шага, раскрываются без скрипта. */
details.more { margin-top: 4px; font-size: 14px; color: var(--text-2); }
details.more summary { width: fit-content; min-height: 24px; cursor: pointer; color: var(--link); }
details.more summary:hover { color: var(--accent-hover); }
details.more ul { margin: 6px 0 0; padding-left: 20px; }
.card > details.more + .actions { margin-top: 16px; }

/* ── Сообщения ─────────────────────────────────────────────────────── */

.error, .notice {
  margin: 0;
  padding: 11px 14px;
  font-size: 14px;
  border-radius: var(--r-sm);
  border: 1px solid;
}
.error { color: var(--bad); background: var(--bad-soft); border-color: color-mix(in oklch, var(--bad) 30%, transparent); }
/* Сводка ошибок формы: строка и список ссылок на поля. */
.error > p { margin: 0; }
.error > ul { margin: 6px 0 0; padding-left: 20px; }
.error a { color: inherit; }
.notice { color: var(--ok); background: var(--ok-soft); border-color: color-mix(in oklch, var(--ok) 30%, transparent); }

/* Постоянное предупреждение — не итог действия: что учесть до операции. */
.callout {
  margin: 0; padding: 11px 14px;
  font-size: 14px;
  color: var(--text-2); background: var(--surface-2);
  border: 1px solid var(--line-strong);
  border-radius: var(--r-sm);
  max-width: 82ch;
}
.callout.wait { color: var(--warn); background: var(--warn-soft); border-color: color-mix(in oklch, var(--warn) 30%, transparent); }
.callout.bad { color: var(--bad); background: var(--bad-soft); border-color: color-mix(in oklch, var(--bad) 30%, transparent); }

/* ── Цены ──────────────────────────────────────────────────────────── */

.ticker {
  display: flex; justify-content: space-between; align-items: flex-end; flex-wrap: wrap; gap: 12px;
  background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius); padding: 20px 22px;
}
.ticker-price { text-align: right; }
.price { font-family: var(--mono); font-size: 26px; font-variant-numeric: tabular-nums; }
.up { color: var(--ok); }
.down { color: var(--bad); }
.stale { color: var(--warn); }

.tf { display: flex; gap: 6px; margin-bottom: 12px; flex-wrap: wrap; }
.tf-item {
  padding: 5px 11px;
  font-size: 13px; font-variant-numeric: tabular-nums;
  color: var(--muted); text-decoration: none;
  border: 1px solid var(--line); border-radius: var(--r-sm);
}
.tf-item:hover { color: var(--text); background: var(--hover); }
.tf-on { color: var(--text); border-color: var(--accent); background: var(--accent-soft); }
/* Несколько групп ссылок-фильтров одной строкой (актив | период), между
   группами — волосяной разделитель; на телефоне строка переносится, и
   разделитель не нужен. */
.tf-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin-bottom: 12px; }
.tf-bar .tf { margin-bottom: 0; }
.tf-bar .tf + .tf { padding-left: 10px; border-left: 1px solid var(--line); }
@media (max-width: 480px) { .tf-bar .tf + .tf { padding-left: 0; border-left: 0; } }
/* Ссылка с якорем (#price-title) открывает заголовок под липкой полосой меню. */
:target { scroll-margin-top: 16px; }

/* ── Графики (internal/charts; DESIGN.md, «Charts») ─────────────────── */

/* Рамка: заголовок, легенда, область, таблица значений. Цвет меток — классы
   рядов (s1 s2 s3 ink ctx), порядковых ступеней (o1 o2 o3) и состояний
   (t-ok t-wait t-bad t-none t-gap):
   каждый ставит одну переменную --c, метки и ключи легенды берут её. */
.chart {
  min-width: 0;
  margin: 0;
  padding: 14px 16px 10px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
figure.chart { margin-inline: 0; }
.chart-head { display: flex; flex-direction: column; gap: 2px; margin: 0 0 10px; }
.chart-title { font-size: 13.5px; font-weight: 600; line-height: 1.35; color: var(--text); }
.chart-sub { font-size: 12.5px; color: var(--muted); }

:where(.chart, .stat, .meter) .s1 { --c: var(--viz-1); }
:where(.chart, .stat, .meter) .s2 { --c: var(--viz-2); }
:where(.chart, .stat, .meter) .s3 { --c: var(--viz-3); }
:where(.chart, .stat, .meter) .o1 { --c: var(--viz-o1); }
:where(.chart, .stat, .meter) .o2 { --c: var(--viz-o2); }
:where(.chart, .stat, .meter) .o3 { --c: var(--viz-o3); }
:where(.chart, .stat, .meter) .ink { --c: var(--viz-ink); }
:where(.chart, .stat, .meter) .ctx { --c: var(--viz-ctx); }
:where(.chart, .stat, .meter) .t-ok { --c: var(--ok); }
:where(.chart, .stat, .meter) .t-wait { --c: var(--warn); }
:where(.chart, .stat, .meter) .t-bad { --c: var(--bad); }
:where(.chart, .stat, .meter) .t-none { --c: var(--viz-none); }
:where(.chart, .stat, .meter) .t-gap { --c: var(--viz-track); }
/* На таймлайне обычное состояние — тихое: полоса, ключ легенды и ключ
   подписи берут спокойную ступень, сбой остаётся полным --bad. */
.chart-timeline .t-ok { --c: var(--viz-ok-quiet); }

/* Легенда: текст — цветом текста, цвет несёт только ключ; ключ повторяет
   метку (линия у линий, квадрат у столбцов и полос). */
.chart-legend, .chart-marks {
  display: flex; flex-wrap: wrap; gap: 4px 16px;
  margin: 0 0 10px; padding: 0;
  list-style: none;
  font-size: 12.5px; color: var(--text-2);
}
.chart-legend li, .chart-marks li { display: inline-flex; align-items: center; gap: 6px; min-width: 0; }
.chart-legend-value { color: var(--muted); font-variant-numeric: tabular-nums; }
.chart-key { flex: none; display: inline-block; background: var(--c); }
.chart-key.rect { width: 10px; height: 10px; border-radius: 2px; }
.chart-key.line { width: 14px; height: 2px; border-radius: 1px; }
.chart-key.mark { width: 2px; height: 12px; background: var(--viz-rule); }
.chart-marks { color: var(--muted); }

/* Область: подписи шкалы — в отступе слева (класс g24…g96 по самой
   длинной), даты — под ней; уже своей наименьшей ширины (mw…) не
   сжимается, а прокручивается вбок. */
.chart-plot { position: relative; overflow-x: auto; padding: 0 16px 0 0; container-type: inline-size; }
.chart-plot.g24 { padding-left: 24px; }
.chart-plot.g32 { padding-left: 32px; }
.chart-plot.g40 { padding-left: 40px; }
.chart-plot.g48 { padding-left: 48px; }
.chart-plot.g56 { padding-left: 56px; }
.chart-plot.g64 { padding-left: 64px; }
.chart-plot.g72 { padding-left: 72px; }
.chart-plot.g80 { padding-left: 80px; }
.chart-plot.g88 { padding-left: 88px; }
.chart-plot.g96 { padding-left: 96px; }
svg.viz { display: block; width: 100%; overflow: visible; font-family: var(--font); }
svg.viz.mw240 { min-width: 240px; }
svg.viz.mw280 { min-width: 280px; }
svg.viz.mw320 { min-width: 320px; }
svg.viz.mw360 { min-width: 360px; }
svg.viz.mw400 { min-width: 400px; }
svg.viz.mw440 { min-width: 440px; }
svg.viz.mw480 { min-width: 480px; }
svg.viz.mw560 { min-width: 560px; }
svg.viz.mw640 { min-width: 640px; }
svg.viz.mw720 { min-width: 720px; }
svg.viz.mw800 { min-width: 800px; }
/* Телефон: карточка и область теснее, а у линии нет наименьшей ширины —
   сжимать ей нечего, прокручиваются только столбцы. Иначе при 375 px и
   подписях шкалы «7,2 млн» (g56) область цены прокручивалась на 3 px,
   при 360 и 320 px — больше. */
@media (max-width: 520px) {
  .chart { padding: 12px 12px 8px; }
  .chart-plot { padding-right: 8px; }
  .chart-line svg.viz { min-width: 0; }
}
.viz-paths { overflow: visible; }

/* Сетка и оси — волосяные, сплошные; нулевая линия на шаг темнее. */
.viz-grid { stroke: var(--viz-grid); stroke-width: 1; }
.viz-base { stroke: var(--viz-axis); stroke-width: 1; }
.viz-tick { fill: var(--viz-label); font-size: 11px; font-variant-numeric: tabular-nums; }
.viz-tick-y { text-anchor: end; }
.viz-tick-x { text-anchor: middle; }
.viz-tick-x.viz-tick-start { text-anchor: start; }
.viz-tick-x.viz-tick-end { text-anchor: end; }
/* Узкая область — каждая вторая дата прячется, последняя остаётся. */
@container (max-width: 460px) { .viz-tick-alt { display: none; } }
.viz-row-name { fill: var(--text-2); font-size: 12px; }

/* Метки: линия 2px, заливка области ~10 %, маркер r 5 с кольцом 2px цвета
   поверхности, столбцы и части — цветом ряда, зазор 2px — поверхностью. */
.viz-line { fill: none; stroke: var(--c); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.viz-area { fill: var(--c); fill-opacity: var(--viz-wash); stroke: none; }
.viz-bar, .viz-seg, .viz-state { fill: var(--c); }
.viz-dot { fill: var(--c); stroke: var(--viz-surface); stroke-width: 2; }
.viz-gap { fill: var(--viz-surface); }
.viz-track { fill: var(--viz-track); }
.viz-rule { stroke: var(--viz-rule); stroke-width: 1; }
.viz-rule-label {
  fill: var(--text-2); font-size: 11px; text-anchor: start;
  paint-order: stroke; stroke: var(--viz-surface); stroke-width: 3px; stroke-linejoin: round;
}
.viz-mark, .meter-mark { stroke: var(--viz-rule); stroke-width: 2; }
.viz-mark-halo { stroke: var(--viz-surface); stroke-width: 6; }
/* Подпись внутри части — цветом, читаемым на её заливке (≥ 4,5 : 1 в обеих
   темах); у первого слота подписи внутри нет, она в легенде. */
.viz-seg-label { font-size: 12px; font-weight: 560; font-variant-numeric: tabular-nums; pointer-events: none; }
.viz-seg-label.s2 { fill: var(--viz-on-2); }
.viz-seg-label.s3 { fill: var(--viz-on-3); }
.viz-seg-label.ctx { fill: var(--viz-on-ctx); }
.viz-seg-label.ink { fill: var(--viz-on-ink); }

/* Подсказка без скрипта: у каждой точки, столбца или части — группа с
   tabindex="0" и прозрачной областью ≥ 24px; перекрестье, маркеры, полоса
   и подпись уже нарисованы и видны по :hover и :focus. Кольцо фокуса —
   обводка области. */
.viz-hit { outline: none; }
.viz-hit:focus, .viz-hit:focus-visible { outline: none; }
.viz-hit-area { fill: transparent; pointer-events: all; }
.viz-hit .viz-cross, .viz-hit .viz-dot, .viz-hit .viz-band, .viz-hit .viz-tip { visibility: hidden; pointer-events: none; }
.viz-hit:hover :is(.viz-cross, .viz-dot, .viz-band, .viz-tip),
.viz-hit:focus :is(.viz-cross, .viz-dot, .viz-band, .viz-tip),
.viz-hit:focus-within :is(.viz-cross, .viz-dot, .viz-band, .viz-tip),
.viz-hit.is-on :is(.viz-cross, .viz-dot, .viz-band, .viz-tip) { visibility: visible; }
.viz-hit:focus-visible .viz-hit-area { stroke: var(--focus); stroke-width: 2; }
.viz-cross { stroke: var(--viz-cross); stroke-width: 1; }
.viz-band { fill: var(--viz-band); }
.viz-tip { overflow: visible; }
.viz-tip-box { fill: var(--surface); stroke: var(--line-strong); stroke-width: 1; }
.viz-tip text { font-size: 12px; }
.viz-tip .viz-tip-x { fill: var(--muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.viz-tip-v { fill: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.viz-tip-n { fill: var(--text-2); }
.viz-tip-key { stroke: var(--c); stroke-width: 2; stroke-linecap: round; }

/* Полоса «часть — целое» и таймлайн по ширине карточки; подпись при
   наведении выходит под полосу, поверх легенды. */
.chart-parts .chart-plot, .chart-timeline .chart-plot { overflow: visible; padding: 0; z-index: 1; }
.chart-parts .chart-legend { margin: 10px 0 0; }
.chart-parts .chart-marks { margin: 6px 0 0; }

/* Таблица значений — под каждым графиком: доступная копия и место для
   значения, до которого не дотянуться наведением. */
.chart-data { margin: 8px 0 0; font-size: 12.5px; }
.chart-data summary { width: fit-content; min-height: 24px; cursor: pointer; color: var(--muted); }
.chart-data summary:hover { color: var(--text); }
.chart-data table.grid {
  width: 100%;
  border-collapse: separate; border-spacing: 0;
  background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius);
  font-size: 13.5px;
}
.chart-data table.grid th, .chart-data table.grid td { padding: 7px 12px; text-align: left; border-bottom: 1px solid var(--line); }
.chart-data table.grid thead th { font-size: 12.5px; font-weight: 600; color: var(--muted); background: var(--surface-2); white-space: nowrap; }
.chart-data table.grid tbody th { font-weight: 500; color: var(--text-2); white-space: nowrap; }
.chart-data table.grid tbody tr:last-child > * { border-bottom: 0; }
.chart-data table.grid .num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* Пустая форма графика: рамка, нулевая линия и фраза, откуда возьмутся
   данные, — не плоская линия на нуле. */
.chart-empty {
  display: flex; align-items: center; justify-content: center;
  min-height: 160px; padding: 16px;
  border-bottom: 1px solid var(--viz-axis);
  font-size: 13px; color: var(--muted); text-align: center;
}
.chart-empty p { margin: 0; max-width: 52ch; text-wrap: pretty; }

/* Стат-плитки: полоса с волосяными линиями между плитками (как .tiles);
   число пропорциональными цифрами, изменение — знаком и словами, тон
   только повторяет их. */
.stats {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  margin: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
  overflow: hidden;
}
.stat {
  display: flex; flex-direction: column; gap: 2px;
  min-width: 0;
  margin: 0 -1px -1px 0;
  padding: 14px 16px 12px;
  border-right: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
}
.stat-label { font-size: 12.5px; color: var(--muted); }
a.stat-label { color: var(--text-2); width: fit-content; }
a.stat-label:hover { color: var(--text); }
.stat-value { font-size: 24px; line-height: 1.25; font-weight: 600; letter-spacing: -0.02em; color: var(--text); overflow-wrap: anywhere; }
.stat-unit { margin-left: 4px; font-size: 13px; font-weight: 500; letter-spacing: 0; color: var(--muted); }
.stat-delta { font-size: 12.5px; font-variant-numeric: tabular-nums; }
.stat-delta.good { color: var(--ok); }
.stat-delta.bad { color: var(--bad); }
.stat-delta.flat { color: var(--muted); }
.stat-period, .stat-note { font-size: 12.5px; color: var(--muted); }
svg.spark { display: block; margin-top: 6px; overflow: visible; }

/* Метр: заполнение на треке той же гаммы (чернила на сером, тон на
   светлом шаге тона), отметки порогов — чернилами; состояние — словом. */
.meter { display: flex; flex-direction: column; gap: 4px; max-width: 680px; margin: 0; }
.meter-head { display: flex; flex-wrap: wrap; justify-content: space-between; align-items: baseline; gap: 2px 12px; font-size: 13px; }
.meter-label { color: var(--text-2); }
.meter-value { font-weight: 600; font-variant-numeric: tabular-nums; color: var(--text); white-space: nowrap; }
svg.meter-bar { display: block; overflow: visible; }
.meter-track { fill: var(--viz-track); }
.meter-fill { fill: var(--viz-ink); }
.meter.t-ok .meter-track { fill: var(--ok-soft); }
.meter.t-ok .meter-fill { fill: var(--ok); }
.meter.t-wait .meter-track { fill: var(--warn-soft); }
.meter.t-wait .meter-fill { fill: var(--warn); }
.meter.t-bad .meter-track { fill: var(--bad-soft); }
.meter.t-bad .meter-fill { fill: var(--bad); }
.meter-state { margin: 0; font-size: 12.5px; color: var(--text-2); }
.meter.t-ok .meter-state { color: var(--ok); }
.meter.t-wait .meter-state { color: var(--warn); }
.meter.t-bad .meter-state { color: var(--bad); }
.meter-marks { display: flex; flex-wrap: wrap; gap: 2px 14px; margin: 0; padding: 0; list-style: none; font-size: 12px; color: var(--muted); }
.meter-marks li { display: inline-flex; align-items: center; gap: 6px; }
.meter-note { margin: 0; font-size: 12px; color: var(--muted); }

/* Режим принудительных цветов (Windows): график — как картинка, система его
   не перекрашивает (цвет меток — это данные), и он рисуется на своей
   поверхности; подписи вокруг и таблица значений — системными цветами. */
@media (forced-colors: active) {
  svg.viz, svg.spark, svg.meter-bar { forced-color-adjust: none; background: var(--viz-surface); }
  .chart-key { forced-color-adjust: none; }
}

/* Свечной график терминала (web.Chart): div.chart с SVG прямо внутри. */
div.chart { padding: 10px 8px; overflow-x: auto; }
.chart > svg { display: block; width: 100%; height: auto; min-width: 520px; }
.chart > svg .grid { stroke: var(--line); stroke-width: 1; }
.chart > svg .axis { fill: var(--muted); font-size: 10px; font-family: var(--mono); }
.chart .wick.up, .chart .body.up { stroke: var(--ok); fill: var(--ok); }
.chart .wick.down, .chart .body.down { stroke: var(--bad); fill: var(--bad); }
.chart .wick, .chart .body { stroke-width: 1; }

/* Автозаполнение браузера красит поле своим фоном; перекрываем тенью. */
input:-webkit-autofill,
input:-webkit-autofill:hover,
input:-webkit-autofill:focus {
  -webkit-box-shadow: 0 0 0 1000px var(--surface) inset;
  box-shadow: 0 0 0 1000px var(--surface) inset;
  -webkit-text-fill-color: var(--text);
  caret-color: var(--text);
  transition: background-color 100000s ease-in-out 0s;
}

/* ── Телефон: меню сворачивается в полосу ──────────────────────────── */

@media (max-width: 900px) {
  :target { scroll-margin-top: 72px; }
  body:has(> .side) { display: block; }
  .side-toggle { display: block; position: absolute; opacity: 0; width: 1px; height: 1px; pointer-events: none; }
  .side {
    position: sticky; top: 0; z-index: var(--z-menu);
    height: auto; max-height: 100vh; max-height: 100dvh;
    border-right: 0; border-bottom: 1px solid var(--line);
  }
  .side-head { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 10px 16px; }
  .side-menu-btn {
    display: inline-flex; align-items: center; min-height: 36px;
    padding: 6px 14px;
    font-size: 14px; font-weight: 600; color: var(--text);
    background: var(--surface);
    border: 1px solid var(--line-strong);
    border-radius: var(--r-sm);
    cursor: pointer;
  }
  .side-toggle:focus-visible ~ .side .side-menu-btn { outline: 2px solid var(--focus); outline-offset: 2px; }
  .side-nav, .side-me { display: none; }
  .side-toggle:checked ~ .side .side-nav { display: block; overflow-y: auto; max-height: calc(100vh - 124px); max-height: calc(100dvh - 124px); }
  .side-toggle:checked ~ .side .side-me { display: flex; }
  .wrap { padding: 20px 16px 48px; gap: 24px; }
  .banners { padding: 12px 16px 0; }
  .foot { padding: 16px; }
  .card { padding: 20px 18px; }
  .account-no { font-size: 18px; }
  .scroll-x { overflow-x: auto; }
}

@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; }
}

/* Печать подтверждения: только содержимое страницы. */
@media print {
  .side, .side-toggle, .banners, .foot, .actions, .subnav, .screen-only { display: none !important; }
  body:has(> .side) { display: block; }
  .wrap { padding: 0; max-width: none; }
  .scroll-x { overflow: visible; }
}

/* ── Согласия в профиле (#consents) ────────────────────────────────── */
/* Отдельный блок (правки онбординга, 04.11.2026). Один список без
   вложенных карточек: строка на согласие — название и текст, к которому оно
   даётся (мелко); справа — состояние словом и «Отозвать»; под строкой у
   недающегося — флажок со своей подписью и компактная кнопка. На телефоне
   состояние — под названием. «Не дано» — нейтрально: это не тревога, а
   следующее действие. DESIGN.md, «Согласия». */
ul.consents {
  list-style: none; margin: 0; padding: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: var(--radius);
}
section > * + ul.consents { margin-top: 12px; }
/* Итог действия в разделе — там, куда ведёт якорь (web.FlashAt), — по
   ширине списка или формы раздела. */
:is(#consents, #questionnaire) > :is(.notice, .error) { max-width: none; }
#consents > .hint + :is(.notice, .error) { margin-top: 12px; }
ul.consents > li {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start;
  column-gap: 24px; row-gap: 10px;
  padding: 14px 18px;
  border-top: 1px solid var(--line);
}
ul.consents > li:first-child { border-top: 0; }
.consent-about { min-width: 0; }
.consent-name { margin: 0; font-size: 15px; font-weight: 600; line-height: 1.4; overflow-wrap: break-word; }
.consent-optional { margin-left: 4px; font-size: 13px; font-weight: 400; color: var(--muted); white-space: nowrap; }
.consent-edition { margin: 2px 0 0; font-size: 13px; line-height: 1.45; color: var(--muted); max-width: 82ch; }
.consent-state { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.consent-state form { margin: 0; }
.consent-state > a, .consent-state button.link {
  display: inline-flex; align-items: center; min-height: 24px;
  font-size: 14px; font-weight: 500;
}
/* Флажок, затем кнопка — каждый на своей строке: кнопка стоит в одном
   месте у любой длины подписи. */
.consent-act { grid-column: 1 / -1; display: flex; flex-direction: column; align-items: flex-start; gap: 8px; margin: 0; }
/* Флажок — вровень с названием над ним и с первой строкой своей подписи,
   когда она переносится. */
.consent-act label:has(> input[type="checkbox"]) { align-items: flex-start; margin: 0; min-height: 24px; }
.consent-act input[type="checkbox"] { margin: 3px 0 0; }
.consent-act button, .consent-act .as-button { min-height: 32px; margin-top: 0; padding: 5px 12px; font-size: 14px; }
.consent-act .field-error { margin: 0; }
p.consent-act { margin: 0; }
/* Флажок согласия — то же кольцо фокуса, что у ссылок и кнопок: на
   заливке флажка кольцо полей в 22 % почти не видно. */
.consent-act input[type="checkbox"]:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; box-shadow: none; }
@media (max-width: 520px) {
  ul.consents > li { grid-template-columns: minmax(0, 1fr); row-gap: 8px; padding: 12px 14px; }
  .consent-state { flex-direction: row; flex-wrap: wrap; align-items: center; gap: 4px 14px; }
}
