/* Замер 13.08.2026: в системе жили ДВА семейства серого сразу — tailwind
   `gray` (нейтральный) и `slate` (с синим подмесом). Подложки везде slate
   (#f8fafc, #e2e8f0, #0f172a и тёмные с синим), а текст half-and-half:
   --text-primary брал gray-50, --text-muted gray-400, --text-secondary при
   этом slate-300. На холодных подложках нейтральный серый читается чуть
   теплее соседнего — отсюда ощущение грязи без единого явного дефекта.
   97 литералов переведены в slate той же ступени. Сдвиг светлотно-
   нейтральный: у #9ca3af и #94a3b8 зелёный канал одинаковый (163), у
   #111827 и #0f172a — 24 против 23, поэтому контраст сдвинуться не может.
   Шкала --gray-* оставлена под своим именем: её верх (700/800/900) уже
   переопределён в собственные тёмные поверхности проекта. */
:root {
  /* Палитра-примитивы (по шкалам Tailwind), одинаковые в обеих темах.
     Заведены 24.09.2026, когда цвета-литералы tenant_portal.css и
     portal_base.css переводились на токены без изменения вида: у этих
     оттенков не было токена с тем же значением. Использовать там, где
     нужен именно этот оттенок в обеих темах; тема-зависимые роли — через
     шкалы success, danger, warning, info и gray. */
  --emerald-50: #ecfdf5;
  --emerald-900: #064e3b;
  --green-200: #bbf7d0;
  --green-500: #22c55e;
  --green-600: #16a34a;
  --red-200: #fecaca;
  --red-800: #991b1b;
  --blue-50: #eff6ff;
  --blue-200: #bfdbfe;
  --blue-500: #3b82f6;
  --blue-900: #1e3a8a;
  --orange-50: #fff7ed;
  --orange-700: #c2410c;
  --orange-900: #7c2d12;
  --indigo-100: #e0e7ff;
  --indigo-300: #a5b4fc;
  --indigo-600: #4f46e5;
  --indigo-700: #4338ca;
  --violet-600: #7c3aed;
  --purple-600: #9333ea;
  --slate-800: #1e293b;
  --emerald-500: #10b981;
  --blue-100: #dbeafe;
  --blue-800: #1e40af;
  --red-50: #fef2f2;
  --indigo-50: #eef2ff;
  --indigo-200: #c7d2fe;
  /* 26.09.2026 — вторая партия (unified-bundle, ds-components, admin_monitoring,
     user_settings, documents_review, login, accounting, meters). Tailwind
     «gray» (не slate) и старые серые литералы получили имена как есть. */
  --black: #000000;
  --gray-cool-200: #e5e7eb;
  --gray-cool-500: #6b7280;
  --gray-cool-800: #1f2937;
  --gray-legacy-222: #222222;
  --gray-legacy-444: #444444;
  --gray-legacy-666: #666666;
  --gray-legacy-999: #999999;
  --gray-legacy-e9: #e9ecef;
  --violet-200: #ddd6fe;
  --violet-300: #c4b5fd;
  --violet-700: #6d28d9;
  --violet-900: #5b21b6;
  --purple-400: #c084fc;
  --blue-600: #2563eb;
  --blue-700: #1d4ed8;
  --emerald-400: #34d399;
  --emerald-700: #047857;
  --emerald-800: #065f46;
  --teal-800: #115e59;
  --green-100: #dcfce7;
  --amber-50: #fffbeb;
  --amber-100: #fef3c7;
  --amber-300: #fcd34d;
  --red-100: #fee2e2;
  --cream-50: #fff8e1;
  --rose-50: #fff0f0;
  --bs-warning-bg: #fff3cd;
  --bs-warning-text: #856404;
  --bs-danger-bg: #f8d7da;
  --bs-danger-text: #721c24;
  --bs-success-bg: #d4edda;
  --bs-success-text: #155724;
  --gray-legacy-f8: #f8f9fa;
  --gray-legacy-f0: #f0f0f0;
  --gray-legacy-ee: #eeeeee;
  --gradient-indigo-a: #667eea;
  --gradient-purple-b: #764ba2;
  --yellow-600: #ca8a04;
  /* Именно `0px`, а не `0`. Значение подставляется в шесть мест через
     calc() и max() — `calc(0 + 1rem)` и `max(62px, 0)` невалидны, и
     браузер выбрасывает объявление целиком. Из-за этого палитра команд
     прилипала к верхней кромке экрана, а `scroll-margin-top` и липкие
     шапки на /properties и /contractors теряли отступ под шапку.
     16.08.2026 */
  --app-top-offset: 0px;
  /* Светлая тема - базовые цвета */
  --gray-0: #ffffff;
  --gray-50: #f8fafc;
  --gray-100: #f1f5f9;
  --gray-200: #e2e8f0;
  --gray-500: #64748b;
  /* Палитра 23.08.2026 (отчёт docs/redesign/101-palette-23-08.md):
     карточка и фон страницы были неразличимы (1,05), разделители — 1,23 к
     поверхности. Фон страницы опущен на ступень, разделители подняты до
     slate-300 — карточка читается заливкой, границей и тенью сразу. */
  --bg-primary: #eef2f7;
  --bg-secondary: #ffffff;
  --bg-tertiary: #e2e8f0;
  --text-secondary: #334155;
  --border-color: #cbd5e1;
  --border-color-subtle: #f1f5f9;
  /* --primary-color — семантический алиас бренда (= --primary-500).
       Канон P3: variant-14 влит в базовые light/dark токены. */
  --primary-50: #f8fafc;
  --primary-100: #e2e8f0;
  --primary-200: #e0e3ff;
  --primary-300: #cbd1ff;
  --primary-500: #64748b;
  --primary-500-rgb: 100, 116, 139;
  --primary-600: #475569;
  --primary-700: #334155;
  --primary-900: #0f172a;
  --surface-primary: #ffffff;
  --surface-secondary: #f8fafc;
  --surface-tertiary: #e2e8f0;
  /* Наведение почти не отвечало: 1,29 к белой карточке — строку под
     курсором приходилось искать глазами. Ступень ниже: 1,40. Активное
     состояние идёт следом, чтобы «нажато» отличалось от «под курсором».
     Токен ведёт и строку таблицы, и пункт меню, и плитку. 23.08.2026 */
  --surface-hover: #cfdbeb;
  --surface-active: #c2d0e3;
  --bg-inverse: var(--gray-900);
  --surface-inverse: var(--bg-inverse);
  /* Светлые ступени шкал заведены 12.08.2026: в тёмной теме красный
     --error-600 (#dc2626) и зелёный --success-700 (#15803d) дают на
     подложке карточки 3.7 и 3.42 — ниже нормы. Ступени 400 нужны как
     цвет текста и иконок в тёмной теме: 6.20 и 9.84.
     Мина: до этого правки ссылались на var(--error-400), которого не
     существовало, — объявление становилось недействительным и цвет
     молча наследовался от родителя (та же мина, что у плашки cookies). */
  --error-300: #fca5a5;
  --error-400: #f87171;
  --error-500: #ef4444;
  --error-600: #dc2626;
  --error-700: #b91c1c;
  --success-400: #4ade80;
  --nav-hover: var(--surface-hover);
  --focus-ring-color: #64748b;
  --focus-ring-color-rgb: 100, 116, 139;
  /* Было 0,45. Замер 17.08.2026: кольцо фокуса при такой прозрачности даёт
     1,56–1,94 к фону страницы при норме 3,0 — признак фокуса формально
     есть, а увидеть его нельзя. Тот же цвет без прозрачности: 4,55–4,76 в
     светлой теме и 5,71–7,09 в тёмной. Цвет остаётся серым: кольцо не
     должно спорить с акцентом. */
  --focus-ring-opacity: 1;
  --shadow-color-rgb: 0 0 0;
  --shadow-xs: 0 0 1px rgb(var(--shadow-color-rgb) / 0.04),
    0 1px 2px rgb(var(--shadow-color-rgb) / 0.04);
  --shadow-sm: 0 1px 2px 0 rgb(var(--shadow-color-rgb) / 0.05);
  --shadow: 0 1px 3px 0 rgb(var(--shadow-color-rgb) / 0.1),
    0 1px 2px -1px rgb(var(--shadow-color-rgb) / 0.1);
  --shadow-md: 0 4px 6px -1px rgb(var(--shadow-color-rgb) / 0.1),
    0 2px 4px -2px rgb(var(--shadow-color-rgb) / 0.1);
  --shadow-lg: 0 10px 15px -3px rgb(var(--shadow-color-rgb) / 0.1),
    0 4px 6px -4px rgb(var(--shadow-color-rgb) / 0.1);
  --shadow-xl: 0 20px 25px -5px rgb(var(--shadow-color-rgb) / 0.1),
    0 8px 10px -6px rgb(var(--shadow-color-rgb) / 0.1);
  --shadow-2xl: 0 25px 50px -12px rgb(var(--shadow-color-rgb) / 0.25);
  --card-shadow: var(--shadow-sm);
  --radius-base: 0.375rem;
  --radius-full: 9999px;
  --radius-xl: 0.625rem;
  --border-radius: var(--radius-base);
  --transition-normal: 250ms cubic-bezier(0.4, 0, 0.2, 1);
  --transition-slow: 350ms cubic-bezier(0.4, 0, 0.2, 1);
  --font-family-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-family-mono: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono",
    Consolas, "Courier New", monospace;
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.25rem;
  --font-size-2xl: 1.5rem;
  --font-size-3xl: 1.875rem;
  --font-size-4xl: 2.25rem;
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  /* Шкала межстрочного. Значения выбраны по замеру 13.08.2026, а не из
     головы: на десяти страницах отрисовано 12 разных отношений, из них
     несущих четыре — 1.60 (1355 узлов), 1.30 (509), 1.25 (290), 1.20 (203),
     1.40 (201), остальные единичный хвост. Прежние 1.25 / 1.5 / 1.75 были
     объявлены и применены ТРИ раза на весь проект — они не описывали
     систему, а спорили с ней.
     `line-height: 1` намеренно не входит в шкалу: у иконок и плашек
     коробка должна обнимать глиф. */
  --line-height-tight: 1.2;
  --line-height-snug: 1.35;
  --line-height-normal: 1.6;
  --line-height-relaxed: 1.75;
  --z-dropdown: 1000;
  --z-sticky: 1020;
  --z-fixed: 1030;
  /* Замер 12.08.2026 на /calendar: шкала z-index бралась бутстраповская
     (1000..1060), а собственный хром приложения живёт выше — back-to-top
     2000, app-menu 2100/2140, header-minimal 2160. Модалка календаря
     получала 1040 и уезжала ПОД шапку и под кнопку «наверх». Именно
     поэтому compat-слой прописывал `.modal { z-index: 2200 }` числом,
     мимо токена. Ступени модалки и выше подняты над хромом; --z-dropdown,
     --z-sticky и --z-fixed оставлены как были: им положено быть ниже
     шапки приложения. */
  --z-modal: 2200;
  --z-popover: 2250;
  --z-tooltip: 2260;
  --container-sm: 640px;
  --container-md: 768px;
  --container-lg: 1024px;
  --container-xl: 1280px;
  --container-2xl: 1536px;

  --space-1: 0.25rem;
  --space-1_5: 0.375rem;
  --space-2: 0.5rem;
  --space-3: 0.75rem;
  --space-4: 1rem;
  --space-5: 1.25rem;
  --space-6: 1.5rem;
  --space-8: 2rem;
  --space-10: 2.5rem;
  --space-12: 3rem;
  --space-16: 4rem;
  /* ── высота управляющих элементов: две ступени ──────────────────────
     Замер 17.08.2026. Одно и то же поле фильтра было шести разных
     размеров — по одному на страницу:

       «Документы» 34, «Контрагенты» 35, «Объекты» 34,
       «Финансы» 40, «Приборы» 40, кабинет 40,
       плюс контексты 30 (меню), 32 (панель кабинета, листалка),
       36 (`.rec-filters`) и 44 (поиск на «Финансах»).

     Кнопка — двух: 34 на «Документах», «Финансах», «Календаре» и в
     кабинете; 40 на «Приборах», «Контрагентах», «Объектах».

     Разнобой не был решением: базовый `.filter-control` высоту вообще не
     задаёт (её даёт паддинг), и каждая страница дописывала свою.

     Теперь ступеней две, и выбор между ними осознанный:
       `--control-h`     обычный размер, 40 px — удобен пальцу и мыши;
       `--control-h-sm`  плотный, 32 px — для панелей, где элементов
                         много и они вспомогательные (листалка, меню).
     Третьей ступени нет намеренно: 34, 35, 36 и 44 различались на
     глаз-два и ничего не выражали. */
  /* ── о порогах ──────────────────────────────────────────────────────
     В продукте 23 разных значения `max-width` в медиа-запросах и ДВЕ
     несовместимые договорённости о границе:

       «≤767 / ≥768»   6 и 8 правил
       «≤768 / ≥769»   20 и 3 правила

     Обе внутренне верны, но вместе означают, что на ширине ровно 768 px
     правила одной считают экран узким, а другой — широким. Замер
     17.08.2026 на четырёх страницах при 767, 768 и 769: видимой разницы
     в раскладке нет, то есть прямо сейчас это не дефект. Но любая
     будущая пара, написанная во второй договорённости рядом с первой,
     оставит дырку в один пиксель — а 768 это портретный планшет.

     Для нового кода: «≤767 / ≥768». Порог «список → карточки» — 860
     (канон в app-record.css). Старое не переписывал: 26 правок ради
     невидимого сейчас различия — плохой размен. */
  --control-h: 40px;
  --control-h-sm: 32px;

  --space-xs: var(--space-1);
  --space-sm: var(--space-2);
  --space-md: var(--space-3);
  --space-lg: var(--space-4);
  --space-xl: var(--space-6);
  --space-2xl: var(--space-8);
  --card-padding-sm: var(--space-lg);
  --card-padding-md: var(--space-xl);
  --card-padding-lg: var(--space-2xl);
  --button-height-xs: 1.75rem;
  --button-height-sm: 2.125rem;
  --button-height-md: 2.5rem;
  --button-height-lg: 2.875rem;
  --button-padding-y: var(--space-sm);
  --button-padding-x: var(--space-lg);
  --button-gap: var(--space-sm);
  --button-primary-bg: #7c3aed;
  --button-primary-bg-hover: #6d28d9;
  --button-primary-bg-active: #5b21b6;
  /* Акцент интерактивных состояний: «включено», отметка чекбокса, активный
     сегмент. Отдельно от --primary-color: тот в тёмной теме серо-голубой,
     потому что 53 правила используют его как цвет ТЕКСТА, где фиолетовый
     не проходит по контрасту. Измерено 11.08.2026, docs/ui-audit.md. */
  --accent-interactive: #7c3aed;
  /* Акцент КАК ТЕКСТ. Отдельно от --accent-interactive сознательно: тот
     служит фоном кнопки, где на нём стоит белый, и осветлять его нельзя —
     белое на светло-фиолетовом перестанет читаться. А акцентный текст на
     тёмном фоне, наоборот, обязан быть светлее: замер 13.08.2026 показал
     #9333ea на #10161d = 3.38 при норме 4.5. Пара значений ниже: 5.40
     на светлой, 7.62 на тёмной. */
  --accent-text: #7c3aed;
  /* Статусный цвет КАК ТЕКСТ. Та же причина, что у --accent-text: цвета
     `--button-danger-bg`, `--warning-500` и прочие служат ФОНОМ, на них
     стоит белый, и осветлять их нельзя. Текст же на тёмной подложке обязан
     быть светлее. Замер 13.08.2026 на /admin/invitations/manage в тёмной
     теме: .btn-outline-danger 3.77, .status-pending 3.69 при норме 4.5. */
  --danger-text: #dc2626;
  /* 15.09.2026. Семья контурных кнопок была неполной: `.btn-outline-warning`,
     `.btn-outline-success` и глобальный `.btn-outline-info` правил не имели, а
     разметка и documents_review.js их ставят. Цвет текста выбран замером
     контраста на поверхности страницы, как в своё время `--danger-text`:
     светлая — warning 700 (5.02), success 600 (7.68);
     тёмная — warning 500 (7.98), success 400 (9.84).
     Ступени различаются по темам, одной шкалой обе не закрыть.
     У info шкала `--info-*` СЕРАЯ (600 = #475569, ровно как `--primary-*`, см.
     [ui-accent-token-split]) — контурная кнопка «инфо» на ней не отличалась бы
     от secondary. Берём `--link-color`: это фирменный фиолетовый (5.70 и 6.49),
     и ровно им documents_review.css уже красит `.btn.btn-outline-info`. */
  --warning-text: var(--warning-700);
  --success-text: var(--success-600);
  --info-text: var(--link-color);
  /* 17.08.2026: сплошная красная подложка под БЕЛЫМ текстом. Утилита
     `.bg-danger` брала `--danger-500`, а это приглушённая заливка: белый
     на #cb968e даёт 2.53 в светлой теме и 3.60 на #ef4444 в тёмной —
     страница «Ошибка», тост приглашений и два бейджа не проходили норму
     ни в одной теме. Тёмный конец настоящей красной шкалы даёт 6.2–6.5. */
  --surface-danger-solid: #b91c1c;
  /* Плашка стоит не на белом, а на собственной подложке в 20 % своего же
     цвета. Замер 13.08.2026 по скомпонованному фону: #d97706 на #fef2d3
     даёт 2.86, #dc2626 на #fcdada — 3.72, #2563eb на #d8e6fd — 4.10.
     Взяты значения на тон-два темнее: 6.37 / 4.99 / 5.32.
     Именованные токены здесь не годятся: `--info-700` в этом проекте
     равен #334155, то есть серому. */
  --status-warning-text: #92400e;
  --status-error-text: var(--error-700, #b91c1c);
  --status-info-text: #1d4ed8;
  --status-neutral-text: #475569;
  --status-success-text: #166534;

  /* ───── имена, которые уже использовались, но нигде не объявлялись ─────

     Обход 17.08.2026: шестнадцать имён вида `var(--нет-такого, литерал)`.
     Такая запись не падает и ничего не сообщает — просто всегда берёт
     запасной литерал, а он один на обе темы. Так «всего приборов» на
     `/meters/` оказалось белым по белому: `var(--surface, #fff)` при
     отсутствующем `--surface` давало белую плитку, а число наследовало
     белый `--text-primary`.

     Объявляем недостающие имена парами (светлая тема здесь, тёмная —
     в блоке `html[data-theme="dark"]`), чтобы литералы перестали
     работать вовсе. */
  --text-tertiary: #64748b;
  --brand-600: var(--accent-interactive, #7c3aed);
  --danger-800: #991b1b;
  --success-800: #065f46;
  --status-error-bg: #fef2f2;
  --status-warning-bg: #fffbeb;
  --status-success-bg: #f0fdf4;
  --border-subtle: var(--border-color);
  --color-bg-soft: rgba(17, 24, 39, 0.03);
  --info-bg: rgba(37, 99, 235, 0.1);
  --color-warn: #b45309;
  /* «В работе» — четвёртое состояние рядом с успехом, предупреждением
     и ошибкой. Замер 13.08.2026: синий у `processing` жил литералом
     rgba(59,130,246,.9) и числился «цветом вне палитры». Он не вне
     палитры — он просто не был объявлен. Отдельно от --category-1
     (того же оттенка) СОЗНАТЕЛЬНО: вид документа и состояние обработки
     не должны съезжаться в один токен, даже если сегодня похожи. */
  --status-progress: #3b82f6;
  --button-primary-text: #ffffff;
  --button-primary-border: #7c3aed;
  --button-primary-shadow: 0 10px 18px rgba(124, 58, 237, 0.24);
  --button-secondary-bg: #ffffff;
  /* #f8fafc давал 1,05 к белой кнопке — наведение на вторичную кнопку
     не читалось вовсе. 23.08.2026 */
  --button-secondary-bg-hover: var(--surface-tertiary);
  --button-secondary-text: #1e293b;
  --button-secondary-border: #475569;
  --button-secondary-border-hover: #334155;
  --input-border: #64748b;
  --input-border-hover: #334155;
  --form-check-border: #64748b;
  --button-link-text: var(--primary-700);
  --button-link-text-hover: var(--primary-900);
  --button-ghost-bg: transparent;
  --button-ghost-bg-hover: rgba(15, 23, 42, 0.06);
  --button-ghost-text: var(--text-secondary);
  --button-ghost-border: transparent;
  --button-danger-bg: #dc2626;
  --button-danger-bg-hover: #b91c1c;
  --button-danger-text: #ffffff;
  --button-danger-border: #dc2626;
  --button-destructive-bg: var(--button-danger-bg);
  --button-destructive-border: var(--button-danger-border);
  --button-destructive-text: var(--button-danger-text);
  --app-header-bar-border: var(--border-color);
  --app-menu-toggle-color: #475569;
  --app-menu-toggle-hover-color: #1e293b;
  --quick-nav-item-color: #1e293b;
  --header-minimal-shell-border: #cbd5e1;
  --workspace-theme-btn-shadow: none;
  --workspace-theme-btn-hover-shadow: none;
  --workspace-action-link-bg: transparent;
  --workspace-action-link-border: transparent;
  --workspace-action-link-text: #1e293b;
  --workspace-action-link-active-bg: rgba(var(--focus-ring-color-rgb), 0.12);
  --workspace-action-link-active-border: var(--border-color-strong);
  --workspace-action-link-active-text: var(--primary-color);
  --filter-control-color: var(--text-primary);
  --text-highlight-color: var(--primary-color);
  --heading-primary-color: #0f172a;
  --heading-secondary-color: #1e293b;
  --text-secondary-strong: #0f172a;
  --button-base-border-color: var(--border-color);
  --sidebar-surface-bg: var(--bg-secondary);
  --sidebar-surface-border: var(--border-color);
  --sidebar-nav-bg: var(--bg-secondary);
  --sidebar-nav-text: var(--text-secondary);
  /* Замысел «тот же шаг шкалы в фирменном тоне» (см. комментарий в тёмном
     блоке) здесь не выполнялся: --primary-* — СЕРАЯ шкала (память
     ui-primary-scale-is-grey), и активный пункт в светлой теме был серым
     при фиолетовом в тёмной. Выровнено: purple-100/800/200; текст #5b21b6
     на #ede9fe — 7,57. 23.08.2026 */
  --sidebar-nav-active-bg: #ede9fe;
  --sidebar-nav-active-text: #5b21b6;
  --sidebar-nav-active-border: #ddd6fe;
  --modal-close-hover-bg: #f1f5f9;
  --modal-close-hover-border: #cbd5e1;
  --modal-close-hover-text: #0f172a;
  --entity-section-border: var(--border-color-strong);
  --entity-section-bg: var(--surface-tertiary);
  --entity-section-title-color: var(--text-secondary);
  --entity-label-color: var(--text-secondary);
  --entity-field-bg: var(--surface-primary);
  --entity-field-border: var(--input-border);
  --entity-field-text: var(--text-primary);
  --entity-field-placeholder: var(--text-muted);
  --entity-field-focus-border: var(--input-focus, var(--focus-ring-color));
  --entity-field-focus-shadow: 0 0 0 3px rgba(var(--focus-ring-color-rgb), 0.22);
  --page-accent-gradient: transparent;
  --panel-muted-bg: var(--surface-secondary);
  --panel-muted-border: var(--border-color);
  --panel-muted-shadow: var(--shadow-sm);
  --entity-modal-footer-bg: var(--glass-bg);
  --entity-modal-footer-border: var(--border-color);
  /* Значок-предупреждение окна «Сохранить изменения?» (ds-confirm-icon).
     Одним токеном обе темы не закрыть: --warning-600 на --warning-100 даёт 2.86
     в светлой и 2.85 в тёмной (замер в браузере) — ниже 3:1 для графики.
     Поэтому передний план задан по темам: 700 в светлой (4.51), 500 в тёмной. */
  --confirm-icon-bg: var(--warning-100);
  --confirm-icon-fg: var(--warning-700);
  /* Текст в `.alert-error`. Отдельно от `--danger-text`, потому что фон у
     алерта ТОНИРОВАННЫЙ, а не поверхность страницы, и цифры выходят другие.
     Замер: `--danger-700` даёт 5.55 в светлой и 2.37 в тёмной, `--danger-text`
     — 4.14 и 5.54. Одним значением обе темы не закрыть, берём лучшее в каждой. */
  --alert-error-text: var(--danger-700);
  --entity-modal-esc-color: #64748b;
  --skeleton-shimmer: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.4) 50%,
    transparent 100%
  );
  --footer-link-color: #0f172a;
  --properties-floating-menu-bg: var(--color-bg-card);
  --properties-floating-menu-border: var(--color-border);
  --properties-floating-menu-shadow: 0 18px 44px rgba(15, 23, 42, 0.18),
    0 3px 12px rgba(15, 23, 42, 0.08);
  --properties-floating-menu-header-text: #667085;
  --properties-floating-menu-header-border: rgba(226, 232, 240, 0.9);
  --properties-floating-menu-item-text: #334155;
  --properties-floating-menu-item-hover-bg: linear-gradient(
    135deg,
    rgba(99, 102, 241, 0.12),
    rgba(59, 130, 246, 0.08)
  );
  --properties-floating-menu-item-hover-text: #0f172a;
  --properties-confirm-popup-bg: #ffffff;
  --properties-confirm-popup-border: #e2e8f0;
  --properties-confirm-text-color: #334155;
  --properties-archive-active-text: var(--primary-color);
  --properties-archive-active-shadow: 0 0 0 1px rgba(var(--primary-rgb), 0.2),
    0 8px 18px rgba(var(--primary-rgb), 0.16);
  --properties-page-border-top: #e2e8f0;
  --properties-table-row-even-bg: #f8fafc;
  --properties-table-row-hover-bg: #f1f5f9;
  --properties-table-row-border: #e2e8f0;
  /* Шесть токенов --property-status-*-accent удалены 23.08.2026: они
     описывали РУЧНОЙ статус объекта, а его сняли ещё 18.08 — состояние
     объекта стало следствием договора ([[property-card-lease-and-prolong]]).
     Ни одной ссылки на них не осталось ни в CSS, ни в JS, ни в шаблонах:
     список объектов кодирует срок полосой группы (properties.css:1718).
     Если статус вернётся, вернуть и токены — но не держать палитру под
     сущность, которой в продукте нет. */
  --property-type-apartment-hover-bg: rgba(59, 130, 246, 0.05);
  --property-type-house-hover-bg: rgba(16, 185, 129, 0.05);
  --property-type-commercial-hover-bg: rgba(245, 158, 11, 0.05);
  --properties-font-address-color: #475569;
  --property-party-cell-text: #334155;
  --text-table-primary-color: #0f172a;
  --text-table-secondary-color: #475569;
  --secondary-50: #f8fafc;
  --secondary-100: #f1f5f9;
  --secondary-500: #64748b;
  --secondary-600: #475569;
  --secondary-700: #334155;
  --secondary-900: #0f172a;
  --border-light: var(--border-color-subtle);
  --cadastral-progress-bg: var(--surface-tertiary);
  --cadastral-progress-bar-track: rgba(0, 0, 0, 0.08);
  --cadastral-progress-details-bg: var(--surface-secondary);
  --property-modal-rent-wrap-border: var(--border-color-strong);
  --property-modal-rent-wrap-bg: var(--surface-secondary);
  --property-modal-progress-shell-border: var(--border-color-strong);
  --property-modal-progress-shell-bg: var(--surface-secondary);
  --property-modal-progress-title-color: var(--text-primary);
  --property-modal-progress-log-color: var(--text-secondary);
  --property-modal-details-log-border: var(--border-color);
  --property-modal-details-log-bg: var(--surface-primary);
  --property-modal-details-log-color: var(--text-secondary);
  --property-modal-details-toggle-bg: var(--surface-primary);
  --property-modal-details-toggle-border: var(--border-color-strong);
  --property-modal-details-toggle-color: var(--text-secondary);
  --property-modal-details-toggle-hover-bg: var(--surface-tertiary);
  --property-modal-details-toggle-hover-color: var(--text-primary);
  --property-modal-cancel-bg: rgba(var(--danger-rgb), 0.1);
  --property-modal-cancel-border: rgba(var(--danger-rgb), 0.28);
  --property-modal-cancel-color: var(--danger-500);
  --property-modal-rent-data-hint-border: var(--border-color);
  --property-modal-rent-data-hint-bg: rgba(var(--primary-rgb), 0.08);
  --property-modal-rent-data-hint-color: var(--text-secondary);
  --property-modal-rights-toolbar-border: var(--border-color);
  --property-modal-rights-note-border: var(--border-color-strong);
  --property-modal-rights-note-bg: var(--surface-secondary);
  --property-modal-rights-note-color: var(--text-muted);
  --property-modal-rights-empty-border: var(--border-color-strong);
  --property-modal-rights-empty-bg: var(--surface-secondary);
  --property-modal-rights-empty-color: var(--text-secondary);
  --property-modal-rights-row-border: var(--border-color-strong);
  --property-modal-rights-row-bg: var(--surface-secondary);
  --property-modal-rights-row-label-color: var(--text-primary);
  --property-modal-rights-field-border: var(--input-border);
  --property-modal-rights-field-bg: var(--surface-primary);
  --property-modal-rights-field-color: var(--text-primary);
  --contractor-field-changed-bg: rgba(180, 188, 252, 0.06);
  --table-row-border-contrast: var(--gray-400);
  /* Замер 13.08.2026 внутри раскрытой модалки контрагента: #64748b даёт
     3.86 на белом при кегле 12 — норма 4.5. На тон темнее: 5.72. */
  --contractor-bank-caption-color: #475569;
  --contractor-bank-row-border: #dbe4ee;
  --contractor-bank-row-bg: #ffffff;
  --contractor-bank-header-border: #eef2f7;
  --contractor-bank-title-color: #334155;
  --contractor-bank-index-border: #dbe4ee;
  --contractor-bank-index-bg: #f8fafc;
  --contractor-bank-index-color: #64748b;
  --contractor-row-selected-bg: rgba(37, 99, 235, 0.07);

  /* Дополнительные переменные для совместимости */
  --surface-secondary: #f8fafc;
  --gray-100: #f1f5f9;
  --gray-200: #e2e8f0;
  --gray-700: #334155;
  --gray-800: #1e293b;
  --primary-400: #9ea8fb;
  --primary-rgb: 180, 188, 252;
  --warning-rgb: 245, 158, 11;

  /* Алиасы для старой системы переменных (для совместимости) */
  --color-secondary: var(--primary-600);
  --color-accent-light: var(--primary-400);
  --color-accent-dark: var(--primary-700);
  --color-bg-primary: var(--bg-primary);
  --color-bg-secondary: var(--bg-secondary);

  --color-text-main: var(--text-primary);
  --color-text-muted: var(--text-muted);
  --color-border: var(--border-color);
  --color-bg-card: var(--surface-primary);
  --color-bg-body: var(--surface-secondary);
  --color-bg-input: var(--input-bg);
  --color-bg-hover: var(--surface-hover);
  --hover-bg: var(--surface-hover);
  --primary-dark: var(--primary-700);
  --warning-bg: var(--warning-50);

  /* Цвета для темной темы */
  --dark-gray-800: #151c25;
  --dark-gray-900: #10161d;
  --dark-gray-700: #1a2430;
  --dark-gray-600: #475569;
  --dark-gray-400: #94a3b8;
  --dark-gray-300: #cbd5e1;
  --dark-gray-0: #f8fafc;
  --dark-bg-primary: #10161d;
  --dark-bg-secondary: #151c25;
  --dark-bg-tertiary: #1a2430;
  --dark-text-primary: #f8fafc;
  --dark-text-secondary: #cbd5e1;
  --dark-border-color: #1f2a36;
  --dark-border-color-subtle: #121922;
  --dark-primary-color: #94a3b8;
  --dark-glass-bg: rgba(15, 23, 42, 0.6);
  --dark-glass-border: rgba(148, 163, 184, 0.2);
  --dark-surface-primary: #151c25;
  --dark-surface-secondary: #10161d;
  /* Пара к светлой правке: наведение давало 1,11 к карточке. 23.08.2026 */
  --dark-surface-hover: #2c384a;
  --dark-surface-tertiary: #1f2a36;
  --dark-surface-active: #364560;
  --dark-focus-ring-color: #94a3b8;
  --dark-focus-ring-color-rgb: 148, 163, 184;
  --dark-shadow-color-rgb: 0 0 0;

  /* Цвета статусов для светлой темы */
  --success-50: #f0fdf4;
  --success-100: #dcfce7;
  --danger-100: #fee2e2;
  --warning-50: #fffbeb;
  --warning-100: #fef3c7;
  --warning-500: #f59e0b;
  --warning-600: #d97706;
  --warning-700: #b45309;
  --info-50: #f8fafc;
  --info-100: #dbeafe;
  --info-500: #64748b;
  --info-600: #475569;
  --info-700: #334155;

  /* Цвета статусов для темной темы */
  --dark-success-50: #052e16;
  --dark-success-100: #14532d;
  --dark-success-500: #15803d;
  --dark-success-600: #166534;
  --dark-success-700: #15803d;
  --dark-danger-50: #450a0a;
  --dark-danger-100: #7f1d1d;
  --dark-danger-500: #ef4444;
  --dark-danger-600: #dc2626;
  --dark-danger-700: #b91c1c;
  --dark-warning-50: #451a03;
  --dark-warning-100: #78350f;
  --dark-warning-500: #f59e0b;
  --dark-warning-600: #d97706;
  --dark-warning-700: #b45309;
  --dark-info-50: #e2e8f0;
  --dark-info-100: #cbd5e1;
  --dark-info-500: #94a3b8;
  --dark-info-600: #64748b;
  --dark-info-700: #475569;

  /* Дополнительные переменные для темной темы */
  --dark-text-inverse: #ffffff;
  /* Замер 12.08.2026: --dark-text-secondary объявлялся здесь второй раз
     (#f1f5f9) и молча перебивал палитру выше (#cbd5e1). Контраст на
     карточке выходил 15.65 против 16.41 у основного текста — то есть в
     тёмной теме вторичного текста не существовало: подписи, подзаголовки
     и пояснения читались так же громко, как основной текст. В светлой
     теме шаг есть: 17.74 против 10.35. Дубли сняты, значения берутся из
     палитры (--dark-text-secondary: #cbd5e1 → 11.55). --dark-text-muted
     был #e2e8f0 — ярче вторичного, то есть порядок был перевёрнут;
     переведён на #94a3b8 (6.9). */
  --dark-text-muted: var(--dark-gray-400);
  --dark-filter-chip-bg: #1e293b;
  --dark-filter-chip-text: #cbd5e1;
  --dark-border-ghost: #475569;
  --dark-border-ghost-hover: #64748b;
  --dark-button-base-border: #475569;
  --dark-surface-secondary: #10161d;
  --dark-primary-50: #e2e8f0;
  --dark-primary-100: #cbd5e1;
  --dark-primary-200: #344055;
  --dark-primary-300: #9ea8fb;
  --dark-primary-500: var(--dark-primary-color);
  --dark-primary-600: #64748b;
  --dark-primary-400: #9ea8fb;
  --dark-primary-700: #475569;
  --dark-primary-800: #3730a3;
  --dark-primary-900: #e2e8f0;
  --dark-primary-rgb: 180, 188, 252;
  --dark-success-rgb: 34, 197, 94;
  --dark-warning-rgb: 245, 158, 11;
  --dark-danger-rgb: 239, 68, 68;
  --dark-info-rgb: 59, 130, 246;

  /* Алиасы для старой системы переменных в темной теме */
  --dark-color-warning: var(--dark-warning-500);
  --dark-color-primary: var(--dark-primary-500);
  --dark-color-secondary: var(--dark-primary-600);
  --dark-color-accent-light: var(--dark-primary-400);
  --dark-color-accent-dark: var(--dark-primary-700);
  --dark-color-success: var(--dark-success-500);
  --dark-color-info: var(--dark-info-500);
  --dark-color-bg-primary: var(--dark-bg-primary);
  --dark-color-bg-secondary: var(--dark-bg-secondary);

  /* W2.0: keep legacy light-theme semantics while moving token ownership
     from unified-bundle.css into the token layer. */
  --primary-rgb: 180, 188, 252;
  --success-rgb: 16, 185, 129;
  --warning-rgb: 245, 158, 11;
  --danger-rgb: 220, 38, 38;
  --info-rgb: 180, 188, 252;
  --primary-color: var(--primary-600);
  --secondary-50: #f8fafc;
  --secondary-100: #f1f5f9;
  --secondary-500: #64748b;
  --secondary-600: #475569;
  --secondary-700: #334155;
  --secondary-900: #0f172a;
  --success-50: #f0fdf4;
  --success-500: #047857;
  --success-600: #065f46;
  --success-700: #047857;
  --warning-50: #fffbeb;
  --warning-500: #f59e0b;
  --warning-600: #d97706;
  --warning-700: #b45309;
  /* Было #cb968e/#b6877f/#a27871 — блёклый розовый, второе «семейство
     красного» рядом с --error-* (память ui-danger-vs-error-tokens); этим
     розовым по ошибке уже заливали плитку «Расходы». Значения сведены к
     --error-*: семейство одно, полоса состояния строки и тонировки —
     настоящий красный. Тёмная тема давно на этих значениях. 23.08.2026 */
  --danger-50: #fef2f2;
  --danger-500: #ef4444;
  --danger-600: #dc2626;
  --danger-700: #b91c1c;
  --gray-0: #ffffff;
  --gray-50: #f8fafc;
  --gray-100: #f1f5f9;
  --gray-200: #e2e8f0;
  --gray-300: #cbd5e1;
  --gray-400: #94a3b8;
  --gray-500: #64748b;
  --gray-600: #475569;
  --gray-700: #334155;
  --gray-800: #1e293b;
  --gray-900: #0f172a;
  --font-family-sans: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI",
    Roboto, "Helvetica Neue", Arial, sans-serif;
  --font-family-mono: "SF Mono", Monaco, "Cascadia Code", "Roboto Mono",
    Consolas, "Courier New", monospace;
  --font-size-xs: 0.75rem;
  --font-size-sm: 0.875rem;
  --font-size-base: 1rem;
  --font-size-lg: 1.125rem;
  --font-size-xl: 1.25rem;
  --font-size-2xl: 1.5rem;
  --font-size-3xl: 1.875rem;
  --font-size-4xl: 2.25rem;
  --font-weight-normal: 400;
  --font-weight-medium: 500;
  --font-weight-semibold: 600;
  --font-weight-bold: 700;
  /* Шкала межстрочного. Значения выбраны по замеру 13.08.2026, а не из
     головы: на десяти страницах отрисовано 12 разных отношений, из них
     несущих четыре — 1.60 (1355 узлов), 1.30 (509), 1.25 (290), 1.20 (203),
     1.40 (201), остальные единичный хвост. Прежние 1.25 / 1.5 / 1.75 были
     объявлены и применены ТРИ раза на весь проект — они не описывали
     систему, а спорили с ней.
     `line-height: 1` намеренно не входит в шкалу: у иконок и плашек
     коробка должна обнимать глиф. */
  --line-height-tight: 1.2;
  --line-height-snug: 1.35;
  --line-height-normal: 1.6;
  --line-height-relaxed: 1.75;
  --radius-sm: 0.25rem;
  --radius-base: 0.375rem;
  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.625rem;
  --radius-full: 9999px;
  --border-radius: var(--radius-base);
  --shadow-color-rgb: 0 0 0;
  --shadow-xs: 0 0 1px rgb(var(--shadow-color-rgb) / 0.04),
    0 1px 2px rgb(var(--shadow-color-rgb) / 0.04);
  --shadow-sm: 0 1px 2px 0 rgb(var(--shadow-color-rgb) / 0.05);
  --shadow: 0 1px 3px 0 rgb(var(--shadow-color-rgb) / 0.1),
    0 1px 2px -1px rgb(var(--shadow-color-rgb) / 0.1);
  --shadow-md: 0 4px 6px -1px rgb(var(--shadow-color-rgb) / 0.1),
    0 2px 4px -2px rgb(var(--shadow-color-rgb) / 0.1);
  --shadow-lg: 0 10px 15px -3px rgb(var(--shadow-color-rgb) / 0.1),
    0 4px 6px -4px rgb(var(--shadow-color-rgb) / 0.1);
  --shadow-xl: 0 20px 25px -5px rgb(var(--shadow-color-rgb) / 0.1),
    0 8px 10px -6px rgb(var(--shadow-color-rgb) / 0.1);
  --shadow-2xl: 0 25px 50px -12px rgb(var(--shadow-color-rgb) / 0.25);
  --card-shadow: var(--shadow-sm);
  --glass-bg: rgba(255, 255, 255, 0.6);
  --glass-border: rgba(255, 255, 255, 0.4);
  --glass-shadow: 0 10px 30px rgba(var(--shadow-color-rgb) / 0.08);
  --glass-blur: 14px;
  --subtle-noise: radial-gradient(
    circle at 1px 1px,
    rgba(15, 23, 42, 0.06) 0,
    rgba(15, 23, 42, 0.06) 1px,
    transparent 1px
  );
  --transition-fast: 150ms cubic-bezier(0.4, 0, 0.2, 1);
  --transition-normal: 250ms cubic-bezier(0.4, 0, 0.2, 1);
  --transition-slow: 350ms cubic-bezier(0.4, 0, 0.2, 1);
  --transition: var(--transition-normal);
  --z-dropdown: 1000;
  --z-sticky: 1020;
  --z-fixed: 1030;
  /* Замер 12.08.2026 на /calendar: шкала z-index бралась бутстраповская
     (1000..1060), а собственный хром приложения живёт выше — back-to-top
     2000, app-menu 2100/2140, header-minimal 2160. Модалка календаря
     получала 1040 и уезжала ПОД шапку и под кнопку «наверх». Именно
     поэтому compat-слой прописывал `.modal { z-index: 2200 }` числом,
     мимо токена. Ступени модалки и выше подняты над хромом; --z-dropdown,
     --z-sticky и --z-fixed оставлены как были: им положено быть ниже
     шапки приложения. */
  --z-modal: 2200;
  --z-popover: 2250;
  --z-tooltip: 2260;
  --container-sm: 640px;
  --container-md: 768px;
  --container-lg: 1024px;
  --container-xl: 1280px;
  --container-2xl: 1536px;
  --bg-inverse: var(--gray-900);
  --surface-inverse: var(--bg-inverse);
  --text-primary: var(--gray-900);
  --text-secondary: #334155;
  --text-muted: #475569;
  --text-inverse: var(--gray-0);
  --border-color-strong: var(--gray-300);
  --page-accent-gradient: transparent;
  --panel-muted-bg: var(--surface-secondary);
  --panel-muted-border: var(--border-color);
  --panel-muted-shadow: var(--shadow-sm);
  --border-light: var(--border-color-subtle);
  --header-bg: var(--bg-secondary);
  --input-bg: var(--surface-tertiary);
  --input-focus: var(--focus-ring-color);
  /* Обязательное и ошибочное поле — признак на самом поле, а не только у
     подписи: у 110 полей с required видимой метки не было, правило на
     ошибку жило только в login.css. Янтарь = «обязательно» — приём уже
     введён конструктором документов (плашка «ОБЯЗАТЕЛЬНО»). 23.08.2026 */
  --required-accent: var(--warning-700);
  --invalid-border: var(--error-600);
  --invalid-bg: #fef2f2;
  /* Было 0,45. Замер 17.08.2026: кольцо фокуса при такой прозрачности даёт
     1,56–1,94 к фону страницы при норме 3,0 — признак фокуса формально
     есть, а увидеть его нельзя. Тот же цвет без прозрачности: 4,55–4,76 в
     светлой теме и 5,71–7,09 в тёмной. Цвет остаётся серым: кольцо не
     должно спорить с акцентом. */
  --focus-ring-opacity: 1;
  --color-primary: var(--primary-600);
  --color-primary-hover: var(--primary-700);
  --color-primary-light: var(--primary-50);
  --color-success: var(--success-600);
  --color-success-hover: var(--success-700);
  --color-success-light: var(--success-50);
  --color-warning: var(--warning-600);
  --color-warning-hover: var(--warning-700);
  --color-warning-light: var(--warning-50);
  --color-danger: var(--danger-600);
  --color-danger-hover: var(--danger-700);
  --color-danger-light: var(--danger-50);
  --color-info: var(--info-600);
  --color-info-hover: var(--info-700);
  --color-info-light: var(--info-50);
  /* Категориальный набор. Отдельный от состояний СОЗНАТЕЛЬНО: успех,
     предупреждение и ошибка живут в --success/--warning/--error, и если
     красить ими виды и типы, цвет вида начинает читаться как статус.
     Набор совпадает с легендой календаря — это один и тот же язык
     категорий на всю систему. Шаг -500 для заливок и меток, -text для
     текста (он должен держать контраст на подложке строки). */
  --category-1: #3b82f6;
  --category-1-text: #1e40af;
  --category-2: #14b8a6;
  --category-2-text: #115e59;
  --category-3: #8b5cf6;
  --category-3-text: #5b21b6;
  --category-neutral-text: var(--gray-700);

  --docs-queue-doc-type-primary: var(--category-1-text);
  --docs-queue-doc-type-secondary: var(--category-2-text);
  --docs-queue-doc-type-neutral: var(--category-neutral-text);
  --docs-queue-deleted-title-color: var(--danger-color);
  --docs-queue-danger-action-color: var(--danger-600);
  --docs-queue-status-queued-bg: #6c757d;
  --docs-queue-status-active-bg: #0ea5e9;
  --docs-queue-status-processing-bg: #0d6efd;
  --docs-queue-status-needs-review-bg: #ffc107;
  --docs-queue-status-needs-review-text: #000000;
  --docs-queue-status-completed-bg: #198754;
  --docs-queue-status-error-bg: #dc3545;
  --docs-queue-status-quarantine-bg: #6f42c1;
  --docs-queue-status-ocr-ready-bg: #20c997;
  --docs-queue-status-progress-icon-start: #2563eb;
  --docs-queue-status-progress-icon-end: #1d4ed8;
  --docs-queue-status-waiting-icon-start: #64748b;
  --docs-queue-status-waiting-icon-end: #475569;
  --docs-queue-status-ready-icon-start: #10b981;
  --docs-queue-status-ready-icon-end: #059669;
  --docs-queue-preview-pane-bg: #333333;
  --docs-queue-preview-surface-bg: var(--gray-0);
  --docs-queue-code-view-bg: #1e1e1e;
  --docs-queue-code-view-text: #d4d4d4;
  --calendar-legend-meeting: var(--category-1);
  --calendar-legend-inspection: var(--category-2);
  --calendar-legend-maintenance: #f59e0b;
  --calendar-legend-deadline: #ef4444;
  --calendar-legend-reminder: var(--category-3);
  --calendar-legend-priority-high: #ef4444;
  --calendar-legend-priority-medium: #f59e0b;
  --calendar-legend-priority-low: #22c55e;
  --card-bg: var(--surface-primary);
  /* Токены поверхности карточки. Значения — те же, что раньше стояли
     свойствами в темовых блоках portal_base.css (см. комментарий там).
     Вариант карточки меняет ТОКЕН у себя, а не свойство. 16.08.2026 */
  --card-border: var(--border-color);
  --card-shadow: var(--shadow-sm);
  --docs-muted-color: #6c757d;
  --docs-link-color: #0d6efd;
  --docs-code-bg: #f8f9fa;
  --docs-code-radius: 0.25rem;

  /* ── имена, которые использовались, но никогда не объявлялись ───────
     Проверка 12.08.2026: в CSS 456 обращений `var(--x)` без запасного
     значения при 526 объявленных токенах; 36 имён из них не объявлены
     нигде. Каждое такое объявление недействительно — свойство молча не
     применяется, и это не видно ни в файле, ни на глаз: элемент просто
     наследует цвет родителя. Так были невидимы названия документов в
     очереди (нашёл Tim, контраст 1.12).
     Ниже — псевдонимы к существующим токенам и недостающие ступени шкал.
     Псевдонимы намеренно ссылаются на токены, а не на значения: тогда
     они переключаются вместе с темой. */
  --danger-color: var(--error-600);
  --text-color: var(--text-primary);
  --text-dark: var(--text-primary);
  --text-light-muted: var(--text-secondary);
  --color-text-secondary: var(--text-secondary);
  --color-primary-text: var(--button-primary-text);
  /* Ссылка — это ТЕКСТ. `--accent-interactive` служит заливкой кнопки,
     и на тёмном фоне даёт 3.19 (замер 13.08.2026, ссылка «Назад к списку
     объектов» на /api/properties/create). Парный текстовый токен. */
  --link-color: var(--accent-text, #7c3aed);
  --bg-hover: var(--surface-hover);
  --surface-muted: var(--surface-secondary);
  /* #f8fafc давал шапке таблицы 1,05 к карточке — шапка не читалась.
     Ступень ниже; токен впервые подключён к .rec-table (app-record.css).
     Светлое значение теперь литерал, поэтому тёмная пара обязательна —
     добавлена в тёмный блок. 23.08.2026 */
  --table-header-bg: #eef2f7;
  --table-hover-bg: var(--surface-hover);
  --color-bg-subtle: var(--surface-secondary);
  --color-secondary-light: var(--surface-secondary);
  --accent: var(--accent-interactive);
  --border-radius-md: var(--radius-md);
  --border-radius-lg: var(--radius-lg);
  --color-primary-700: var(--primary-700);
  --color-primary-800: var(--primary-800);
  --gradient-primary: linear-gradient(
    135deg,
    var(--accent-interactive),
    color-mix(in srgb, var(--accent-interactive) 62%, #0f172a)
  );
  --warning-200: #fde68a;
  --warning-400: #fbbf24;
  --warning-800: #92400e;
  --warning-900: #78350f;
  --success-900: #14532d;
  --danger-900: #7f1d1d;
  /* Ступень 400 у остальных статусов была, у danger — нет. Она нужна как
     ПЕРЕДНИЙ план на тёмной подложке: в тёмной теме `--danger-700`
     (#b91c1c) на `--danger-50` (#450a0a) давал контраст 2.50 — ниже
     нормы 3:1 для неподписанной графики. 16.08.2026 */
  --danger-400: #f87171;
  --info-400: #60a5fa;
  /* Бутстраповские имена на /admin/invoice-recognition/ — десять
     применений, все мёртвые. Сведены к палитре проекта. */
  --bs-primary: var(--accent-interactive);
  --bs-success: var(--success-600);
  --bs-danger: var(--error-600);
  --bs-warning: var(--warning-600);
  --bs-info: var(--info-500);
}

html[data-theme="dark"] {
  color-scheme: dark;
  /* Карточка в тёмной теме была светлее страницы: раньше тёмный блок в
     portal_base.css ставил ей литералы #1e293b / #334155 и двойную тень.
     Те же значения — теперь токенами. 16.08.2026 */
  --card-bg: #1e293b;
  --card-border: #334155;
  --card-shadow: 0 1px 2px 0 rgba(0, 0, 0, 0.2), 0 1px 3px 0 rgba(0, 0, 0, 0.1);
  --gray-800: var(--dark-gray-800);
  --gray-900: var(--dark-gray-900);
  --gray-700: var(--dark-gray-700);
  --gray-600: var(--dark-gray-600);
  --gray-400: var(--dark-gray-400);
  --gray-300: var(--dark-gray-300);
  --gray-0: var(--dark-gray-0);
  --glass-bg: var(--dark-glass-bg);
  --glass-border: var(--dark-glass-border);
  --primary-color: var(--dark-primary-color);
  --bg-primary: var(--dark-bg-primary);
  --bg-secondary: var(--dark-bg-secondary);
  --bg-tertiary: var(--dark-bg-tertiary);
  --surface-primary: var(--dark-surface-primary);
  --surface-secondary: var(--dark-surface-secondary);
  --surface-tertiary: var(--dark-surface-tertiary);
  --surface-hover: var(--dark-surface-hover);
  --surface-active: var(--dark-surface-active);
  --button-secondary-text: var(--dark-text-secondary);
  --button-secondary-bg: color-mix(
    in srgb,
    var(--dark-surface-primary) 88%,
    rgba(255, 255, 255, 0.08)
  );
  --button-secondary-bg-hover: color-mix(
    in srgb,
    var(--dark-surface-hover) 82%,
    rgba(196, 181, 253, 0.16)
  );
  --button-secondary-border: #64748b;
  --button-secondary-border-hover: #94a3b8;
  --button-primary-bg: #9333ea;
  /* #7c3aed отличался от базы #9333ea на 1,06 — наведение на главную
     кнопку в тёмной теме было незаметно. #7e22ce даёт 1,30 и держит
     белый текст (6,98). Светлее не берём: на #a855f7 белый текст
     проваливается до 3,96. 23.08.2026 */
  --button-primary-bg-hover: #7e22ce;
  --button-primary-bg-active: #6d28d9;
  --accent-interactive: #9333ea;
  --accent-text: #c084fc;
  --danger-text: #f87171;
  --warning-text: var(--warning-500);
  --success-text: var(--success-400);
  --info-text: var(--link-color);
  --surface-danger-solid: #b91c1c;
  --status-warning-text: #fcd34d;
  --status-error-text: #fca5a5;
  --status-info-text: #93c5fd;
  --status-neutral-text: #cbd5e1;
  --status-success-text: #86efac;

  /* Пары к именам, объявленным выше. Тёмные заливки — не осветлённые
     светлые, а собственные: розовый #fef2f2 под светло-красным текстом
     в тёмной теме даёт нечитаемое сочетание. */
  --text-tertiary: #94a3b8;
  --brand-600: var(--accent-interactive, #9333ea);
  --danger-800: #fca5a5;
  --success-800: #86efac;
  --status-error-bg: rgba(239, 68, 68, 0.16);
  --status-warning-bg: rgba(245, 158, 11, 0.16);
  --status-success-bg: rgba(34, 197, 94, 0.16);
  --border-subtle: var(--border-color);
  --color-bg-soft: rgba(248, 250, 252, 0.05);
  --info-bg: rgba(96, 165, 250, 0.16);
  --color-warn: #fcd34d;
  --status-progress: #60a5fa;
  --button-primary-border: #8b5cf6;
  --button-primary-shadow: 0 14px 28px rgba(139, 92, 246, 0.34);
  --button-ghost-bg-hover: rgba(196, 181, 253, 0.16);
  --button-ghost-text: var(--dark-text-primary);
  --button-link-text: #c4b5fd;
  --button-link-text-hover: #ddd6fe;
  /* В тёмной теме заливку опасной кнопки светлили до #ef4444 — белая
     подпись на ней даёт 3.76 при 14.4 px, ниже нормы (замер 12.08.2026
     на /admin/ai-management, кнопка «Удалить»). Тот же #dc2626, что и в
     светлой теме, даёт 4.83. Наведение — ступенью темнее. */
  --button-danger-bg: #dc2626;
  --button-danger-bg-hover: #b91c1c;
  --button-danger-border: #f87171;
  --button-danger-text: #ffffff;
  --button-destructive-bg: var(--button-danger-bg);
  --button-destructive-border: var(--button-danger-border);
  --button-destructive-text: var(--button-danger-text);
  --nav-hover: var(--dark-surface-hover);
  --sidebar-surface-bg: #0f172a;
  --sidebar-surface-border: #1e293b;
  --sidebar-nav-bg: #0f172a;
  /* 13.08.2026: боковое меню админки в тёмной теме было целиком выкрашено
     в бутстраповский синий (blue-200/900/700). В светлой теме тех же
     пунктов правило не касается — там работает `.admin-sidenav__item--active`
     на фирменном фиолетовом, и меню выглядит по-другому. Тот же шаг шкалы,
     сдвинутый в фирменный тон: purple-100/900/700. */
  --sidebar-nav-text: var(--text-secondary);
  --sidebar-nav-active-bg: #581c87;
  --sidebar-nav-active-text: #f3e8ff;
  --sidebar-nav-active-border: #7e22ce;
  --focus-ring-color: var(--dark-focus-ring-color);
  --focus-ring-color-rgb: var(--dark-focus-ring-color-rgb);
  --shadow-color-rgb: var(--dark-shadow-color-rgb);
  --success-50: var(--dark-success-50);
  --success-100: var(--dark-success-100);
  --success-500: var(--dark-success-500);
  --success-600: var(--dark-success-600);
  --success-700: var(--dark-success-700);
  --danger-50: var(--dark-danger-50);
  --danger-100: var(--dark-danger-100);
  --danger-500: var(--dark-danger-500);
  --danger-600: var(--dark-danger-600);
  --danger-700: var(--dark-danger-700);
  --warning-50: var(--dark-warning-50);
  --warning-100: var(--dark-warning-100);
  --warning-500: var(--dark-warning-500);
  --warning-600: var(--dark-warning-600);
  --warning-700: var(--dark-warning-700);
  --info-50: var(--dark-info-50);
  --info-100: var(--dark-info-100);
  --info-500: var(--dark-info-500);
  --info-600: var(--dark-info-600);
  --info-700: var(--dark-info-700);
  --text-inverse: var(--dark-text-inverse);
  --text-muted: var(--dark-text-muted);
  --surface-secondary: var(--dark-surface-secondary);
  --primary-50: var(--dark-primary-50);
  --primary-100: var(--dark-primary-100);
  --primary-200: var(--dark-primary-200);
  --primary-300: var(--dark-primary-300);
  --primary-500: var(--dark-primary-500);
  --primary-500-rgb: 148, 163, 184;
  --primary-600: var(--dark-primary-600);
  --primary-800: var(--dark-primary-800);
  --primary-400: var(--dark-primary-400);
  --primary-700: var(--dark-primary-700);
  --primary-900: var(--dark-primary-900);
  --primary-rgb: var(--dark-primary-rgb);
  --success-rgb: var(--dark-success-rgb);
  --warning-rgb: var(--dark-warning-rgb);
  --danger-rgb: var(--dark-danger-rgb);
  --info-rgb: var(--dark-info-rgb);
  --text-primary: var(--dark-text-primary);
  --text-secondary: var(--dark-text-secondary);
  /* #1f2a36 давал 1,18 к поверхности — граница не читалась. Slate-700:
     тот же цвет, что уже стоит у --card-border тёмной темы. 23.08.2026 */
  --border-color: #334155;
  --border-color-subtle: var(--dark-border-color-subtle);
  --color-warning: var(--dark-color-warning);
  --color-primary: var(--dark-color-primary);
  --color-secondary: var(--dark-color-secondary);
  --color-accent-light: var(--dark-color-accent-light);
  --color-accent-dark: var(--dark-color-accent-dark);
  --color-success: var(--dark-color-success);
  --color-info: var(--dark-color-info);
  --color-bg-primary: var(--dark-color-bg-primary);
  --color-bg-secondary: var(--dark-color-bg-secondary);
  /* P3 dark-caркас: restore dark overrides dropped with unified.css.
     Without these, dark falls back to root/light values (e.g. --input-bg: #f8fafc),
     causing the input/filter/header/table-chrome drift on dashboard pages. */
  --app-header-bar-border: var(--dark-glass-border);
  --app-menu-toggle-color: var(--dark-text-secondary);
  --app-menu-toggle-hover-color: var(--dark-text-primary);
  --quick-nav-item-color: var(--dark-text-primary);
  --header-minimal-shell-border: var(--dark-glass-border);
  --workspace-theme-btn-shadow: 0 8px 18px rgba(15, 23, 42, 0.24);
  --workspace-theme-btn-hover-shadow: 0 12px 24px rgba(15, 23, 42, 0.3);
  --workspace-action-link-bg: var(--dark-surface-secondary);
  --workspace-action-link-border: var(--dark-border-ghost);
  --workspace-action-link-text: var(--dark-text-primary);
  --workspace-action-link-active-bg: rgba(
    var(--dark-focus-ring-color-rgb),
    0.22
  );
  --workspace-action-link-active-border: var(--dark-border-ghost);
  --workspace-action-link-active-text: #ddd6fe;
  --filter-control-color: var(--dark-primary-color);
  --text-highlight-color: var(--dark-primary-900);
  --heading-primary-color: var(--dark-text-primary);
  --heading-secondary-color: var(--dark-text-primary);
  --text-secondary-strong: var(--dark-text-secondary);
  --button-base-border-color: var(--dark-button-base-border);
  --modal-close-hover-bg: #1e293b;
  --modal-close-hover-border: #475569;
  --modal-close-hover-text: #f8fafc;
  --entity-section-border: #334155;
  --entity-section-bg: #0f172a;
  --entity-section-title-color: #cbd5e1;
  --entity-label-color: #cbd5e1;
  /* Поле было тем же цветом, что подложка секции (#0f172a на #0f172a —
     ровно 1,00), рамка #475569 — 2,36 при норме 3,0: единственный провал
     AA, оставшийся после проверки 17.08 (там считался только текст).
     Поле светлее секции (1,55), рамка — как у остальных полей темы. */
  --entity-field-bg: #1f2a36;
  --entity-field-border: #94a3b8;
  --entity-field-text: #f8fafc;
  /* Пара к правке заливки выше: на прежнем #0f172a slate-500 давал норму,
     на посветлевшем #1f2a36 — 3,06 при норме 4,5. Ступень выше: 5,54.
     Ровно та мина, про которую записано «проверяй замером ПОСЛЕ правки»:
     подняли фон поля — подсказка на нём провалилась. 23.08.2026 */
  --entity-field-placeholder: #94a3b8;
  --entity-field-focus-border: #94a3b8;
  --entity-field-focus-shadow: 0 0 0 3px rgba(148, 163, 184, 0.14);
  --entity-modal-footer-bg: #0f172a;
  --entity-modal-footer-border: #334155;
  --confirm-icon-bg: var(--warning-100);
  --confirm-icon-fg: var(--warning-500);
  --alert-error-text: var(--danger-text);
  --entity-modal-esc-color: #94a3b8;
  --border-color-strong: var(--dark-gray-600);
  /* Заливка поля равнялась карточке (#1f2a36 на #1e293b — 1,01), поле
     держалось на одной рамке. Теперь поле ТЕМНЕЕ карточки, как в тёмной
     теме GitHub: заливка 1,22 + рамка 6,96. Наведение рамки было равно
     покою (--dark-gray-400 = #94a3b8 = рамка) — стало на ступень светлее.
     Замер 23.08.2026. */
  --input-bg: #0f172a;
  --input-border: #94a3b8;
  --input-border-hover: var(--dark-gray-300);
  --form-check-border: #94a3b8;
  /* Пары к светлым литералам 23.08.2026 (см. комментарии в :root). */
  --required-accent: var(--warning-500);
  --invalid-border: var(--error-400);
  --invalid-bg: rgba(239, 68, 68, 0.1);
  --table-header-bg: var(--dark-bg-primary);
  --header-bg: rgba(15, 23, 42, 0.85);
  /* Здесь стояло `255, 255, 255` — и это ломало тени во всей тёмной теме,
     причём двумя способами сразу. Первый: цвет белый, то есть тень
     превращалась в свечение (замер 12.08.2026: `header-minimal-shell`
     имел белый ореол rgba(255,255,255,0.24)). Второй и главный: токены
     `--shadow-*` собраны на современном синтаксисе
     `rgb(var(--shadow-color-rgb) / 0.05)`, где значение должно быть через
     ПРОБЕЛЫ. Запятые делают всё выражение недействительным — и весь набор
     `--shadow-xs/sm/md/lg/xl/2xl` в тёмной теме вычислялся в `none`.
     То есть у карточек, модалок и выпадающих меню теней не было вовсе.
     Выше в этом же блоке уже стоит правильное
     `--shadow-color-rgb: var(--dark-shadow-color-rgb)` (= `0 0 0`);
     это второе объявление его перебивало. */
  --color-primary-hover: var(--primary-400);
  --color-primary-light: rgba(59, 130, 246, 0.1);
  --color-success-hover: var(--success-400);
  --color-success-light: rgba(16, 185, 129, 0.1);
  --color-warning-hover: var(--warning-400);
  --color-warning-light: rgba(245, 158, 11, 0.1);
  --color-danger-hover: var(--error-400);
  --color-danger-light: rgba(239, 68, 68, 0.1);
  --color-info-hover: var(--info-400);

  /* Бутстраповские имена в тёмной теме: те же значения, что в светлой,
     на тёмной подложке не проходят по контрасту — замер 12.08.2026 на
     /admin/invoice-recognition/: уровень ERROR 3.55, число в плитке 3.19.
     Берём светлые ступени шкал (6.20 / 10.27 / 6.68 / 9.84). Фоном эти
     токены заливают только точки-индикаторы 12 × 12 без текста, так что
     осветление им не вредит. */
  --bs-primary: #a78bfa;
  --bs-success: var(--success-400);
  --bs-danger: var(--error-400);
  --bs-warning: #fbbf24;
  --bs-info: #94a3b8;
  --color-info-light: rgba(14, 165, 233, 0.1);
  --category-1: #60a5fa;
  --category-1-text: #bfdbfe;
  --category-2: #2dd4bf;
  --category-2-text: #99f6e4;
  --category-3: #a78bfa;
  --category-3-text: #ddd6fe;
  --category-neutral-text: var(--gray-200);

  --docs-queue-doc-type-primary: var(--category-1-text);
  --docs-queue-doc-type-secondary: var(--category-2-text);
  --docs-queue-doc-type-neutral: var(--category-neutral-text);
  --docs-queue-deleted-title-color: #fca5a5;
  --docs-queue-danger-action-color: var(--danger-600);
  --docs-queue-status-queued-bg: #6c757d;
  --docs-queue-status-active-bg: #0ea5e9;
  --docs-queue-status-processing-bg: #0d6efd;
  --docs-queue-status-needs-review-bg: #ffc107;
  --docs-queue-status-needs-review-text: #000000;
  --docs-queue-status-completed-bg: #198754;
  --docs-queue-status-error-bg: #dc3545;
  --docs-queue-status-quarantine-bg: #6f42c1;
  --docs-queue-status-ocr-ready-bg: #20c997;
  --docs-queue-status-progress-icon-start: #2563eb;
  --docs-queue-status-progress-icon-end: #1d4ed8;
  --docs-queue-status-waiting-icon-start: #64748b;
  --docs-queue-status-waiting-icon-end: #475569;
  --docs-queue-status-ready-icon-start: #10b981;
  --docs-queue-status-ready-icon-end: #059669;
  --docs-queue-preview-pane-bg: #333333;
  --docs-queue-preview-surface-bg: var(--gray-0);
  --docs-queue-code-view-bg: #1e1e1e;
  --docs-queue-code-view-text: #d4d4d4;
  --calendar-legend-meeting: var(--category-1);
  --calendar-legend-inspection: var(--category-2);
  --calendar-legend-maintenance: #f59e0b;
  --calendar-legend-deadline: #ef4444;
  --calendar-legend-reminder: var(--category-3);
  --calendar-legend-priority-high: #ef4444;
  --calendar-legend-priority-medium: #f59e0b;
  --calendar-legend-priority-low: #22c55e;
  --glass-shadow: 0 10px 30px rgba(0, 0, 0, 0.35);
  --glass-blur: 14px;
  --subtle-noise: radial-gradient(
    circle at 1px 1px,
    rgba(148, 163, 184, 0.15) 0,
    rgba(148, 163, 184, 0.15) 1px,
    transparent 1px
  );
  --skeleton-shimmer: linear-gradient(
    90deg,
    transparent 0%,
    rgba(255, 255, 255, 0.08) 50%,
    transparent 100%
  );
  --footer-link-color: var(--dark-text-primary);
  --properties-floating-menu-bg: rgba(31, 41, 55, 0.94);
  --properties-floating-menu-border: rgba(75, 85, 99, 0.95);
  --properties-floating-menu-shadow: 0 20px 46px rgba(0, 0, 0, 0.42);
  --properties-floating-menu-header-text: #94a3b8;
  --properties-floating-menu-header-border: #334155;
  --properties-floating-menu-item-text: #cbd5e1;
  --properties-floating-menu-item-hover-bg: rgba(75, 85, 99, 0.92);
  --properties-floating-menu-item-hover-text: #f1f5f9;
  --properties-confirm-popup-bg: #1e293b;
  --properties-confirm-popup-border: #334155;
  --properties-confirm-text-color: #cbd5e1;
  --properties-archive-active-text: #dbeafe;
  --properties-archive-active-shadow: 0 0 0 1px rgba(147, 197, 253, 0.25),
    0 10px 22px rgba(15, 23, 42, 0.32);
  --properties-page-border-top: transparent;
  --properties-table-row-even-bg: var(--surface-primary);
  --properties-table-row-hover-bg: var(--surface-hover);
  --properties-table-row-border: var(--border-color);
  /* Тёмные пары к удалённым --property-status-*-accent — см. :root. */
  --property-type-apartment-hover-bg: rgba(59, 130, 246, 0.15);
  --property-type-house-hover-bg: rgba(16, 185, 129, 0.15);
  --property-type-commercial-hover-bg: rgba(245, 158, 11, 0.15);
  --properties-font-address-color: #94a3b8;
  --property-party-cell-text: #e2e8f0;
  --text-table-primary-color: #f1f5f9;
  --text-table-secondary-color: #e2e8f0;
  --cadastral-progress-bg: var(--surface-primary);
  --cadastral-progress-bar-track: rgba(255, 255, 255, 0.12);
  --cadastral-progress-details-bg: var(--surface-secondary);
  --property-modal-rent-wrap-border: #334155;
  --property-modal-rent-wrap-bg: #0f172a;
  --property-modal-progress-shell-border: #334155;
  --property-modal-progress-shell-bg: #0f172a;
  --property-modal-progress-title-color: #cbd5e1;
  --property-modal-progress-log-color: #94a3b8;
  --property-modal-details-log-border: #475569;
  --property-modal-details-log-bg: #0f172a;
  --property-modal-details-log-color: #94a3b8;
  --property-modal-details-toggle-bg: #0f172a;
  --property-modal-details-toggle-border: #334155;
  --property-modal-details-toggle-color: #cbd5e1;
  --property-modal-details-toggle-hover-bg: #0f172a;
  --property-modal-details-toggle-hover-color: #cbd5e1;
  --property-modal-cancel-bg: rgba(239, 68, 68, 0.12);
  --property-modal-cancel-border: rgba(239, 68, 68, 0.28);
  --property-modal-cancel-color: #fca5a5;
  --property-modal-rent-data-hint-border: #334155;
  --property-modal-rent-data-hint-bg: #0f172a;
  --property-modal-rent-data-hint-color: #94a3b8;
  --property-modal-rights-toolbar-border: #334155;
  --property-modal-rights-note-border: #334155;
  --property-modal-rights-note-bg: #0f172a;
  --property-modal-rights-note-color: #94a3b8;
  --property-modal-rights-empty-border: #334155;
  --property-modal-rights-empty-bg: #0f172a;
  --property-modal-rights-empty-color: #94a3b8;
  --property-modal-rights-row-border: #334155;
  --property-modal-rights-row-bg: #0f172a;
  --property-modal-rights-row-label-color: #cbd5e1;
  --property-modal-rights-field-border: #475569;
  --property-modal-rights-field-bg: #0f172a;
  --property-modal-rights-field-color: #94a3b8;
  --contractor-field-changed-bg: rgba(180, 188, 252, 0.16);
  --table-row-border-contrast: var(--dark-gray-600);
  --contractor-bank-caption-color: #94a3b8;
  --contractor-bank-row-border: #475569;
  --contractor-bank-row-bg: #0f172a;
  --contractor-bank-header-border: #1e293b;
  --contractor-bank-title-color: #cbd5e1;
  --contractor-bank-index-border: #334155;
  --contractor-bank-index-bg: #0f172a;
  --contractor-bank-index-color: #94a3b8;
  --contractor-row-selected-bg: rgba(59, 130, 246, 0.12);
  --docs-muted-color: #6c757d;
  --docs-link-color: #0d6efd;
  --docs-code-bg: #f8f9fa;
  --docs-code-radius: 0.25rem;
}

.pma-noscript-warning {
  background: var(--warning-50);
  color: var(--warning-700);
  padding: 10px 16px;
  text-align: center;
  font-size: var(--font-size-sm);
  border-bottom: 1px solid var(--warning-500);
}

#cookie-consent-banner {
  position: fixed;
  bottom: 0;
  left: 0;
  right: 0;
  z-index: 99998;
  /* Токенов --surface-raised и --border-default в проекте нет: объявление
     с несуществующей переменной недействительно, поэтому подложка плашки
     была полностью прозрачной и текст ложился поверх страницы.
     Замер 12.08.2026: background rgba(0, 0, 0, 0). */
  background: var(--surface-primary, #ffffff);
  border-top: 1px solid var(--border-color, #e2e8f0);
  padding: 14px 20px;
  box-shadow: 0 -4px 12px rgba(0, 0, 0, 0.08);
  font-size: var(--font-size-sm);
}

/* Пока плашка висит, резервируем под неё место, чтобы она не закрывала
   нижние строки таблиц и плавающие кнопки. */
body.has-cookie-banner {
  padding-bottom: 96px;
}

body.has-cookie-banner #back-to-top {
  bottom: 120px;
}

.cookie-consent-banner__inner {
  max-width: 960px;
  margin: 0 auto;
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
}

.cookie-consent-banner__inner > span {
  flex: 1 1 320px;
  min-width: 0;
  color: var(--text-primary);
}

.cookie-consent-banner__link {
  color: var(--text-primary);
  text-decoration: underline;
}

/* 23.09.2026: подписи кнопок стали длиннее («Только необходимые» /
   «Разрешить статистику»); на 360 px две кнопки с nowrap не помещаются в
   строку — переносим кнопку, а не выталкиваем её за край. */
.cookie-consent-banner__actions {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.cookie-consent-btn {
  padding: 8px 20px;
  border-radius: 10px;
  cursor: pointer;
  font-weight: 600;
  white-space: nowrap;
}

#cookie-consent-reject {
  background: var(--button-secondary-bg, var(--surface-primary));
  color: var(--button-secondary-text, var(--text-primary));
  border: 1px solid var(--button-secondary-border, var(--border-color, #e2e8f0));
}

#cookie-consent-accept {
  background: var(--button-primary-bg);
  color: var(--button-primary-text, var(--text-inverse));
  border: 1px solid var(--button-primary-border);
  box-shadow: var(
    --button-primary-shadow,
    0 10px 18px rgba(124, 58, 237, 0.24)
  );
}

#back-to-top {
  position: fixed;
  bottom: 32px;
  right: 24px;
  z-index: 2000;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  /* Было `--primary-600` — в этом проекте это серая шкала (#475569),
     см. память ui-accent-token-split. Плавающая кнопка действия красилась
     серым, тогда как цвет действия в системе — фиолетовый. */
  background: var(--accent-interactive, #7c3aed);
  color: var(--button-primary-text, var(--text-inverse, #ffffff));
  border: none;
  cursor: pointer;
  box-shadow: 0 4px 12px rgba(0, 0, 0, 0.2);
  font-size: var(--font-size-xl);
  line-height: 1;
  transition:
    opacity 0.2s,
    transform 0.2s;
}
