/* VELAR · слой компонентов (docs/design-audit/02_CONSOLIDATION.md, шаг 4).
   Подключается до таблиц страниц: страницы раскладывают компонент, но не перекрашивают его. */

/* ───────────────────────────── 01 · Кнопка ─────────────────────────────
   Спека: docs/design-audit/03_button.md, docs/parts/DESIGN-QUALITY.md §5.
   44 px · радиус 10 · 15/20 вес 500 · поля 24 на десктопе, 16 на телефоне (≤ 600 px) и у компактной.

   Классы — псевдонимы поколений вёрстки, разметку и JS не трогаем:
     база        .button (лендинг, кабинет, контентные) · .btn (кабинет счёта, crypto)
                 .cta / .button-secondary (страницы волны v36)
                 .modal-actions > button / .dialog-actions > button (строка действий модалки, элемент 06)
     вторичная   .button-outline .button-light .button-secondary .header-account .btn-ghost .btn.sec
                 .quiet («Отмена» пульта)
     нейтральная .button-dark      опасная .button-danger
     компактная  .header-account .today-action
   Без класса варианта кнопка — главная (янтарная): так её рисовали все семьи страниц.

   Цвета берутся из семантических токенов страницы (--amber, --bone, --rule-strong, --void,
   --loss, --focus/--gold), поэтому светлая тема кабинета работает без отдельных правил.
   Страница с собственной палитрой задаёт крючки --button-primary-* на :root (консьерж).

   :root в начале селектора поднимает специфичность на один класс: правила ссылок страниц
   вида `.crypto-body a` (0,1,1) больше не перекрашивают подпись — там было 1.27:1. */

:root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button) {
  --button-bg: var(--button-primary-bg, var(--amber, var(--color-accent)));
  --button-fg: var(--button-primary-fg, var(--amber-ink, var(--color-accent-ink)));
  --button-border: var(--button-primary-border, var(--button-bg));
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 44px;
  max-width: 100%;
  padding: 0 24px;
  border: 1px solid var(--button-border);
  border-radius: 10px;
  background: var(--button-bg);
  color: var(--button-fg);
  font-family: inherit;
  font-size: 15px;
  font-weight: 500;
  line-height: 20px;
  letter-spacing: 0;
  text-align: center;
  text-decoration: none;
  vertical-align: middle;
  box-shadow: none;
  filter: none;
  transform: none;
  cursor: pointer;
  appearance: none;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 160ms ease-out, border-color 160ms ease-out, color 160ms ease-out;
}

/* Вторичная: контур 1 px на прозрачном фоне. Контраст рамки к фону ≥ 3:1 (WCAG 1.4.11). */
:root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button):is(.button-outline, .button-light, .button-secondary, .header-account, .btn-ghost, .sec, .quiet) {
  --button-bg: transparent;
  --button-fg: var(--button-secondary-fg, var(--bone, var(--color-text-1)));
  --button-border: var(--button-secondary-border, var(--rule-strong, var(--color-rule-strong)));
}

/* Нейтральная: светлая заливка на тёмной теме, тёмная — на светлой (токены меняются местами). */
:root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button).button-dark {
  --button-bg: var(--bone, var(--color-text-1));
  --button-fg: var(--void, var(--color-bg));
  --button-border: var(--button-bg);
}

/* Опасная: только контур и текст, без заливки — не спорит с главной кнопкой экрана. */
:root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button).button-danger {
  --button-bg: transparent;
  --button-fg: var(--loss, var(--color-danger));
  --button-border: var(--button-fg);
}

/* Компактная: шапка и строка «сегодня» — та же высота 44 (тап-таргет), поля 16, кегль 14. */
:root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button):is(.header-account, .today-action) {
  padding: 0 16px;
  font-size: 14px;
}

/* Телефон: поля 16 — пара действий кабинета остаётся в одной строке на 390 px. */
@media (max-width: 600px) {
  :root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button) { padding: 0 16px; }
}

/* Наведение — подмес 6 % цвета подписи в фон: янтарь темнеет, контур и тёмная заливка светлеют.
   Только на устройствах с настоящим hover, иначе состояние залипает после тапа.
   filter/transform сбрасываются: правила голых <button> кабинета счёта (0,2,1) иначе дотягиваются до .btn. */
@media (hover: hover) {
  :root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button):not(:disabled, [aria-disabled="true"], [aria-busy="true"]):hover {
    background-color: color-mix(in srgb, var(--button-bg), var(--button-fg) 6%);
    filter: none;
    transform: none;
  }
}

:root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button):not(:disabled, [aria-disabled="true"], [aria-busy="true"]):active {
  background-color: color-mix(in srgb, var(--button-bg), var(--button-fg) 12%);
  filter: none;
  transform: none;
}

:root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button):focus-visible {
  outline: 2px solid var(--button-focus, var(--focus, var(--gold, var(--color-focus))));
  outline-offset: 2px;
}

/* Недоступна: видно, что нельзя нажать; причину страница пишет рядом с кнопкой. */
:root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button):is(:disabled, [aria-disabled="true"]) {
  opacity: .45;
  cursor: not-allowed;
}

/* Загрузка: подпись прозрачная, но занимает место — ширина не прыгает; спиннер 16 px по центру. */
:root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button)[aria-busy="true"] {
  position: relative;
  color: transparent;
  cursor: progress;
}

/* display:inline-flex базы перебивает [hidden] браузера — скрытая скриптом кнопка должна скрываться. */
:root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button)[hidden] { display: none; }
:root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button)[aria-busy="true"]::after {
  content: "";
  position: absolute;
  inset: 0;
  width: 16px;
  height: 16px;
  margin: auto;
  border: 2px solid var(--button-fg);
  border-right-color: transparent;
  border-radius: 50%;
  animation: button-spin 700ms linear infinite;
}
@keyframes button-spin { to { transform: rotate(1turn); } }

@media (prefers-reduced-motion: reduce) {
  :root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button) { transition: none; }
  :root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button)[aria-busy="true"]::after { animation-duration: 2s; }
}

@media (forced-colors: active) {
  :root :is(.button, .btn, .cta, .button-secondary, :where(.modal-actions, .dialog-actions) > button) { border-color: ButtonText; }
}

/* ───────────────────────────── 02 · Поле ввода ─────────────────────────────
   Спека: docs/design-audit/04_field.md, docs/parts/DESIGN-QUALITY.md §5.
   44 px · радиус 10 · рамка 1 px · 16/24 вес 400 (16 — iOS не зумит при фокусе) · поля 0 12 ·
   табличные цифры. Лейбл над полем, ошибка под полем — разметка страниц (aria-describedby).

   Поле — любой input/select/textarea формы, без класса: разметку не трогаем. Не поле:
   переключатели языка в шапке и подвале (навигация, элемент 07) и input внутри составного
   .v24-amount-field — составное поле целиком описано ниже.
   Ширину и сетку задаёт страница; вид и состояния — только здесь.

   Цвета — семантические токены страницы (--surface, --rule-strong, --bone, --text-3, --focus,
   --loss, --up); у страниц со своей палитрой — крючки --field-* на :root (пульт, консьерж,
   симулятор). Рамка по умолчанию #5E626B к фону #06070B — 3.3:1 (WCAG 1.4.11). */

:root :is(input:not([type=checkbox], [type=radio], [type=range], [type=hidden], [type=submit], [type=button], [type=reset], [type=file], [type=color], [type=image]), select, textarea):not(:is(.language-control, .footer-language, .page-lang, .cabinet-lang, .lang, .landing-menu-language, .v24-amount-field) *) {
  box-sizing: border-box;
  min-height: 44px;
  padding: 0 12px;
  border: 1px solid var(--field-border, var(--rule-strong, var(--color-rule-strong)));
  border-radius: 10px;
  background-color: var(--field-bg, var(--surface, var(--color-surface)));
  color: var(--field-fg, var(--bone, var(--color-text-1)));
  font-family: inherit;
  font-size: 16px;
  font-weight: 400;
  line-height: 24px;
  font-variant-numeric: tabular-nums;
  caret-color: var(--field-focus, var(--focus, var(--gold, var(--color-focus))));
  box-shadow: none;
  outline: 2px solid transparent;
  outline-offset: 0;
  transition: border-color 160ms ease-out, box-shadow 160ms ease-out;
}

/* Список: своя стрелка вместо системной — одинаковая на всех платформах. */
:root select:not([multiple], [size]):not(:is(.language-control, .footer-language, .page-lang, .cabinet-lang, .lang, .landing-menu-language, .v24-amount-field) *) {
  appearance: none;
  padding-right: 36px;
  background-image: linear-gradient(45deg, transparent 50%, var(--field-placeholder, var(--text-3, var(--color-text-3))) 50%),
    linear-gradient(135deg, var(--field-placeholder, var(--text-3, var(--color-text-3))) 50%, transparent 50%);
  background-position: calc(100% - 19px) 50%, calc(100% - 14px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
}

/* :not([hidden]) уравнивает специфичность с базой (0,3,1): иначе база перебивает высоту и поля textarea.
   Высоту страница задаёт крючком --field-textarea-height. */
:root textarea:not(:is(.language-control, .footer-language, .page-lang, .cabinet-lang, .lang, .landing-menu-language, .v24-amount-field) *):not([hidden]) {
  min-height: var(--field-textarea-height, 96px);
  padding: 10px 12px;
  resize: vertical;
}

/* Поиск: без системного вида Safari (скруглённое поле со своими отступами). */
:root input[type=search] { appearance: none; }
:root input[type=search]::-webkit-search-decoration { appearance: none; }

/* Числа: без стрелок-спиннеров — сумма вводится с клавиатуры, стрелки ↑↓ работают. */
:root input[type=number] { appearance: textfield; }
:root input[type=number]::-webkit-inner-spin-button,
:root input[type=number]::-webkit-outer-spin-button { appearance: none; margin: 0; }

:root :is(input:not([type=checkbox], [type=radio], [type=range], [type=hidden], [type=submit], [type=button], [type=reset], [type=file], [type=color], [type=image]), select, textarea)::placeholder {
  color: var(--field-placeholder, var(--text-3, var(--color-text-3)));
  opacity: 1;
}

@media (hover: hover) {
  :root :is(input:not([type=checkbox], [type=radio], [type=range], [type=hidden], [type=submit], [type=button], [type=reset], [type=file], [type=color], [type=image]), select, textarea):not(:is(.language-control, .footer-language, .page-lang, .cabinet-lang, .lang, .landing-menu-language, .v24-amount-field) *):not(:disabled, :focus, [aria-invalid="true"]):hover {
    border-color: var(--field-border-hover, var(--text-3, var(--color-text-3)));
  }
}

/* Фокус — рамка 2 px акцентом: 1 px рамки + 1 px кольца того же цвета, вёрстка не сдвигается.
   Прозрачный outline остаётся видимым в режиме высокой контрастности. */
:root :is(input:not([type=checkbox], [type=radio], [type=range], [type=hidden], [type=submit], [type=button], [type=reset], [type=file], [type=color], [type=image]), select, textarea):not(:is(.language-control, .footer-language, .page-lang, .cabinet-lang, .lang, .landing-menu-language, .v24-amount-field) *):focus {
  border-color: var(--field-focus, var(--focus, var(--gold, var(--color-focus))));
  box-shadow: 0 0 0 1px var(--field-focus, var(--focus, var(--gold, var(--color-focus))));
  outline: 2px solid transparent;
  outline-offset: 0;
}

/* Ошибка — рамка цвета ошибки; текст ошибки под полем связан через aria-describedby.
   :user-invalid — только после ввода, пустая форма при открытии не краснеет. */
:root :is(input:not([type=checkbox], [type=radio], [type=range], [type=hidden], [type=submit], [type=button], [type=reset], [type=file], [type=color], [type=image]), select, textarea):not(:is(.language-control, .footer-language, .page-lang, .cabinet-lang, .lang, .landing-menu-language, .v24-amount-field) *):is([aria-invalid="true"], :user-invalid) {
  border-color: var(--field-error, var(--loss, var(--color-danger)));
}
:root :is(input:not([type=checkbox], [type=radio], [type=range], [type=hidden], [type=submit], [type=button], [type=reset], [type=file], [type=color], [type=image]), select, textarea):not(:is(.language-control, .footer-language, .page-lang, .cabinet-lang, .lang, .landing-menu-language, .v24-amount-field) *):is([aria-invalid="true"], :user-invalid):focus {
  box-shadow: 0 0 0 1px var(--field-error, var(--loss, var(--color-danger)));
}

/* Успех — по явному сигналу скрипта (data-state="success"), а не на каждое валидное поле. */
:root :is(input:not([type=checkbox], [type=radio], [type=range], [type=hidden], [type=submit], [type=button], [type=reset], [type=file], [type=color], [type=image]), select, textarea):not(:is(.language-control, .footer-language, .page-lang, .cabinet-lang, .lang, .landing-menu-language, .v24-amount-field) *)[data-state="success"] {
  border-color: var(--field-success, var(--up, var(--color-success)));
}
:root :is(input:not([type=checkbox], [type=radio], [type=range], [type=hidden], [type=submit], [type=button], [type=reset], [type=file], [type=color], [type=image]), select, textarea):not(:is(.language-control, .footer-language, .page-lang, .cabinet-lang, .lang, .landing-menu-language, .v24-amount-field) *)[data-state="success"]:focus {
  box-shadow: 0 0 0 1px var(--field-success, var(--up, var(--color-success)));
}

:root :is(input:not([type=checkbox], [type=radio], [type=range], [type=hidden], [type=submit], [type=button], [type=reset], [type=file], [type=color], [type=image]), select, textarea):not(:is(.language-control, .footer-language, .page-lang, .cabinet-lang, .lang, .landing-menu-language, .v24-amount-field) *):disabled {
  opacity: .45;
  cursor: not-allowed;
}

/* Составное поле суммы лендинга: подпись и большая цифра внутри одной рамки — рамка и состояния
   те же, что у поля; раскладку и кегль цифры задаёт landing-conversion.css. */
:root .v24-amount-field {
  box-sizing: border-box;
  min-height: 44px;
  padding: 0 12px;
  /* Рамка на поверхности карточки: #5E626B давал 2,99:1 к #12151C, #646871 — 3,27:1 (WCAG 1.4.11). */
  border: 1px solid var(--field-border, var(--color-rule-control));
  border-radius: 10px;
  background-color: var(--field-bg, var(--surface, var(--color-surface)));
  transition: border-color 160ms ease-out, box-shadow 160ms ease-out;
}
/* Самые узкие телефоны: длинная подпись (ka, hy) не съедает цифру — подпись над значением (§5 «лейбл над полем»). */
@media (max-width: 360px) {
  :root .v24-amount-field { flex-direction: column; align-items: stretch; gap: 0; padding-block: 8px; }
  :root .v24-amount-field > span { white-space: normal; }
  :root .v24-amount-field input { max-width: none; }
}
:root .v24-amount-field:focus-within {
  border-color: var(--field-focus, var(--focus, var(--gold, var(--color-focus))));
  box-shadow: 0 0 0 1px var(--field-focus, var(--focus, var(--gold, var(--color-focus))));
}
:root .v24-amount-field:has([aria-invalid="true"]) {
  border-color: var(--field-error, var(--loss, var(--color-danger)));
}
:root .v24-amount-field:has([aria-invalid="true"]):focus-within {
  box-shadow: 0 0 0 1px var(--field-error, var(--loss, var(--color-danger)));
}
:root .v24-amount-field:has([data-state="success"]) {
  border-color: var(--field-success, var(--up, var(--color-success)));
}
:root .v24-amount-field:has(:disabled) {
  opacity: .45;
  cursor: not-allowed;
}

@media (prefers-reduced-motion: reduce) {
  :root :is(input, select, textarea, .v24-amount-field) { transition: none; }
}

@media (forced-colors: active) {
  :root :is(input:not([type=checkbox], [type=radio], [type=range], [type=hidden], [type=submit], [type=button], [type=reset], [type=file], [type=color], [type=image]), select, textarea):focus { outline-color: Highlight; }
}

/* ───────────────────────────── 03 · Таблица ─────────────────────────────
   Спека: docs/design-audit/05_table.md, docs/parts/DESIGN-QUALITY.md §5, §8.
   Шапка 12/16 капсом · строка 56 (плотная — 44) · ячейка 0 16 (на телефоне 0 12) · 14/20 ·
   табличные цифры · разделитель 1 px · числа справа · ховер — фон на 4 % светлее.

   Таблица данных — любой <table> без класса: разметку не трогаем. Не таблица: биржевой стакан и
   лента сделок (.market-book / .market-trades) — плотный виджет со своей сеткой.
   Смысл колонок (какая выравнивается вправо, какая не переносится, какие прятать на телефоне)
   и рамку-обёртку задаёт страница; вид и состояния — только здесь.

   Цвета — токены страницы (--rule, --rule-strong, --text-3, --bone, --amber, --surface);
   своя палитра — крючки --table-* на :root. */

:root table:not(:is(.market-book, .market-trades) *) {
  width: 100%;
  border-collapse: collapse;
  font-size: 14px;
  line-height: 20px;
  font-variant-numeric: tabular-nums;
}

:root table:not(:is(.market-book, .market-trades) *) caption {
  caption-side: top;
  padding: 0 0 8px;
  font-size: 13px;
  line-height: 18px;
  color: var(--table-head, var(--text-3, var(--color-text-3)));
}

/* Выравнивание по умолчанию — с нулевой специфичностью: смысл колонок перекрывает страница. */
:where(table) :is(caption, th) { text-align: start; }

:root table:not(:is(.market-book, .market-trades) *) :is(th, td) {
  height: 56px;
  padding: 0 16px;
  border-bottom: 1px solid var(--table-rule, var(--rule, var(--color-rule)));
}

/* Шапка не рвёт слово посередине: страница может унаследовать overflow-wrap: anywhere от body
   («ПЛА Н», «МИНИМУ М» на счёте) — в шапке перенос только по слогам. */
:root table:not(:is(.market-book, .market-trades) *) thead th {
  height: 40px;
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--table-head, var(--text-3, var(--color-text-3)));
  border-bottom-color: var(--table-rule-strong, var(--rule-strong, var(--color-rule-strong)));
  overflow-wrap: normal;
  hyphens: auto;
}

:root table:not(:is(.market-book, .market-trades) *) tbody th { font-weight: 500; }
:root table:not(:is(.market-book, .market-trades) *) tbody tr:last-child > :is(th, td) { border-bottom: 0; }

/* Итог: двойной вес разделителя сверху, полужирный — без заливки и акцента. */
:root table:not(:is(.market-book, .market-trades) *) :is(tfoot, .p5-report-total) :is(th, td) {
  border-top: 2px solid var(--table-rule-strong, var(--rule-strong, var(--color-rule-strong)));
  border-bottom: 0;
  font-weight: 600;
}

/* Числа справа: разметка помечает числовые ячейки классом .num или атрибутом data-num. */
:root table:not(:is(.market-book, .market-trades) *) :is(th, td):is(.num, [data-num]) { text-align: right; }

/* Плотная — таблица внутри карточки калькулятора и формулы: 44 px, шапка 32 px. */
:root table:is(.v24-plan-table, .hero-plans-table, .formula-table, :where(form[data-seo-calc] ~ .table-wrap > table)) :is(th, td) { height: 44px; }
:root table:is(.v24-plan-table, .hero-plans-table, .formula-table, :where(form[data-seo-calc] ~ .table-wrap > table)) thead th { height: 32px; }

/* Ховер строки — фон на 4 % светлее (на светлой теме — темнее: подмес цвета текста). */
@media (hover: hover) {
  :root table:not(:is(.market-book, .market-trades) *) tbody tr:hover > :is(th, td) {
    background-color: color-mix(in srgb, transparent, var(--table-fg, var(--bone, var(--color-text-1))) 4%);
  }
}

/* Текущая строка (выбранный план, своя ступень): акцент 8 % — одно выделение на таблицу;
   под курсором — 12 %, чтобы и она отвечала на наведение. */
:root table:not(:is(.market-book, .market-trades) *) tbody tr:is([aria-current="true"], [aria-selected="true"], .is-recommended) > :is(th, td) {
  background-color: color-mix(in srgb, transparent, var(--table-accent, var(--amber, var(--color-accent))) 8%);
}
@media (hover: hover) {
  :root table:not(:is(.market-book, .market-trades) *) tbody tr:is([aria-current="true"], [aria-selected="true"], .is-recommended):hover > :is(th, td) {
    background-color: color-mix(in srgb, transparent, var(--table-accent, var(--amber, var(--color-accent))) 12%);
  }
}

/* Телефон: слова в ячейках переносятся по слогам, но не по буквам (overflow-wrap в ячейке
   сжимает колонку до символа и рвёт код). Таблица шире экрана прокручивается внутри своей
   обёртки — страница вбок не едет; плотная таблица — ячейка 0 8, текст 13/18. */
@media (max-width: 600px) {
  :root table:not(:is(.market-book, .market-trades) *) :is(th, td) {
    padding: 0 12px;
    hyphens: auto;
  }
  /* Шапку капсом не дробим: её ширина — минимум колонки, остальное прокручивает обёртка. */
  :root table:not(:is(.market-book, .market-trades) *) thead th {
    white-space: nowrap;
    hyphens: manual;
  }
  :root table:is(.v24-plan-table, .hero-plans-table, .formula-table, :where(form[data-seo-calc] ~ .table-wrap > table)) :is(th, td) {
    padding: 0 8px;
    font-size: 13px;
    line-height: 18px;
  }
}

/* Карточки: у таблицы с подписями колонок (td[data-label]) каждая строка на телефоне — карточка,
   подпись колонки слева, значение справа, первая ячейка — заголовок карточки. */
@media (max-width: 700px) {
  :root :is([data-accruals-table], [data-accruals-deposits], [data-cover-table], .part5-history-table, table:has(td[data-label])) {
    display: block;
    width: 100%;
    border: 0;
    background: none;
  }
  :root :is([data-accruals-table], [data-accruals-deposits], [data-cover-table], .part5-history-table, table:has(td[data-label])) thead { display: none; }
  :root :is([data-accruals-table], [data-accruals-deposits], [data-cover-table], .part5-history-table, table:has(td[data-label])) tbody { display: block; }
  :root :is([data-accruals-table], [data-accruals-deposits], [data-cover-table], .part5-history-table, table:has(td[data-label])) caption {
    display: block;
    width: 100%;
    box-sizing: border-box;
    white-space: normal;
  }
  :root :is([data-accruals-table], [data-accruals-deposits], [data-cover-table], .part5-history-table, table:has(td[data-label])) tr {
    display: block;
    margin: 0 0 8px;
    padding: 12px 16px;
    border: 1px solid var(--table-rule, var(--rule, var(--color-rule)));
    border-radius: 14px;
    background: var(--table-card, var(--surface, var(--color-surface)));
  }
  :root :is([data-accruals-table], [data-accruals-deposits], [data-cover-table], .part5-history-table, table:has(td[data-label])) td {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    /* Подпись прижата влево (margin-right: auto у ::before), значение — вправо и тогда, когда
       перенеслось на свою строку; длинное значение переносится внутри карточки. */
    justify-content: flex-end;
    overflow-wrap: anywhere;
    gap: 2px 12px;
    height: auto;
    padding: 4px 0;
    border: 0;
    text-align: right;
  }
  /* Фон ховера и текущей строки в карточке ложится на всю карточку, а не полосами на ячейки;
     tr:nth-child(n) — только чтобы перевесить правила строк таблицы выше (0,3,4). */
  :root :is([data-accruals-table], [data-accruals-deposits], [data-cover-table], .part5-history-table, table:has(td[data-label])) tbody tr:nth-child(n) > :is(th, td) { background: none; }
  :root :is([data-accruals-table], [data-accruals-deposits], [data-cover-table], .part5-history-table, table:has(td[data-label])) tbody tr:is([aria-current="true"], [aria-selected="true"], .is-recommended) {
    background: color-mix(in srgb, var(--table-card, var(--surface, var(--color-surface))), var(--table-accent, var(--amber, var(--color-accent))) 8%);
  }
  @media (hover: hover) {
    :root :is([data-accruals-table], [data-accruals-deposits], [data-cover-table], .part5-history-table, table:has(td[data-label])) tbody tr:hover {
      background: color-mix(in srgb, var(--table-card, var(--surface, var(--color-surface))), var(--table-fg, var(--bone, var(--color-text-1))) 4%);
    }
  }
  /* Итог в карточке — без двойной черты над каждым значением. */
  :root :is([data-accruals-table], [data-accruals-deposits], [data-cover-table], .part5-history-table, table:has(td[data-label])) :is(tfoot, .p5-report-total) > :is(th, td) { border-top: 0; }
  :root :is([data-accruals-table], [data-accruals-deposits], [data-cover-table], .part5-history-table, table:has(td[data-label])) td::before {
    content: attr(data-label);
    flex: 0 0 auto;
    margin-right: auto;
    font-size: 12px;
    line-height: 16px;
    letter-spacing: .06em;
    text-transform: uppercase;
    color: var(--table-head, var(--text-3, var(--color-text-3)));
    text-align: left;
  }
  /* Заголовок карточки — первая ячейка или заголовок строки (th scope=row, например «Итого»);
     tbody tr > — чтобы черта под заголовком не терялась у последней карточки. */
  :root :is([data-accruals-table], [data-accruals-deposits], [data-cover-table], .part5-history-table, table:has(td[data-label])) tbody tr > :is(td:first-child, th) {
    display: block;
    height: auto;
    margin: 0 0 4px;
    padding: 0 0 8px;
    border-bottom: 1px solid var(--table-rule, var(--rule, var(--color-rule)));
    font-weight: 600;
    text-align: left;
  }
  :root :is([data-accruals-table], [data-accruals-deposits], [data-cover-table], .part5-history-table, table:has(td[data-label])) td:first-child::before { content: ""; }
  :root :is([data-accruals-table], [data-accruals-deposits], [data-cover-table], .part5-history-table, table:has(td[data-label])) td small {
    display: block;
    flex: 1 0 100%;
    text-align: left;
    color: var(--table-head, var(--text-3, var(--color-text-3)));
  }
}

/* Строка ленты операций (кабинет): та же высота, разделитель и ховер, что у строки таблицы. */
:root .operation-row {
  min-height: 56px;
  border-bottom: 1px solid var(--table-rule, var(--rule, var(--color-rule)));
}
@media (hover: hover) {
  :root .operation-row:hover { background-color: color-mix(in srgb, transparent, var(--table-fg, var(--bone, var(--color-text-1))) 4%); }
}

/* ───────────────────────────── 04 · Карточка и плитка ─────────────────────────────
   Спека: docs/design-audit/06_card.md, docs/parts/DESIGN-QUALITY.md §1, §4, §5, §6.
   Карточка: радиус 14 · поля 24 (телефон ≤ 600 px — 20) · рамка 1 px · фон поверхности ·
   без тени, градиента, стекла и подъёма. Плитка метрики: поля 20 · подпись 12/16 капсом +.06em ·
   число 32/40 вес 600 табличными цифрами · пояснение 14/20. Главная плитка .tile-main — число 40/48
   (телефон 32/40), одна на экран. Компактная плитка (полосы второстепенных
   метрик под главной цифрой счёта: .metric-line, .dash-cell) — поля 12 16, число 20/28, пояснение 12/16.
   Классы — псевдонимы поколений вёрстки, разметку и JS не трогаем:
     карточка      .card (контентные, v36, счёт, симулятор) · .panel (пульт, консьерж) · .contact-card ·
                   .public-plan · .why-card .quote-card .tile (crypto) · .auth-card (вход в счёт) ·
                   .v24-calc-card .v24-pay-card .v24-ref-card .v24-step .v24-ledger (лендинг) · .crypto-wallet-card
                   .scenario-card .onboarding .profile-welcome (кабинет v21) · .login-panel
                   .queue-panel .collapse-panel .queue-state (пульт)
     плитка        .metric (счёт, пульт) · .metric-link (пульт) · .tile с .k/.v/.n (сводка, симулятор)
     плоская       раздел кабинета v21 (.cabinet-v21 .panel), его плитка .metric-card и вклад
                   .investment-card — без плашки, разделитель снизу
     кликабельная  .metric-link .network-card (<button>) — наведение, нажатие, фокус
     тона          заметка .status-note .legal-translation-note · предупреждение .warn ·
                   опасность .bad .collapse-panel — только цвет рамки и подложки, геометрия общая
   Панель графика (.chart-panel, .calculator-chart-panel) и форма калькулятора (#calculator-form) — поверхность
   и в плоском разделе кабинета; результат калькулятора кабинета (.calculator-result) — карточка. Внутренности —
   разделы 10 «График и панель» и 11 «Калькулятор».
   Цвета — семантические токены страницы (--surface, --rule, --rule-strong, --text-3, --bone, --amber,
   --focus, --loss); своя палитра — крючки --card-* на :root (счёт, пульт, консьерж, сводка, симулятор)
   или на самой карточке (вложенная карточка пульта). Раскладку (grid, gap, margin) задаёт страница.
   Фон по умолчанию #12151C на #06070B — поверхность на ~6 % светлее фона (§4). */
:root :is(.card, .tile, .metric, .panel, .metric-link, .network-card, .queue-state, .collapse-panel, .login-panel, .queue-panel, .status-note, .legal-translation-note, .contact-card, .public-plan, .why-card, .quote-card, .auth-card, .v24-calc-card, .v24-pay-card, .v24-ref-card, .v24-step, .v24-ledger, .crypto-wallet-card, .scenario-card, .onboarding, .profile-welcome, .calculator-result) {
  box-sizing: border-box;
  padding: 24px;
  border: 1px solid var(--card-border, var(--rule, var(--color-rule)));
  border-radius: 14px;
  background-color: var(--card-bg, var(--surface, var(--color-surface)));
  background-image: none;
  box-shadow: none;
  backdrop-filter: none;
}

@media (max-width: 600px) {
  :root :is(.card, .tile, .metric, .panel, .metric-link, .network-card, .queue-state, .collapse-panel, .login-panel, .queue-panel, .status-note, .legal-translation-note, .contact-card, .public-plan, .why-card, .quote-card, .auth-card, .v24-calc-card, .v24-pay-card, .v24-ref-card, .v24-step, .v24-ledger, .crypto-wallet-card, .scenario-card, .onboarding, .profile-welcome, .calculator-result) {
    padding: 20px;
  }
}

/* Панель со списком во всю ширину (очередь пульта): поля дают строки списка. */
:root .queue-panel { padding: 0; }

/* Плитка: поля 20; подпись — число — пояснение столбиком через 4 px. */
:root :is(.tile, .metric, .metric-link) { padding: 20px; }
:root :is(.metric-card, .metric, .metric-link) {
  display: grid;
  align-content: start;
  gap: 4px;
}

:root :is(.metric-card, .metric, .metric-link) > span:first-child, :root .tile > .k {
  display: block;
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--card-muted, var(--text-3, var(--color-text-3)));
}

:root :is(.metric-card, .metric, .metric-link) > strong, :root .tile > .v {
  display: block;
  margin: 0;
  font-size: 32px;
  line-height: 40px;
  font-weight: 600;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums lining-nums;
}

:root :is(.metric-card, .metric, .metric-link) > small, :root .tile > .n {
  display: block;
  margin: 0;
  font-size: 14px;
  line-height: 20px;
  color: var(--card-muted, var(--text-3, var(--color-text-3)));
}

:root .tile > :is(.v, .n) { margin-top: 4px; }

/* Компактная плитка — полосы второстепенных метрик счёта под главной цифрой (#metrics .metric-line,
   «Сводка» .dash-cell): не спорят с ней. */
:root .metric:is(.metric-line, .dash-cell) { padding: 12px 16px; }
:root .metric:is(.metric-line, .dash-cell) > strong { font-size: 20px; line-height: 28px; }
:root .metric:is(.metric-line, .dash-cell) > small { font-size: 12px; line-height: 16px; }

/* Главная плитка — одна главная цифра экрана (результат симулятора): число 40/48, на телефоне 32/40 —
   длинное число не переносится на 390. Поддержка рядом — компактные плитки. */
:root .tile.tile-main > .v { font-size: 40px; line-height: 48px; }
@media (max-width: 600px) {
  :root .tile.tile-main > .v { font-size: 32px; line-height: 40px; }
}

/* Плоская: раздел кабинета v21, его плитка и вклад — без плашки; плитка и вклад делятся линией.
   Панель графика остаётся поверхностью (элемент 10): данные на плашке читаются как один объект. */
:root .cabinet-v21 .panel:not(:where(.chart-panel, .calculator-chart-panel, #calculator-form)), :root .metric-card, :root .investment-card {
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
  box-shadow: none;
}

:root .metric-card {
  padding: 16px 0;
  border-bottom: 1px solid var(--card-rule, var(--rule, var(--color-rule)));
}

:root .investment-card {
  padding: 24px 0;
  border-bottom: 1px solid var(--card-rule, var(--rule, var(--color-rule)));
}

/* Кликабельная карточка (<button>): наведение — фон на 4 % светлее и рамка сильнее, нажатие — 8 %;
   без подъёма, масштаба и тени. Наведение только на устройствах с настоящим hover.
   filter/transform сбрасываются: правила голых button пульта (brightness, scale .97) дотягиваются до карточки. */
:root :is(.metric-link, .network-card) {
  font: inherit;
  color: inherit;
  text-align: start;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 160ms ease-out, border-color 160ms ease-out;
}

@media (hover: hover) {
  :root :is(.metric-link, .network-card):not(:disabled, [aria-disabled="true"]):hover {
    border-color: var(--card-border-hover, var(--rule-strong, var(--color-rule-strong)));
    background-color: color-mix(in srgb, var(--card-bg, var(--surface, var(--color-surface))), var(--card-fg, var(--bone, var(--color-text-1))) 4%);
    filter: none;
    transform: none;
  }
}

:root :is(.metric-link, .network-card):not(:disabled, [aria-disabled="true"]):active {
  background-color: color-mix(in srgb, var(--card-bg, var(--surface, var(--color-surface))), var(--card-fg, var(--bone, var(--color-text-1))) 8%);
  filter: none;
  transform: none;
}

:root :is(.metric-link, .network-card):focus-visible {
  outline: 2px solid var(--card-focus, var(--focus, var(--gold, var(--color-focus))));
  outline-offset: 2px;
}

/* Выбранная / текущая / рекомендованная: рамка акцентом, фон на 6 % теплее — одно выделение на экран. */
:root :is(.card, .tile, .metric, .panel, .metric-link, .network-card, .queue-state, .public-plan, .crypto-wallet-card, .scenario-card):is([aria-current="true"], [aria-current="page"], [aria-selected="true"], [aria-pressed="true"], .is-selected), :root .public-plan-starter, :root .queue-state.awaiting {
  border-color: var(--card-accent, var(--amber, var(--color-accent)));
  background-color: color-mix(in srgb, var(--card-bg, var(--surface, var(--color-surface))), var(--card-accent, var(--amber, var(--color-accent))) 6%);
}

/* Недоступная: видно, что нельзя нажать; причину страница пишет внутри карточки. */
:root :is(.metric-link, .network-card):is(:disabled, [aria-disabled="true"]), :root :is(.card, .tile, .metric, .panel, .public-plan, .crypto-wallet-card, .scenario-card)[aria-disabled="true"] {
  opacity: .45;
  cursor: not-allowed;
}

/* Пустой слот (кошелёк не подключён): пунктирная рамка, без заливки. */
:root :is(.card, .tile, .crypto-wallet-card, .scenario-card):is([data-state="empty"], .wallet-inactive) {
  border-style: dashed;
  border-color: var(--card-border-strong, var(--rule-strong, var(--color-rule-strong)));
  background-color: transparent;
}

/* Пустое состояние внутри карточки или раздела: объяснение и одно действие (§6). */
:root .empty-state {
  display: grid;
  justify-items: start;
  gap: 12px;
  padding: 32px 0;
  color: var(--card-empty-fg, var(--text-2, currentColor));
  font-size: 16px;
  line-height: 24px;
}

/* Загрузка: скелетон той же геометрии — строки на месте, текст прозрачный, без спиннера и анимации. */
:root :is(.card, .tile, .metric, .metric-card, .panel, .metric-link, .public-plan)[aria-busy="true"] {
  cursor: progress;
}

:root :is(.card, .tile, .metric, .metric-card, .panel, .metric-link, .public-plan)[aria-busy="true"] :is(h2, h3, p, span, strong, small, dt, dd, .k, .v, .n) {
  color: transparent;
  border-radius: 4px;
  background-color: color-mix(in srgb, transparent, var(--card-fg, var(--bone, var(--color-text-1))) 8%);
}

/* Тоны: только цвета через крючки, геометрия общая; смысл всегда ещё и в тексте карточки. */
:root :is(.status-note, .legal-translation-note) {
  --card-bg: var(--card-note-bg, var(--palette-grey-810));
  --card-border: var(--card-note-border, var(--palette-amber-550));
}

:root :is(.card, .tile, .metric, .panel).warn {
  --card-border: var(--card-warn, var(--color-warn));
}

:root :is(.card, .tile, .metric, .panel):is(.bad, .collapse-panel), :root .collapse-panel {
  --card-border: var(--card-danger, var(--loss, var(--color-danger)));
}

@media (prefers-reduced-motion: reduce) {
  :root :is(.metric-link, .network-card) { transition: none; }
}

@media (forced-colors: active) {
  :root :is(.metric-link, .network-card):focus-visible { outline-color: Highlight; }
  :root :is(.metric-card, .investment-card) { border-bottom-color: CanvasText; }
}

/* ───────────────────────────── 05 · Бейдж статуса ─────────────────────────────
   Спека: docs/design-audit/07_badge.md, docs/parts/DESIGN-QUALITY.md §3, §4, §10.
   Служебный голос интерфейса — 12/16, капс, трекинг +6 %, — в трёх ролях и двух подписях:
     надзаголовок   .eyebrow и *-kicker над заголовком — вес 600, приглушённый (--text-3); акцентом —
                    только надзаголовок первого экрана (тот, за которым сразу идёт h1): одно выделение на экран;
     бейдж          .badge .status-chip .today-badge .v24-plan-badge .public-plan-badge .doc-lang-badge .risk-tag —
                    24 px (поля 3 12, рамка 1), радиус 12 — пилюля; метка в одну строку (длинную подпись
                    страница переносит сама: шапка пульта); в ячейке сетки — по ширине текста (justify-self: start);
                    вес 500, табличные цифры; не кликабелен — бейджей-кнопок
                    и фильтров на страницах нет, состояний ховер/фокус у него нет;
                    тон — точкой 6 px (≥ 3:1) и текстом статуса: цвет не единственный носитель смысла;
                    подпись нейтральная (≥ 4.5:1), рамка — 50 % цвета подписи (≥ 3:1 на тёмных палитрах,
                    светлые ставят --badge-border-mix: 70 %);
                    отметка выбора (.v24-plan-badge «рекомендуем», .public-plan-badge, .today-badge) — текстом
                    акцента, без точки;
     статус в строке .pending-tag — часть предложения («· поле не заполнено»): 14/20 тоном «внимание»;
     текст ошибки   .form-error .journey-field-error .v24-error — под полем, 14/20, цвет ошибки поля (элемент 02);
     подпись ячейки .cabinet-epochs-table small, .payout-context — 12/16, не мельче 12 px (§3).
   Тоны: успех .st-active, .st-done, [data-tone="success"] · внимание .st-review, .st-awaiting, .st-approved, .sandbox, [data-tone="warn"] ·
   ошибка .st-terminated, .st-rejected, .critical, .high, .risk-tag, [data-tone="danger"]; без класса тона — нейтральный. Цвета — токены страницы
   (--text-2, --text-3, --up, --accent-text/--amber, --loss); своя палитра — крючки --badge-* / --eyebrow-* на :root
   (кабинет счёта, пульт, консьерж, эпохи). Раскладку (отступы, display:none на телефоне) задаёт страница. */

:root :is(.eyebrow, .lab-kicker, .v24-kicker, .crypto-eyebrow, .crypto-kicker, .epochs-kicker, .epochs-step-badge, .p6-kicker, .today-kicker, .academy-kicker, .auth-kicker) {
  font-family: inherit;
  font-size: 12px;
  line-height: 16px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--eyebrow-color, var(--text-3, var(--color-text-3)));
}

/* Надзаголовок первого экрана — над h1 страницы: единственное выделение акцентом. */
:root :is(.eyebrow, .lab-kicker, .v24-kicker, .crypto-eyebrow, .crypto-kicker, .epochs-kicker, .epochs-step-badge, .p6-kicker, .today-kicker, .academy-kicker, .auth-kicker):has(+ h1) {
  color: var(--eyebrow-accent, var(--accent-text, var(--amber, var(--color-accent-text))));
}

:root :is(.badge, .status-chip, .today-badge, .v24-plan-badge, .public-plan-badge, .doc-lang-badge, .risk-tag) {
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  justify-self: start;
  min-height: 24px;
  padding: 3px 12px;
  border: 1px solid var(--badge-border, color-mix(in srgb, currentColor var(--badge-border-mix, 50%), transparent));
  border-radius: 12px;
  background: transparent;
  color: var(--badge-fg, var(--text-2, var(--color-text-2)));
  font-family: inherit;
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  vertical-align: middle;
}

:root :is(.badge, .status-chip, .today-badge, .v24-plan-badge, .public-plan-badge, .doc-lang-badge, .risk-tag):is(.st-active, .st-done, [data-tone="success"]) { --badge-tone: var(--badge-success, var(--up, var(--color-success))); }
:root :is(.badge, .status-chip, .today-badge, .v24-plan-badge, .public-plan-badge, .doc-lang-badge, .risk-tag):is(.st-review, .st-awaiting, .st-approved, .sandbox, [data-tone="warn"]) { --badge-tone: var(--badge-warn, var(--color-warn)); }
:root :is(.badge, .status-chip, .today-badge, .v24-plan-badge, .public-plan-badge, .doc-lang-badge, .risk-tag):is(.st-terminated, .st-rejected, .critical, .high, .risk-tag, [data-tone="danger"]) { --badge-tone: var(--badge-danger, var(--loss, var(--color-danger))); }

/* Критический (пульт: приоритет дела) — сильнее «высокого» формой, не только оттенком: заливка тона 16 %,
   подпись цветом тона, вес 600. Рядом с «высоким» (точка и контур) различим без цвета — по заливке и весу. */
:root :is(.badge, .status-chip).critical {
  background-color: color-mix(in srgb, var(--badge-tone) 16%, transparent);
  color: var(--badge-tone);
  font-weight: 600;
}
/* Точка тона: 6 px, до подписи; у нейтрального бейджа точки нет. */
:root :is(.badge, .status-chip, .today-badge, .v24-plan-badge, .public-plan-badge, .doc-lang-badge, .risk-tag):is(.st-active, .st-done, [data-tone="success"], .st-review, .st-awaiting, .st-approved, .sandbox, [data-tone="warn"], .st-terminated, .st-rejected, .critical, .high, .risk-tag, [data-tone="danger"])::before {
  content: "";
  flex: none;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--badge-tone);
}

/* Отметка выбора — текстом акцента; рамка берёт тот же цвет через currentColor. */
:root :is(.v24-plan-badge, .public-plan-badge, .today-badge) {
  color: var(--badge-accent, var(--accent-text, var(--amber, var(--color-accent-text))));
}

:root .pending-tag {
  color: var(--badge-warn, var(--color-warn));
  font-size: 14px;
  line-height: 20px;
  font-weight: 400;
}

:root :is(.form-error, .journey-field-error, .v24-error) {
  color: var(--field-error, var(--loss, var(--color-danger)));
  font-size: 14px;
  line-height: 20px;
  font-weight: 400;
}

:root :is(.cabinet-epochs-table small, .payout-context) {
  font-size: 12px;
  line-height: 16px;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
}

/* Грузинский и армянский: заглавных форм у письма нет — капс и трекинг ломают начертание;
   у надзаголовка строка 20 под высокие знаки. */
:root:is(:lang(ka), :lang(hy)) :is(.eyebrow, .lab-kicker, .v24-kicker, .crypto-eyebrow, .crypto-kicker, .epochs-kicker, .epochs-step-badge, .p6-kicker, .today-kicker, .academy-kicker, .auth-kicker, .badge, .status-chip, .today-badge, .v24-plan-badge, .public-plan-badge, .doc-lang-badge, .risk-tag) {
  letter-spacing: 0;
  text-transform: none;
}
:root:is(:lang(ka), :lang(hy)) :is(.eyebrow, .lab-kicker, .v24-kicker, .crypto-eyebrow, .crypto-kicker, .epochs-kicker, .epochs-step-badge, .p6-kicker, .today-kicker, .academy-kicker, .auth-kicker) { line-height: 20px; }

@media (forced-colors: active) {
  :root :is(.badge, .status-chip, .today-badge, .v24-plan-badge, .public-plan-badge, .doc-lang-badge, .risk-tag) { border-color: CanvasText; }
  :root :is(.badge, .status-chip, .today-badge, .v24-plan-badge, .public-plan-badge, .doc-lang-badge, .risk-tag)::before { background: CanvasText; }
}

/* ───────────────────────────── 07 · Шапка и навигация ─────────────────────────────
   Спека: docs/design-audit/09_header.md, docs/parts/DESIGN-QUALITY.md §2, §5, §8.
   Панель 64 px на десктопе и 56 px на телефоне (≤ 600 px) вместе с линией 1 px снизу, контент 44 по
   центру · ссылка навигации 14/20 вес 500, цель 44 × 44, поля 0 12, радиус 10 · контролы шапки (язык,
   меню, тема) 44 px, радиус 10, рамка 1 px · текстовый вордмарк 20/24 (18 на телефоне) ·
   skip-link 44 px, виден только в фокусе.

   Классы — поколения вёрстки, разметку не трогаем:
     панель       .site-header (лендинг, 404) · .topbar (контентные, крипто, эпохи, счёт, пульт) ·
                  .cabinet-topbar (кабинет) · body > header (консьерж)
     вордмарк     .wordmark · .brand · .mobile-brand — только SVG-знак «VELAR.» (текстового знака нет)
     ссылки       nav a в панели · .header-login · .topbar-home
     контролы     язык: .language-compact · .page-lang · .cabinet-lang · .lang консьержа;
                  кнопки: .landing-menu-button (aria-expanded — меню открыто) · .theme-toggle кабинета
     язык в форме .language-control без .language-compact (меню лендинга, настройки кабинета) — как поле
     пропуск      .skip-link · .skip · .cabinet-skip
   Раскладку (липкость, поля по краям, промежутки между группами, порядок, что прятать на телефоне)
   задаёт страница; вид и состояния — только здесь. Своя палитра — крючки на :root или body:
   --header-bg --header-rule --header-fg --header-link --header-muted --header-accent --header-focus
   --header-control-bg --header-control-border --header-skip-bg --header-skip-fg.
   :where() держит специфичность групп одинаковой: консьерж (body > header) не перевешивает классы. */

:root { --header-height: 64px; }
@media (max-width: 600px) { :root { --header-height: 56px; } }

/* Панель: 64 / 56 вместе с линией. Вторая строка (лента разделов, инструменты) на телефоне
   прибавляет 44 без зазора: 56 + 44 = 100. Липкость и фон-подложку под прокруткой задаёт страница
   (фон — крючком --header-bg). */
:root :is(.site-header, .topbar, .cabinet-topbar, :where(body) > header) {
  --header-pad: calc((var(--header-height) - 45px) / 2);
  box-sizing: border-box;
  display: flex;
  align-items: center;
  row-gap: 0;
  min-height: var(--header-height);
  padding-top: var(--header-pad);
  padding-bottom: var(--header-pad);
  border-bottom: 1px solid var(--header-rule, var(--rule, var(--color-rule)));
  background-color: var(--header-bg, transparent);
}
/* Липкая шапка лендинга под вырезом экрана: отступ сверху растёт на safe-area. */
:root .site-header {
  min-height: calc(var(--header-height) + env(safe-area-inset-top, 0px));
  padding-top: calc(var(--header-pad) + env(safe-area-inset-top, 0px));
}

/* Липкая шапка не закрывает цель якоря: отступ прокрутки = её высота + 24. */
:root:has(.site-header, .cabinet-topbar) { scroll-padding-top: calc(var(--header-height) + 24px); }

/* Вордмарк: цель 44, цвет текста шапки; на наведение не меняется — это знак, а не ссылка-раздел.
   :where(панель) — специфичность 0,2,0: страница может спрятать логотип (кабинет: .mobile-brand на десктопе). */
:root :where(.site-header, .topbar, .cabinet-topbar, body > header) :is(.wordmark, .brand, .mobile-brand) {
  display: inline-flex;
  align-items: center;
  flex: none;
  min-height: 44px;
  border-radius: 4px;
  color: var(--header-fg, var(--bone, var(--color-text-1)));
  text-decoration: none;
}
:root :is(.wordmark, :where(body > header) > .brand) {
  font-family: "Science Gothic", "Onest", system-ui, sans-serif;
  font-size: 20px;
  line-height: 24px;
  font-weight: 600;
  letter-spacing: .02em;
  white-space: nowrap;
}

/* Ссылки разделов: 14/20 вес 500, цель 44 × 44, поля 0 12 — подпись между ссылками 28 px. */
:root :is(.desktop-nav, .topbar-nav, :where(body > header) nav) { gap: 4px; }
:root :is(.desktop-nav a, .topbar-nav a, :where(body > header) nav a, .header-login, .topbar-home) {
  box-sizing: border-box;
  display: inline-flex;
  flex: none;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  min-height: 44px;
  padding: 0 12px;
  border-radius: 10px;
  color: var(--header-link, var(--text-2, var(--color-text-2)));
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  text-decoration: none;
  white-space: nowrap;
  transition: color 160ms ease-out, background-color 160ms ease-out;
}
:root :is(.desktop-nav a, .topbar-nav a, :where(body > header) nav a, .header-login, .topbar-home)[hidden] { display: none; }

/* Текущая страница: цвет текста + черта 2 px акцентом — не только цветом (aria-current="page"). */
:root :is(.desktop-nav a, .topbar-nav a, :where(body > header) nav a)[aria-current="page"] {
  color: var(--header-fg, var(--bone, var(--color-text-1)));
  text-decoration-line: underline;
  text-decoration-thickness: 2px;
  text-decoration-color: var(--header-accent, var(--amber, var(--color-accent)));
  text-underline-offset: 6px;
}

/* Контролы шапки: язык, меню, тема — 44 px, радиус 10, рамка 1 px (контраст ≥ 3:1), как компактная
   кнопка. display задаёт страница (кнопка меню видна только без ленты разделов). */
:root :is(.language-compact, .page-lang, .cabinet-lang, :where(body > header) .lang, .landing-menu-button, :where(.cabinet-topbar) .theme-toggle) {
  box-sizing: border-box;
  position: relative;
  align-items: center;
  justify-content: center;
  gap: 6px;
  min-width: 44px;
  height: 44px;
  padding: 0 12px;
  border: 1px solid var(--header-control-border, var(--rule-strong, var(--color-rule-strong)));
  border-radius: 10px;
  background-color: var(--header-control-bg, transparent);
  color: var(--header-fg, var(--bone, var(--color-text-1)));
  font-family: inherit;
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  text-decoration: none;
  cursor: pointer;
  transition: background-color 160ms ease-out, border-color 160ms ease-out;
}
:root :is(.language-compact, .page-lang, .cabinet-lang, :where(body > header) .lang) {
  display: inline-flex;
  flex: 0 1 auto;
  min-width: 44px;
  max-width: 100%;
  margin-block: 0;
}
:root .landing-menu-button { width: 44px; padding: 0; }
:root .landing-menu-button[aria-expanded="true"] {
  background-color: color-mix(in srgb, var(--header-control-bg, transparent), var(--header-fg, var(--bone, var(--color-text-1))) 12%);
}

/* Подпись «Язык» — для чтеца экрана (у select есть aria-label); видимое имя — код или выбранный язык. */
:root :is(.language-compact, .page-lang, :where(body > header) .lang) > span:first-child {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* Компактный: глобус, код языка 12/16 капсом и шеврон; нативный select — прозрачная накладка на всю
   площадь контрола (16 px — iOS не зумит). */
:root .language-current {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  color: inherit;
  font-family: var(--font-mono, inherit);
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: .06em;
  white-space: nowrap;
  pointer-events: none;
}
:root .language-current svg { display: block; flex: none; width: 16px; height: 16px; }
:root .language-current .language-chevron { width: 16px; height: 16px; color: var(--header-muted, var(--text-3, var(--color-text-3))); }
:root .language-compact select {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  min-width: 0;
  max-width: none;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  opacity: 0;
  font-size: 16px;
  cursor: pointer;
}

/* Со списком на виду (контентные, счёт, консьерж): select заполняет контрол, шеврон — фоном,
   длинное имя языка обрезается, а не раздвигает шапку. */
:root :is(.page-lang, .cabinet-lang, :where(body > header) .lang) { padding: 0; }
:root :is(.page-lang, .cabinet-lang, :where(body > header) .lang) select {
  box-sizing: border-box;
  appearance: none;
  width: 100%;
  min-width: 0;
  max-width: 100%;
  height: 42px;
  min-height: 0;
  margin: 0;
  padding: 0 32px 0 12px;
  border: 0;
  border-radius: 9px;
  background-color: transparent;
  background-image: linear-gradient(45deg, transparent 50%, var(--header-muted, var(--text-3, var(--color-text-3))) 50%),
    linear-gradient(135deg, var(--header-muted, var(--text-3, var(--color-text-3))) 50%, transparent 50%);
  background-position: calc(100% - 19px) 50%, calc(100% - 14px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  color: inherit;
  font: inherit;
  text-overflow: ellipsis;
  cursor: pointer;
}
/* Фокус рисует контрол целиком (ниже), у самого списка рамки нет — иначе две рамки. */
:root :is(.page-lang, .cabinet-lang, :where(body > header) .lang) select:focus-visible { outline: 2px solid transparent; }

/* Язык в форме (меню лендинга, настройки кабинета): подпись видна, список — как поле 02. */
:root .language-control:not(.language-compact) {
  color: var(--header-link, var(--text-2, var(--color-text-2)));
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
}
:root .language-control:not(.language-compact) select {
  box-sizing: border-box;
  appearance: none;
  min-height: 44px;
  padding: 0 36px 0 12px;
  border: 1px solid var(--field-border, var(--rule-strong, var(--color-rule-strong)));
  border-radius: 10px;
  background-color: var(--field-bg, var(--surface, var(--color-surface)));
  background-image: linear-gradient(45deg, transparent 50%, var(--field-placeholder, var(--text-3, var(--color-text-3))) 50%),
    linear-gradient(135deg, var(--field-placeholder, var(--text-3, var(--color-text-3))) 50%, transparent 50%);
  background-position: calc(100% - 19px) 50%, calc(100% - 14px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  color: var(--field-fg, var(--bone, var(--color-text-1)));
  font-family: inherit;
  font-size: 16px;
  line-height: 24px;
  font-weight: 400;
  cursor: pointer;
  outline: 2px solid transparent;
  transition: border-color 160ms ease-out, box-shadow 160ms ease-out;
}
:root .language-control:not(.language-compact) select:focus {
  border-color: var(--field-focus, var(--focus, var(--gold, var(--color-focus))));
  box-shadow: 0 0 0 1px var(--field-focus, var(--focus, var(--gold, var(--color-focus))));
}

/* Наведение — подмес 6 % цвета текста в фон, как у кнопки; только при настоящем hover. */
@media (hover: hover) {
  :root :is(.desktop-nav a, .topbar-nav a, :where(body > header) nav a, .header-login, .topbar-home):hover {
    color: var(--header-fg, var(--bone, var(--color-text-1)));
    background-color: color-mix(in srgb, transparent, var(--header-fg, var(--bone, var(--color-text-1))) 6%);
  }
  :root :is(.language-compact, .page-lang, .cabinet-lang, :where(body > header) .lang, .landing-menu-button, :where(.cabinet-topbar) .theme-toggle):hover {
    background-color: color-mix(in srgb, var(--header-control-bg, transparent), var(--header-fg, var(--bone, var(--color-text-1))) 6%);
  }
  :root :where(.site-header, .topbar, .cabinet-topbar, body > header) :is(.wordmark, .brand, .mobile-brand):hover { color: var(--header-fg, var(--bone, var(--color-text-1))); }
  :root .language-control:not(.language-compact) select:not(:focus):hover { border-color: var(--field-border-hover, var(--text-3, var(--color-text-3))); }
}
:root :is(.landing-menu-button, :where(.cabinet-topbar) .theme-toggle):active {
  background-color: color-mix(in srgb, var(--header-control-bg, transparent), var(--header-fg, var(--bone, var(--color-text-1))) 12%);
  transform: none;
}

/* Фокус с клавиатуры — рамка 2 px акцентом вне контура; у языка — на всём контроле. */
:root :is(.site-header, .topbar, .cabinet-topbar, :where(body) > header) :is(a, button):focus-visible,
:root :is(.language-compact, .page-lang, .cabinet-lang, :where(body > header) .lang):has(:focus-visible) {
  outline: 2px solid var(--header-focus, var(--focus, var(--gold, var(--color-focus))));
  outline-offset: 2px;
}

/* Пропуск к содержимому: 44 px, светлая плашка (на светлой теме — тёмная), за краем экрана до фокуса. */
:root :is(.skip-link, .skip, .cabinet-skip) {
  position: fixed;
  top: 12px;
  left: 16px;
  z-index: 200;
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  width: auto;
  height: auto;
  min-height: 44px;
  padding: 0 16px;
  overflow: visible;
  clip-path: none;
  border: 0;
  border-radius: 10px;
  background: var(--header-skip-bg, var(--bone, var(--color-text-1)));
  color: var(--header-skip-fg, var(--void, var(--color-bg)));
  font-size: 14px;
  line-height: 20px;
  font-weight: 600;
  text-decoration: none;
  white-space: nowrap;
  transform: translateY(calc(-100% - 24px));
}
:root :is(.skip-link, .skip, .cabinet-skip):focus {
  transform: none;
  outline: 2px solid var(--header-focus, var(--focus, var(--gold, var(--color-focus))));
  outline-offset: 2px;
}

/* Телефон: текстовый вордмарк 18 px. Навигация без кнопки меню (.topbar-nav) — лента 44 px второй
   строкой панели: прокручивается вбок внутри себя, страница вбок не едет; язык — справа в первой. */
@media (max-width: 600px) {
  :root :is(.wordmark, :where(body > header) > .brand) { font-size: 18px; }
  :root :is(.page-lang, .cabinet-lang, :where(body > header) .lang) select { font-size: 16px; }
  :root .topbar .topbar-nav {
    order: 3;
    flex: 1 0 100%;
    flex-wrap: nowrap;
    justify-content: flex-start;
    margin-inline: -12px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scrollbar-width: none;
  }
  :root .topbar .topbar-nav::-webkit-scrollbar { display: none; }
  :root .topbar :is(.page-lang, .cabinet-lang) { margin-inline-start: auto; }
  /* Список на виду не переносится строкой ниже, а сжимается до своей ширины (имя языка обрезается). */
  :root :is(.page-lang, .cabinet-lang, :where(body > header) .lang) { flex: 1 1 0; max-width: max-content; }
}

@media (prefers-reduced-motion: reduce) {
  :root :is(.desktop-nav a, .topbar-nav a, :where(body > header) nav a, .header-login, .topbar-home, .language-compact, .page-lang, .cabinet-lang, .landing-menu-button, .theme-toggle, .language-control select) { transition: none; }
}

@media (forced-colors: active) {
  :root :is(.language-compact, .page-lang, .cabinet-lang, :where(body > header) .lang, .landing-menu-button, :where(.cabinet-topbar) .theme-toggle) { border-color: ButtonText; }
  :root :is(.desktop-nav a, .topbar-nav a, :where(body > header) nav a)[aria-current="page"] { text-decoration-color: LinkText; }
}

/* Самые узкие телефоны (≤ 360 px): длинная подпись «Открыть счёт» (ka, uk, be, tg, ro) наезжала кнопкой меню
   на знак на 8–31 px. Знак не сжимается, подпись кнопки сокращается многоточием — имя ссылки остаётся полным. */
@media (max-width: 360px) {
  :root .site-header .brand { flex: none; }
  :root .site-header .header-tools { min-width: 0; }
  :root .site-header .header-account { flex: 0 1 auto; min-width: 0; padding-inline: 12px; overflow: hidden; }
  :root .site-header .header-account > span { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
}

/* 07 · Одна шапка публичных страниц и меню сайта (полировка текстов 1.2, 2026-10-30).
   Разметка — tools/site-header.mjs: <header class="topbar site-nav"> (документы) и <header class="site-header site-nav">
   (404) — вордмарк страницы · «Планы · Как это работает · FAQ · Протокол» · язык · «Войти» · «Попробовать стартовый
   счёт» · кнопка меню. Набор и имена — как в шапке главной (её якорь «Выплаты» — секция самой главной).
   ≤ 1279 px (тот же порог, что у шапки главной) — ссылки и «Войти» уходят в меню: <details class="site-menu"> (без JavaScript; Esc и клик мимо закрывают его —
   dist/site-footer.js), кнопка — .landing-menu-button; ≤ 600 px — главная кнопка шапки тоже в меню (первый экран
   не держит две главные кнопки, на телефоне знак + кнопка не помещаются в 390). Панель меню — карточка 04:
   ссылки 14/20 вес 500, цель 44, главная кнопка на всю ширину. Палитра — те же крючки --header-*. */
:root .site-nav { flex-wrap: nowrap; gap: 8px; }
:root .site-nav > :is(.wordmark, .brand) { margin-inline-end: 16px; }
:root .site-nav > .topbar-nav { display: flex; flex-wrap: nowrap; margin-inline: 0 auto; }
:root .site-nav > .header-tools { display: flex; flex: 0 1 auto; align-items: center; gap: 8px; min-width: 0; margin-inline-start: auto; }
:root .site-nav > .header-tools > .language-compact { display: inline-flex; }
:root .site-nav .site-menu { display: none; position: relative; }
/* Своя оболочка у <details> меню: правила раскрытий страницы (details { … } документов) её не трогают. */
:root .site-nav details.site-menu { box-sizing: border-box; max-width: none; margin: 0; padding: 0; border: 0; border-radius: 0; background: none; }
:root .site-menu > summary { list-style: none; display: inline-flex; }
:root .site-menu > summary::-webkit-details-marker { display: none; }
:root .site-menu[open] > summary {
  background-color: color-mix(in srgb, var(--header-control-bg, transparent), var(--header-fg, var(--bone, var(--color-text-1))) 12%);
}
:root .site-menu-panel {
  position: absolute;
  inset-inline-end: 0;
  top: calc(100% + 8px);
  z-index: 60;
  box-sizing: border-box;
  display: grid;
  gap: 8px;
  width: min(320px, calc(100vw - 32px));
  padding: 12px;
  border: 1px solid var(--header-rule, var(--rule, var(--color-rule)));
  border-radius: 14px;
  background-color: var(--header-menu-bg, var(--surface, var(--color-surface)));
}
:root .site-menu-links { display: grid; gap: 4px; }
:root .site-menu-links a {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: flex-start;
  min-height: 44px;
  padding: 0 12px;
  border-radius: 10px;
  color: var(--header-link, var(--text-2, var(--color-text-2)));
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  text-decoration: none;
}
:root .site-menu-links a[aria-current="page"] {
  color: var(--header-fg, var(--bone, var(--color-text-1)));
  text-decoration-line: underline;
  text-decoration-thickness: 2px;
  text-decoration-color: var(--header-accent, var(--amber, var(--color-accent)));
  text-underline-offset: 6px;
}
:root .site-menu-links a:focus-visible {
  outline: 2px solid var(--header-focus, var(--focus, var(--gold, var(--color-focus))));
  outline-offset: 2px;
}
:root .site-menu-cta { width: 100%; justify-content: center; }
/* Кнопка меню — <summary>, а не <button>: общий фокус шапки (a, button) её не покрывает. */
:root .site-menu > summary:focus-visible,
:root :is(.trust-page, .v36-faq, main) details.src-more > summary:focus-visible {
  outline: 2px solid var(--header-focus, var(--focus, var(--gold, var(--color-focus))));
  outline-offset: 2px;
  border-radius: 10px;
}
@media (hover: hover) {
  :root .site-menu-links a:hover {
    color: var(--header-fg, var(--bone, var(--color-text-1)));
    background-color: color-mix(in srgb, transparent, var(--header-fg, var(--bone, var(--color-text-1))) 6%);
  }
}
@media (max-width: 1279px) {
  :root .site-nav > .topbar-nav,
  :root .site-nav > .header-tools > .header-login { display: none; }
  :root .site-nav .site-menu { display: block; }
}
@media (max-width: 600px) {
  :root :is(.site-nav, .site-header) > .header-tools > .header-account { display: none; }
  :root .site-nav > .header-tools > .doc-lang-badge { display: none; }
}
@media (forced-colors: active) {
  :root .site-menu-panel { border-color: CanvasText; }
  :root .site-menu-links a[aria-current="page"] { text-decoration-color: LinkText; }
}

/* ───────────────────────────── 08 · Подвал ─────────────────────────────
   Спека: docs/design-audit/10_footer.md, docs/parts/DESIGN-QUALITY.md §2–§5, §8.
   Один подвал на 353 публичные страницы (разметку печатает dist/site-footer.js, она же пререндерена в
   HTML) и короткая строка-подвал счёта и консьержа (body > footer без .site-footer). Отдельного
   site-footer.css больше нет: подвал — такой же раздел слоя компонентов, как кнопка и шапка.

   Сетка     1440: 4 колонки, гаттер 24 — бренд на двух первых, CTA с третьей (до 420 px), группы ссылок
             по колонке, правовая строка во всю ширину; между блоками 40, сверху 48, снизу 32 ·
             ≤ 900: блоки друг под другом, группы в две колонки · ≤ 640: одна колонка, группы — гармошки
             <details> (заголовок 48 px, «Поддержка» открыта), снизу 24 + safe-area.
   Текст     ссылка 14/20 · заголовок группы 12/16 капсом .06em, 500 · подпись бренда 14/20 ·
             правовая строка 12/16 — ничего мельче 12 px; цвета ≥ 4.5:1 на фоне подвала.
   Ссылка    цель 44 на любом указателе; наведение — цвет текста + черта 1 px; фокус — рамка 2 px вне
             контура; текущая страница (aria-current="page", ставит site-footer.js) — цвет текста и черта
             2 px акцентом, как в шапке 07. Акцент в подвале один — CTA.
   CTA       кнопка 01 (класс .button в разметке): 44, радиус 10, 15/20 500, янтарь — здесь только раскладка.
   Контролы  язык и пауза анимации — 44 px, радиус 10, рамка 1 px ≥ 3:1, 14/20 500, как контролы шапки;
             список языка на телефоне 16 px (iOS не зумит). «Наверх» — ссылка-кнопка 44 px.
   Контейнер (.wrap: ширина и поля по краям) и отступы вокруг задаёт страница. Своя палитра — крючки на
   :root: --footer-rule --footer-fg --footer-link --footer-muted --footer-accent --footer-focus
   --footer-control-border --footer-control-bg. */

:root .site-footer {
  box-sizing: border-box;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  grid-template-areas: 'brand brand action action' 'cols cols cols cols' 'legal legal legal legal';
  align-items: start;
  gap: 40px 24px;
  padding-block: 48px 32px;
  border-top: 1px solid var(--footer-rule, var(--rule, var(--color-rule)));
  background: transparent;
  color: var(--footer-muted, var(--text-3, var(--color-text-3)));
  font-family: var(--font-text, 'Onest', 'Onest Fallback', system-ui, sans-serif);
  font-size: 14px;
  line-height: 20px;
  text-align: start;
}
/* Части подвала считаются от рамки: на страницах без глобального border-box ссылка с полями
   вырастала до 48, а заголовок группы до 32. Над фоновой анимацией страницы (дождь цифр лендинга)
   содержимое подвала лежит своим слоем. */
:root .site-footer *, :root .site-footer *::before, :root .site-footer *::after { box-sizing: border-box; }
:root .site-footer > * { position: relative; isolation: isolate; min-width: 0; }
/* Подвал внутри контейнера страницы не добавляет второй слой полей. */
:root :is(.wrap, .epochs-wrap) > .site-footer { padding-inline: 0; }

/* Бренд: знак — цель 44, на наведение не меняется (как в шапке 07); подпись 14/20 до 34 знаков. */
:root .site-footer .footer-brand {
  grid-area: brand;
  display: grid;
  gap: 8px;
  align-content: start;
  justify-items: start;
}
:root .site-footer .footer-brand .brand {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  border-radius: 4px;
  color: var(--footer-fg, var(--bone, var(--color-text-1)));
  font: inherit;
  letter-spacing: normal;
  text-decoration: none;
}
:root .site-footer .footer-brand svg { display: block; width: 92px; height: auto; }
:root .site-footer .footer-tagline {
  max-width: 34ch;
  margin: 0;
  color: var(--footer-muted, var(--text-3, var(--color-text-3)));
  font-size: 14px;
  line-height: 20px;
}

/* Действие: CTA — кнопка 01 во всю ширину своей ячейки, подпись слева, стрелка справа. */
:root .site-footer .footer-action {
  grid-area: action;
  display: grid;
  width: 100%;
  max-width: 420px;
}
:root .site-footer .footer-cta { display: flex; width: 100%; justify-content: space-between; }
:root .site-footer .footer-cta svg { flex: none; width: 16px; height: 16px; }

/* Группы: на широком экране — колонки (заголовок не нажимается, site-footer.js держит их открытыми). */
:root .site-footer .footer-cols {
  grid-area: cols;
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: 32px 24px;
  margin: 0;
}
:root .site-footer .footer-group {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
}
:root .site-footer .footer-group-summary {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  min-height: 24px;
  margin: 0 0 8px;
  padding: 4px 0;
  color: var(--footer-muted, var(--text-3, var(--color-text-3)));
  font: 500 12px/16px var(--font-text, 'Onest', 'Onest Fallback', system-ui, sans-serif);
  letter-spacing: .06em;
  text-transform: uppercase;
  list-style: none;
  cursor: default;
}
:root .site-footer .footer-group-summary::-webkit-details-marker { display: none; }
:root .site-footer .footer-group-summary::after {
  display: none;
  flex: none;
  width: 8px;
  height: 8px;
  border-right: 1.5px solid currentColor;
  border-bottom: 1.5px solid currentColor;
  content: "";
  transform: rotate(45deg);
  transition: transform 160ms ease-out;
}
:root .site-footer .footer-group-nav { display: block; min-width: 0; margin: 0; padding: 0; }

/* Ссылка: 14/20, цель 44, без подчёркивания до наведения. */
:root .site-footer :is(.footer-group-nav a, .footer-contact) {
  display: flex;
  align-items: center;
  min-height: 44px;
  padding: 0;
  border-radius: 4px;
  color: var(--footer-link, var(--text-2, var(--color-text-2)));
  font-size: 14px;
  line-height: 20px;
  font-weight: 400;
  text-decoration: none;
  text-underline-offset: 4px;
  overflow-wrap: anywhere;
  transition: color 160ms ease-out;
}
/* Текущая страница: цвет текста + черта 2 px акцентом — не только цветом. */
:root .site-footer .footer-group-nav a[aria-current="page"] {
  color: var(--footer-fg, var(--bone, var(--color-text-1)));
  text-decoration-line: underline;
  text-decoration-thickness: 2px;
  text-decoration-color: var(--footer-accent, var(--amber, var(--color-accent)));
  text-underline-offset: 6px;
}
:root .site-footer .footer-contacts {
  display: grid;
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--footer-rule, var(--rule, var(--color-rule)));
}
:root .site-footer .footer-contacts[hidden] { display: none; }

/* Правовая строка: ©, язык, пауза анимации, «Наверх» — 12/16, контролы 44. */
:root .site-footer .footer-legal {
  grid-area: legal;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 24px;
  padding-top: 16px;
  border-top: 1px solid var(--footer-rule, var(--rule, var(--color-rule)));
  color: var(--footer-muted, var(--text-3, var(--color-text-3)));
  font-size: 12px;
  line-height: 16px;
}
:root .site-footer .footer-copy {
  margin: 0;
  margin-inline-end: auto;
  color: inherit;
  font-size: 12px;
  line-height: 16px;
}
/* .footer-language — <label>: правила форм страниц (label { color; font-size } калькулятора) сюда не доходят. */
:root .site-footer :is(.footer-language, .footer-settings) {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  min-height: 44px;
  margin: 0;
  color: var(--footer-muted, var(--text-3, var(--color-text-3)));
  font-size: 12px;
  line-height: 16px;
  font-weight: 400;
}
:root .site-footer .footer-language > span { white-space: nowrap; }
:root .site-footer .footer-settings-label {
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
}
:root .site-footer .footer-language select {
  appearance: none;
  min-width: 0;
  max-width: 100%;
  height: 44px;
  margin: 0;
  padding: 0 32px 0 12px;
  border: 1px solid var(--footer-control-border, var(--rule-strong, var(--color-rule-strong)));
  border-radius: 10px;
  background-color: var(--footer-control-bg, var(--void, var(--color-bg)));
  background-image: linear-gradient(45deg, transparent 50%, var(--footer-muted, var(--text-3, var(--color-text-3))) 50%),
    linear-gradient(135deg, var(--footer-muted, var(--text-3, var(--color-text-3))) 50%, transparent 50%);
  background-position: calc(100% - 19px) 50%, calc(100% - 14px) 50%;
  background-size: 5px 5px, 5px 5px;
  background-repeat: no-repeat;
  color: var(--footer-link, var(--text-2, var(--color-text-2)));
  font-family: inherit;
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  text-overflow: ellipsis;
  cursor: pointer;
  transition: background-color 160ms ease-out;
}
:root .site-footer .footer-motion {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  height: 44px;
  margin: 0;
  padding: 0 12px;
  border: 1px solid var(--footer-control-border, var(--rule-strong, var(--color-rule-strong)));
  border-radius: 10px;
  background-color: var(--footer-control-bg, var(--void, var(--color-bg)));
  color: var(--footer-link, var(--text-2, var(--color-text-2)));
  font-family: inherit;
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
  transition: background-color 160ms ease-out;
}
:root .site-footer .footer-motion svg { flex: none; width: 16px; height: 16px; }
/* Пауза включена — кнопка «нажата»: подмес 12 % цвета текста, как у открытого меню шапки. */
:root .site-footer .footer-motion[aria-pressed="true"] {
  background-color: color-mix(in srgb, var(--footer-control-bg, var(--void, var(--color-bg))), var(--footer-fg, var(--bone, var(--color-text-1))) 12%);
}
:root .site-footer .footer-top {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px; /* короткое «Վերև» / «Up» — цель не уже 44 px (техэтап 2026-10-30) */
  min-height: 44px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 4px;
  background: transparent;
  color: var(--footer-link, var(--text-2, var(--color-text-2)));
  font-family: inherit;
  font-size: 14px;
  line-height: 20px;
  font-weight: 400;
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
  cursor: pointer;
  transition: color 160ms ease-out;
}

/* Наведение — только при настоящем hover: ссылка — цвет текста и черта, контролы — подмес 6 %. */
@media (hover: hover) {
  :root .site-footer :is(.footer-group-nav a, .footer-contact, .footer-top):not([aria-current="page"]):hover {
    color: var(--footer-fg, var(--bone, var(--color-text-1)));
    text-decoration-line: underline;
    text-decoration-thickness: 1px;
  }
  :root .site-footer :is(.footer-motion, .footer-language select):hover {
    background-color: color-mix(in srgb, var(--footer-control-bg, var(--void, var(--color-bg))), var(--footer-fg, var(--bone, var(--color-text-1))) 6%);
  }
}

/* Фокус с клавиатуры — рамка 2 px вне контура у всего, что нажимается. */
:root .site-footer :is(a, button, select, summary):focus-visible {
  outline: 2px solid var(--footer-focus, var(--focus, var(--gold, var(--color-focus))));
  outline-offset: 2px;
}

/* Короткая строка-подвал (счёт — в .wrap, консьерж — прямо в body): линия сверху, 12/16 приглушённым тоном. Ширину, поля
   по краям и отступ снизу (над нижними вкладками кабинета) задаёт страница. */
:root :where(body, body > .wrap) > footer:not(.site-footer) {
  padding-top: 24px;
  border-top: 1px solid var(--footer-rule, var(--rule, var(--color-rule)));
  color: var(--footer-muted, var(--text-3, var(--color-text-3)));
  font-size: 12px;
  line-height: 16px;
}

/* Планшет: блоки друг под другом, группы — в две колонки. */
@media (max-width: 900px) {
  :root .site-footer {
    grid-template-columns: minmax(0, 1fr);
    grid-template-areas: 'brand' 'action' 'cols' 'legal';
    gap: 32px;
  }
  :root .site-footer .footer-action { max-width: none; }
  :root .site-footer .footer-cols { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Телефон: одна колонка, группы — гармошки (site-footer.js открывает «Поддержку»), safe-area снизу. */
@media (max-width: 640px) {
  :root .site-footer {
    gap: 24px;
    padding-block: 32px calc(24px + env(safe-area-inset-bottom, 0px));
  }
  :root .site-footer .footer-tagline { max-width: 40ch; }
  :root .site-footer .footer-cols { grid-template-columns: minmax(0, 1fr); gap: 0; }
  :root .site-footer .footer-group { border-top: 1px solid var(--footer-rule, var(--rule, var(--color-rule))); }
  :root .site-footer .footer-group-summary {
    min-height: 48px;
    margin: 0;
    padding: 0;
    color: var(--footer-fg, var(--bone, var(--color-text-1)));
    font: 500 14px/20px var(--font-text, 'Onest', 'Onest Fallback', system-ui, sans-serif);
    letter-spacing: 0;
    text-transform: none;
    cursor: pointer;
  }
  :root .site-footer .footer-group-summary::after { display: block; margin-inline-end: 4px; }
  :root .site-footer .footer-group[open] > .footer-group-summary::after { transform: rotate(-135deg); }
  :root .site-footer .footer-group-nav { padding-bottom: 8px; }
  :root .site-footer .footer-legal {
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    gap: 8px 12px;
  }
  /* © и «Наверх» — первой строкой, язык и пауза — своими строками. Подпись паузы переносится по словам,
     кнопка — нет; на 320, где подпись не помещается и в одно слово, кнопка уходит строкой ниже. */
  :root .site-footer .footer-copy { grid-row: 1; grid-column: 1; }
  :root .site-footer .footer-top { grid-row: 1; grid-column: 2; justify-self: end; }
  :root .site-footer :is(.footer-language, .footer-settings) { grid-column: 1 / -1; justify-content: space-between; }
  :root .site-footer .footer-settings { flex-wrap: wrap; row-gap: 8px; }
  :root .site-footer .footer-settings-label { flex: 1 1 0; overflow-wrap: normal; }
  :root .site-footer .footer-language select { font-size: 16px; }
}

@media (prefers-reduced-motion: reduce) {
  :root .site-footer :is(a, button, select), :root .site-footer .footer-group-summary::after { transition: none; }
}

@media (forced-colors: active) {
  :root .site-footer :is(.footer-motion, .footer-language select) { border-color: ButtonText; }
  :root .site-footer .footer-group-nav a[aria-current="page"] { text-decoration-color: LinkText; }
}

/* ───────────────────────────── 06 · Модалка ─────────────────────────────
   Спека: docs/design-audit/08_modal.md, docs/parts/DESIGN-QUALITY.md §4, §5, §7, §8.
   Подложка — затемнение 60 % (rgb(6 7 11 / .6)) без размытия; клик по ней закрывает окно, если в окне
   нет несохранённого ввода (скрипты: demo-app.js, console-ops.js, account.html).
   Окно: ширина 520 (широкое — 760 крючком --modal-width: пульт, детали вклада и уведомления счёта),
   поля 24 (телефон 20), радиус 16 — на ступень больше карточки (14), рамка 1 px, без тени;
   высота — не больше видимой области − 48 px (--vvh счёта: клавиатура телефона), длинное содержимое
   прокручивается внутри окна, крестик и строка действий остаются на месте.
   Заголовок 20/28 вес 600, справа 44 px под крестик. Крестик 44×44, радиус 10, 16/16 от правого верхнего угла,
   подпись для чтения с экрана — в разметке (aria-label). Кнопки строки действий — кнопки компонента 01
   (псевдоним `.modal-actions > button`, вторичная — .sec / .quiet); главная одна; строка отделена чертой.
   Телефон ≤ 600 px — нижний лист во всю ширину: кнопки в зоне большого пальца, сверху видна страница
   (тап по ней закрывает окно), радиус 16 только сверху, отступ под домашний индикатор (safe-area).
   Движение: появление 200 мс ease-out — подложка проявляется, окно поднимается на 8 px (лист — на 16 px);
   при prefers-reduced-motion и паузе движения (data-motion-pref="paused") — только проявление.
   Закрытие мгновенное. Прокрутка страницы под окном заблокирована (:has, без скрипта).
   Разметка трёх поколений — псевдонимы, классы и JS не переименовываем:
     окно        dialog.demo-dialog (#modal: лендинг, кабинет — demo-app.js) · dialog#action-dialog (пульт) ·
                 .modal внутри .modal-bg (кабинет счёта: role="dialog" aria-modal="true")
     заголовок   #modal-title · #dialog-title · #plan-dialog-title
     крестик     .dialog-close · #close-dialog · .modal-x
     прокрутка   #modal-body · #dialog-content (у пульта шапка и низ — вне её) · само окно .modal
                 (у счёта крестик и строка действий липкие)
     действия    .dialog-actions · .modal-actions
   Цвета — токены страницы (--surface, --bone, --text-2, --rule, --focus); своя палитра — крючки
   --modal-bg / --modal-fg / --modal-muted / --modal-border / --modal-focus на :root страницы (пульт, счёт).
   Меню 404 (#pg-menu) — вопрос элемента 07: его вид пока задаёт pages.css. */
:root :is(dialog.demo-dialog, dialog:where(#action-dialog), .modal) {
  --modal-pad: 24px;
  box-sizing: border-box;
  width: 100%;
  max-width: min(var(--modal-width, 520px), 100vw - 32px);
  max-height: calc(var(--vvh, 100dvh) - 48px);
  margin: auto;
  padding: 0;
  border: 1px solid var(--modal-border, var(--rule, var(--color-rule)));
  border-radius: 16px;
  background-color: var(--modal-bg, var(--surface, var(--color-surface)));
  background-image: none;
  color: var(--modal-fg, var(--bone, var(--color-text-1)));
  box-shadow: none;
  overflow: hidden;
  overscroll-behavior: contain;
}

/* <dialog>: колонка «крестик + область прокрутки» (лендинг, кабинет) или «форма» (пульт). */
:root :is(dialog.demo-dialog, dialog:where(#action-dialog))[open] {
  display: flex;
  flex-direction: column;
}

/* Подложка. ::backdrop не наследует крючки страницы в старых браузерах — значение по умолчанию в fallback. */
:root :is(dialog.demo-dialog, dialog:where(#action-dialog))::backdrop {
  background-color: var(--modal-scrim, rgb(6 7 11 / .6));
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
/* Подложка счёта — свой слой поверх страницы: выше липкой плашки стартового режима (z 60) и нижних табов,
   иначе плашка закрывает крестик и заголовок окна. Высота — видимая область (клавиатура телефона). */
:root .modal-bg {
  position: fixed;
  inset-inline: 0;
  top: var(--vvt, 0px);
  z-index: 80;
  display: none;
  align-items: center;
  justify-content: center;
  height: var(--vvh, 100dvh);
  padding: 24px 16px;
  overflow: hidden;
  background-color: var(--modal-scrim, rgb(6 7 11 / .6));
  -webkit-backdrop-filter: none;
  backdrop-filter: none;
}
:root .modal-bg.open { display: flex; }

/* Область прокрутки <dialog>: содержимое листается, окно — нет. */
:root :is(#modal-body, #dialog-content) {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  overscroll-behavior: contain;
}
:root #modal-body {
  display: grid;
  align-content: start;
  gap: 16px;
  padding: var(--modal-pad);
}

/* Пульт: форма — колонка «шапка · содержимое · статус · действия»; листается только содержимое. */
:root dialog:where(#action-dialog) > form {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  min-height: 0;
  margin: 0;
}
:root .dialog-heading {
  display: flex;
  align-items: center;
  flex: 0 0 auto;
  padding: var(--modal-pad) var(--modal-pad) 16px;
}
:root #dialog-content {
  display: grid;
  align-content: start;
  gap: 16px;
  padding: 0 var(--modal-pad) 16px;
}
:root #dialog-feedback {
  flex: 0 0 auto;
  margin: 0;
  padding: 0 var(--modal-pad);
}

/* Счёт: листается само окно (содержимое — плоский поток из скрипта); крестик и низ липкие.
   div.modal — та же специфичность, что у базового правила окна (0,2,1), и стоит после него. */
:root div.modal {
  position: relative;
  display: flex;
  flex-direction: column;
  padding: var(--modal-pad) var(--modal-pad) 0;
  overflow: auto;
  scroll-padding-bottom: 96px;
}
/* Окно без строки действий (ошибка, «Закрыть») сохраняет нижнее поле. */
:root .modal > :last-child:not(.modal-actions) { margin-bottom: var(--modal-pad); }

/* Заголовок окна — заголовок блока §3. */
:root :is(#modal-title, #dialog-title, #plan-dialog-title) {
  margin: 0;
  padding-inline-end: 44px;
  font-family: inherit;
  font-size: 20px;
  font-weight: 600;
  line-height: 28px;
  letter-spacing: 0;
  color: var(--modal-fg, var(--bone, var(--color-text-1)));
  overflow-wrap: break-word;
}

/* Счёт: содержимое — плоский поток без сетки; заголовок отделён от него шагом 16, как в #modal-body. */
:root div.modal > #plan-dialog-title { margin-bottom: 16px; }

/* Крестик. Фон — цвет окна: прокрученный текст не просвечивает под ним. */
:root :is(.dialog-close, .modal-x, button:where(#close-dialog)) {
  box-sizing: border-box;
  z-index: 3;
  display: grid;
  place-items: center;
  width: 44px;
  height: 44px;
  min-width: 44px;
  min-height: 44px;
  padding: 0;
  border: 0;
  border-radius: 10px;
  background-color: var(--modal-bg, var(--surface, var(--color-surface)));
  color: var(--modal-muted, var(--text-2, var(--color-text-2)));
  font-family: inherit;
  font-size: 24px;
  font-weight: 400;
  line-height: 1;
  box-shadow: none;
  filter: none;
  transform: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 160ms ease-out, color 160ms ease-out;
}
:root :is(.dialog-close, .modal-x, button:where(#close-dialog)) svg {
  width: 20px;
  height: 20px;
}
:root :is(dialog.demo-dialog, dialog:where(#action-dialog)) :is(.dialog-close, button:where(#close-dialog)) {
  position: absolute;
  top: 16px;
  inset-inline-end: 16px;
}
/* Счёт: окно листается целиком — крестик липнет к верху и не занимает места в потоке. */
:root .modal-x {
  position: sticky;
  top: calc(16px - var(--modal-pad));
  flex: none;
  align-self: flex-end;
  /* верх −8 (16 от края окна), низ −36: заголовок остаётся на поле 24 и по центру с крестиком */
  margin: calc(16px - var(--modal-pad)) calc(16px - var(--modal-pad)) calc(var(--modal-pad) - 60px) 0;
}
@media (hover: hover) {
  :root :is(.dialog-close, .modal-x, button:where(#close-dialog)):hover {
    background-color: color-mix(in srgb, var(--modal-bg, var(--surface, var(--color-surface))), var(--modal-fg, var(--bone, var(--color-text-1))) 6%);
    color: var(--modal-fg, var(--bone, var(--color-text-1)));
    filter: none;
  }
}
:root :is(.dialog-close, .modal-x, button:where(#close-dialog)):active {
  background-color: color-mix(in srgb, var(--modal-bg, var(--surface, var(--color-surface))), var(--modal-fg, var(--bone, var(--color-text-1))) 12%);
  transform: none;
}
:root :is(.dialog-close, .modal-x, button:where(#close-dialog)):focus-visible {
  outline: 2px solid var(--modal-focus, var(--focus, var(--gold, var(--color-focus))));
  outline-offset: 2px;
}

/* Строка действий: кнопки компонента 01 справа, черта сверху; всегда видна над прокруткой. */
:root :is(.modal-actions, .dialog-actions) {
  position: sticky;
  bottom: 0;
  z-index: 2;
  display: flex;
  flex: 0 0 auto;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-end;
  gap: 12px;
  border-top: 1px solid var(--modal-border, var(--rule, var(--color-rule)));
  background-color: var(--modal-bg, var(--surface, var(--color-surface)));
  box-shadow: none;
}
:root .dialog-actions { padding: 16px var(--modal-pad) var(--modal-pad); }
:root .modal-actions {
  margin: 16px calc(var(--modal-pad) * -1) 0;
  padding: 16px var(--modal-pad) var(--modal-pad);
}

/* Блокировка прокрутки страницы под окном; место полосы прокрутки сохраняется — страница не прыгает. */
:root:has(:is(dialog.demo-dialog, dialog#action-dialog):modal, .modal-bg.open) {
  overflow: hidden;
  scrollbar-gutter: stable;
}

/* Телефон: нижний лист во всю ширину. */
@media (max-width: 600px) {
  :root :is(dialog.demo-dialog, dialog:where(#action-dialog), .modal) {
    --modal-pad: 20px;
    max-width: none;
    margin: auto 0 0;
    border-width: 1px 0 0;
    border-radius: 16px 16px 0 0;
  }
  :root .modal-bg {
    align-items: flex-end;
    padding: 0;
  }
  :root #modal-body { padding-bottom: calc(var(--modal-pad) + env(safe-area-inset-bottom)); }
  :root :is(.dialog-actions, .modal-actions) { padding-bottom: calc(var(--modal-pad) + env(safe-area-inset-bottom)); }
  :root .modal > :last-child:not(.modal-actions) { margin-bottom: calc(var(--modal-pad) + env(safe-area-inset-bottom)); }
  :root :is(.modal-actions, .dialog-actions) > * { flex: 1 1 auto; }
}

/* Появление: подложка проявляется, окно поднимается. Закрытие — мгновенно. */
@keyframes modal-enter {
  from { opacity: 0; transform: translateY(8px); }
}
@keyframes modal-sheet-enter {
  from { opacity: 0; transform: translateY(16px); }
}
@keyframes modal-fade-enter {
  from { opacity: 0; }
}
@media (prefers-reduced-motion: no-preference) {
  :root :is(dialog.demo-dialog, dialog:where(#action-dialog))[open], :root .modal-bg.open > .modal { animation: modal-enter 200ms ease-out; }
  :root :is(dialog.demo-dialog, dialog:where(#action-dialog))[open]::backdrop, :root .modal-bg.open { animation: modal-fade-enter 200ms ease-out; }
}
@media (prefers-reduced-motion: no-preference) and (max-width: 600px) {
  :root :is(dialog.demo-dialog, dialog:where(#action-dialog))[open], :root .modal-bg.open > .modal { animation-name: modal-sheet-enter; }
}
/* Без движения: только проявление. */
@media (prefers-reduced-motion: reduce) {
  :root :is(dialog.demo-dialog, dialog:where(#action-dialog))[open], :root .modal-bg.open > .modal { animation: modal-fade-enter 200ms ease-out; }
  :root :is(dialog.demo-dialog, dialog:where(#action-dialog))[open]::backdrop, :root .modal-bg.open { animation: modal-fade-enter 200ms ease-out; }
  :root :is(.dialog-close, .modal-x, button:where(#close-dialog)) { transition: none; }
}
body[data-motion-pref="paused"] :is(dialog.demo-dialog, dialog:where(#action-dialog))[open], body[data-motion-pref="paused"] .modal-bg.open > .modal { animation-name: modal-fade-enter; }

@media (forced-colors: active) {
  :root :is(dialog.demo-dialog, dialog:where(#action-dialog), .modal) { border-color: CanvasText; }
  :root :is(.dialog-close, .modal-x, button:where(#close-dialog)) { border: 1px solid ButtonText; }
}

/* ───────────────────────────── 09 · Первый экран ─────────────────────────────
   Спека: docs/design-audit/11_hero.md, docs/parts/DESIGN-QUALITY.md §1–§4, §7, §10.
   Оболочка первого экрана лендинга (.lab-hero — главная × 14 локалей, hero-a, hero-b):
     секция       на десктопе (> 900 px) сетка = 100svh − шапка 64: экран кончается на сгибе, калькулятор
                  начинается под ним; на телефоне — по содержимому; фон — фон страницы, без ореолов и виньетки
     сетка        две колонки 6/6, промежуток clamp(24, 3vw, 48); поля сверху/снизу clamp(40, 7vh, 88) /
                  clamp(96, 14vh, 140) — текст стоит выше оптического центра; колонка текста ≤ 720;
                  телефон — одна колонка, поля 40 / 24, знак — слой под текстом
     надзаголовок шрифт — элемент 05 (12/16 капс, акцент — только этот, перед h1); черта 18 × 1 перед ним;
                  до прописных h1 — 16 ± 3 px собственного интерлиньяжа заголовка
     h1           один плавный кегль clamp(32px, 13.5cqi, 88px) от ширины колонки (контейнер): 88 на 1440,
                  46 на 390, 38 на 320, в одну колонку (≤ 900) — не больше 64; самое длинное слово
                  14 локалей (5.7 em) занимает ≤ 77 % колонки;
                  межстрочный 1 (грузинский, армянский — 1.12, вес 680); трекинг −1.4 % кириллица,
                  −2.2 % латиница, 0 — ka/hy; без свечения
     подзаголовок 20/28 (телефон ≤ 600 — 16/24, текст §3), вес 400, без трекинга, ≤ 34em (≈ 65 знаков),
                  отступ 32 (телефон 24)
     действия     одна главная кнопка (элемент 01) и текстовая ссылка 16/24 вес 500, цель 44; промежуток
                  12 × 24, отступ 32 (телефон 28, столбиком, кнопка во всю ширину)
     калькулятор  отступ от первого экрана clamp(16, 3vw, 32); снизу до черты следующей секции 80 / 64 / 48
                  (1440 / ≤ 1100 / ≤ 700) — как её верхнее поле; поверхность — элемент 04, содержимое — 11
     движение     вход 200 мс ease-out: строки h1 поднимаются на 0.1em (вторая +40 мс), подзаголовок
                  проявляется (+80 мс), знак печатается сверху вниз; только при prefers-reduced-motion:
                  no-preference и не на паузе (html[data-motion-pref="paused"]); имена кадров lab-* ждёт
                  demo-app.js (снимает .hero-opening по окончании)
   Подложка под текстом (::before колонки) — не декор: держит контраст текста над знаком и дождём цифр.
   Крючки на :root или body: --hero-bg --hero-fg --hero-muted --hero-accent --hero-rule --hero-focus
   --hero-scrim. Знак (--dot --digits --sign-mask --pitch) — токены страницы. */

:root .lab-hero {
  position: relative;
  isolation: isolate;
  display: block;
  box-sizing: border-box;
  min-height: calc(100svh - var(--header-height, 64px));
  padding: 0;
  overflow: clip;
  border-top: 0;
  background: var(--hero-bg, transparent);
}

:root .lab-hero-grid {
  position: relative;
  z-index: 21;
  box-sizing: border-box;
  display: grid;
  grid-template-columns: minmax(0, 6fr) minmax(0, 6fr);
  column-gap: clamp(24px, 3vw, 48px);
  align-items: center;
  width: 100%;
  min-height: calc(100svh - var(--header-height, 64px));
  padding-block: clamp(40px, 7vh, 88px) clamp(96px, 14vh, 140px);
}

:root .lab-hero-copy {
  position: relative;
  z-index: 1;
  max-width: 720px;
  container-type: inline-size;
}
:root .lab-hero-copy::before {
  content: "";
  position: absolute;
  inset: -18% -26% -18% -14%;
  z-index: -1;
  pointer-events: none;
  background: radial-gradient(closest-side, color-mix(in srgb, var(--hero-scrim, var(--color-bg)) 78%, transparent), color-mix(in srgb, var(--hero-scrim, var(--color-bg)) 35%, transparent) 62%, transparent);
}

:root .lab-kicker {
  display: inline-flex;
  align-items: center;
  gap: 8px;
}
:root .lab-kicker::before {
  content: "";
  width: 18px;
  height: 1px;
  background: color-mix(in srgb, var(--hero-accent, var(--amber, var(--color-accent))) 60%, transparent);
}

:root .lab-h1 {
  margin: 0;
  color: var(--hero-fg, var(--bone, var(--color-text-1)));
  /* Волна 3: по одной фразе лозунга в строку во всех 14 языках — главная кнопка в первом экране и на 1366 × 768
     (было 88 px max: 4 строки, кнопка за сгибом у 6 языков; docs/design-audit/screens/w3-home.md, proposal). */
  font-size: clamp(32px, 9.2cqi, 64px);
  line-height: 1;
  font-weight: 540;
  letter-spacing: -.014em;
  text-wrap: balance;
  hyphens: none;
  text-shadow: none;
}
:root:is(:lang(en), :lang(ro), :lang(az), :lang(tk), :lang(uz-Latn)) .lab-h1 { letter-spacing: -.022em; }
:root:is(:lang(ka), :lang(hy)) .lab-h1 { line-height: 1.12; letter-spacing: 0; font-weight: 680; }
/* Строка — маска для подъёма при входе: поля 0.14em не режут выносные элементы. */
:root .lab-line {
  display: block;
  overflow: visible;
  padding-block: .14em;
  margin-block: -.14em;
}
:root .lab-line-text {
  display: inline-block;
  overflow-wrap: normal;
  word-break: normal;
  hyphens: none;
}

:root .hero-description {
  margin: 32px 0 0;
  max-width: 34em;
  color: var(--hero-muted, var(--text-2, var(--color-text-2)));
  font-size: 20px;
  line-height: 28px;
  font-weight: 400;
  letter-spacing: normal;
}

:root .hero-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: flex-start;
  gap: 12px 24px;
  margin-top: 32px;
}
:root .hero-secondary {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  border-radius: 4px;
  color: var(--hero-fg, var(--bone, var(--color-text-1)));
  font-size: 16px;
  line-height: 24px;
  font-weight: 500;
  text-decoration-line: underline;
  text-decoration-thickness: 1px;
  text-decoration-color: var(--hero-rule, var(--rule-strong, var(--color-rule-strong)));
  text-underline-offset: 6px;
  transition: text-decoration-color 160ms ease-out;
}
@media (hover: hover) {
  :root .hero-secondary:hover { text-decoration-color: var(--hero-fg, var(--bone, var(--color-text-1))); }
}
:root .hero-secondary:active { text-decoration-color: var(--hero-fg, var(--bone, var(--color-text-1))); text-decoration-thickness: 2px; }
:root .hero-secondary:focus-visible {
  outline: 2px solid var(--hero-focus, var(--focus, var(--gold, var(--color-focus))));
  outline-offset: 2px;
}

/* Декор: знак ₿ из точек (кадр ноль рассказчика, narrator.js) и дождь цифр — во второй колонке,
   вне потока; не ловит указатель. */
:root .lab-sign-block {
  position: absolute;
  top: auto;
  right: auto;
  z-index: 0;
  display: block;
  grid-column: 2;
  align-self: center;
  width: 100%;
  overflow: hidden;
  transform: none;
  pointer-events: none;
}
:root .lab-sign {
  position: relative;
  width: 100%;
  height: auto;
  max-width: min(84svh, 800px);
  aspect-ratio: 1;
  margin-inline: auto;
}
:root :is(.lab-sign-dots, .lab-sign-graticule) {
  position: absolute;
  display: block;
  background-image: var(--dot);
  background-size: var(--pitch) var(--pitch);
  background-position: 0 0;
}
:root .lab-sign-dots {
  inset: 0;
  background-image: var(--digits);
  background-size: 108px 108px;
  -webkit-mask: var(--sign-mask) center / auto 92% no-repeat;
  mask: var(--sign-mask) center / auto 92% no-repeat;
  transition: opacity 200ms ease-out;
}
:root .lab-sign[data-narrator] .lab-sign-dots { visibility: hidden; }
:root .lab-sign[data-narrator="live"] .lab-sign-dots { visibility: visible; opacity: 0; }
:root .lab-sign-graticule { display: none; }
:root .lab-sign-still {
  position: absolute;
  inset: 0;
  z-index: 1;
  width: 100%;
  height: 100%;
  pointer-events: none;
}
:root .lab-sign-block > #coin-rain {
  position: absolute;
  inset: 0;
  z-index: 2;
  width: 100%;
  height: 100%;
  opacity: .26;
  mix-blend-mode: screen;
  pointer-events: none;
}

/* Вариант A (hero-a, ?v=A): знак слева, текст справа, колонки 1/1 с промежутком 48–80.
   Знак — только в своей колонке (полировка 7.2): у абсолютно позиционированного элемента сетки «auto» конечной
   линии — это край поля контейнера, и grid-column: 1 растягивал блок знака на всю сетку (1392 px на 1440) —
   знак лежал под подзаголовком и кнопкой. Явные линии 1 / 2 и промежуток ≥ 48 держат правый край знака
   не ближе 48 px к колонке текста. Вариант B (знак справа, до края) не меняется. */
:root .lab-hero[data-ab-label="A"] .lab-hero-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); column-gap: clamp(48px, 5vw, 80px); }
:root .lab-hero[data-ab-label="A"] .lab-sign-block { grid-column: 1 / 2; grid-row: 1 / 2; pointer-events: auto; }
:root .lab-hero[data-ab-label="A"] .lab-hero-copy { grid-column: 2; grid-row: 1; }

:root .lab-hero-calc {
  position: relative;
  z-index: 2;
  margin-top: clamp(16px, 3vw, 32px);
  /* Низ карточки не ложится на черту секции «Как это работает» (было 0): поле, а не margin — у .lab-hero
     overflow: clip не создаёт BFC, и margin схлопнулся бы с соседней секцией. */
  padding-bottom: 80px;
}

@media (max-width: 1100px) {
  :root .lab-sign-block { opacity: .9; }
  :root .lab-hero-calc { padding-bottom: 64px; }
}

@media (max-width: 700px) {
  :root .lab-hero-calc { padding-bottom: 48px; }
}

/* Телефон и планшет: одна колонка по содержимому; знак — слоем под текстом, подложка плотнее. */
@media (max-width: 900px) {
  :root .lab-hero { min-height: 0; }
  /* Одна колонка шириной до 720: кегль ограничен 64, иначе на планшете h1 вырос бы до 88. */
  :root .lab-h1 { font-size: clamp(32px, 13.5cqi, 64px); }
  :root .lab-hero-grid {
    display: flex;
    flex-direction: column;
    align-items: stretch;
    min-height: 0;
    padding-block: 40px 24px;
  }
  :root .lab-hero-copy::before {
    background: radial-gradient(closest-side, color-mix(in srgb, var(--hero-scrim, var(--color-bg)) 94%, transparent), color-mix(in srgb, var(--hero-scrim, var(--color-bg)) 72%, transparent) 66%, transparent);
  }
  :root .lab-sign-block {
    grid-column: auto;
    max-width: 460px;
    margin-top: 28px;
    margin-inline: auto;
  }
  :root .lab-sign { width: min(92vw, 460px); }
  :root .lab-hero[data-ab-label="A"] .lab-hero-copy { width: 100%; max-width: none; }
  :root .lab-hero[data-ab-label="A"] .lab-sign-block { max-width: 380px; }
}

@media (max-width: 600px) {
  :root .hero-description { margin-top: 24px; font-size: 16px; line-height: 24px; }
  :root .hero-actions { flex-direction: column; align-items: flex-start; margin-top: 28px; }
  :root .hero-actions .lab-cta { width: 100%; }
  :root .hero-secondary { margin: 0; align-self: flex-start; }
  :root .lab-sign-dots { background-size: 96px 96px; }
}

/* Альбомная ориентация телефона (высота 320–480): первый экран не требует прокрутки сквозь знак. */
@media (orientation: landscape) and (max-height: 480px) {
  :root .lab-hero { min-height: 0; padding-top: 24px; }
  :root .lab-sign { height: min(60vh, 200px); }
}

/* Вход: только при первом показе (.hero-opening до data-hero-ready) и без запроса на покой. */
@media (prefers-reduced-motion: no-preference) {
  :root .hero-opening:not([data-hero-ready]) .lab-line { overflow: hidden; }
  :root .hero-opening:not([data-hero-ready]) .lab-line-text { animation: lab-rise 200ms var(--ease-out, ease-out) both; }
  :root .hero-opening:not([data-hero-ready]) .lab-line + .lab-line .lab-line-text { animation-delay: 40ms; }
  :root .hero-opening:not([data-hero-ready]) .hero-description { animation: lab-settle 200ms var(--ease-out, ease-out) 80ms both; }
  :root .hero-opening:not([data-hero-ready]) .lab-sign-dots { animation: lab-print 200ms ease-out 40ms both; }
}
:root[data-motion-pref="paused"] .hero-opening:not([data-hero-ready]) * { animation: none !important; }
@keyframes lab-rise { from { transform: translateY(.1em); } }
@keyframes lab-settle { from { opacity: .72; transform: translateY(8px); } }
@keyframes lab-print { from { clip-path: inset(100% 0 0 0); } to { clip-path: inset(0 0 0 0); } }

@media (prefers-reduced-motion: reduce) {
  :root :is(.hero-secondary, .lab-sign-dots) { transition: none; }
}

/* Повышенный контраст: подзаголовок — цветом заголовка. */
@media (prefers-contrast: more) {
  :root .hero-description { color: var(--hero-fg, var(--bone, var(--color-text-1))); }
}

@media (forced-colors: active) {
  :root .lab-sign-dots { forced-color-adjust: none; background-color: CanvasText; background-image: none; }
  :root .lab-hero-copy::before { display: none; }
}

/* ───────────────────────────── 10 · График и панель ─────────────────────────────
   Спека: docs/design-audit/12_chart.md, docs/parts/DESIGN-QUALITY.md §3, §4, §6, §7.
   Панель графика — поверхность карточки 04 (r14 · поля 24, телефон 20 · рамка 1 px · фон поверхности) и
   в плоском разделе кабинета (вариант в разделе 04): .chart-panel (доход), .calculator-chart-panel (сценарий).
   Сверху вниз: заголовок и единица · легенда · инспектор точки · холст 240 px с осью справа · даты ·
   ползунок точки · пояснения · таблица значений (компонент 03).
     единица      14/20 --chart-label
     легенда      14/20 --chart-label; образец линии 16 × 2 рамкой (сплошная · штрих · пунктир) —
                  без градиента, виден в forced-colors
     инспектор    компактная плитка 04: подпись 12/16 капсом +.06em, число 20/28 600 табличными; три колонки,
                  телефон (≤ 600) — день во всю строку, суммы в две колонки, число 16/24
     ось и даты   12/16 моноширинным табличными, --chart-label; ось 88 px (телефон 64), зазор 12
     сетка        1 px --chart-grid (≈ 1.5:1 — опора, не данные); тонкие линии всех положений ползунка —
                  --chart-context (≈ 1.3:1), ниже исходной суммы — --chart-context-loss
     данные       ≥ 3:1 к поверхности в обеих темах: база 2 px --chart-base (--bone), стресс 2 px штрих 6 4
                  --chart-stress (--loss), исходная сумма 1 px пунктир 1 4 --chart-principal (--text-3),
                  курсор 1 px штрих 3 3 --chart-cursor; заливка под линией — 6 % без градиента;
                  зона ниже исходной суммы — штриховка --chart-loss-zone цвета --loss
     пояснения    14/20 --chart-label, строка ≤ 72 знака; первое — на 12 px ниже дат или ползунка
   Состояния:
     наведение    мышь ведёт курсор и инспектор (demo-app.js); перекрестие — только (hover: hover) и (pointer: fine)
     клавиатура   ползунок точки input[type=range] — цель 44 px, фокус 2 px --focus вне контура, стрелки двигают точку
     касание      касание холста ставит точку (pointerup, demo-app.js); подсветка касания снята
     ошибка       сумма вне границ — ползунок недоступен: холст пунктирной рамкой с объяснением из data-empty
     данных       (текст ошибки поля), ось и даты скрыты, инспектор «—» приглушён, ползунок .45 not-allowed,
                  пустая таблица значений снята
     загрузка     aria-busy="true" на панели — скелетон холста той же высоты, линий и подписей нет
     движение     переходов нет; reduced-motion глушит всё внутри графика; prefers-contrast — линии 3 px
   Цвета — одно место: крючки --chart-grid · -context · -context-loss · -base · -stress · -principal · -cursor ·
   -label · -loss-zone · -accent поверх семантических токенов страницы (--bone, --loss, --text-3, --rule-strong,
   --focus), поэтому светлая тема кабинета работает без своих правил; страница со своей палитрой задаёт крючки
   на :root. Раскладка: --chart-axis-width (88 / 64). Место панели в сетке (grid-column) — страница. */
:root .chart-unit {
  color: var(--chart-label, var(--text-3, var(--color-text-3)));
  font-size: 14px;
  line-height: 20px;
}

:root :is(.chart-legend, .income-chart-caption) {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 24px;
  margin: 0 0 16px;
  color: var(--chart-label, var(--text-3, var(--color-text-3)));
  font-size: 14px;
  line-height: 20px;
}

:root :is(.chart-legend, .income-chart-caption) > span { display: inline-flex; align-items: center; gap: 8px; }

:root :is(.chart-legend, .income-chart-caption) i {
  display: inline-block;
  flex: none;
  width: 16px;
  height: 0;
  border-top: 2px solid var(--chart-base, var(--bone, var(--color-text-1)));
  background: none;
}

:root .chart-legend > span:nth-child(2) i { border-top-style: dashed; border-top-color: var(--chart-stress, var(--loss, var(--color-danger))); }
:root .chart-legend .legend-principal i { border-top-style: dotted; border-top-color: var(--chart-principal, var(--text-3, var(--color-text-3))); }

/* Инспектор точки — строка компактных плиток: что показывает курсор. */
:root .chart-inspector {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 16px 24px;
  margin: 0 0 16px;
}

/* Подпись сверху, число снизу: подпись в две строки (телефон) не сдвигает числа соседей. */
:root .chart-inspector > div { display: flex; flex-direction: column; justify-content: space-between; gap: 4px; min-width: 0; }

:root .chart-inspector span {
  display: block;
  color: var(--chart-label, var(--text-3, var(--color-text-3)));
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
}

:root .chart-inspector strong {
  display: block;
  color: var(--chart-value, var(--bone, var(--color-text-1)));
  font-size: 20px;
  line-height: 28px;
  font-weight: 600;
  font-variant-numeric: tabular-nums lining-nums;
  white-space: nowrap;
}

/* Холст и ось. */
:root .chart-frame {
  display: grid;
  grid-template-columns: minmax(0, 1fr) var(--chart-axis-width, 88px);
  gap: 12px;
  align-items: stretch;
}

:root .chart-canvas {
  position: relative;
  min-width: 0;
  height: 240px;
  color: var(--chart-base, var(--bone, var(--color-text-1)));
  -webkit-tap-highlight-color: transparent;
}

:root .chart-canvas svg { display: block; width: 100%; height: 100%; overflow: visible; }

@media (hover: hover) and (pointer: fine) {
  :root .chart-canvas[data-chart-pointer] { cursor: crosshair; }
}

:root .chart-grid path {
  fill: none;
  stroke: var(--chart-grid, color-mix(in srgb, var(--rule-strong, var(--color-rule-strong)) 40%, transparent));
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

:root :is(.chart-line, .scenario-chart .scenario-base) {
  fill: none;
  stroke: var(--chart-base, var(--bone, var(--color-text-1)));
  stroke-width: 2;
  vector-effect: non-scaling-stroke;
}

:root .scenario-chart .scenario-stress {
  fill: none;
  stroke: var(--chart-stress, var(--loss, var(--color-danger)));
  stroke-width: 2;
  stroke-dasharray: 6 4;
  vector-effect: non-scaling-stroke;
}

:root .scenario-chart .scenario-principal {
  fill: none;
  stroke: var(--chart-principal, var(--text-3, var(--color-text-3)));
  stroke-width: 1;
  stroke-dasharray: 1 4;
  vector-effect: non-scaling-stroke;
}

:root .scenario-chart .scenario-harp {
  fill: none;
  stroke: var(--chart-context, color-mix(in srgb, var(--rule-strong, var(--color-rule-strong)) 30%, transparent));
  stroke-width: 1;
  vector-effect: non-scaling-stroke;
}

:root .scenario-chart .scenario-harp-loss { stroke: var(--chart-context-loss, color-mix(in srgb, var(--loss, var(--color-danger)) 30%, transparent)); }

:root .chart-crosshair {
  fill: none;
  stroke: var(--chart-cursor, var(--text-3, var(--color-text-3)));
  stroke-width: 1;
  stroke-dasharray: 3 3;
  vector-effect: non-scaling-stroke;
}

:root :is(.chart-area, .scenario-chart #scenario-area) { fill: var(--chart-base, var(--bone, var(--color-text-1))); stroke: none; opacity: .06; }

:root .scenario-loss-zone {
  position: absolute;
  inset: auto 0 0;
  pointer-events: none;
  background: var(--chart-loss-zone, repeating-linear-gradient(135deg, color-mix(in srgb, var(--loss, var(--color-danger)) 14%, transparent) 0 1px, transparent 1px 6px));
}

:root .chart-axis { position: relative; min-width: 0; }
:root .chart-axis > div { position: relative; height: 100%; }

:root .chart-axis span {
  position: absolute;
  right: 0;
  transform: translateY(-50%);
  color: var(--chart-label, var(--text-3, var(--color-text-3)));
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 12px;
  line-height: 16px;
  font-weight: 400;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

:root .chart-xlabels {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  margin: 8px calc(var(--chart-axis-width, 88px) + 12px) 0 0;
  color: var(--chart-label, var(--text-3, var(--color-text-3)));
  font-family: var(--font-mono, ui-monospace, monospace);
  font-size: 12px;
  line-height: 16px;
  font-variant-numeric: tabular-nums;
}

/* Ползунок точки — клавиатура и касание. */
:root .chart-probe {
  display: grid;
  gap: 4px;
  margin: 16px 0 0;
  color: var(--chart-label, var(--text-3, var(--color-text-3)));
  font-size: 14px;
  line-height: 20px;
}

:root .chart-probe input[type="range"] {
  display: block;
  width: 100%;
  min-height: 44px;
  margin: 0;
  accent-color: var(--chart-accent, var(--bone, var(--color-text-1)));
  cursor: pointer;
}

:root .chart-probe input[type="range"]:focus-visible {
  outline: 2px solid var(--focus, var(--gold, var(--color-focus)));
  outline-offset: 2px;
}

:root .chart-probe input[type="range"]:disabled { opacity: .45; cursor: not-allowed; }

:root .chart-method {
  max-width: 72ch;
  color: var(--chart-label, var(--text-3, var(--color-text-3)));
  font-size: 14px;
  line-height: 20px;
}

/* Первое пояснение отходит от дат или ползунка на 12 px — не прилипает к подписям. */
:root :is(.chart-xlabels, .chart-probe) + .chart-method { margin-top: 12px; }

:root .chart-values { margin: 16px 0 0; }

/* Ошибка данных: сумма вне границ — линий нет, холст объясняет, что исправить (текст ошибки поля). */
:root .calculator-chart-panel:has(.chart-probe input:disabled) .chart-canvas {
  border: 1px dashed var(--chart-empty-border, var(--rule-strong, var(--color-rule-strong)));
  border-radius: 10px;
}

:root .calculator-chart-panel:has(.chart-probe input:disabled) .chart-canvas::after {
  content: attr(data-empty);
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  padding: 0 24px;
  color: var(--chart-empty-fg, var(--text-2, var(--color-text-2)));
  font-size: 14px;
  line-height: 20px;
  text-align: center;
}

:root .calculator-chart-panel:has(.chart-probe input:disabled) :is(.chart-axis, .chart-xlabels) { visibility: hidden; }
:root .calculator-chart-panel:has(.chart-probe input:disabled) .chart-values { display: none; }
:root .calculator-chart-panel:has(.chart-probe input:disabled) .chart-inspector strong { color: var(--chart-label, var(--text-3, var(--color-text-3))); }

/* Загрузка: скелетон холста той же геометрии; подписи плиток гасит компонент 04 (aria-busy). */
:root :is(.chart-panel, .calculator-chart-panel)[aria-busy="true"] .chart-canvas {
  border-radius: 10px;
  background-color: color-mix(in srgb, transparent, var(--card-fg, var(--bone, var(--color-text-1))) 8%);
}

:root :is(.chart-panel, .calculator-chart-panel)[aria-busy="true"] :is(.chart-canvas svg, .scenario-loss-zone, .chart-axis span, .chart-xlabels) { visibility: hidden; }

@media (max-width: 600px) {
  :root .chart-frame { grid-template-columns: minmax(0, 1fr) var(--chart-axis-width-phone, 64px); }
  :root .chart-xlabels { margin-right: calc(var(--chart-axis-width-phone, 64px) + 12px); }
  :root .chart-inspector { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 16px; }
  :root .chart-inspector > div:first-child { grid-column: 1 / -1; }
  :root .chart-inspector strong { font-size: 16px; line-height: 24px; }
}

@media (prefers-contrast: more) {
  :root :is(.chart-line, .scenario-chart .scenario-base, .scenario-chart .scenario-stress) { stroke-width: 3; }
}

@media (prefers-reduced-motion: reduce) {
  :root :is(.chart-frame, .chart-inspector, .chart-probe) * { transition: none; animation: none; }
}

/* Происхождение рыночных свечей: «Binance · свечи 1 ч · обновлено 14:05» / «… · последние известные» /
   «Свечи: модель платформы». Подпись графика (14/20 --chart-label), устаревшее и модель — тем же цветом
   с отметкой слева, а не красным: это не ошибка, а честное «откуда число». Стакан и лента подписаны
   так же. Лупа знака первого экрана: строки подсказки — блоки (время и источник · O/H/L/C · объём). */
:root :is(.market-candles-source, .market-model-note) {
  margin: 0;
  color: var(--chart-label, var(--text-3, var(--color-text-3)));
  font: 400 14px/20px var(--font-ui, inherit);
}
:root :is(.market-candles-source[data-state="stale"], .market-candles-source[data-state="model"], .market-model-note) {
  padding-left: 8px;
  border-left: 2px solid var(--chart-context, var(--rule-strong, var(--palette-grey-634)));
}
:root .lab-loupe { max-width: calc(100vw - 16px); }
:root .lab-loupe > span { display: block; white-space: normal; }
:root .lab-loupe > span + span { color: var(--chart-label, var(--text-3, var(--color-text-3))); }

@media (forced-colors: active) {
  :root :is(.chart-line, .scenario-chart .scenario-base) { stroke: CanvasText; }
  :root .scenario-chart .scenario-stress { stroke: Highlight; }
  :root :is(.chart-grid path, .chart-crosshair, .scenario-chart .scenario-principal, .scenario-chart .scenario-harp) { stroke: GrayText; }
  :root :is(.chart-legend, .income-chart-caption) i { border-top-color: CanvasText; }
  :root .chart-legend > span:nth-child(2) i { border-top-color: Highlight; }
  :root .chart-legend .legend-principal i { border-top-color: GrayText; }
  :root .scenario-loss-zone { background: none; }
  :root .chart-probe input[type="range"]:focus-visible { outline-color: Highlight; }
}

/* ───────────────────────────── 11 · Калькулятор ─────────────────────────────
   Спека: docs/design-audit/14_calculator.md, docs/parts/DESIGN-QUALITY.md §3, §5, §6.
   Три живых калькулятора, один вид. Поверхность — карточка 04, поле — 02, кнопка — 01, текст ошибки — 05,
   таблица плана — 03 (плотная), ползунок — как ползунок точки графика (10).
     лендинг       карточка .v24-calc-card в первом экране (раскладку блока задаёт страница и раздел 09)
     calculator    форма [data-seo-calc] страницы calculator.html: поля, плитки .result, оговорка #calc-note
     кабинет       #calculator-form (поверхность и в плоском разделе кабинета — вариант в разделе 04) и
                   .calculator-result (карточка 04) рядом, график сценария (10) — под ними
   Форма:
     подпись        12/16 капсом +.06em 500 --text-3 (шапка карточки); подписи полей — 14/20 500 --text-2
     сегменты       срок и план (.v24-term): 44 px, r10, 14/20 500, рамка 1 px --rule-strong, без заливки, между ними 8;
                    наведение (hover: hover) — рамка --text-3, фон +4 %; выбранный (aria-pressed / .is-active) —
                    рамка --amber, фон --amber 8 %, текст 600 (одно выделение; главное действие — кнопка 01);
                    фокус 2 px --focus вне контура; недоступный .45 not-allowed
     ступень        бейдж 12/16 600 табличными, рамка 1 px --rule-strong, --text-2 — без акцентного цвета
     ползунки       срок и сценарий цены — 44 px, accent-color --bone, фокус 2 px; значение в подписи 600 табличными
   Результат — одна главная цифра:
     главная        итог (лендинг «Итог на конец срока», calculator «За срок», кабинет «При изменении цены»):
                    подпись 12/16 капсом --text-3, число 40/48 600 табличными (телефон 32/40); в карточке лендинга
                    32/40 (телефон 28/36) — карточка 520 px
     строки         остальное — строки 14/20: подпись --text-3, значение --bone 600 табличными, без акцентного цвета;
                    вторичная сумма кабинета («Без изменения цены») — компактная плитка 20/28 под чертой
     плитки v36     .result > div — компактная плитка: поля 12 16, r10, рамка --card-border, подпись 12/16 капсом,
                    число 20/28, три колонки (телефон — ступень во всю строку, ставка и начисление в две); итог —
                    во всю строку, поля 16
     пояснение      14/20 --text-3 («Забрать завтра…», «Расчёт по модели…», #calc-note)
     оговорка       «модель, а не обещание» — 12/16 --text-3 в карточке лендинга, 14/20 в кабинете; контраст ≥ 4.5:1
   Состояния:
     пусто / вне    поле — ошибка 02 (рамка --loss), текст — 05 под полем; результат прежнего расчёта
     границ         приглушён (.45) — устарел; кабинет и calculator — «—»; calculator — подпись ступени
                    («Ниже минимума T1») цветом ошибки
     пересчёт       синхронный: цифры табличные — ширина строк не пляшет, переходов нет
     результат      как выше
     движение       reduced-motion — без переходов у сегментов; forced-colors — выбранный сегмент Highlight
   Цвета — семантические токены страницы (--rule-strong, --text-2, --text-3, --bone, --amber, --focus, --loss);
   своя палитра — крючки --calc-* (--calc-segment-border, --calc-accent, --calc-label, --calc-value). */
:root .v24-calc-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin: 0 0 12px;
}

:root .v24-calc-label {
  color: var(--calc-label, var(--text-3, var(--color-text-3)));
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
}

:root .v24-calc-tier {
  padding: 2px 8px;
  border: 1px solid var(--calc-segment-border, var(--rule-strong, var(--color-rule-strong)));
  border-radius: 999px;
  background: none;
  color: var(--text-2, var(--color-text-2));
  font-family: inherit;
  font-size: 12px;
  line-height: 16px;
  font-weight: 600;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
}

/* Сегменты срока и плана. */
:root .v24-term-row { display: flex; align-items: center; gap: 8px; margin: 12px 0 0; }

:root :is(.v24-term-label, .v24-plan-bar-label) {
  margin: 0 4px 0 0;
  color: var(--text-2, var(--color-text-2));
  font-size: 14px;
  line-height: 20px;
  white-space: nowrap;
}

:root .v24-term {
  flex: 1;
  box-sizing: border-box;
  min-width: 0;
  min-height: 44px;
  padding: 0 8px;
  border: 1px solid var(--calc-segment-border, var(--rule-strong, var(--color-rule-strong)));
  border-radius: 10px;
  background: transparent;
  color: var(--text-2, var(--color-text-2));
  font-family: inherit;
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 160ms ease-out, border-color 160ms ease-out, color 160ms ease-out;
}

@media (hover: hover) {
  :root .v24-term:not(:disabled, .is-active, [aria-pressed="true"]):hover {
    border-color: var(--text-3, var(--color-text-3));
    background-color: color-mix(in srgb, transparent, var(--bone, var(--color-text-1)) 4%);
    color: var(--bone, var(--color-text-1));
  }
}

:root .v24-term:is(.is-active, [aria-pressed="true"]) {
  border-color: var(--calc-accent, var(--amber, var(--color-accent)));
  background-color: color-mix(in srgb, transparent, var(--calc-accent, var(--amber, var(--color-accent))) 8%);
  color: var(--bone, var(--color-text-1));
  font-weight: 600;
}

:root .v24-term:focus-visible {
  outline: 2px solid var(--focus, var(--gold, var(--color-focus)));
  outline-offset: 2px;
}

:root .v24-term:disabled { opacity: .45; cursor: not-allowed; }

/* Результат карточки лендинга: строки и одна главная цифра. */
:root .v24-out {
  display: grid;
  gap: 8px;
  margin: 16px 0 0;
  padding: 12px 0 0;
  border-top: 1px solid var(--card-rule, var(--rule, var(--color-rule)));
}

:root .v24-out > div { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; padding: 0; }

:root .v24-out dt {
  margin: 0;
  color: var(--calc-label, var(--text-3, var(--color-text-3)));
  font-size: 14px;
  line-height: 20px;
  font-weight: 400;
}

:root .v24-out dd {
  margin: 0;
  color: var(--calc-value, var(--bone, var(--color-text-1)));
  font-size: 14px;
  line-height: 20px;
  font-variant-numeric: tabular-nums lining-nums;
  white-space: nowrap;
}

:root .v24-out dd b {
  color: inherit;
  font-family: inherit;
  font-size: inherit;
  line-height: inherit;
  font-weight: 600;
  letter-spacing: 0;
}

:root .v24-out .v24-out-total {
  display: grid;
  gap: 4px;
  margin: 4px 0 0;
  padding: 12px 0 0;
  border-top: 1px solid var(--card-rule, var(--rule, var(--color-rule)));
}

:root .v24-out-total dt {
  color: var(--calc-label, var(--text-3, var(--color-text-3)));
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
}

:root .v24-out-total dd b { font-size: 32px; line-height: 40px; }

:root .v24-early {
  margin: 8px 0 0;
  color: var(--calc-label, var(--text-3, var(--color-text-3)));
  font-size: 14px;
  line-height: 20px;
  font-variant-numeric: tabular-nums;
}

:root .v24-cta { margin-top: 16px; }
:root .v24-error { margin: 8px 0 0; }

:root .v24-demo {
  max-width: 60ch;
  margin: 12px 0 0;
  color: var(--calc-label, var(--text-3, var(--color-text-3)));
  font-size: 12px;
  line-height: 16px;
}

/* Таблица плана на лендинге — компонент 03 (плотная); подпись ступени под названием не мельче 12 px. */
:root .v24-plan-bar { display: flex; align-items: center; gap: 8px; }
:root .v24-plan-name { font-size: 14px; line-height: 20px; }
:root .v24-plan-code { color: var(--text-3, var(--color-text-3)); font-size: 12px; line-height: 16px; letter-spacing: .06em; }

/* Ввод вне границ: прежний результат устарел — приглушён, пока сумма не исправлена (текст — под полем). */
:root .v24-calc-card:has([aria-invalid="true"]) :is(.v24-out, .v24-early) { opacity: .45; }

/* Кабинет: форма и результат. Поверхность формы — раздел 04 (не плоская), результата — карточка 04. */
:root #calculator-form { display: grid; align-content: start; gap: 8px; }
:root #calculator-form label { color: var(--text-2, var(--color-text-2)); font-size: 14px; line-height: 20px; font-weight: 500; }
:root #calculator-form label:not(:first-child) { margin-top: 12px; }
:root #calculator-form label output { color: var(--bone, var(--color-text-1)); font-weight: 600; font-variant-numeric: tabular-nums; }

:root :is(#calculator-form, .lab-form) input[type="range"] {
  display: block;
  width: 100%;
  min-height: 44px;
  margin: 0;
  accent-color: var(--calc-accent-range, var(--bone, var(--color-text-1)));
  cursor: pointer;
}

:root :is(#calculator-form, .lab-form) input[type="range"]:focus-visible {
  outline: 2px solid var(--focus, var(--gold, var(--color-focus)));
  outline-offset: 2px;
}

:root :is(#calculator-form, .lab-form) input[type="range"]:disabled { opacity: .45; cursor: not-allowed; }

:root .calculator-result { display: grid; align-content: start; gap: 16px; }
:root .calculator-result .scenario-comparison { display: grid; gap: 4px; }

:root .calculator-result .scenario-comparison h2 {
  margin: 0;
  color: var(--calc-label, var(--text-3, var(--color-text-3)));
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
}

:root .calculator-result #calc-risk {
  display: block;
  color: var(--calc-value, var(--bone, var(--color-text-1)));
  font-family: inherit;
  font-size: 40px;
  line-height: 48px;
  font-weight: 600;
  letter-spacing: 0;
  font-variant-numeric: tabular-nums lining-nums;
}

:root .calculator-result .result-baseline {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 8px;
  padding: 16px 0 0;
  border-top: 1px solid var(--card-rule, var(--rule, var(--color-rule)));
}

:root .calculator-result .result-baseline > span:first-child {
  flex-basis: 100%;
  color: var(--calc-label, var(--text-3, var(--color-text-3)));
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
}

:root .calculator-result #calc-total {
  color: var(--calc-value, var(--bone, var(--color-text-1)));
  font-family: inherit;
  font-size: 20px;
  line-height: 28px;
  font-weight: 600;
  font-variant-numeric: tabular-nums lining-nums;
}

:root .calculator-result :is(.result-unit, .result-baseline > span:last-child, .calc-net-line, .calc-guarantee, .result-line), :root .calculator-result > p {
  margin: 0;
  color: var(--calc-label, var(--text-3, var(--color-text-3)));
  font-size: 14px;
  line-height: 20px;
}

:root .calculator-result .result-line { display: flex; flex-wrap: wrap; gap: 4px 8px; }

:root .calculator-result :is(.calc-net-line b, .result-line strong) {
  color: var(--calc-value, var(--bone, var(--color-text-1)));
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

:root .calculator-result .calc-net-line b.is-negative { color: var(--loss, var(--color-danger)); }
:root .calculator-result .button { justify-self: start; }

/* calculator.html: плитки результата и оговорка. */
:root [data-seo-calc] .result {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 12px;
  margin: 16px 0 0;
}

:root [data-seo-calc] .result > div {
  box-sizing: border-box;
  padding: 12px 16px;
  border: 1px solid var(--card-border, var(--rule, var(--color-rule)));
  border-radius: 10px;
  background-color: var(--panel-2, color-mix(in srgb, transparent, var(--bone, var(--color-text-1)) 3%));
}

:root [data-seo-calc] .result span {
  display: block;
  margin: 0 0 4px;
  color: var(--calc-label, var(--text-3, var(--color-text-3)));
  font-size: 12px;
  line-height: 16px;
  font-weight: 500;
  letter-spacing: .06em;
  text-transform: uppercase;
}

:root [data-seo-calc] .result strong {
  display: block;
  color: var(--calc-value, var(--bone, var(--color-text-1)));
  font-size: 20px;
  line-height: 28px;
  font-weight: 600;
  font-variant-numeric: tabular-nums lining-nums;
}

:root [data-seo-calc] .result > div:has([data-calc="total"]) { grid-column: 1 / -1; padding: 16px; }
:root [data-seo-calc] .result [data-calc="total"] { font-size: 40px; line-height: 48px; }

:root [data-seo-calc] #calc-note {
  margin: 16px 0 0;
  color: var(--calc-label, var(--text-3, var(--color-text-3)));
  font-size: 14px;
  line-height: 20px;
}

:root [data-seo-calc]:has(#calc-amount:user-invalid) [data-calc="tier"] { color: var(--loss, var(--color-danger)); }

@media (max-width: 600px) {
  :root :is(.calculator-result #calc-risk, [data-seo-calc] .result [data-calc="total"]) { font-size: 32px; line-height: 40px; }
  :root .v24-out-total dd b { font-size: 28px; line-height: 36px; }
  :root [data-seo-calc] .result { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  :root [data-seo-calc] .result > div:first-child { grid-column: 1 / -1; }
  :root .v24-term { padding: 0 4px; }
}

@media (prefers-reduced-motion: reduce) {
  :root .v24-term { transition: none; }
}

@media (forced-colors: active) {
  :root .v24-term:is(.is-active, [aria-pressed="true"]) { border-color: Highlight; background-color: Highlight; color: HighlightText; }
  :root .v24-term:focus-visible, :root :is(#calculator-form, .lab-form) input[type="range"]:focus-visible { outline-color: Highlight; }
}

/* ───────────────────────────── Движение · появление блоков ─────────────────────────────
   Спека: docs/parts/DESIGN-QUALITY.md §7. Блок с data-reveal проявляется при прокрутке: opacity 0 → 1 и подъём
   на 12 px, 200 мс ease-out, один раз; соседи в data-reveal-group — со ступенью 40 мс (--reveal-i из reveal.js,
   не больше 6 ступеней). Скрытие действует только под :root.js-reveal — класс ставит reveal.js; без JS,
   без IntersectionObserver, при prefers-reduced-motion и на паузе движения всё видно сразу. Анимируются
   только opacity и transform — вёрстка не сдвигается. */
:root.js-reveal [data-reveal] {
  transition: opacity 200ms ease-out, transform 200ms ease-out;
  transition-delay: calc(var(--reveal-i, 0) * 40ms);
}
:root.js-reveal [data-reveal]:not(.is-revealed) {
  opacity: 0;
  transform: translateY(12px);
}
@media (prefers-reduced-motion: reduce) {
  :root.js-reveal [data-reveal] { opacity: 1; transform: none; transition: none; }
}
@media print {
  :root.js-reveal [data-reveal] { opacity: 1; transform: none; }
}

/* ───────────────────────────── Ясность · строка «зачем» и подсказка «?» ─────────────────────────────
   Спека: docs/design-audit/screens/clarity.md (вход и кабинет, 2026-10-29), DESIGN-QUALITY §1, §5, §7.
   Строка «зачем» (.section-why) — одна строка под заголовком раздела или блока: заголовок → зачем → содержимое,
   14/20, приглушённый цвет, без капса (заголовки карточек кабинета набраны капсом — строка под ними нет).
   Подсказка «?» — короткое пояснение термина рядом с подписью: <span class="hint"><button class="hint-q"
   aria-describedby="…" aria-label="Что это значит?"> + SVG-иконка 16 </button><span class="hint-tip" role="tooltip"
   id="…">текст</span></span>. Текст читается по aria-describedby (не title); виден по наведению, фокусу с
   клавиатуры и нажатию (dist/hint-tip.js ставит aria-expanded и держит пузырь в окне), Escape закрывает.
   Без JS — по наведению и фокусу. Цель касания на грубом указателе — 44 px за счёт ::after, вёрстка не сдвигается.
   Цвета — крючки --hint-* поверх токенов страницы (счёт: --card-muted / --modal-*; кабинет v21: --text-3 / --surface). */
:root .section-why {
  margin: 4px 0 16px;
  max-width: 72ch;
  font-size: 14px;
  line-height: 20px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  color: var(--hint-muted, var(--card-muted, var(--text-3, var(--palette-grey-296))));
}
:root .hint {
  position: relative;
  display: inline-flex;
  align-items: center;
  vertical-align: middle;
  margin-inline-start: 4px;
  text-transform: none;
  letter-spacing: 0;
}
:root .hint-q {
  position: relative;
  display: inline-grid;
  place-items: center;
  width: 24px;
  height: 24px;
  min-width: 24px;
  min-height: 24px;
  margin: -4px 0;
  padding: 0;
  border: 0;
  border-radius: 999px;
  background: transparent;
  box-shadow: none;
  color: var(--hint-muted, var(--card-muted, var(--text-3, var(--palette-grey-296))));
  cursor: help;
  transition: color 150ms ease-out, background-color 150ms ease-out;
}
:root .hint-q svg { width: 16px; height: 16px; }
:root .hint-q:hover,
:root .hint-q[aria-expanded="true"] {
  color: var(--hint-fg, var(--modal-fg, var(--bone, var(--color-text-1))));
  background: color-mix(in srgb, currentColor 6%, transparent);
}
:root .hint-q:focus-visible { outline: 2px solid var(--focus, var(--color-focus)); outline-offset: 2px; }
/* Зона касания 44 × 44 у любого указателя (техэтап: и мышь при масштабе 200 %, и палец): вид значка — 24 px. */
:root .hint-q::after { content: ''; position: absolute; inset: -10px; }
:root .hint-tip {
  position: absolute;
  z-index: 40;
  inset-block-start: calc(100% + 8px);
  inset-inline-start: -8px;
  display: none;
  box-sizing: border-box;
  width: max-content;
  max-width: min(280px, calc(100vw - 32px));
  padding: 8px 12px;
  border: 1px solid var(--hint-border, var(--modal-border, var(--rule-strong, var(--color-rule-strong))));
  border-radius: 8px;
  background: var(--hint-bg, var(--modal-bg, var(--surface, var(--color-surface))));
  color: var(--hint-fg, var(--modal-fg, var(--bone, var(--color-text-1))));
  font-size: 14px;
  line-height: 20px;
  font-weight: 400;
  letter-spacing: 0;
  text-transform: none;
  text-align: start;
  white-space: normal;
  overflow-wrap: anywhere;
}
:root .hint-q[aria-expanded="true"] + .hint-tip { display: block; animation: hint-in 150ms ease-out; }
:root:not(.js-hint) .hint-q:hover + .hint-tip,
:root:not(.js-hint) .hint-q:focus-visible + .hint-tip { display: block; }
@keyframes hint-in { from { opacity: 0; transform: translateY(4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  :root .hint-q[aria-expanded="true"] + .hint-tip { animation: none; }
  :root .hint-q { transition: none; }
}

/* ───────────────────────────── 13 · Документ · контентные страницы ─────────────────────────────
   Спека: docs/design-audit/screens/content.md (2026-10-29), DESIGN-QUALITY §1–§3, §5–§8.
   Страница-документ — article.trust-page (правовые документы, FAQ, глоссарий, калькулятор, ступени, рынок, поддержка…):
     колонка    1120 с полями 20 (≤ 600 px — 16) — общая у шапки (.wrap с .topbar) и статьи: один левый край;
                текст (абзацы, списки, лид, заголовки) — мера --doc-measure 54ch ≈ 60–75 знаков в строке (Onest, кириллица);
                блоки (таблицы, карточки, заметки, раскрытия, оглавление, формы) — до --doc-block 880
     шкала      h1 40/48 (≤ 600 — 28/36) · h2 24/32 (20/28), сверху 48 (40), снизу 16 · h3 18/28 600 ·
                лид 18/28 · текст 16/24 · заметка 14/20; заголовки переносятся по слогам, длинное слово
                (ka, hy, «конфиденциальности» на 320) и код не раздвигают страницу
     ритм       абзац 16 · пункт списка 8 · блок 24 сверху и снизу · страница 48 сверху, 80 снизу (32 / 64)
     заметка    .note — карточка 04 тона «заметка»: без янтарной полосы — акцент один на экран (§4)
     оглавление nav.doc-toc перед первым h2 длинного документа — карточка 04, подпись 12/16 капсом,
                ссылки 14/20 вес 500, цель 44, две колонки от 2 × 280
     раскрытие  details вопроса (.trust-page, .v36-faq; гармошка подвала — раздел 08) — карточка 04 с полями 0 24,
                между пунктами 8; заголовок 56, 16/24 вес 500; знак .doc-faq-icon — SVG «+» 20 одной системы
                (у открытого «−»); наведение — рамка и знак светлее 150 мс; фокус 2 px; ответ — мера строки;
                открытие — проявление 200 мс ease-out (reduced-motion — без движения)
     таблица    вид — 03; на телефоне (≤ 700) таблица с td[data-label] — карточки 03, обёртка без рамки и прокрутки
     действия   .v36-cta / .cta-row — строка кнопок 01, промежуток 12
     модель     .model-mark — бейдж 05 «модель» первой строкой абзаца с цифрами будущего дохода */
:root body:has(.trust-page) {
  --doc-max: 1120px;
  --doc-gutter: 20px;
  --doc-measure: 54ch;
  --doc-block: 880px;
}
@media (max-width: 600px) { :root body:has(.trust-page) { --doc-gutter: 16px; } }
:root body:has(.trust-page) > .wrap:has(> .topbar) {
  box-sizing: border-box;
  max-width: var(--doc-max);
  margin-inline: auto;
  padding-inline: var(--doc-gutter);
}
:root .trust-page {
  box-sizing: border-box;
  max-width: var(--doc-max);
  margin-inline: auto;
  padding: 48px var(--doc-gutter) 80px;
  font-size: 16px;
  line-height: 24px;
}
/* Документы и faq кладут статью внутрь .wrap шапки — поля уже есть. */
:root .wrap .trust-page { padding-inline: 0; }
@media (max-width: 600px) { :root .trust-page { padding-top: 32px; padding-bottom: 64px; } }

/* Мера строки — у текста; блоки шире текста, но не шире 880. */
:root .trust-page :is(p, ul, ol, blockquote, h1, h2, h3, h4) { max-width: var(--doc-measure); }
:root .trust-page :is(.table-wrap, .tscroll, .card, .note, .status-note, .operator-pending, .doc-toc, .v36-faq, .market-stats, .doc-nav) { box-sizing: border-box; max-width: var(--doc-block); }

:root .trust-page :is(h1, h2, h3) { overflow-wrap: break-word; }
/* h1–h2 — без автопереноса по слогам (полировка 7.3): «про-центы», «вопро-сы» в крупном заголовке на 390 читались
   хуже, чем слово целиком на новой строке. Перенос — только там, где в тексте стоит мягкий перенос (&shy;);
   слово длиннее строки (hy на 320) рвёт overflow-wrap выше — страница вбок не едет. h3 переносится по слогам. */
:root :is(.trust-page, [data-epochs-page], body.crypto-body) :is(h1, h2) { -webkit-hyphens: manual; hyphens: manual; }
:root :is(.trust-page, [data-epochs-page], body.crypto-body) h3 { -webkit-hyphens: auto; hyphens: auto; }
:root .trust-page h1 { margin: 8px 0 16px; font-size: 40px; line-height: 48px; }
:root .trust-page h2 { margin: 48px 0 16px; font-size: 24px; line-height: 32px; }
:root .trust-page h3 { margin: 32px 0 8px; font-family: inherit; font-size: 18px; line-height: 28px; font-weight: 600; }
@media (max-width: 600px) {
  :root .trust-page h1 { font-size: 28px; line-height: 36px; }
  :root .trust-page h2 { margin-top: 40px; font-size: 20px; line-height: 28px; }
}
:root .trust-page p { margin: 0 0 16px; }
:root .trust-page .lead { margin: 0 0 24px; font-size: 18px; line-height: 28px; }
:root .trust-page :is(ul, ol):not(.doc-toc ol, .breadcrumbs ol, .faq-toc, [class]) { margin: 0 0 16px; padding-inline-start: 24px; }
:root .trust-page li + li { margin-top: 8px; }
:root .trust-page code { overflow-wrap: anywhere; word-break: break-word; }

/* Заметка — карточка 04 тона «заметка». */
:root .trust-page .note {
  margin: 24px 0;
  padding: 16px 24px;
  border: 1px solid var(--card-border, var(--rule, var(--color-rule)));
  border-radius: 14px;
  background: var(--card-bg, var(--surface, var(--color-surface)));
  color: var(--text-2, var(--color-text-2));
  font-size: 14px;
  line-height: 20px;
}
:root .trust-page :is(.table-wrap, .tscroll) { margin: 24px 0; }

/* Оглавление длинного документа; «Разделы» faq (nav > .faq-toc) — тот же вид. */
:root .trust-page nav:has(> .faq-toc) {
  box-sizing: border-box;
  max-width: var(--doc-block);
  margin: 32px 0 8px;
  padding: 20px 24px 12px;
  border: 1px solid var(--card-border, var(--rule, var(--color-rule)));
  border-radius: 14px;
  background: var(--card-bg, var(--surface, var(--color-surface)));
}
:root .trust-page nav:has(> .faq-toc) > h2 {
  margin: 0 0 4px;
  font-family: inherit;
  font-size: 12px;
  line-height: 16px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-3, var(--muted, var(--palette-grey-325)));
}
:root .trust-page .faq-toc { max-width: none; margin: 0; padding: 0; list-style: none; columns: 2 280px; column-gap: 24px; }
:root .trust-page .faq-toc li { margin: 0; break-inside: avoid; }
:root .trust-page .faq-toc a {
  display: flex;
  align-items: center;
  min-height: 44px;
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  color: var(--text-2, var(--text, var(--palette-grey-105)));
  text-decoration: none;
}
@media (hover: hover) { :root .trust-page .faq-toc a:hover { color: var(--bone, var(--palette-grey-044)); text-decoration: underline; } }
:root .trust-page .doc-toc {
  box-sizing: border-box;
  margin: 32px 0 8px;
  padding: 20px 24px 12px;
  border: 1px solid var(--card-border, var(--rule, var(--color-rule)));
  border-radius: 14px;
  background: var(--card-bg, var(--surface, var(--color-surface)));
}
:root .trust-page .doc-toc-title {
  margin: 0 0 4px;
  font-size: 12px;
  line-height: 16px;
  font-weight: 600;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-3, var(--muted, var(--palette-grey-325)));
}
:root .trust-page .doc-toc ol { max-width: none; margin: 0; padding: 0; list-style: none; columns: 2 280px; column-gap: 24px; }
:root .trust-page .doc-toc li { margin: 0; break-inside: avoid; }
:root .trust-page .doc-toc a {
  display: flex;
  align-items: center;
  min-height: 44px;
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  color: var(--text-2, var(--text, var(--palette-grey-105)));
  text-decoration: none;
  transition: color 150ms ease-out;
}
@media (hover: hover) { :root .trust-page .doc-toc a:hover { color: var(--bone, var(--palette-grey-044)); text-decoration: underline; } }
:root .trust-page .doc-toc a:focus-visible { outline: 2px solid var(--focus, var(--gold, var(--color-accent))); outline-offset: 2px; border-radius: 6px; }

/* Раскрытие вопроса — как FAQ главной: карточка 04 и SVG-знак. */
:root :is(.trust-page, .v36-faq) details:not(.footer-group) {
  box-sizing: border-box;
  max-width: var(--doc-block, 880px);
  margin: 0 0 8px;
  padding: 0 24px;
  border: 1px solid var(--card-border, var(--rule, var(--color-rule)));
  border-radius: 14px;
  background: var(--card-bg, var(--surface, var(--color-surface)));
  transition: border-color 150ms ease-out;
}
:root :is(.trust-page, .v36-faq) details:not(.footer-group)[open] { padding-bottom: 24px; }
:root :is(.trust-page, .v36-faq) details:not(.footer-group) > summary {
  box-sizing: border-box;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 56px;
  margin: 0;
  padding: 16px 0;
  font-size: 16px;
  line-height: 24px;
  font-weight: 500;
  color: var(--bone, var(--palette-grey-044));
  cursor: pointer;
  list-style: none;
}
:root :is(.trust-page, .v36-faq) details:not(.footer-group) > summary::-webkit-details-marker { display: none; }
:root :is(.trust-page, .v36-faq) details:not(.footer-group) > summary:focus-visible {
  outline: 2px solid var(--focus, var(--gold, var(--color-accent)));
  outline-offset: 4px;
  border-radius: 8px;
}
:root .doc-faq-q { min-width: 0; }
:root .doc-faq-icon { flex: none; color: var(--text-3, var(--muted, var(--palette-grey-325))); transition: color 150ms ease-out; }
:root .doc-faq-icon path:last-child { transition: opacity 150ms ease-out; }
:root details[open] > summary .doc-faq-icon path:last-child { opacity: 0; }
:root :is(.trust-page, .v36-faq) details:not(.footer-group) > :not(summary) {
  max-width: var(--doc-measure, 54ch);
  margin: 0 0 16px;
  font-size: 16px;
  line-height: 24px;
  color: var(--text, var(--text-2, var(--palette-grey-105)));
}
:root :is(.trust-page, .v36-faq) details:not(.footer-group) > :last-child:not(summary) { margin-bottom: 0; }
@media (hover: hover) {
  :root :is(.trust-page, .v36-faq) details:not(.footer-group):hover { border-color: var(--rule-strong, var(--color-rule-strong)); }
  :root :is(.trust-page, .v36-faq) details:not(.footer-group):hover .doc-faq-icon { color: var(--bone, var(--palette-grey-044)); }
}
@media (prefers-reduced-motion: no-preference) {
  :root body:not([data-motion-pref="paused"]) :is(.trust-page, .v36-faq) details:not(.footer-group)[open] > :not(summary) { animation: doc-open 200ms ease-out; }
}
@keyframes doc-open { from { opacity: 0; transform: translateY(-4px); } to { opacity: 1; transform: none; } }
@media (prefers-reduced-motion: reduce) {
  :root :is(.trust-page, .v36-faq) details:not(.footer-group), :root .doc-faq-icon, :root .doc-faq-icon path, :root .trust-page .doc-toc a { transition: none; }
}

/* «Для проверяющих: исходный код» (полировка текстов 1.5, 1.14): строки «Проверить: …» и маршруты свёрнуты в конце
   ответа или страницы — подпись-ссылка 14/20 без карточки, цель 44; раскрытый блок — текст заметки 14/20.
   Специфичность та же, что у карточки раскрытия выше: правило стоит после неё. */
:root :is(.trust-page, .v36-faq, main) details.src-more {
  max-width: var(--doc-measure, 54ch);
  margin: 16px 0 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: none;
}
:root :is(.trust-page, .v36-faq, main) details.src-more[open] { padding-bottom: 0; }
:root :is(.trust-page, .v36-faq, main) details.src-more > summary {
  display: inline-flex;
  justify-content: flex-start;
  min-height: 44px;
  padding: 0;
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  color: var(--text-3, var(--muted, var(--color-text-3)));
  text-decoration: underline;
  text-decoration-color: var(--rule-strong, var(--color-rule-strong));
  text-underline-offset: 4px;
}
:root :is(.trust-page, .v36-faq, main) details.src-more > :not(summary) {
  margin: 4px 0 0;
  font-size: 14px;
  line-height: 20px;
  color: var(--text-3, var(--muted, var(--color-text-3)));
}
@media (hover: hover) {
  :root :is(.trust-page, .v36-faq, main) details.src-more:hover { border-color: transparent; }
  :root :is(.trust-page, .v36-faq, main) details.src-more:hover > summary { color: var(--bone, var(--palette-grey-044)); }
}

/* Таблица на телефоне: строки — карточки 03 (td[data-label]), обёртке нечего прокручивать. */
@media (max-width: 700px) {
  :root .trust-page .table-wrap:has(td[data-label]), :root .trust-page .tscroll:has(td[data-label]) {
    overflow: visible;
    border: 0;
    border-radius: 0;
    background: none;
  }
}

/* Строка действий: кнопки 01. */
:root :is(.v36-cta, .trust-page .cta-row) { display: flex; flex-wrap: wrap; gap: 12px; margin: 32px 0 0; }

/* «модель» у цифр будущего дохода — бейдж 05 в начале абзаца. */
:root .trust-page .model-mark { margin-inline-end: 8px; vertical-align: 1px; }
/* Хлебные крошки: строкой текста — длинное название страницы переносится сразу за «/», а не отдельным блоком
   с разделителем в начале второй строки; ссылка сохраняет цель 44. */
:root .trust-page .breadcrumbs ol { display: block; margin: 0 0 16px; padding: 0; font-size: 14px; line-height: 20px; }
:root .trust-page .breadcrumbs li { display: inline; }
:root .trust-page .breadcrumbs li + li::before { margin-inline: 8px; }
:root .trust-page .breadcrumbs a { vertical-align: middle; }
/* Подпись источника под графиком рынка: биржа или модель платформы — подпись 14/20. */
:root .trust-page .market-source { margin: 12px 0 0; font-size: 14px; line-height: 20px; }
/* Флажок согласия формы поддержки — 20 px по первой строке подписи (цель — вся подпись label.agree). */
:root .trust-page .agree input[type="checkbox"] { flex: none; width: 20px; height: 20px; margin: 2px 0 0; }

/* 404: ссылки не прилипают к подвалу. */
:root body.velar-pages .pg-404 .pg-body { padding-block-end: 64px; }
/* Крипта и эпохи — свои колонки (1120 / 20 и 1120 / 24); абзацы эпох — мера строки. */
:root [data-epochs-page] :is(.epochs-lead, .epochs-note, .epochs-step p, .epochs-section > p) { max-width: 54ch; }
/* Длинное слово заголовка (hy «արձանագրությունը» при 34 px на 320) не раздвигает страницу — как у документов. */
:root :is([data-epochs-page], body.crypto-body) :is(h1, h2, h3) { overflow-wrap: break-word; }
/* Заголовки разделов крипты и эпох — та же ступень h2, что у документов (24/32, телефон 20/28); h1 первого экрана — свой. */
:root body.crypto-body :is(.crypto-section, .crypto-close) h2, :root [data-epochs-page] .epochs-section > h2 { font-size: 24px; line-height: 32px; }
@media (max-width: 600px) {
  :root body.crypto-body :is(.crypto-section, .crypto-close) h2, :root [data-epochs-page] .epochs-section > h2 { font-size: 20px; line-height: 28px; }
}

/* ───────────────────────────── 14 · Сводка (дашборд пульта и владельца) ─────────────────────────────
   Спека: скилл dataviz + docs/parts/DESIGN-QUALITY.md §3–§7; разметку строит dist/ops-charts.js.
   Сверху вниз: главная цифра (одна на экран) · ряд плиток 04 · графики · таблица значений под каждым.
     главная      подпись 12/16 капсом +.06em · число 48/56 600 (телефон 40/48), пропорциональные цифры ·
                  пояснение 14/20 · изменение к прошлому периоду 14/20 со стрелкой SVG 16 · «Модель, не обещание»
     плитка       компонент 04 (компактная): подпись 12/16 капсом · значение 20/28 600 · изменение · источник 12/16
     график       заголовок 16/24 600 · пояснение 14/20 · легенда (≥ 2 рядов) · холст: сетка 1 px сплошная, база 1 px,
                  линия 2 px, точка 8 px с кольцом 2 px цвета поверхности, столбец ≤ 24 px, конец r4, база квадратная;
                  ось справа 12/16 табличными; даты 12/16; подпись значения — только на конце главного ряда
     подсказка    перекрестие 1 px; значение жирным впереди подписи; ключ ряда — отрезок 12 × 2; textContent
     таблица      <details> «Таблица значений» — компонент 03; когорты — ячейки с подложкой --viz-s1 по доле
   Цвета — только крючки --viz-* (проверено validate_palette.js: категории s1/s2 и ступени этапов на тёмной
   поверхности --color-surface пульта и владельца; светлая — --palette-grey-009, там у светлых ступеней подписи текстом):
     --viz-s1 синий · --viz-s2 оранжевый (порядок фиксирован) · --viz-prev прошлый период (серый) ·
     --viz-step-1…3 этапы воронки (одна синяя шкала) — примитивы слоя 1 по поверхности · --viz-good / --viz-warn /
     --viz-bad — статус: семантика --color-success / --color-warn / --color-danger (этап «Палитра»), всегда со словом.
   Тёмная — по умолчанию (пульт и экран владельца тёмные); светлая — [data-viz-surface="light"] или
   :root[data-theme="light"]. Движение: только смена прозрачности подсказки и перекрестия 150 мс; reduced-motion — без.
   Контейнер: графики и подписи — только внутри .viz (#summary-body пульта, #owner-dashboard владельца); у дашборда
   клиента те же имена классов (раздел 15) живут внутри .cabinet-insights и сюда не протекают. Вне .viz работают
   только плитки (.viz-tiles · .viz-tile*), .viz-delta, .viz-status, .viz-filters и .viz-empty. */
:root .viz {
  --viz-surface: var(--card-bg, var(--color-surface));
  --viz-ink: var(--card-fg, var(--palette-grey-048));
  --viz-label: var(--card-muted, var(--palette-grey-188));
  --viz-grid: var(--card-border, var(--palette-grey-708));
  --viz-base: color-mix(in srgb, var(--viz-label) 45%, transparent);
  --viz-s1: var(--palette-blue-378);
  --viz-s2: var(--palette-orange-378);
  --viz-prev: var(--palette-grey-377);
  --viz-step-1: var(--palette-blue-473);
  --viz-step-2: var(--palette-blue-378);
  --viz-step-3: var(--palette-blue-283);
  --viz-good: var(--color-success);
  --viz-warn: var(--color-warn);
  --viz-bad: var(--color-danger);
  --viz-good-text: var(--color-success-ink);
  --viz-bad-text: var(--color-danger-ink);
  --viz-warn-text: var(--color-warn-ink);
  display: grid;
  gap: 24px;
  min-width: 0;
}
:root[data-theme="light"] .viz, :root .viz[data-viz-surface="light"] {
  --viz-surface: var(--palette-grey-009); --viz-ink: var(--palette-grey-850); --viz-label: var(--palette-grey-565); --viz-grid: var(--palette-grey-094); --viz-base: var(--palette-grey-188);
  --viz-s1: var(--palette-blue-425); --viz-s2: var(--palette-orange-329); --viz-prev: var(--palette-grey-377); --viz-step-1: var(--palette-blue-236); --viz-step-2: var(--palette-blue-329); --viz-step-3: var(--palette-blue-425);
  --viz-good-text: var(--palette-green-567); --viz-bad-text: var(--palette-red-499); --viz-warn-text: var(--palette-amber-529);
}
:root .viz .viz-hero { display: grid; gap: 8px; padding: 24px; border: 1px solid var(--card-border, var(--color-rule)); border-radius: 14px; background: var(--viz-surface); }
:root .viz .viz-hero p { margin: 0; }
:root .viz .viz-hero-label, :root .viz-tile-label { font-size: 12px; line-height: 16px; letter-spacing: .06em; text-transform: uppercase; color: var(--viz-label); }
:root .viz .viz-hero-value { font-size: 48px; line-height: 56px; font-weight: 600; letter-spacing: -.01em; color: var(--viz-ink); }
:root .viz .viz-hero-note { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; font-size: 14px; line-height: 20px; color: var(--viz-label); }
:root .viz-tiles { display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); gap: 16px; }
:root .viz-tile { display: grid; align-content: start; gap: 8px; min-width: 0; padding: 16px 20px; border: 1px solid var(--card-border, var(--color-rule)); border-radius: 14px; background: var(--viz-surface); }
:root .viz-tile p { margin: 0; }
:root .viz-tile-value { font-size: 20px; line-height: 28px; font-weight: 600; color: var(--viz-ink); overflow-wrap: anywhere; }
:root .viz-tile-note { font-size: 12px; line-height: 16px; color: var(--viz-label); }
:root .viz-delta { display: inline-flex; align-items: center; gap: 4px; font-size: 14px; line-height: 20px; color: var(--viz-label); }
:root .viz-delta svg { flex: none; }
:root .viz-delta[data-tone="good"] { color: var(--viz-good-text); }
:root .viz-delta[data-tone="bad"] { color: var(--viz-bad-text); }
:root .viz .viz-model { justify-self: start; font-size: 12px; line-height: 16px; padding: 2px 8px; border: 1px solid var(--card-border, var(--color-rule)); border-radius: 999px; color: var(--viz-label); }
:root .viz-status { display: inline-flex; align-items: center; gap: 6px; color: var(--viz-ink); font-weight: 600; }
/* Статус живёт и вне .viz (настройки, управление аккаунтом): у каждого крючка — запасной цвет палитры статуса. */
:root .viz-status::before { content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--viz-label, var(--palette-grey-377)); }
:root .viz-status[data-tone="good"]::before { background: var(--viz-good, var(--color-success)); }
:root .viz-status[data-tone="warn"]::before { background: var(--viz-warn, var(--color-warn)); }
:root .viz-status[data-tone="bad"]::before { background: var(--viz-bad, var(--color-danger)); }
:root .viz-tile[data-tone="bad"] { border-color: var(--viz-bad); }
:root .viz-tile[data-tone="warn"] { border-color: var(--viz-warn); }
:root .viz .viz-grid-2 { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
:root .viz .viz-chart { margin: 0; display: grid; gap: 12px; min-width: 0; padding: 20px 24px 16px; border: 1px solid var(--card-border, var(--color-rule)); border-radius: 14px; background: var(--viz-surface); }
:root .viz .viz-chart-head { display: grid; gap: 4px; }
:root .viz .viz-chart-title { margin: 0; font-size: 16px; line-height: 24px; font-weight: 600; color: var(--viz-ink); }
:root .viz .viz-chart-note { margin: 0; font-size: 14px; line-height: 20px; color: var(--viz-label); max-width: 72ch; }
:root .viz .viz-legend { display: flex; flex-wrap: wrap; gap: 4px 16px; margin: 0; padding: 0; list-style: none; font-size: 14px; line-height: 20px; color: var(--viz-label); }
:root .viz .viz-legend li { display: inline-flex; align-items: center; gap: 8px; }
:root .viz .viz-key { display: inline-block; width: 12px; height: 2px; border-radius: 1px; background: var(--viz-s1); flex: none; }
:root .viz .viz-key[data-series="s2"] { background: var(--viz-s2); }
:root .viz .viz-key[data-series="prev"] { background: var(--viz-prev); }
:root .viz .viz-plot { position: relative; padding-right: 72px; outline: none; border-radius: 8px; touch-action: pan-y; }
:root .viz .viz-plot:focus-visible { outline: 2px solid var(--button-focus, var(--color-focus)); outline-offset: 4px; }
:root .viz .viz-svg { display: block; width: 100%; height: 200px; overflow: visible; }
:root .viz .viz-canvas, :root .viz .viz-bars { position: relative; }
:root .viz .viz-grid { stroke: var(--viz-grid); stroke-width: 1; }
:root .viz .viz-base { stroke: var(--viz-base); stroke-width: 1; }
:root .viz .viz-line { fill: none; stroke: var(--viz-s1); stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
:root .viz .viz-line[data-series="s2"] { stroke: var(--viz-s2); }
:root .viz .viz-line[data-series="prev"] { stroke: var(--viz-prev); }
:root .viz .viz-cross { stroke: var(--viz-label); stroke-width: 1; transition: opacity 150ms ease-out; }
:root .viz .viz-axis { position: absolute; top: 0; right: 0; bottom: 0; width: 64px; pointer-events: none; }
:root .viz .viz-axis span { position: absolute; right: 0; transform: translateY(-50%); font-size: 12px; line-height: 16px; color: var(--viz-label); font-variant-numeric: tabular-nums; white-space: nowrap; }
:root .viz .viz-end { position: absolute; right: 0; transform: translate(0, -130%); font-size: 12px; line-height: 16px; font-weight: 600; color: var(--viz-ink); white-space: nowrap; pointer-events: none; }
:root .viz .viz-dot { position: absolute; width: 12px; height: 12px; margin: -6px 0 0 -6px; border-radius: 50%; background: var(--viz-s1); box-shadow: 0 0 0 2px var(--viz-surface); pointer-events: none; }
:root .viz .viz-dot[data-series="s2"] { background: var(--viz-s2); }
:root .viz .viz-dot[data-series="prev"] { background: var(--viz-prev); }
:root .viz .viz-dot[hidden], :root .viz .viz-tip[hidden] { display: none; }
:root .viz .viz-tip { position: absolute; top: 0; z-index: 2; transform: translateX(-50%); display: grid; gap: 4px; min-width: 160px; padding: 8px 12px; border: 1px solid var(--card-border, var(--color-rule)); border-radius: 10px; background: var(--viz-surface); color: var(--viz-ink); font-size: 12px; line-height: 16px; pointer-events: none; }
:root .viz .viz-tip-row { display: flex; align-items: center; gap: 8px; }
:root .viz .viz-tip-row b { font-variant-numeric: tabular-nums; }
:root .viz .viz-tip-row span:last-child { color: var(--viz-label); }
:root .viz .viz-dates { position: relative; height: 16px; margin-right: 72px; font-size: 12px; line-height: 16px; color: var(--viz-label); }
:root .viz .viz-dates span { position: absolute; transform: translateX(-50%); white-space: nowrap; }
:root .viz .viz-dates span:first-child { transform: none; }
:root .viz .viz-dates span:last-child:not(:first-child) { transform: translateX(-100%); }
:root .viz .viz-bars-frame { position: relative; padding-right: 72px; outline: none; touch-action: pan-y; }
:root .viz .viz-bars { display: flex; align-items: flex-end; gap: 2px; height: var(--viz-bars-h, 160px); border-bottom: 1px solid var(--viz-base); background-image: linear-gradient(var(--viz-grid), var(--viz-grid)); background-size: 100% 1px; background-repeat: no-repeat; background-position: 0 0; }
:root .viz .viz-bar { flex: 1 1 0; display: flex; align-items: flex-end; justify-content: center; height: 100%; min-width: 0; }
:root .viz .viz-bars-frame:focus-visible { outline: 2px solid var(--button-focus, var(--color-focus)); outline-offset: 4px; border-radius: 8px; }
:root .viz .viz-bar-fill { display: block; width: 100%; max-width: 24px; border-radius: 4px 4px 0 0; background: var(--viz-s1); }
:root .viz .viz-bar:hover .viz-bar-fill, :root .viz .viz-bar.active .viz-bar-fill { background: color-mix(in srgb, var(--viz-s1) 94%, var(--viz-ink)); }
:root .viz .viz-axis-bars { bottom: auto; height: var(--viz-bars-h, 160px); }
:root .viz .viz-bar.active { background: color-mix(in srgb, var(--viz-ink) 8%, transparent); border-radius: 4px 4px 0 0; }
:root .viz .table-wrap { overflow-x: auto; max-width: 100%; }
:root .viz .table-wrap:focus-visible { outline: 2px solid var(--button-focus, var(--color-focus)); outline-offset: 2px; }
:root .viz .viz-funnel { display: grid; gap: 16px; margin: 0; padding: 0; list-style: none; }
:root .viz .viz-funnel-label { display: flex; justify-content: space-between; gap: 16px; margin: 0 0 8px; font-size: 14px; line-height: 20px; color: var(--viz-label); }
:root .viz .viz-funnel-label b { color: var(--viz-ink); font-variant-numeric: tabular-nums; white-space: nowrap; }
:root .viz .viz-funnel-track { display: block; height: 16px; }
:root .viz .viz-funnel-fill { display: block; height: 100%; border-radius: 0 4px 4px 0; background: var(--viz-step-1); }
:root .viz .viz-funnel-fill[data-step="2"] { background: var(--viz-step-2); }
:root .viz .viz-funnel-fill[data-step="3"] { background: var(--viz-step-3); }
:root .viz .viz-cell { background: color-mix(in srgb, var(--viz-s1) calc(var(--viz-level, 0) * 60%), transparent); }
/* «Таблица значений» сводки: знак, цель и наведение — раздел 17; здесь только цвета палитры сводки — у светлой
   поверхности (.viz[data-viz-surface="light"]) свои --viz-label / --viz-ink, общий --text-2 там не читается. */
:root .viz .viz-table > summary { color: var(--viz-label); }
:root .viz .viz-table > summary:hover, :root .viz .viz-table[open] > summary { color: var(--viz-ink); }
:root .viz-empty { margin: 0; padding: 16px 20px; border: 1px dashed var(--card-border, var(--color-rule)); border-radius: 14px; color: var(--viz-label); font-size: 14px; line-height: 20px; }
:root .viz-filters { display: flex; flex-wrap: wrap; align-items: end; gap: 12px 16px; }
@media (max-width: 760px) {
  :root .viz .viz-grid-2 { grid-template-columns: minmax(0, 1fr); }
  :root .viz .viz-hero { padding: 20px; }
  :root .viz .viz-hero-value { font-size: 40px; line-height: 48px; }
  :root .viz .viz-chart { padding: 16px; }
  :root .viz .viz-plot, :root .viz .viz-bars-frame { padding-right: 56px; }
  :root .viz .viz-dates { margin-right: 56px; }
  :root .viz .viz-axis { width: 52px; }
  :root .viz-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
@media (max-width: 360px) { :root .viz-tiles { grid-template-columns: minmax(0, 1fr); } }
@media (prefers-reduced-motion: reduce) { :root .viz .viz-cross { transition: none; } }
@media (forced-colors: active) {
  :root .viz .viz-line, :root .viz .viz-grid, :root .viz .viz-base, :root .viz .viz-cross { stroke: CanvasText; }
  :root .viz .viz-bar-fill, :root .viz .viz-funnel-fill, :root .viz .viz-dot, :root .viz .viz-key { background: CanvasText; forced-color-adjust: none; }
}

/* ───────────────────────────── 14 · Выбор актива · стартовое пополнение ─────────────────────────────
   Спека: docs/design-audit/screens/payments-flow.md, docs/TRAINING-WALLETS.md, DESIGN-QUALITY §1, §5, §7.
   Три шага одной карточки: 1 — криптовалюта (сетка кликабельных карточек 04 .network-card со знаками
   coin-marks.json) и сеть (сегменты 11 .v24-term), 2 — сумма (поле 02, быстрые суммы — те же сегменты,
   строка пересчёта), 3 — заявка с вымышленным адресом и «Стартовое зачисление».
     шаг           h3 16/24 600, номер — круг 24 px с рамкой --rule-strong; бейдж статуса (05) у края
     карточка      мин. высота 64, поля 12 16, знак 40 px (тон монеты 12 % под знаком), код 16/24 600,
                   имя 14/20 --text-2, сети 12/16 --text-3; выбранная — aria-pressed (одно выделение, 04)
     сетка         auto-fit от 200 px, зазор 8 — на 1440 четыре в ряд, на телефоне (≤ 480) две колонки,
                 на ≤ 380 знак над подписью
     чипы          сегменты 44 px без растяжения, «скоро» — недоступный сегмент с подписью 12/16 и подсказкой «?»
                   (компонент «Ясность»: что за сеть, почему не подключена, что выбрать) — пара не разрывается
     не подключены строка 14/20 --text-3 со знаками 24 px — это ответ поиску, а не кнопки
   Цвета — токены страницы; тон монеты — --coin-tint из coin-marks.json (тот же, что у первого экрана). */
:root .topup-step {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 24px 0 12px;
  font-size: 16px;
  line-height: 24px;
  font-weight: 600;
}
:root .topup-picker > .topup-step:first-child { margin-top: 8px; }
:root .topup-step-n {
  display: inline-grid;
  place-items: center;
  flex: none;
  box-sizing: border-box;
  width: 24px;
  height: 24px;
  border: 1px solid var(--rule-strong, var(--color-rule-strong));
  border-radius: 999px;
  color: var(--text-2, var(--color-text-2));
  font-size: 12px;
  line-height: 16px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
:root .topup-step .badge { margin-inline-start: auto; }
:root .topup-search { display: grid; gap: 8px; margin: 0 0 12px; }
:root .topup-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 8px;
}
@media (max-width: 480px) {
  :root .topup-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}
:root .topup-asset {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  min-width: 0;
  min-height: 64px;
  height: auto;
  margin: 0;
  padding: 12px 16px;
  overflow: visible;
  white-space: normal;
}
@media (max-width: 600px) {
  :root .topup-asset { padding: 12px; gap: 8px; }
}
/* Узкий телефон: знак над подписью — код и имя не переносятся по буквам в колонке 130 px. */
@media (max-width: 380px) {
  :root .topup-asset { flex-direction: column; align-items: flex-start; }
}
:root .topup-coin {
  display: grid;
  place-items: center;
  flex: none;
  width: 40px;
  height: 40px;
  border-radius: 999px;
  color: var(--coin-tint, var(--bone, var(--color-text-1)));
  background-color: color-mix(in srgb, var(--coin-tint, var(--bone, var(--color-text-1))) 12%, transparent);
}
:root .topup-coin svg { display: block; width: 20px; height: 20px; }
:root .topup-asset-text { display: grid; min-width: 0; }
:root .topup-asset-code { font-size: 16px; line-height: 24px; font-weight: 600; }
:root .topup-asset-name { color: var(--text-2, var(--color-text-2)); font-size: 14px; line-height: 20px; }
:root .topup-asset-nets { color: var(--text-3, var(--color-text-3)); font-size: 12px; line-height: 16px; overflow-wrap: anywhere; }
:root .topup-off { margin: 12px 0 0; color: var(--text-3, var(--color-text-3)); font-size: 14px; line-height: 20px; }
:root .topup-off-list { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 8px 0 0; padding: 0; list-style: none; }
:root .topup-off-item { display: inline-flex; align-items: center; gap: 8px; }
:root .topup-off-item .topup-coin { width: 24px; height: 24px; color: var(--text-3, var(--color-text-3)); background-color: transparent; }
:root .topup-off-item .topup-coin svg { width: 16px; height: 16px; }
:root .topup-net { margin: 16px 0 0; }
:root .topup-net-title { margin: 0 0 8px; color: var(--text-2, var(--color-text-2)); font-size: 14px; line-height: 20px; font-weight: 500; }
:root :is(.topup-chips, .topup-presets) { display: flex; flex-wrap: wrap; gap: 8px; }
:root .topup-presets { margin: 8px 0 0; }
:root :is(.topup-chip, .topup-preset) { flex: 0 0 auto; padding: 0 16px; }
:root .topup-chip-soon { margin-inline-start: 8px; color: var(--text-3, var(--color-text-3)); font-size: 12px; line-height: 16px; }
/* Волна 3: чип «скоро» и его «?» — одна пара, «?» не уходит на другую строку от своей сети. Зона касания «?» — 44 px
   за счёт ::after компонента; 2 px поля справа + зазор 8 — она не заходит на соседний чип. «?» растянут на высоту
   чипа (stretch, значок по центру) — пузырь открывается на 8 px ниже чипа, а не поверх его нижнего края. */
:root .topup-chip-wrap { display: inline-flex; align-items: stretch; flex: 0 0 auto; margin-inline-end: 2px; }
/* Код сети в тексте подсказки («TRC-20») не рвётся по дефису — как на чипах и карточках (полировка 5.11). */
:root .topup-chip-hint .topup-net-code { white-space: nowrap; }
:root .topup-convert { margin: 8px 0 0; color: var(--text-2, var(--color-text-2)); font-size: 14px; line-height: 20px; font-variant-numeric: tabular-nums; }
:root .topup-actions { display: flex; flex-wrap: wrap; gap: 8px; margin: 16px 0 0; }
:root .topup-intent { margin: 24px 0 0; padding: 0; border-top: 1px solid var(--rule, var(--color-rule)); }
:root .topup-addr-row { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; }
:root .topup-addr-row .addr { flex: 1 1 280px; min-width: 0; overflow-wrap: anywhere; }
:root .topup-history-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 12px; }
:root .topup-history-amount { font-variant-numeric: tabular-nums; font-weight: 600; }
@media (forced-colors: active) {
  :root .topup-coin { forced-color-adjust: auto; background-color: transparent; border: 1px solid CanvasText; }
}

/* ───────────────────────────── 15 · Дашборд кабинета · события и графики ─────────────────────────────
   Спека: скилл dataviz (форма → цвет → проверка палитры → метки → наведение → доступность), DESIGN-QUALITY §1, §3,
   §6, §7. Разметку строит dist/cabinet-insights.js в /account.html → «Обзор».
     события      карточка 04, список: иконка 20 (SVG 24 · stroke 1.5), заголовок 14/20 600 + дата 12/16 --text-3,
                  сумма 14/20 табличными, «что дальше» 14/20 --text-2, действие — вторичная кнопка 01
     сетка        две колонки от 960 px, одна — ниже; зазор 16; одинаковые по роли карточки — одинаковые
     карточка     .viz-card — поверхность 04, поля 24 / 20; заголовок 16/24 600, подзаголовок 14/20 --text-3
     линия        2 px (non-scaling-stroke), заливка 10 %, модель — тот же цвет штрихом 6 4; конечная точка 8 px с
                  кольцом 2 px цвета поверхности; подпись значения у конца линии — текстом, не цветом ряда
     столбцы      ≤ 24 px, стопка по вкладам с зазором 2 px, скругление 4 px только у вершины, от одной базовой линии
     полосы       16 px, скругление 4 px у конца, значение и доля — у конца полосы
     оси          сетка 1 px сплошная --viz-grid; деления 12/16 табличными --text-3; одна ось, справа
     наведение    перекрестие 1 px и подсказка (поверхность 04, 12/16); столбец — подмес 8 % поверх
     таблица      под каждым графиком в раскрытии «Таблица значений» (компонент 03)
   Цвета — роли --viz-*: ряд одного графика — слот 1; вклады — слоты 1–4 в порядке открытия (палитра проверена
   validate_palette.js: тёмная поверхность #0C0E14 — всё PASS; светлая #FFFFFF — PASS, контраст слотов 3–4 WARN,
   поэтому легенда + таблица обязательны). Светлые значения — только под [data-theme="light"].
   Контейнер: все правила раздела — внутри .cabinet-insights (имена .viz-* совпадают со сводкой пульта, раздел 14,
   но там другие формы: столбцы снизу вверх, ключ легенды 12 × 2, бейдж «модель»); вне контейнера они не действуют. */
:root .cabinet-insights {
  --viz-surface: var(--card-bg, var(--surface, var(--color-surface)));
  --viz-grid: var(--rule, var(--color-rule));
  --viz-label: var(--text-3, var(--color-text-3));
  --viz-cursor: var(--rule-strong, var(--color-rule-strong));
  --viz-s1: var(--palette-blue-378);
  --viz-s2: var(--palette-orange-378);
  --viz-s3: var(--palette-green-379);
  --viz-s4: var(--palette-amber-330);
  --viz-s0: var(--palette-grey-325);
  display: grid;
  gap: 16px;
  margin: 24px 0 0;
}
:root[data-theme="light"] .cabinet-insights {
  --viz-s1: var(--palette-blue-425);
  --viz-s2: var(--palette-orange-329);
  --viz-s3: var(--palette-green-331);
  --viz-s4: var(--palette-amber-236);
  --viz-s0: var(--palette-grey-476);
}
:root .cabinet-insights[hidden] { display: none; }
:root .cabinet-insights .insights-head h2 { margin: 0; font-size: 20px; line-height: 28px; }
:root .cabinet-insights .insights-head .section-why { margin: 4px 0 0; }
:root .cabinet-insights .viz-grid-cards { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; }
@media (max-width: 960px) { :root .cabinet-insights .viz-grid-cards { grid-template-columns: minmax(0, 1fr); } }
:root .cabinet-insights .viz-card {
  box-sizing: border-box;
  min-width: 0;
  margin: 0;
  padding: 24px;
  border: 1px solid var(--card-border, var(--rule, var(--color-rule)));
  border-radius: 14px;
  background: var(--viz-surface);
}
@media (max-width: 600px) { :root .cabinet-insights .viz-card { padding: 20px; } }
:root .cabinet-insights .viz-card figcaption { display: grid; gap: 4px; margin: 0 0 16px; }
:root .cabinet-insights .viz-title { font-size: 16px; line-height: 24px; font-weight: 600; }
:root .cabinet-insights .viz-sub, :root .cabinet-insights .viz-note { color: var(--viz-label); font-size: 14px; line-height: 20px; }
:root .cabinet-insights .viz-note { margin: 12px 0 0; }
:root .cabinet-insights .viz-legend { display: flex; flex-wrap: wrap; gap: 8px 16px; margin: 0 0 12px; padding: 0; list-style: none; color: var(--text-2, var(--color-text-2)); font-size: 14px; line-height: 20px; }
:root .cabinet-insights .viz-legend li { display: inline-flex; align-items: center; gap: 8px; }
:root .cabinet-insights .viz-key { display: inline-block; width: 12px; height: 12px; border-radius: 3px; background: var(--viz-s1); }
:root .cabinet-insights .viz-key-line, :root .cabinet-insights .viz-key-dash { width: 16px; height: 0; border-radius: 0; border-top: 2px solid var(--viz-s1); background: none; }
:root .cabinet-insights .viz-key-dash { border-top-style: dashed; }
:root .cabinet-insights .viz-frame { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 8px; }
:root .cabinet-insights .viz-plot { position: relative; height: 180px; order: 1; touch-action: pan-y; }
:root .cabinet-insights .viz-plot svg { display: block; width: 100%; height: 100%; overflow: visible; }
:root .cabinet-insights .viz-y { position: relative; order: 2; min-width: 48px; height: 180px; color: var(--viz-label); font-size: 12px; line-height: 16px; font-variant-numeric: tabular-nums; }
:root .cabinet-insights .viz-y span { position: absolute; right: 0; transform: translateY(50%); white-space: nowrap; }
:root .cabinet-insights .viz-x { display: flex; justify-content: space-between; margin: 8px 56px 0 0; color: var(--viz-label); font-size: 12px; line-height: 16px; font-variant-numeric: tabular-nums; }
:root .cabinet-insights .viz-grid { stroke: var(--viz-grid); stroke-width: 1; }
:root .cabinet-insights .viz-line { fill: none; stroke: var(--viz-s1); stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
:root .cabinet-insights .viz-model { stroke-dasharray: 6 4; }
:root .cabinet-insights .viz-area { fill: var(--viz-s1); fill-opacity: .1; stroke: none; }
:root .cabinet-insights :is(.viz-dot, .viz-hover-dot) {
  position: absolute;
  box-sizing: border-box;
  width: 12px;
  height: 12px;
  margin: 0 0 -6px -6px;
  border: 2px solid var(--viz-surface);
  border-radius: 999px;
  background: var(--viz-s1);
  pointer-events: none;
}
:root .cabinet-insights .viz-end { position: absolute; right: 8px; transform: translateY(-4px); padding: 0 4px; border-radius: 4px; background: var(--viz-surface); color: var(--text-1, var(--fg, var(--color-text-1))); font-size: 12px; line-height: 16px; font-weight: 600; font-variant-numeric: tabular-nums; pointer-events: none; }
:root .cabinet-insights .viz-cross { position: absolute; top: 0; bottom: 0; width: 0; border-left: 1px solid var(--viz-cursor); pointer-events: none; }
:root .cabinet-insights .viz-tip {
  position: absolute;
  top: 0;
  z-index: 2;
  display: grid;
  gap: 2px;
  transform: translate(-50%, -100%);
  padding: 8px 12px;
  border: 1px solid var(--rule-strong, var(--color-rule-strong));
  border-radius: 10px;
  background: var(--panel2, var(--surface, var(--color-surface)));
  color: var(--text-2, var(--color-text-2));
  font-size: 12px;
  line-height: 16px;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  pointer-events: none;
}
:root .cabinet-insights .viz-tip strong { color: var(--text-1, var(--fg, var(--color-text-1))); font-weight: 600; }
:root .cabinet-insights .viz-tip[hidden], :root .cabinet-insights .viz-cross[hidden], :root .cabinet-insights .viz-hover-dot[hidden] { display: none; }
:root .cabinet-insights .viz-plot-cols { display: block; }
:root .cabinet-insights .viz-gridline { position: absolute; left: 0; right: 0; height: 0; border-top: 1px solid var(--viz-grid); pointer-events: none; }
:root .cabinet-insights .viz-cols { position: absolute; inset: 0; display: flex; align-items: stretch; justify-content: space-between; gap: 2px; }
:root .cabinet-insights .viz-col { position: relative; display: flex; flex: 1 1 0; flex-direction: column-reverse; align-items: center; gap: 2px; min-width: 0; border-radius: 4px 4px 0 0; transition: background-color 150ms ease-out; }
:root .cabinet-insights .viz-col.is-hover { background-color: color-mix(in srgb, transparent, var(--text-1, var(--color-text-1)) 8%); }
:root .cabinet-insights .viz-seg { display: block; flex: none; width: min(24px, 70%); background: var(--viz-s1); }
:root .cabinet-insights .viz-col .viz-seg:last-child { border-radius: 4px 4px 0 0; }
:root .cabinet-insights :is(.viz-seg, .viz-key, .viz-bar).viz-s1 { background: var(--viz-s1); }
:root .cabinet-insights :is(.viz-seg, .viz-key, .viz-bar).viz-s2 { background: var(--viz-s2); }
:root .cabinet-insights :is(.viz-seg, .viz-key, .viz-bar).viz-s3 { background: var(--viz-s3); }
:root .cabinet-insights :is(.viz-seg, .viz-key, .viz-bar).viz-s4 { background: var(--viz-s4); }
:root .cabinet-insights :is(.viz-seg, .viz-key, .viz-bar).viz-s0 { background: var(--viz-s0); }
:root .cabinet-insights .viz-bars { display: grid; gap: 12px; }
:root .cabinet-insights .viz-bar-row { display: grid; grid-template-columns: 48px minmax(0, 1fr) auto; align-items: center; gap: 12px; font-size: 14px; line-height: 20px; }
:root .cabinet-insights .viz-bar-label { font-weight: 600; }
:root .cabinet-insights .viz-bar-track { display: block; height: 16px; }
:root .cabinet-insights .viz-bar { display: block; height: 16px; min-width: 2px; border-radius: 0 4px 4px 0; }
:root .cabinet-insights .viz-bar-value { color: var(--text-2, var(--color-text-2)); font-variant-numeric: tabular-nums; white-space: nowrap; }
:root .cabinet-insights .viz-pick { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 12px; }
:root .cabinet-insights .viz-pick .v24-term { flex: 0 0 auto; padding: 0 12px; }
:root .cabinet-insights .viz-table { margin: 12px 0 0; }
:root .cabinet-insights .viz-table-scroll { max-height: 320px; overflow: auto; }
:root .cabinet-insights .ins-events h2 { margin: 0 0 16px; }
:root .cabinet-insights .ins-event-list { display: grid; gap: 0; margin: 0; padding: 0; list-style: none; }
:root .cabinet-insights .ins-event { display: grid; grid-template-columns: 20px minmax(0, 1fr) auto; align-items: start; gap: 12px; padding: 16px 0; border-top: 1px solid var(--rule, var(--color-rule)); }
:root .cabinet-insights .ins-event:first-child { padding-top: 0; border-top: 0; }
:root .cabinet-insights .ins-icon { margin-top: 2px; color: var(--text-3, var(--color-text-3)); }
:root .cabinet-insights .ins-event-body { display: grid; gap: 4px; min-width: 0; }
:root .cabinet-insights .ins-event-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 4px 12px; margin: 0; font-size: 14px; line-height: 20px; }
:root .cabinet-insights .ins-event-head time { color: var(--text-3, var(--color-text-3)); font-size: 12px; line-height: 16px; font-variant-numeric: tabular-nums; }
:root .cabinet-insights .ins-event-amount { font-size: 14px; line-height: 20px; font-variant-numeric: tabular-nums; }
:root .cabinet-insights .ins-event-next { margin: 0; color: var(--text-2, var(--color-text-2)); font-size: 14px; line-height: 20px; }
:root .cabinet-insights .ins-event-action { margin: 0; white-space: nowrap; }
@media (max-width: 600px) {
  :root .cabinet-insights .ins-event { grid-template-columns: 20px minmax(0, 1fr); }
  :root .cabinet-insights .ins-event-action { grid-column: 2; justify-self: start; }
}
:root .cabinet-insights .ins-empty { padding: 24px; border: 1px dashed var(--rule-strong, var(--color-rule-strong)); border-radius: 14px; }
:root .cabinet-insights .ins-empty h3 { margin: 0; font-size: 16px; line-height: 24px; }
:root .cabinet-insights .ins-empty p { margin: 0; color: var(--text-2, var(--color-text-2)); }
:root .cabinet-insights .ins-empty-steps { display: grid; gap: 8px; margin: 0; padding-inline-start: 20px; color: var(--text-2, var(--color-text-2)); }
:root .cabinet-insights .ins-empty-steps [aria-current="step"] { color: var(--text-1, var(--fg, var(--color-text-1))); }
:root .cabinet-insights .ins-empty-actions { display: flex; flex-wrap: wrap; gap: 8px; }
:root .cabinet-insights .ins-empty-actions button { margin: 0; width: auto; }
@media (prefers-reduced-motion: reduce) { :root .cabinet-insights .viz-col { transition: none; } }
@media (forced-colors: active) {
  :root .cabinet-insights :is(.viz-seg, .viz-bar, .viz-key, .viz-dot, .viz-hover-dot) { forced-color-adjust: none; background: CanvasText; }
  :root .cabinet-insights .viz-line { stroke: CanvasText; }
}
@media print { :root .cabinet-insights .viz-tip, :root .cabinet-insights .viz-cross { display: none; } }

/* ───────────────────────────── 16 · Мобильная версия · цели, липкие полосы, клавиатура ─────────────────────────────
   Спека: TECH-TASK п. 3, DESIGN-QUALITY §6. Ширины 390 / 360 / 320 и масштаб 200 % (640 × 400 CSS px) на всех экранах:
     прокрутка вбок   нет (scrollWidth = ширине окна) — держат разделы 01–15, здесь не меняется
     цели             ≥ 44 × 44: у значка «?» (24 px) зона касания 44 × 44 (::after в разделе «Ясность») — теперь у
                      любого указателя; ссылка-строка (одна ссылка в абзаце: «Полный разбор…», почта поддержки) —
                      inline-block с полями 12 px (20 + 24 = 44); «Связанные страницы» и крошки — 44 px; «Наверх» в подвале
                      не уже 44 px на любом языке (min-width в разделе 08)
     поля             16 px — раздел 02 (iOS не увеличивает страницу при фокусе)
     липкие полосы    ≤ 15 % высоты экрана вместе: на низком экране (≤ 480 px — телефон боком, масштаб 200 %) шапка сайта,
                      шапка кабинета и плашка стартового режима не прилипают (плашка остаётся первой строкой страницы);
                      на телефоне (≤ 760 px) шапка cabinet.html (бренд + строка о суммах, 105 px) не прилипает — нижние
                      вкладки остаются; на ≤ 380 px плашка переносится в две строки и тоже не прилипает: вместе с нижней
                      панелью счёта было 16–19 % экрана, стало 9–11 %; на низком экране нижние панели кабинета — только
                      значки 44 px (подпись остаётся в aria-label кнопки), панель 56 px = 14 %
     клавиатура       пока фокус в поле ввода на узком экране, нижние панели и кнопка помощника скрыты: не закрывают поле
                      и кнопку действия под ним (у /account.html это уже делает body.vv-keyboard — правило то же)
     безопасные зоны  нижние панели и шапки берут env(safe-area-inset-*) в своих разделах; страницы без viewport-fit=cover
                      браузер сам держит внутри безопасной зоны
   Специфичность: правила страниц вида body.cabinet-v21 .mobile-tabs (0,2,1) — поэтому префикс html:root body (0,2,2). */
:root :is(.faq-more, .link-row) > a { display: inline-block; padding-block: 12px; }
/* «Связанные страницы» языковых копий (208 страниц): ссылка — строка списка высотой 44 px. */
:root .seo-related a { display: inline-flex; align-items: center; min-height: 44px; }
/* Крошки: короткое «Home» / «Գլխավոր» — не уже 44 px. */
:root .breadcrumbs li > a { display: inline-flex; align-items: center; justify-content: center; min-width: 44px; min-height: 44px; }
@media (max-height: 480px) {
  html:root body :is(.site-header, .cabinet-topbar) { position: relative; top: auto; }
  html:root body :is(.cabinet-bottom-nav, .mobile-tabs) { min-height: 0; }
  html:root body :is(.cabinet-bottom-nav button, .mobile-tabs :is(a, button)) { grid-template-rows: 22px; align-content: center; min-height: 44px; padding-block: 11px; }
  html:root body :is(.cabinet-bottom-nav button, .mobile-tabs :is(a, button)) > span {
    position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap;
  }
}
@media (max-width: 760px) {
  html:root body .cabinet-topbar { position: relative; top: auto; }
}
@media (max-width: 380px) {
  /* «Криптокошелёк» / «Калькулятор сценариев» на 320 px наезжали друг на друга: длинное слово переносится внутри ячейки. */
  html:root body :is(.mobile-tabs :is(a, button), .cabinet-bottom-nav button) > span { overflow-wrap: anywhere; hyphens: auto; }
}
@media (max-width: 760px) {
  html:root body:has(:is(input:not([type=checkbox], [type=radio], [type=range], [type=button], [type=submit], [type=reset]), textarea, select):focus) :is(.cabinet-bottom-nav, .mobile-tabs, #assistant-launcher) { visibility: hidden; }
}

/* ───────────────────────────── 17 · Раскрытие · знак и единый вид ─────────────────────────────
   Спека: финальный проход, раздел B (B3, B4, B6) — docs/design-audit/screens/final-comp-content.md, DESIGN-QUALITY §5, §7, §8.
   Знак раскрытия — шеврон 16 одной системы иконок (Lucide chevron-down: viewBox 24, линия 1.5, round). Он рисуется маской
   по --disclosure-chevron цветом текста (currentColor), поэтому JS-разметке (ops-charts.js, cabinet-insights.js, пульт) не
   нужен свой <svg>. После текста подписи, промежуток 8; у открытого раскрытия повёрнут на 180° за 150 мс ease-out
   (reduced-motion — без движения). Родной треугольник браузера скрыт (list-style none, ::-webkit-details-marker).
     таблица значений  .viz-table (счёт, пульт, владелец) · .chart-values (симулятор, калькулятор) · .market-values (рынок):
                       подпись-действие 14/20 вес 500 --text-2, цель 44; наведение — цвет текста 1 и черта 1 px снизу;
                       фокус 2 px --color-focus. Раньше — простой текст без знака, в симуляторе — шеврон вправо перед
                       текстом, на рынке — «+» 20 с подчёркнутой подписью: три вида одного действия.
     раскрытия экранов .days-help · .dash-detail · .help-item · .plans-compare-fold · .mechanics-card · .p5-report-spec (счёт),
                       .gc-steps «Что сделать, чтобы начать» и .cabinet-epochs-formula «Как считается распределение цикла»
                       («Обзор»; финал · остатки, п. 7: были без знака в Chrome и без снятия маркера WebKit),
                       «Уведомления кабинета» в настройках (details с #journey-inbox, без класса; :where — без веса),
                       .metrics-explanation · .gap-details (пульт) и класс .ds-disclosure на <details> для новых мест:
                       вид подписи остаётся экрана, вместо родного «▶» — тот же шеврон после текста.
   FAQ, подвал, меню, «Для проверяющих» — свои знаки (13, 08, 07) и сюда не входят. */
:root { --disclosure-chevron: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='black' stroke-width='1.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E"); }
:root :is(.viz-table, .chart-values, .market-values, .ds-disclosure, .days-help, .dash-detail, .help-item, .plans-compare-fold, .mechanics-card, .p5-report-spec, .gc-steps, .cabinet-epochs-formula, .metrics-explanation, .gap-details, :where(:has(> #journey-inbox))) > summary {
  display: flex;
  align-items: center;
  gap: 8px;
  list-style: none;
  cursor: pointer;
}
:root :is(.viz-table, .chart-values, .market-values, .ds-disclosure, .days-help, .dash-detail, .help-item, .plans-compare-fold, .mechanics-card, .p5-report-spec, .gc-steps, .cabinet-epochs-formula, .metrics-explanation, .gap-details, :where(:has(> #journey-inbox))) > summary::-webkit-details-marker { display: none; }
:root :is(.viz-table, .chart-values, .market-values, .ds-disclosure, .days-help, .dash-detail, .help-item, .plans-compare-fold, .mechanics-card, .p5-report-spec, .gc-steps, .cabinet-epochs-formula, .metrics-explanation, .gap-details, :where(:has(> #journey-inbox))) > summary::after {
  content: "";
  flex: none;
  width: 16px;
  height: 16px;
  background-color: currentColor;
  -webkit-mask: var(--disclosure-chevron) center / 16px 16px no-repeat;
  mask: var(--disclosure-chevron) center / 16px 16px no-repeat;
  transition: rotate 150ms ease-out;
}
:root :is(.viz-table, .chart-values, .market-values, .ds-disclosure, .days-help, .dash-detail, .help-item, .plans-compare-fold, .mechanics-card, .p5-report-spec, .gc-steps, .cabinet-epochs-formula, .metrics-explanation, .gap-details, :where(:has(> #journey-inbox)))[open] > summary::after { rotate: 180deg; }

/* Таблица значений — подпись-действие. В документе (.trust-page) правило карточки-раскрытия 13 той же специфичности
   стоит выше — это правило идёт позже и перекрывает его для .market-values. */
:root :is(.viz-table, .chart-values, .market-values) > summary,
:root :is(.trust-page, .v36-faq) details.market-values > summary {
  box-sizing: border-box;
  display: inline-flex;
  justify-content: flex-start;
  width: auto;
  max-width: 100%;
  min-height: 44px;
  margin: 0;
  padding: 0;
  border-radius: 4px;
  color: var(--text-2, var(--color-text-2));
  font-size: 14px;
  line-height: 20px;
  font-weight: 500;
  text-decoration: none;
  transition: color 150ms ease-out;
}
:root :is(.viz-table, .chart-values, .market-values)[open] > summary { color: var(--text-1, var(--bone, var(--color-text-1))); }
@media (hover: hover) {
  :root :is(.viz-table, .chart-values, .market-values) > summary:hover {
    color: var(--text-1, var(--bone, var(--color-text-1)));
    text-decoration: underline;
    text-decoration-thickness: 1px;
    text-decoration-color: var(--rule-strong, var(--color-rule-strong));
    text-underline-offset: 4px;
  }
}
:root :is(.viz-table, .chart-values, .market-values) > summary:focus-visible {
  outline: 2px solid var(--focus, var(--color-focus));
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  :root :is(.viz-table, .chart-values, .market-values, .ds-disclosure, .days-help, .dash-detail, .help-item, .plans-compare-fold, .mechanics-card, .p5-report-spec, .gc-steps, .cabinet-epochs-formula, .metrics-explanation, .gap-details, :where(:has(> #journey-inbox))) > summary::after { transition: none; }
  :root :is(.viz-table, .chart-values, .market-values) > summary { transition: none; }
}
@media (forced-colors: active) {
  :root :is(.viz-table, .chart-values, .market-values, .ds-disclosure, .days-help, .dash-detail, .help-item, .plans-compare-fold, .mechanics-card, .p5-report-spec, .gc-steps, .cabinet-epochs-formula, .metrics-explanation, .gap-details, :where(:has(> #journey-inbox))) > summary::after { background-color: CanvasText; }
}

/* Программный фокус на заголовке (h2[tabindex="-1"] помощника, карточки дела пульта) — без рамки у текста: рамка — только
   при фокусе с клавиатуры (:focus-visible). Финал B6. */
:root [tabindex="-1"]:focus:not(:focus-visible) { outline: none; }

/* ───────────────────────────── Помощник · кнопка и панель ─────────────────────────────
   Спека: .claude/design-run/ASSISTANT-TASK.md, DESIGN-QUALITY §1, §5, §7. Скрипт — dist/assistant.js.
   Кнопка — компонент 01 (вторичная, 44 px) в правом нижнем углу: цвет — крючками --button-*, без копии
   кнопки. Над нижними табами кабинета (.cabinet-bottom-nav, .mobile-tabs) её поднимает --assistant-bottom,
   над подвалом — --assistant-lift (свойство translate: transform кнопки 01 сбрасывается на наведении).
   Пока открыто окно страницы (06), кнопка не видна. После закрытия панели — компактная, только иконка.
   Окно ≤ 900 px или ниже 500 px (полировка 7.1, финал B2 — масштаб 200 %): кнопка круглая --assistant-launcher-size (48) —
   иконка 24, имя в aria-label;
   за подвалом не едет, вместо этого корень помощника в конце body держит место высотой кнопки + 16 —
   последняя строка страницы прокручивается выше кнопки, а не остаётся под ней.
   Панель — окно 06 без подложки на десктопе (400 px, справа снизу, не выше видимой области − 96 px),
   на телефоне ≤ 600 px — нижний лист во всю ширину с подложкой 60 %. Сообщения: ответ — текст на фоне
   панели, вопрос посетителя — плашка с подмесом 8 %. Стартовый режим назван один раз — строкой подвала
   .assistant-note (полировка 7.4). Движение §7: панель 200 мс ease-out (подъём 8 px,
   лист — 16 px), новое сообщение 150 мс; при reduce и паузе движения — только проявление. */
:root .assistant-root {
  --assistant-bg: var(--modal-bg, var(--card-bg, var(--surface, var(--color-surface))));
  --assistant-fg: var(--modal-fg, var(--card-fg, var(--bone, var(--color-text-1))));
  --assistant-muted: var(--modal-muted, var(--card-muted, var(--text-2, var(--color-text-2))));
  --assistant-border: var(--modal-border, var(--card-border-strong, var(--rule-strong, var(--color-rule-strong))));
  --assistant-rule: var(--modal-border, var(--card-border, var(--rule, var(--color-rule))));
  --assistant-focus: var(--modal-focus, var(--focus, var(--gold, var(--color-focus))));
  --assistant-launcher-size: 48px;
}
:root .assistant-sr {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
  border: 0;
}
:root .assistant-icon { flex: none; display: block; }

/* Кнопка: вторичная 01 на непрозрачном фоне панели — читается поверх любого содержимого. */
:root .assistant-root .assistant-launcher {
  --button-bg: var(--assistant-bg);
  --button-fg: var(--assistant-fg);
  --button-border: var(--assistant-border);
  position: fixed;
  z-index: 30;
  inset-inline-end: 24px;
  bottom: var(--assistant-bottom, calc(24px + env(safe-area-inset-bottom)));
  translate: 0 calc(-1 * var(--assistant-lift, 0px));
  gap: 8px;
  padding: 0 16px 0 12px;
  font-size: 14px;
}
:root .assistant-root .assistant-launcher[hidden] { display: none; }
:root .assistant-root .assistant-launcher.is-compact { width: 44px; padding: 0; }
:root .assistant-root .assistant-launcher.is-compact .assistant-launcher-label {
  position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}
:root:has(:is(dialog.demo-dialog, dialog#action-dialog)[open], .modal-bg.open) .assistant-launcher { visibility: hidden; }

/* Панель. */
:root .assistant-panel {
  position: fixed;
  z-index: 70;
  inset-inline-end: 24px;
  bottom: var(--assistant-bottom, calc(24px + env(safe-area-inset-bottom)));
  box-sizing: border-box;
  display: flex;
  flex-direction: column;
  width: min(400px, calc(100vw - 48px));
  max-height: min(640px, calc(100dvh - var(--assistant-bottom, 24px) - 96px));
  margin: 0;
  padding: 0;
  border: 1px solid var(--assistant-border);
  border-radius: 16px;
  background: var(--assistant-bg);
  color: var(--assistant-fg);
  font-family: inherit;
  font-size: 15px;
  font-weight: 400;
  line-height: 24px;
  letter-spacing: 0;
  text-align: start;
  text-transform: none;
  box-shadow: none;
  overflow: hidden;
}
:root .assistant-panel[hidden], :root .assistant-scrim[hidden] { display: none; }
:root .assistant-panel :is(p, h2) { margin: 0; }
:root .assistant-head {
  display: flex;
  flex: none;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 12px 12px 24px;
  border-bottom: 1px solid var(--assistant-rule);
}
:root .assistant-panel .assistant-title {
  font-family: inherit;
  font-size: 20px;
  font-weight: 600;
  line-height: 28px;
  letter-spacing: 0;
  text-transform: none;
  color: var(--assistant-fg);
  overflow-wrap: break-word;
}
:root .assistant-title:focus { outline: none; }
:root .assistant-title:focus-visible { outline: 2px solid var(--assistant-focus); outline-offset: 2px; border-radius: 4px; }
:root .assistant-close {
  box-sizing: border-box;
  display: grid;
  flex: none;
  place-items: center;
  width: 44px;
  height: 44px;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 10px;
  background: transparent;
  color: var(--assistant-muted);
  box-shadow: none;
  cursor: pointer;
  -webkit-tap-highlight-color: transparent;
  transition: background-color 150ms ease-out, color 150ms ease-out;
}
@media (hover: hover) {
  :root .assistant-close:hover { background-color: color-mix(in srgb, var(--assistant-bg), var(--assistant-fg) 6%); color: var(--assistant-fg); }
}
:root .assistant-close:focus-visible { outline: 2px solid var(--assistant-focus); outline-offset: 2px; }

:root .assistant-body {
  display: grid;
  flex: 1 1 auto;
  align-content: start;
  gap: 24px;
  min-height: 0;
  padding: 24px;
  overflow: auto;
  overscroll-behavior: contain;
}
:root .assistant-log { display: grid; gap: 16px; }
:root .assistant-msg { display: grid; gap: 8px; min-width: 0; }
:root .assistant-msg .assistant-text { white-space: pre-line; overflow-wrap: anywhere; }
:root .assistant-msg.is-user {
  justify-self: end;
  max-width: 85%;
  padding: 8px 12px;
  border-radius: 12px 12px 4px 12px;
  background: color-mix(in srgb, var(--assistant-bg), var(--assistant-fg) 8%);
}
:root .assistant-panel .assistant-source { font-size: 12px; line-height: 16px; color: var(--assistant-muted); }
:root .assistant-action { display: grid; justify-items: start; gap: 8px; margin-top: 4px; }
:root .assistant-panel :is(.assistant-act, .assistant-chip) {
  min-height: 44px;
  padding: 0 16px;
  font-size: 14px;
  text-align: start;
  white-space: normal;
}
:root .assistant-panel .assistant-act .assistant-icon { transition: translate 150ms ease-out; }
@media (hover: hover) {
  :root .assistant-panel .assistant-act:hover .assistant-icon { translate: 2px 0; }
}
:root .assistant-suggest { display: grid; gap: 8px; }
:root .assistant-panel .assistant-suggest-title { font-size: 13px; font-weight: 600; line-height: 20px; color: var(--assistant-muted); }
:root .assistant-chips { display: flex; flex-wrap: wrap; gap: 8px; }

:root .assistant-panel .assistant-status {
  flex: none;
  min-height: 20px;
  padding: 0 24px 8px;
  font-size: 13px;
  line-height: 20px;
  color: var(--assistant-muted);
}
:root .assistant-form {
  display: flex;
  flex: none;
  gap: 8px;
  margin: 0;
  padding: 12px 24px 0;
  border-top: 1px solid var(--assistant-rule);
}
:root .assistant-form .assistant-input { flex: 1 1 auto; width: auto; min-width: 0; margin: 0; }
:root .assistant-root .assistant-send { flex: none; width: 44px; padding: 0; }
:root .assistant-panel .assistant-note {
  flex: none;
  padding: 8px 24px 16px;
  font-size: 12px;
  line-height: 16px;
  color: var(--assistant-muted);
}

/* Узкое или низкое окно (телефон, планшет, масштаб 200 % — 720 × 450 CSS px): кнопка круглая 48, только иконка
   (финал B2). Пилюля 130 × 44 на 200 % закрывала h1 и лид главной, «Всего на счёте», «Сначала главное» FAQ. */
@media (max-width: 900px), (max-height: 500px) {
  /* Место под кнопкой в конце страницы: высота кнопки + 16 (плюс безопасная зона снизу). Корень — последний
     ребёнок body, поэтому место встаёт после подвала и над полем body под нижними табами кабинета. */
  :root .assistant-root { display: block; block-size: calc(var(--assistant-launcher-size) + 16px + env(safe-area-inset-bottom)); }
  /* Кнопка — круглая, только иконка: закрывает 48 × 48 вместо 130 × 44 и не уезжает за подвалом. */
  :root .assistant-root .assistant-launcher {
    inset-inline-end: max(16px, env(safe-area-inset-right));
    bottom: var(--assistant-bottom, calc(16px + env(safe-area-inset-bottom)));
    width: var(--assistant-launcher-size);
    height: var(--assistant-launcher-size);
    min-height: var(--assistant-launcher-size);
    padding: 0;
    border-radius: 50%;
    translate: none;
  }
  :root .assistant-root .assistant-launcher .assistant-launcher-label {
    position: absolute; width: 1px; height: 1px; margin: -1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
  }
  :root .assistant-root .assistant-launcher.is-compact { width: var(--assistant-launcher-size); }
  :root .assistant-root .assistant-launcher .assistant-icon { width: 24px; height: 24px; }
}

/* Телефон: нижний лист во всю ширину, подложка, отступ под домашний индикатор. */
@media (max-width: 600px) {
  :root .assistant-panel {
    inset-inline: 0;
    bottom: 0;
    z-index: 85;
    width: auto;
    max-height: calc(var(--vvh, 100dvh) - 48px);
    border-width: 1px 0 0;
    border-radius: 16px 16px 0 0;
  }
  :root .assistant-scrim { position: fixed; inset: 0; z-index: 84; background-color: var(--modal-scrim, rgb(6 7 11 / .6)); }
  :root .assistant-head { padding-inline-start: 20px; }
  :root .assistant-body { padding: 20px; }
  :root .assistant-panel .assistant-status { padding-inline: 20px; }
  :root .assistant-form { padding-inline: 20px; }
  :root .assistant-panel .assistant-note { padding: 8px 20px calc(16px + env(safe-area-inset-bottom)); }
  :root.assistant-locked { overflow: hidden; }
}

@keyframes assistant-enter { from { opacity: 0; transform: translateY(8px); } }
@keyframes assistant-sheet-enter { from { opacity: 0; transform: translateY(16px); } }
@keyframes assistant-fade { from { opacity: 0; } }
@keyframes assistant-msg-enter { from { opacity: 0; transform: translateY(4px); } }
@media (prefers-reduced-motion: no-preference) {
  :root .assistant-panel:not([hidden]) { animation: assistant-enter 200ms ease-out; }
  :root .assistant-scrim:not([hidden]) { animation: assistant-fade 200ms ease-out; }
  :root .assistant-msg { animation: assistant-msg-enter 150ms ease-out; }
}
@media (prefers-reduced-motion: no-preference) and (max-width: 600px) {
  :root .assistant-panel:not([hidden]) { animation-name: assistant-sheet-enter; }
}
@media (prefers-reduced-motion: reduce) {
  :root .assistant-panel:not([hidden]) { animation: assistant-fade 200ms ease-out; }
  :root .assistant-close, :root .assistant-panel .assistant-act .assistant-icon { transition: none; }
}
body[data-motion-pref="paused"] .assistant-panel:not([hidden]) { animation-name: assistant-fade; }
body[data-motion-pref="paused"] .assistant-msg { animation: none; }

@media (forced-colors: active) {
  :root .assistant-panel { border-color: CanvasText; }
  :root .assistant-close { border: 1px solid ButtonText; }
  :root .assistant-msg.is-user { border: 1px solid CanvasText; }
}
@media print {
  :root .assistant-root { display: none; }
}
