/* Замер 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) уже
   переопределён в собственные тёмные поверхности проекта. */
/* ==========================================================================
   1. ПАЛИТРА — единственное место в CSS, где цвет записан числом.
   Генерируется из литералов (scripts/design_tokens_audit.py проверяет, что
   вне этого блока литералов цвета нет). Имена — шкалы Tailwind
   (`--pal-slate-700`), свои оттенки — по семействам (`navy`, `mist`,
   `periwinkle`), наследие Bootstrap — `bs-*`, прочее — `legacy-<hex>`.
   `-rgb` — тройка каналов для `rgba(var(--pal-x-rgb), α)`.
   Компоненты палитру напрямую не берут: только роли из разделов 2–3.
   ========================================================================== */
:root {
  --pal-amber-50: #fffbeb;
  --pal-amber-100: #fef3c7;
  --pal-amber-200: #fde68a;
  --pal-amber-300: #fcd34d;
  --pal-amber-400: #fbbf24;
  --pal-amber-500: #f59e0b;
  --pal-amber-500-rgb: 245, 158, 11;
  --pal-amber-600: #d97706;
  --pal-amber-700: #b45309;
  --pal-amber-800: #92400e;
  --pal-amber-900: #78350f;
  --pal-amber-950: #451a03;

  --pal-blue-50: #eff6ff;
  --pal-blue-100: #dbeafe;
  --pal-blue-200: #bfdbfe;
  --pal-blue-300: #93c5fd;
  --pal-blue-300-rgb: 147, 197, 253;
  --pal-blue-400: #60a5fa;
  --pal-blue-400-rgb: 96, 165, 250;
  --pal-blue-500: #3b82f6;
  --pal-blue-500-rgb: 59, 130, 246;
  --pal-blue-600: #2563eb;
  --pal-blue-600-rgb: 37, 99, 235;
  --pal-blue-700: #1d4ed8;
  --pal-blue-800: #1e40af;
  --pal-blue-900: #1e3a8a;

  --pal-cream-50: #fff8e1;

  --pal-emerald-50: #ecfdf5;
  --pal-emerald-400: #34d399;
  --pal-emerald-500: #10b981;
  --pal-emerald-500-rgb: 16, 185, 129;
  --pal-emerald-600: #059669;
  --pal-emerald-600-rgb: 5, 150, 105;
  --pal-emerald-700: #047857;
  --pal-emerald-800: #065f46;
  --pal-emerald-900: #064e3b;

  --pal-gray-cool-500: #6b7280;
  --pal-gray-cool-600-rgb: 75, 85, 99;
  --pal-gray-cool-800-rgb: 31, 41, 55;
  --pal-gray-cool-900-rgb: 17, 24, 39;

  --pal-gray-legacy-222: #222222;
  --pal-gray-legacy-333: #333333;
  --pal-gray-legacy-444: #444444;
  --pal-gray-legacy-666: #666666;
  --pal-gray-legacy-999: #999999;
  --pal-gray-legacy-667085: #667085;

  --pal-green-50: #f0fdf4;
  --pal-green-100: #dcfce7;
  --pal-green-200: #bbf7d0;
  --pal-green-300: #86efac;
  --pal-green-400: #4ade80;
  --pal-green-500: #22c55e;
  --pal-green-500-rgb: 34, 197, 94;
  --pal-green-600: #16a34a;
  --pal-green-600-rgb: 22, 163, 74;
  --pal-green-700: #15803d;
  --pal-green-800: #166534;
  --pal-green-900: #14532d;
  --pal-green-950: #052e16;

  --pal-indigo-50: #eef2ff;
  --pal-indigo-100: #e0e7ff;
  --pal-indigo-200: #c7d2fe;
  --pal-indigo-300: #a5b4fc;
  --pal-indigo-500-rgb: 99, 102, 241;
  --pal-indigo-600: #4f46e5;
  --pal-indigo-700: #4338ca;
  --pal-indigo-800: #3730a3;

  --pal-legacy-555555: #555555;

  --pal-mist-100: #eef2f7;
  --pal-mist-200: #dbe4ee;
  --pal-mist-300: #cfdbeb;
  --pal-mist-400: #c2d0e3;

  --pal-navy-600: #364560;
  --pal-navy-650: #344055;
  --pal-navy-700: #2c384a;
  --pal-navy-800: #1f2a36;
  --pal-navy-850: #1a2430;
  --pal-navy-900: #151c25;
  --pal-navy-925: #121922;
  --pal-navy-950: #10161d;

  --pal-orange-50: #fff7ed;
  --pal-orange-700: #c2410c;
  --pal-orange-900: #7c2d12;

  --pal-black: #000000;
  --pal-black-rgb: 0, 0, 0;

  --pal-bs-blue: #0d6efd;

  --pal-bs-gray: #6c757d;

  --pal-bs-green: #198754;

  --pal-bs-purple: #6f42c1;

  --pal-bs-red: #dc3545;

  --pal-bs-teal: #20c997;

  --pal-bs-yellow: #ffc107;

  --pal-gray-legacy-1e: #1e1e1e;

  --pal-gray-legacy-d4: #d4d4d4;

  --pal-gray-legacy-e9: #e9ecef;

  --pal-gray-legacy-f8: #f8f9fa;

  --pal-legacy-007bff-rgb: 0, 123, 255;

  --pal-legacy-cccccc: #cccccc;

  --pal-legacy-dddddd: #dddddd;

  --pal-white: #ffffff;
  --pal-white-rgb: 255, 255, 255;

  --pal-periwinkle-100: #e0e3ff;
  --pal-periwinkle-200: #cbd1ff;
  --pal-periwinkle-300-rgb: 180, 188, 252;
  --pal-periwinkle-400: #9ea8fb;

  --pal-purple-100: #f3e8ff;
  --pal-purple-400: #c084fc;
  --pal-purple-600: #9333ea;
  --pal-purple-700: #7e22ce;
  --pal-purple-900: #581c87;

  --pal-red-50: #fef2f2;
  --pal-red-100: #fee2e2;
  --pal-red-200: #fecaca;
  --pal-red-300: #fca5a5;
  --pal-red-400: #f87171;
  --pal-red-500: #ef4444;
  --pal-red-500-rgb: 239, 68, 68;
  --pal-red-600: #dc2626;
  --pal-red-600-rgb: 220, 38, 38;
  --pal-red-700: #b91c1c;
  --pal-red-800: #991b1b;
  --pal-red-900: #7f1d1d;
  --pal-red-950: #450a0a;

  --pal-sky-500: #0ea5e9;
  --pal-sky-500-rgb: 14, 165, 233;

  --pal-slate-50: #f8fafc;
  --pal-slate-50-rgb: 248, 250, 252;
  --pal-slate-100: #f1f5f9;
  --pal-slate-200: #e2e8f0;
  --pal-slate-200-rgb: 226, 232, 240;
  --pal-slate-300: #cbd5e1;
  --pal-slate-400: #94a3b8;
  --pal-slate-400-rgb: 148, 163, 184;
  --pal-slate-500: #64748b;
  --pal-slate-500-rgb: 100, 116, 139;
  --pal-slate-600: #475569;
  --pal-slate-600-rgb: 71, 85, 105;
  --pal-slate-700: #334155;
  --pal-slate-800: #1e293b;
  --pal-slate-800-rgb: 30, 41, 59;
  --pal-slate-900: #0f172a;
  --pal-slate-900-rgb: 15, 23, 42;
  --pal-slate-950-rgb: 2, 6, 23;

  --pal-teal-200: #99f6e4;
  --pal-teal-400: #2dd4bf;
  --pal-teal-500: #14b8a6;
  --pal-teal-800: #115e59;

  --pal-violet-100: #ede9fe;
  --pal-violet-200: #ddd6fe;
  --pal-violet-300: #c4b5fd;
  --pal-violet-300-rgb: 196, 181, 253;
  --pal-violet-400: #a78bfa;
  --pal-violet-500: #8b5cf6;
  --pal-violet-500-rgb: 139, 92, 246;
  --pal-violet-600: #7c3aed;
  --pal-violet-600-rgb: 124, 58, 237;
  --pal-violet-700: #6d28d9;
  --pal-violet-700-rgb: 109, 40, 217;
  --pal-violet-800: #5b21b6;

  --pal-yellow-600: #ca8a04;
}

:root {
  /* Палитра-примитивы (по шкалам Tailwind), одинаковые в обеих темах.
     Заведены 24.09.2026, когда цвета-литералы tenant_portal.css и
     portal_base.css переводились на токены без изменения вида: у этих
     оттенков не было токена с тем же значением. Использовать там, где
     нужен именно этот оттенок в обеих темах; тема-зависимые роли — через
     шкалы success, danger, warning, info и gray. */
  --emerald-50: var(--pal-emerald-50);
  --emerald-900: var(--pal-emerald-900);
  --green-200: var(--pal-green-200);
  --green-500: var(--pal-green-500);
  --green-600: var(--pal-green-600);
  --red-200: var(--pal-red-200);
  --red-800: var(--pal-red-800);
  --blue-50: var(--pal-blue-50);
  --blue-200: var(--pal-blue-200);
  --blue-500: var(--pal-blue-500);
  --blue-900: var(--pal-blue-900);
  --orange-50: var(--pal-orange-50);
  --orange-700: var(--pal-orange-700);
  --orange-900: var(--pal-orange-900);
  --indigo-100: var(--pal-indigo-100);
  --indigo-300: var(--pal-indigo-300);
  --indigo-600: var(--pal-indigo-600);
  --indigo-700: var(--pal-indigo-700);
  --violet-600: var(--pal-violet-600);
  --purple-600: var(--pal-purple-600);
  --slate-800: var(--pal-slate-800);
  --blue-100: var(--pal-blue-100);
  --blue-800: var(--pal-blue-800);
  --indigo-50: var(--pal-indigo-50);
  --indigo-200: var(--pal-indigo-200);
  /* 26.09.2026 — вторая партия (unified-bundle, ds-components, admin_monitoring,
     user_settings, documents_review, login, accounting, meters). Tailwind
     «gray» (не slate) и старые серые литералы получили имена как есть. */
  --black: var(--pal-black);
  --gray-legacy-222: var(--pal-gray-legacy-222);
  --gray-legacy-444: var(--pal-gray-legacy-444);
  --gray-legacy-666: var(--pal-gray-legacy-666);
  --gray-legacy-999: var(--pal-gray-legacy-999);
  --gray-legacy-e9: var(--pal-gray-legacy-e9);
  --violet-200: var(--pal-violet-200);
  --violet-300: var(--pal-violet-300);
  --violet-900: var(--pal-violet-800);
  --purple-400: var(--pal-purple-400);
  --blue-600: var(--pal-blue-600);
  --emerald-400: var(--pal-emerald-400);
  --teal-800: var(--pal-teal-800);
  --amber-50: var(--pal-amber-50);
  --amber-300: var(--pal-amber-300);
  /* Именно `0px`, а не `0`. Значение подставляется в шесть мест через
     calc() и max() — `calc(0 + 1rem)` и `max(62px, 0)` невалидны, и
     браузер выбрасывает объявление целиком. Из-за этого палитра команд
     прилипала к верхней кромке экрана, а `scroll-margin-top` и липкие
     шапки на /properties и /contractors теряли отступ под шапку.
     16.08.2026 */
  --app-top-offset: 0px;
  /* Светлая тема - базовые цвета */
  /* Палитра 23.08.2026 (отчёт docs/redesign/101-palette-23-08.md):
     карточка и фон страницы были неразличимы (1,05), разделители — 1,23 к
     поверхности. Фон страницы опущен на ступень, разделители подняты до
     slate-300 — карточка читается заливкой, границей и тенью сразу. */
  --bg-primary: var(--pal-mist-100);
  --bg-secondary: var(--pal-white);
  --bg-tertiary: var(--pal-slate-200);
  --border-color: var(--pal-slate-300);
  --border-color-subtle: var(--pal-slate-100);
  /* --primary-color — семантический алиас бренда (= --primary-500).
       Канон P3: variant-14 влит в базовые light/dark токены. */
  --primary-50: var(--pal-slate-50);
  --primary-100: var(--pal-slate-200);
  --primary-200: var(--pal-periwinkle-100);
  --primary-300: var(--pal-periwinkle-200);
  --primary-500: var(--pal-slate-500);
  --primary-500-rgb: var(--pal-slate-500-rgb);
  --primary-600: var(--pal-slate-600);
  --primary-700: var(--pal-slate-700);
  --primary-900: var(--pal-slate-900);
  --surface-primary: var(--pal-white);
  --surface-tertiary: var(--pal-slate-200);
  /* Наведение почти не отвечало: 1,29 к белой карточке — строку под
     курсором приходилось искать глазами. Ступень ниже: 1,40. Активное
     состояние идёт следом, чтобы «нажато» отличалось от «под курсором».
     Токен ведёт и строку таблицы, и пункт меню, и плитку. 23.08.2026 */
  --surface-hover: var(--pal-mist-300);
  --surface-active: var(--pal-mist-400);
  /* Светлые ступени шкал заведены 12.08.2026: в тёмной теме красный
     --error-600 (#dc2626) и зелёный --success-700 (#15803d) дают на
     подложке карточки 3.7 и 3.42 — ниже нормы. Ступени 400 нужны как
     цвет текста и иконок в тёмной теме: 6.20 и 9.84.
     Мина: до этого правки ссылались на var(--error-400), которого не
     существовало, — объявление становилось недействительным и цвет
     молча наследовался от родителя (та же мина, что у плашки cookies). */
  --error-400: var(--danger-400);
  --error-500: var(--danger-500);
  --error-600: var(--danger-600);
  --error-700: var(--danger-700);
  --success-400: var(--pal-green-400);
  --focus-ring-color: var(--pal-slate-500);
  --focus-ring-color-rgb: var(--pal-slate-500-rgb);
  /* Было 0,45. Замер 17.08.2026: кольцо фокуса при такой прозрачности даёт
     1,56–1,94 к фону страницы при норме 3,0 — признак фокуса формально
     есть, а увидеть его нельзя. Тот же цвет без прозрачности: 4,55–4,76 в
     светлой теме и 5,71–7,09 в тёмной. Цвет остаётся серым: кольцо не
     должно спорить с акцентом. */
  /* Шкала межстрочного. Значения выбраны по замеру 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` намеренно не входит в шкалу: у иконок и плашек
     коробка должна обнимать глиф. */
  /* Замер 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 оставлены как были: им положено быть ниже
     шапки приложения. */

  --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: 34px;
  --control-h-sm: 32px;
  --landing-max-width: 72rem;

  /* ── базовые компоненты: выбор Tim 10.10.2026 ───────────────────────
     Страница «Сверка интерфейса»: на 16 экранах кнопки, поля и таблицы
     шли в 2–9 вариантах. Tim выбрал плотный набор, его значения ниже.
     Сведено к одному: кнопка и поле одной высоты (`--control-h`, 34) —
     иначе в ряду «поиск + кнопка» край гуляет на 2 px; заливка поля и
     списка одна (`--input-bg`); отступ слева в ячейке равен отступу
     в шапке, чтобы колонка читалась ровно. Страницы этих значений не
     переписывают — правка здесь меняет весь сайт. */
  --page-title-size: var(--font-size-2xl);
  --page-title-weight: 700;
  --heading-2-size: var(--font-size-xl);
  --heading-3-size: var(--font-size-lg);
  --heading-4-size: var(--font-size-base);
  --heading-weight: 600;
  /* Заголовок карточки/блока, подпись поля, плашка, карточка — 10.10.2026,
     обход всех экранов: у каждого было по 3–6 своих вариантов. */
  --card-title-size: var(--font-size-lg);
  --card-title-weight: 600;
  --group-title-size: var(--font-size-sm);
  --group-title-weight: 700;
  --label-size: var(--font-size-sm);
  --label-weight: 500;
  --badge-size: var(--font-size-xs);
  --badge-weight: 600;
  --badge-pad: 0.25rem 10px;
  --badge-radius: 9999px;
  /* Нейтральная заливка бейджа под белым текстом — одна на обе темы
     (белый на slate-600 — 7.6). `--surface-tertiary` для этого не годится:
     в светлой теме он светлый, белый на нём — 1.2. 18.10.2026 */
  --badge-neutral-bg: var(--pal-slate-600);
  --card-radius: var(--radius-lg);
  --card-pad: var(--space-5);
  /* Окна: одна шапка, одно тело, один подвал, один крестик. */
  --modal-radius: var(--card-radius);
  --modal-pad-y: var(--space-4);
  --modal-pad-x: var(--space-5);
  --modal-title-size: var(--card-title-size);
  --modal-close-size: 32px;
  --field-pad-x: 10px;
  --table-head-size: var(--font-size-sm);
  --table-head-weight: 600;
  --table-head-pad: 8px 12px;
  --table-cell-size: var(--font-size-base);
  --table-cell-pad: 10px 12px;
  /* Плотная таблица — где в ячейках поля ввода (справочники): там отступ
     обычной ячейки съедал ширину колонок, и «electricity» шёл в две строки. */
  --table-cell-pad-dense: 6px 8px;
  --table-cell-size-dense: var(--font-size-sm);

  --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);
  /* 10.10.2026: у карточек было три отступа (16 / 20 / 24) — один. */
  --card-padding-sm: var(--card-pad);
  --card-padding-md: var(--card-pad);
  --button-height-xs: 1.75rem;
  --button-height-sm: 2.125rem;
  --button-height-md: var(--control-h);
  --button-height-lg: 2.875rem;
  --button-padding-y: var(--space-xs);
  --button-padding-x: var(--space-md);
  --button-gap: var(--space-sm);
  --button-primary-bg: var(--pal-violet-600);
  --button-primary-bg-hover: var(--pal-violet-700);
  --button-primary-bg-active: var(--pal-violet-800);
  /* Акцент интерактивных состояний: «включено», отметка чекбокса, активный
     сегмент. Отдельно от --primary-color: тот в тёмной теме серо-голубой,
     потому что 53 правила используют его как цвет ТЕКСТА, где фиолетовый
     не проходит по контрасту. Измерено 11.08.2026, docs/ui-audit.md. */
  --accent-interactive: var(--pal-violet-600);
  /* Акцент КАК ТЕКСТ. Отдельно от --accent-interactive сознательно: тот
     служит фоном кнопки, где на нём стоит белый, и осветлять его нельзя —
     белое на светло-фиолетовом перестанет читаться. А акцентный текст на
     тёмном фоне, наоборот, обязан быть светлее: замер 13.08.2026 показал
     #9333ea на #10161d = 3.38 при норме 4.5. Пара значений ниже: 5.40
     на светлой, 7.62 на тёмной. */
  --accent-text: var(--pal-violet-600);
  /* Второй ряд графика («Начислено» рядом с «Получено»): светлая полоса
     той же гаммы. `--accent-text` здесь равен `--accent-interactive` —
     ряды сливались (отчёты, 18.10.2026). */
  --chart-series-muted: var(--tint-accent-strong);
  /* Статусный цвет КАК ТЕКСТ. Та же причина, что у --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: var(--pal-red-600);
  /* 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: var(--pal-red-700);
  /* Плашка стоит не на белом, а на собственной подложке в 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: var(--pal-amber-800);
  --status-error-text: var(--error-700, var(--pal-red-700));
  --status-info-text: var(--pal-blue-700);
  --status-neutral-text: var(--pal-slate-600);
  --status-success-text: var(--pal-green-800);

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

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

     Объявляем недостающие имена парами (светлая тема здесь, тёмная —
     в блоке `html[data-theme="dark"]`), чтобы литералы перестали
     работать вовсе. */
  --text-tertiary: var(--text-muted);
  --danger-800: var(--pal-red-800);
  --success-800: var(--pal-emerald-800);
  --status-error-bg: var(--pal-red-50);
  --status-warning-bg: var(--pal-amber-50);
  --status-success-bg: var(--pal-green-50);
  --info-bg: rgba(var(--pal-blue-600-rgb), 0.1);
  /* «В работе» — четвёртое состояние рядом с успехом, предупреждением
     и ошибкой. Замер 13.08.2026: синий у `processing` жил литералом
     rgba(59,130,246,.9) и числился «цветом вне палитры». Он не вне
     палитры — он просто не был объявлен. Отдельно от --category-1
     (того же оттенка) СОЗНАТЕЛЬНО: вид документа и состояние обработки
     не должны съезжаться в один токен, даже если сегодня похожи. */
  --status-progress: var(--pal-blue-500);
  --button-primary-text: var(--pal-white);
  --button-primary-border: var(--pal-violet-600);
  --button-primary-shadow: 0 10px 18px rgba(var(--pal-violet-600-rgb), 0.24);
  --button-secondary-bg: transparent;
  /* #f8fafc давал 1,05 к белой кнопке — наведение на вторичную кнопку
     не читалось вовсе. 23.08.2026 */
  --button-secondary-bg-hover: var(--surface-tertiary);
  --button-secondary-text: var(--pal-slate-800);
  --button-secondary-border: var(--pal-slate-600);
  --button-secondary-border-hover: var(--pal-slate-700);
  --input-border: var(--pal-slate-500);
  --input-border-hover: var(--pal-slate-700);
  --form-check-border: var(--pal-slate-500);
  --button-ghost-bg: transparent;
  --button-ghost-bg-hover: rgba(var(--pal-slate-900-rgb), 0.06);
  --button-ghost-text: var(--text-secondary);
  --button-ghost-border: transparent;
  --button-danger-bg: var(--pal-red-600);
  --button-danger-bg-hover: var(--pal-red-700);
  --button-danger-text: var(--pal-white);
  --button-danger-border: var(--pal-red-600);
  --app-header-bar-border: var(--border-color);
  --app-menu-toggle-color: var(--pal-slate-600);
  --app-menu-toggle-hover-color: var(--pal-slate-800);
  --quick-nav-item-color: var(--pal-slate-800);
  --header-minimal-shell-border: var(--pal-slate-300);
  --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: var(--pal-slate-800);
  --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);
  --text-highlight-color: var(--primary-color);
  --heading-primary-color: var(--pal-slate-900);
  --heading-secondary-color: var(--pal-slate-800);
  --text-secondary-strong: var(--pal-slate-900);
  --sidebar-surface-bg: var(--bg-secondary);
  --sidebar-surface-border: var(--border-color);
  /* Замысел «тот же шаг шкалы в фирменном тоне» (см. комментарий в тёмном
     блоке) здесь не выполнялся: --primary-* — СЕРАЯ шкала (память
     ui-primary-scale-is-grey), и активный пункт в светлой теме был серым
     при фиолетовом в тёмной. Выровнено: purple-100/800/200; текст #5b21b6
     на #ede9fe — 7,57. 23.08.2026 */
  --sidebar-nav-active-bg: var(--pal-violet-100);
  --sidebar-nav-active-text: var(--pal-violet-800);
  --modal-close-hover-bg: var(--pal-slate-100);
  --modal-close-hover-border: var(--pal-slate-300);
  --modal-close-hover-text: var(--pal-slate-900);
  --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(--input-bg);
  --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-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);
  --skeleton-shimmer: linear-gradient(
    90deg,
    transparent 0%,
    rgba(var(--pal-white-rgb), 0.4) 50%,
    transparent 100%
  );
  --footer-link-color: var(--pal-slate-900);
  --floating-menu-bg: var(--color-bg-card);
  --floating-menu-border: var(--color-border);
  --floating-menu-shadow: 0 18px 44px rgba(var(--pal-slate-900-rgb), 0.18),
    0 3px 12px rgba(var(--pal-slate-900-rgb), 0.08);
  --floating-menu-header-text: var(--pal-gray-legacy-667085);
  --floating-menu-header-border: rgba(var(--pal-slate-200-rgb), 0.9);
  --floating-menu-item-text: var(--pal-slate-700);
  --floating-menu-item-hover-bg: linear-gradient(
    135deg,
    rgba(var(--pal-indigo-500-rgb), 0.12),
    rgba(var(--pal-blue-500-rgb), 0.08)
  );
  --floating-menu-item-hover-text: var(--pal-slate-900);
  --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-table-row-even-bg: var(--pal-slate-50);
  --properties-table-row-hover-bg: var(--pal-slate-100);
  --properties-table-row-border: var(--pal-slate-200);
  /* Шесть токенов --property-status-*-accent удалены 23.08.2026: они
     описывали РУЧНОЙ статус объекта, а его сняли ещё 18.08 — состояние
     объекта стало следствием договора ([[property-card-lease-and-prolong]]).
     Ни одной ссылки на них не осталось ни в CSS, ни в JS, ни в шаблонах:
     список объектов кодирует срок полосой группы (properties.css:1718).
     Если статус вернётся, вернуть и токены — но не держать палитру под
     сущность, которой в продукте нет. */
  --property-type-apartment-hover-bg: rgba(var(--pal-blue-500-rgb), 0.05);
  --property-type-house-hover-bg: rgba(var(--pal-emerald-500-rgb), 0.05);
  --property-type-commercial-hover-bg: rgba(var(--pal-amber-500-rgb), 0.05);
  --properties-font-address-color: var(--pal-slate-600);
  --property-party-cell-text: var(--pal-slate-700);
  --text-table-primary-color: var(--pal-slate-900);
  --text-table-secondary-color: var(--pal-slate-600);
  --cadastral-progress-bar-track: rgba(var(--pal-black-rgb), 0.08);
  --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(var(--pal-periwinkle-300-rgb), 0.06);
  --table-row-border-contrast: var(--gray-400);
  --contractor-bank-row-border: var(--pal-mist-200);
  --contractor-bank-row-bg: var(--pal-white);
  --contractor-bank-header-border: var(--pal-mist-100);
  --contractor-bank-title-color: var(--pal-slate-700);
  --contractor-bank-index-border: var(--pal-mist-200);
  --contractor-bank-index-bg: var(--pal-slate-50);
  --contractor-bank-index-color: var(--pal-slate-500);
  --contractor-row-selected-bg: rgba(var(--pal-blue-600-rgb), 0.07);

  /* Дополнительные переменные для совместимости */
  --surface-secondary: var(--pal-slate-50);
  --primary-400: var(--pal-periwinkle-400);

  /* Алиасы для старой системы переменных (для совместимости) */
  --color-border: var(--border-color);
  --color-bg-card: var(--bg-secondary);
  --warning-bg: var(--warning-50);

  /* Цвета для темной темы */
  --dark-text-primary: var(--pal-slate-50);
  --dark-text-secondary: var(--pal-slate-300);
  --dark-primary-color: var(--pal-slate-400);
  --dark-surface-primary: var(--pal-navy-900);
  /* Пара к светлой правке: наведение давало 1,11 к карточке. 23.08.2026 */
  --dark-surface-tertiary: var(--pal-navy-800);

  /* Цвета статусов для светлой темы */
  --success-100: var(--pal-green-100);
  --danger-100: var(--pal-red-100);
  --warning-100: var(--pal-amber-100);
  --info-50: var(--pal-slate-50);
  --info-100: var(--pal-blue-100);
  --info-500: var(--pal-slate-500);
  --info-600: var(--pal-slate-600);
  --info-700: var(--pal-slate-700);

  /* Цвета статусов для темной темы */
  --dark-success-600: var(--pal-green-800);

  /* Дополнительные переменные для темной темы */
  /* Замер 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(--pal-slate-400);
  --dark-surface-secondary: var(--pal-navy-950);

  /* Алиасы для старой системы переменных в темной теме */

  /* W2.0: keep legacy light-theme semantics while moving token ownership
     from unified-bundle.css into the token layer. */
  --primary-rgb: var(--pal-periwinkle-300-rgb);
  --success-rgb: var(--pal-emerald-500-rgb);
  --warning-rgb: var(--pal-amber-500-rgb);
  --danger-rgb: var(--pal-red-600-rgb);
  --info-rgb: var(--pal-periwinkle-300-rgb);
  --primary-color: var(--primary-600);
  --secondary-50: var(--pal-slate-50);
  --secondary-100: var(--pal-slate-100);
  --secondary-500: var(--pal-slate-500);
  --secondary-600: var(--pal-slate-600);
  --secondary-700: var(--pal-slate-700);
  --secondary-900: var(--pal-slate-900);
  --success-50: var(--pal-green-50);
  --success-500: var(--pal-emerald-700);
  --success-600: var(--pal-emerald-800);
  --success-700: var(--pal-emerald-700);
  --warning-50: var(--pal-amber-50);
  --warning-500: var(--pal-amber-500);
  --warning-600: var(--pal-amber-600);
  --warning-700: var(--pal-amber-700);
  /* Было #cb968e/#b6877f/#a27871 — блёклый розовый, второе «семейство
     красного» рядом с --error-* (память ui-danger-vs-error-tokens); этим
     розовым по ошибке уже заливали плитку «Расходы». Значения сведены к
     --error-*: семейство одно, полоса состояния строки и тонировки —
     настоящий красный. Тёмная тема давно на этих значениях. 23.08.2026 */
  --danger-50: var(--pal-red-50);
  --danger-500: var(--pal-red-500);
  --danger-600: var(--pal-red-600);
  --danger-700: var(--pal-red-700);
  --gray-0: var(--pal-white);
  --gray-50: var(--pal-slate-50);
  --gray-100: var(--pal-slate-100);
  --gray-200: var(--pal-slate-200);
  --gray-300: var(--pal-slate-300);
  --gray-400: var(--pal-slate-400);
  --gray-500: var(--pal-slate-500);
  --gray-600: var(--pal-slate-600);
  --gray-700: var(--pal-slate-700);
  --gray-800: var(--pal-slate-800);
  --gray-900: var(--pal-slate-900);
  --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-family-display: var(--font-family-sans);
  --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: var(--radius-md);
  --radius-md: 0.375rem;
  --radius-lg: 0.5rem;
  --radius-xl: 0.625rem;
  --radius-full: 9999px;
  --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);
  --glass-bg: rgba(var(--pal-white-rgb), 0.6);
  --glass-border: rgba(var(--pal-white-rgb), 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(var(--pal-slate-900-rgb), 0.06) 0,
    rgba(var(--pal-slate-900-rgb), 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: 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-backdrop: 2190;
  --z-modal: 2200;
  --z-popover: 2250;
  --z-tooltip: 2260;
  --bg-inverse: var(--gray-900);
  --surface-inverse: var(--bg-inverse);
  --text-primary: var(--gray-900);
  --text-secondary: var(--pal-slate-700);
  --text-muted: var(--pal-slate-600);
  --text-inverse: var(--gray-0);
  --border-color-strong: var(--gray-300);
  --panel-muted-bg: var(--surface-secondary);
  --panel-muted-border: var(--border-color);
  --panel-muted-shadow: var(--shadow-sm);
  --input-bg: var(--surface-secondary);
  --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: var(--pal-red-50);
  /* Было 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-light: var(--primary-50);
  --color-success: var(--success-600);
  --color-danger: var(--danger-600);
  /* Категориальный набор. Отдельный от состояний СОЗНАТЕЛЬНО: успех,
     предупреждение и ошибка живут в --success/--warning/--error, и если
     красить ими виды и типы, цвет вида начинает читаться как статус.
     Набор совпадает с легендой календаря — это один и тот же язык
     категорий на всю систему. Шаг -500 для заливок и меток, -text для
     текста (он должен держать контраст на подложке строки). */
  --category-1: var(--pal-blue-500);
  --category-1-text: var(--pal-blue-800);
  --category-2: var(--pal-teal-500);
  --category-2-text: var(--pal-teal-800);
  --category-3: var(--pal-violet-500);
  --category-3-text: var(--pal-violet-800);

  --docs-queue-deleted-title-color: var(--danger-color);
  --docs-queue-danger-action-color: var(--danger-600);
  --docs-queue-status-queued-bg: var(--pal-bs-gray);
  --docs-queue-status-active-bg: var(--pal-blue-600);
  --docs-queue-status-processing-bg: var(--pal-bs-blue);
  --docs-queue-status-needs-review-bg: var(--pal-bs-yellow);
  --docs-queue-status-needs-review-text: var(--pal-black);
  --docs-queue-status-completed-bg: var(--pal-bs-green);
  --docs-queue-status-error-bg: var(--pal-bs-red);
  --docs-queue-status-quarantine-bg: var(--pal-bs-purple);
  --docs-queue-status-ocr-ready-bg: var(--pal-teal-800);
  --docs-queue-status-progress-icon-start: var(--pal-blue-600);
  --docs-queue-status-progress-icon-end: var(--pal-blue-700);
  --docs-queue-status-waiting-icon-start: var(--pal-slate-500);
  --docs-queue-status-waiting-icon-end: var(--pal-slate-600);
  --docs-queue-status-ready-icon-start: var(--pal-emerald-500);
  --docs-queue-status-ready-icon-end: var(--pal-emerald-600);
  --docs-queue-preview-pane-bg: var(--pal-gray-legacy-333);
  --docs-queue-preview-surface-bg: var(--gray-0);
  --docs-queue-code-view-bg: var(--pal-gray-legacy-1e);
  --docs-queue-code-view-text: var(--pal-gray-legacy-d4);
  --calendar-legend-meeting: var(--category-1);
  --calendar-legend-inspection: var(--category-2);
  --calendar-legend-maintenance: var(--pal-amber-500);
  --calendar-legend-deadline: var(--pal-red-500);
  --calendar-legend-reminder: var(--category-3);
  --calendar-legend-priority-high: var(--pal-red-500);
  --calendar-legend-priority-medium: var(--pal-amber-500);
  --calendar-legend-priority-low: var(--pal-green-500);
  --card-bg: var(--surface-primary);
  /* Токены поверхности карточки. Значения — те же, что раньше стояли
     свойствами в темовых блоках portal_base.css (см. комментарий там).
     Вариант карточки меняет ТОКЕН у себя, а не свойство. 16.08.2026 */
  --card-border: var(--border-color);
  --card-shadow: var(--shadow-sm);
  --docs-muted-color: var(--pal-bs-gray);
  --docs-link-color: var(--pal-bs-blue);
  --docs-code-bg: var(--surface-secondary);
  --docs-code-radius: 0.25rem;

  /* ── имена, которые использовались, но никогда не объявлялись ───────
     Проверка 12.08.2026: в CSS 456 обращений `var(--x)` без запасного
     значения при 526 объявленных токенах; 36 имён из них не объявлены
     нигде. Каждое такое объявление недействительно — свойство молча не
     применяется, и это не видно ни в файле, ни на глаз: элемент просто
     наследует цвет родителя. Так были невидимы названия документов в
     очереди (нашёл Tim, контраст 1.12).
     Ниже — псевдонимы к существующим токенам и недостающие ступени шкал.
     Псевдонимы намеренно ссылаются на токены, а не на значения: тогда
     они переключаются вместе с темой. */
  --danger-color: var(--danger-600);
  /* Ссылка — это ТЕКСТ. `--accent-interactive` служит заливкой кнопки,
     и на тёмном фоне даёт 3.19 (замер 13.08.2026, ссылка «Назад к списку
     объектов» на /api/properties/create). Парный текстовый токен. */
  --link-color: var(--accent-text, var(--pal-violet-600));
  /* #f8fafc давал шапке таблицы 1,05 к карточке — шапка не читалась.
     Ступень ниже; токен впервые подключён к .rec-table (app-record.css).
     Светлое значение теперь литерал, поэтому тёмная пара обязательна —
     добавлена в тёмный блок. 23.08.2026 */
  --table-header-bg: var(--card-bg);
  --color-bg-subtle: var(--surface-secondary);
  --accent: var(--accent-interactive);
  --color-primary-700: var(--primary-700);
  --color-primary-800: var(--primary-800);
  --warning-200: var(--pal-amber-200);
  --warning-400: var(--pal-amber-400);
  --warning-800: var(--pal-amber-800);
  --warning-900: var(--pal-amber-900);
  --danger-900: var(--pal-red-900);
  /* Ступень 400 у остальных статусов была, у danger — нет. Она нужна как
     ПЕРЕДНИЙ план на тёмной подложке: в тёмной теме `--danger-700`
     (#b91c1c) на `--danger-50` (#450a0a) давал контраст 2.50 — ниже
     нормы 3:1 для неподписанной графики. 16.08.2026 */
  --danger-300: var(--pal-red-300);
  --danger-400: var(--pal-red-400);
  --info-400: var(--pal-blue-400);
  /* Бутстраповские имена на /admin/invoice-recognition/ — десять
     применений, все мёртвые. Сведены к палитре проекта. */
}

html[data-theme="dark"] {
  color-scheme: dark;
  /* Карточка в тёмной теме была светлее страницы: раньше тёмный блок в
     portal_base.css ставил ей литералы #1e293b / #334155 и двойную тень.
     Те же значения — теперь токенами. 16.08.2026 */
  --card-bg: var(--pal-slate-800);
  --card-border: var(--pal-slate-700);
  --card-shadow: 0 1px 2px 0 rgba(var(--pal-black-rgb), 0.2),
    0 1px 3px 0 rgba(var(--pal-black-rgb), 0.1);
  --gray-800: var(--pal-navy-900);
  --gray-900: var(--pal-navy-950);
  --gray-700: var(--pal-navy-850);
  --gray-600: var(--pal-slate-600);
  --gray-400: var(--pal-slate-400);
  --gray-300: var(--pal-slate-300);
  --gray-0: var(--pal-slate-50);
  --glass-bg: rgba(var(--pal-slate-900-rgb), 0.6);
  --glass-border: rgba(var(--pal-slate-400-rgb), 0.2);
  --primary-color: var(--dark-primary-color);
  --bg-primary: var(--pal-navy-950);
  --bg-secondary: var(--pal-navy-900);
  --bg-tertiary: var(--pal-navy-850);
  --surface-primary: var(--dark-surface-primary);
  --surface-tertiary: var(--dark-surface-tertiary);
  --surface-hover: var(--pal-navy-700);
  --surface-active: var(--pal-navy-600);
  --button-secondary-text: var(--dark-text-secondary);
  --button-secondary-bg: transparent;
  --button-secondary-bg-hover: color-mix(
    in srgb,
    var(--pal-navy-700) 82%,
    rgba(var(--pal-violet-300-rgb), 0.16)
  );
  --button-secondary-border: var(--pal-slate-500);
  --button-secondary-border-hover: var(--pal-slate-400);
  --button-primary-bg: var(--pal-purple-600);
  /* #7c3aed отличался от базы #9333ea на 1,06 — наведение на главную
     кнопку в тёмной теме было незаметно. #7e22ce даёт 1,30 и держит
     белый текст (6,98). Светлее не берём: на #a855f7 белый текст
     проваливается до 3,96. 23.08.2026 */
  --button-primary-bg-hover: var(--pal-purple-700);
  --button-primary-bg-active: var(--pal-violet-700);
  --accent-interactive: var(--pal-purple-600);
  --accent-text: var(--pal-purple-400);
  --chart-series-muted: var(--pal-purple-400);
  --danger-text: var(--pal-red-400);
  --warning-text: var(--warning-500);
  --success-text: var(--success-400);
  --info-text: var(--link-color);
  --surface-danger-solid: var(--pal-red-700);
  --status-warning-text: var(--pal-amber-300);
  --status-error-text: var(--pal-red-300);
  --status-info-text: var(--pal-blue-300);
  --status-neutral-text: var(--pal-slate-300);
  --status-success-text: var(--pal-green-300);

  /* Пары к именам, объявленным выше. Тёмные заливки — не осветлённые
     светлые, а собственные: розовый #fef2f2 под светло-красным текстом
     в тёмной теме даёт нечитаемое сочетание. */
  --danger-800: var(--pal-red-300);
  --success-800: var(--pal-green-300);
  --status-error-bg: rgba(var(--pal-red-500-rgb), 0.16);
  --status-warning-bg: rgba(var(--pal-amber-500-rgb), 0.16);
  --status-success-bg: rgba(var(--pal-green-500-rgb), 0.16);
  --info-bg: rgba(var(--pal-blue-400-rgb), 0.16);
  --status-progress: var(--pal-blue-400);
  --button-primary-border: var(--pal-violet-500);
  --button-primary-shadow: 0 14px 28px rgba(var(--pal-violet-500-rgb), 0.34);
  --button-ghost-bg-hover: rgba(var(--pal-violet-300-rgb), 0.16);
  --button-ghost-text: var(--dark-text-primary);
  /* В тёмной теме заливку опасной кнопки светлили до #ef4444 — белая
     подпись на ней даёт 3.76 при 14.4 px, ниже нормы (замер 12.08.2026
     на /admin/ai-management, кнопка «Удалить»). Тот же #dc2626, что и в
     светлой теме, даёт 4.83. Наведение — ступенью темнее. */
  --button-danger-bg: var(--pal-red-600);
  --button-danger-bg-hover: var(--pal-red-700);
  --button-danger-border: var(--pal-red-400);
  --button-danger-text: var(--pal-white);
  --sidebar-surface-bg: var(--pal-slate-900);
  --sidebar-surface-border: var(--pal-slate-800);
  /* 13.08.2026: боковое меню админки в тёмной теме было целиком выкрашено
     в бутстраповский синий (blue-200/900/700). В светлой теме тех же
     пунктов правило не касается — там работает `.admin-sidenav__item--active`
     на фирменном фиолетовом, и меню выглядит по-другому. Тот же шаг шкалы,
     сдвинутый в фирменный тон: purple-100/900/700. */
  --sidebar-nav-active-bg: var(--pal-purple-900);
  --sidebar-nav-active-text: var(--pal-purple-100);
  --focus-ring-color: var(--pal-slate-400);
  --focus-ring-color-rgb: var(--pal-slate-400-rgb);
  --shadow-color-rgb: 0 0 0;
  --success-50: var(--pal-green-950);
  --success-100: var(--pal-green-900);
  --success-500: var(--pal-green-700);
  --success-600: var(--dark-success-600);
  --success-700: var(--pal-green-700);
  --danger-50: var(--pal-red-950);
  --danger-100: var(--pal-red-900);
  --danger-500: var(--pal-red-500);
  --danger-600: var(--pal-red-600);
  --danger-700: var(--pal-red-700);
  --warning-50: var(--pal-amber-950);
  --warning-100: var(--pal-amber-900);
  --warning-500: var(--pal-amber-500);
  --warning-600: var(--pal-amber-600);
  --warning-700: var(--pal-amber-700);
  --info-50: var(--pal-slate-200);
  --info-100: var(--pal-slate-300);
  --info-500: var(--pal-slate-400);
  --info-600: var(--pal-slate-500);
  --info-700: var(--pal-slate-600);
  --text-inverse: var(--pal-white);
  --text-muted: var(--dark-text-muted);
  --surface-secondary: var(--dark-surface-secondary);
  --primary-50: var(--pal-slate-200);
  --primary-100: var(--pal-slate-300);
  --primary-200: var(--pal-navy-650);
  --primary-300: var(--pal-periwinkle-400);
  --primary-500: var(--dark-primary-color);
  --primary-500-rgb: var(--pal-slate-400-rgb);
  --primary-600: var(--pal-slate-500);
  --primary-800: var(--pal-indigo-800);
  --primary-400: var(--pal-periwinkle-400);
  --primary-700: var(--pal-slate-600);
  --primary-900: var(--pal-slate-200);
  --primary-rgb: var(--pal-periwinkle-300-rgb);
  --success-rgb: var(--pal-green-500-rgb);
  --warning-rgb: var(--pal-amber-500-rgb);
  --danger-rgb: var(--pal-red-500-rgb);
  --info-rgb: var(--pal-blue-500-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: var(--pal-slate-700);
  --border-color-subtle: var(--pal-navy-925);
  --color-primary: var(--dark-primary-color);
  --color-success: var(--pal-green-700);
  /* 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: rgba(var(--pal-slate-400-rgb), 0.2);
  --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: rgba(var(--pal-slate-400-rgb), 0.2);
  --workspace-theme-btn-shadow: 0 8px 18px rgba(var(--pal-slate-900-rgb), 0.24);
  --workspace-theme-btn-hover-shadow: 0 12px 24px
    rgba(var(--pal-slate-900-rgb), 0.3);
  --workspace-action-link-bg: var(--dark-surface-secondary);
  --workspace-action-link-border: var(--pal-slate-600);
  --workspace-action-link-text: var(--dark-text-primary);
  --workspace-action-link-active-bg: rgba(var(--pal-slate-400-rgb), 0.22);
  --workspace-action-link-active-border: var(--pal-slate-600);
  --workspace-action-link-active-text: var(--pal-violet-200);
  --text-highlight-color: var(--pal-slate-200);
  --heading-primary-color: var(--dark-text-primary);
  --heading-secondary-color: var(--dark-text-primary);
  --text-secondary-strong: var(--dark-text-secondary);
  --modal-close-hover-bg: var(--pal-slate-800);
  --modal-close-hover-border: var(--pal-slate-600);
  --modal-close-hover-text: var(--pal-slate-50);
  --entity-section-border: var(--pal-slate-700);
  --entity-section-bg: var(--pal-slate-900);
  --entity-section-title-color: var(--pal-slate-300);
  --entity-label-color: var(--pal-slate-300);
  /* Поле было тем же цветом, что подложка секции (#0f172a на #0f172a —
     ровно 1,00), рамка #475569 — 2,36 при норме 3,0: единственный провал
     AA, оставшийся после проверки 17.08 (там считался только текст).
     Поле светлее секции (1,55), рамка — как у остальных полей темы. */
  --entity-field-bg: var(--input-bg);
  --entity-field-border: var(--input-border);
  --entity-field-text: var(--pal-slate-50);
  /* Пара к правке заливки выше: на прежнем #0f172a slate-500 давал норму,
     на посветлевшем #1f2a36 — 3,06 при норме 4,5. Ступень выше: 5,54.
     Ровно та мина, про которую записано «проверяй замером ПОСЛЕ правки»:
     подняли фон поля — подсказка на нём провалилась. 23.08.2026 */
  --entity-field-placeholder: var(--pal-slate-400);
  --entity-field-focus-border: var(--pal-slate-400);
  --entity-modal-footer-bg: var(--pal-slate-900);
  --entity-modal-footer-border: var(--pal-slate-700);
  --confirm-icon-bg: var(--warning-100);
  --confirm-icon-fg: var(--warning-500);
  --alert-error-text: var(--danger-text);
  --border-color-strong: var(--pal-slate-600);
  /* Заливка поля равнялась карточке (#1f2a36 на #1e293b — 1,01), поле
     держалось на одной рамке. Теперь поле ТЕМНЕЕ карточки, как в тёмной
     теме GitHub: заливка 1,22 + рамка 6,96. Наведение рамки было равно
     покою (--dark-gray-400 = #94a3b8 = рамка) — стало на ступень светлее.
     Замер 23.08.2026. */
  --input-bg: var(--surface-secondary);
  --input-border: var(--pal-slate-400);
  --input-border-hover: var(--pal-slate-300);
  --form-check-border: var(--pal-slate-400);
  /* Пары к светлым литералам 23.08.2026 (см. комментарии в :root). */
  --required-accent: var(--warning-500);
  --invalid-border: var(--error-400);
  --invalid-bg: rgba(var(--pal-red-500-rgb), 0.1);
  --table-header-bg: var(--pal-navy-950);
  /* Здесь стояло `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: 0 0 0` (= `0 0 0`);
     это второе объявление его перебивало. */
  --color-primary-light: rgba(var(--pal-blue-500-rgb), 0.1);

  /* Бутстраповские имена в тёмной теме: те же значения, что в светлой,
     на тёмной подложке не проходят по контрасту — замер 12.08.2026 на
     /admin/invoice-recognition/: уровень ERROR 3.55, число в плитке 3.19.
     Берём светлые ступени шкал (6.20 / 10.27 / 6.68 / 9.84). Фоном эти
     токены заливают только точки-индикаторы 12 × 12 без текста, так что
     осветление им не вредит. */
  --category-1: var(--pal-blue-400);
  --category-1-text: var(--pal-blue-200);
  --category-2: var(--pal-teal-400);
  --category-2-text: var(--pal-teal-200);
  --category-3: var(--pal-violet-400);
  --category-3-text: var(--pal-violet-200);

  --docs-queue-deleted-title-color: var(--pal-red-300);
  --docs-queue-danger-action-color: var(--danger-600);
  --docs-queue-status-queued-bg: var(--pal-bs-gray);
  --docs-queue-status-active-bg: var(--pal-blue-600);
  --docs-queue-status-processing-bg: var(--pal-bs-blue);
  --docs-queue-status-needs-review-bg: var(--pal-bs-yellow);
  --docs-queue-status-needs-review-text: var(--pal-black);
  --docs-queue-status-completed-bg: var(--pal-bs-green);
  --docs-queue-status-error-bg: var(--pal-bs-red);
  --docs-queue-status-quarantine-bg: var(--pal-bs-purple);
  --docs-queue-status-ocr-ready-bg: var(--pal-teal-800);
  --docs-queue-status-progress-icon-start: var(--pal-blue-600);
  --docs-queue-status-progress-icon-end: var(--pal-blue-700);
  --docs-queue-status-waiting-icon-start: var(--pal-slate-500);
  --docs-queue-status-waiting-icon-end: var(--pal-slate-600);
  --docs-queue-status-ready-icon-start: var(--pal-emerald-500);
  --docs-queue-status-ready-icon-end: var(--pal-emerald-600);
  --docs-queue-preview-pane-bg: var(--pal-gray-legacy-333);
  --docs-queue-preview-surface-bg: var(--gray-0);
  --docs-queue-code-view-bg: var(--pal-gray-legacy-1e);
  --docs-queue-code-view-text: var(--pal-gray-legacy-d4);
  --calendar-legend-meeting: var(--category-1);
  --calendar-legend-inspection: var(--category-2);
  --calendar-legend-maintenance: var(--pal-amber-500);
  --calendar-legend-deadline: var(--pal-red-500);
  --calendar-legend-reminder: var(--category-3);
  --calendar-legend-priority-high: var(--pal-red-500);
  --calendar-legend-priority-medium: var(--pal-amber-500);
  --calendar-legend-priority-low: var(--pal-green-500);
  --glass-shadow: 0 10px 30px rgba(var(--pal-black-rgb), 0.35);
  --glass-blur: 14px;
  --subtle-noise: radial-gradient(
    circle at 1px 1px,
    rgba(var(--pal-slate-400-rgb), 0.15) 0,
    rgba(var(--pal-slate-400-rgb), 0.15) 1px,
    transparent 1px
  );
  --skeleton-shimmer: linear-gradient(
    90deg,
    transparent 0%,
    rgba(var(--pal-white-rgb), 0.08) 50%,
    transparent 100%
  );
  --footer-link-color: var(--dark-text-primary);
  --floating-menu-bg: rgba(var(--pal-gray-cool-800-rgb), 0.94);
  --floating-menu-border: rgba(var(--pal-gray-cool-600-rgb), 0.95);
  --floating-menu-shadow: 0 20px 46px rgba(var(--pal-black-rgb), 0.42);
  --floating-menu-header-text: var(--pal-slate-400);
  --floating-menu-header-border: var(--pal-slate-700);
  --floating-menu-item-text: var(--pal-slate-300);
  --floating-menu-item-hover-bg: rgba(var(--pal-gray-cool-600-rgb), 0.92);
  --floating-menu-item-hover-text: var(--pal-slate-100);
  --properties-archive-active-text: var(--pal-blue-100);
  --properties-archive-active-shadow: 0 0 0 1px
      rgba(var(--pal-blue-300-rgb), 0.25),
    0 10px 22px rgba(var(--pal-slate-900-rgb), 0.32);
  --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(var(--pal-blue-500-rgb), 0.15);
  --property-type-house-hover-bg: rgba(var(--pal-emerald-500-rgb), 0.15);
  --property-type-commercial-hover-bg: rgba(var(--pal-amber-500-rgb), 0.15);
  --properties-font-address-color: var(--pal-slate-400);
  --property-party-cell-text: var(--pal-slate-200);
  --text-table-primary-color: var(--pal-slate-100);
  --text-table-secondary-color: var(--pal-slate-200);
  --cadastral-progress-bar-track: rgba(var(--pal-white-rgb), 0.12);
  --property-modal-progress-shell-border: var(--pal-slate-700);
  --property-modal-progress-shell-bg: var(--pal-slate-900);
  --property-modal-progress-title-color: var(--pal-slate-300);
  --property-modal-progress-log-color: var(--pal-slate-400);
  --property-modal-details-log-border: var(--pal-slate-600);
  --property-modal-details-log-bg: var(--pal-slate-900);
  --property-modal-details-log-color: var(--pal-slate-400);
  --property-modal-details-toggle-bg: var(--pal-slate-900);
  --property-modal-details-toggle-border: var(--pal-slate-700);
  --property-modal-details-toggle-color: var(--pal-slate-300);
  --property-modal-details-toggle-hover-bg: var(--pal-slate-900);
  --property-modal-details-toggle-hover-color: var(--pal-slate-300);
  --property-modal-cancel-bg: rgba(var(--pal-red-500-rgb), 0.12);
  --property-modal-cancel-border: rgba(var(--pal-red-500-rgb), 0.28);
  --property-modal-cancel-color: var(--pal-red-300);
  --property-modal-rent-data-hint-border: var(--pal-slate-700);
  --property-modal-rent-data-hint-bg: var(--pal-slate-900);
  --property-modal-rent-data-hint-color: var(--pal-slate-400);
  --property-modal-rights-toolbar-border: var(--pal-slate-700);
  --property-modal-rights-note-border: var(--pal-slate-700);
  --property-modal-rights-note-bg: var(--pal-slate-900);
  --property-modal-rights-note-color: var(--pal-slate-400);
  --property-modal-rights-empty-border: var(--pal-slate-700);
  --property-modal-rights-empty-bg: var(--pal-slate-900);
  --property-modal-rights-empty-color: var(--pal-slate-400);
  --property-modal-rights-row-border: var(--pal-slate-700);
  --property-modal-rights-row-bg: var(--pal-slate-900);
  --property-modal-rights-row-label-color: var(--pal-slate-300);
  --property-modal-rights-field-border: var(--pal-slate-600);
  --property-modal-rights-field-bg: var(--pal-slate-900);
  --property-modal-rights-field-color: var(--pal-slate-400);
  --contractor-field-changed-bg: rgba(var(--pal-periwinkle-300-rgb), 0.16);
  --table-row-border-contrast: var(--pal-slate-600);
  --contractor-bank-row-border: var(--pal-slate-600);
  --contractor-bank-row-bg: var(--pal-slate-900);
  --contractor-bank-header-border: var(--pal-slate-800);
  --contractor-bank-title-color: var(--pal-slate-300);
  --contractor-bank-index-border: var(--pal-slate-700);
  --contractor-bank-index-bg: var(--pal-slate-900);
  --contractor-bank-index-color: var(--pal-slate-400);
  --contractor-row-selected-bg: rgba(var(--pal-blue-500-rgb), 0.12);
  --docs-muted-color: var(--pal-bs-gray);
  --docs-link-color: var(--pal-bs-blue);
  --docs-code-bg: var(--surface-secondary);
  --docs-code-radius: 0.25rem;
}

/* ==========================================================================
   3б. СЛОИ ПОВЕРХ КОНТЕНТА — общие роли (10.10.2026, унификация).
   До этого каждое окно и выезжающая панель заводили свою «тень под окном»
   (11 разных значений от 0.32 до 0.6 на чёрном и сланце) и своё кольцо
   фокуса. Теперь — две подложки и два кольца на весь сайт.
   ========================================================================== */
:root {
  /* Подложка под модальным окном (окно требует ответа). */
  --overlay-backdrop: rgba(var(--pal-slate-950-rgb), 0.5);
  /* Подложка под выезжающей панелью/меню (контент за ней остаётся «рядом»). */
  --overlay-backdrop-soft: rgba(var(--pal-slate-900-rgb), 0.32);
  /* Полупрозрачные подложки и рамки по смыслу (плашки, строки-состояния,
     выделение). subtle ≈ 6 %, soft ≈ 12 %, strong ≈ 30 % (рамка). До
     10.10.2026 — 60 разных альфа-значений по файлам. */
  --tint-success-subtle: rgba(var(--pal-green-500-rgb), 0.06);
  --tint-success-soft: rgba(var(--pal-green-500-rgb), 0.12);
  --tint-success-strong: rgba(var(--pal-green-500-rgb), 0.3);
  --tint-warning-subtle: rgba(var(--pal-amber-500-rgb), 0.06);
  --tint-warning-soft: rgba(var(--pal-amber-500-rgb), 0.12);
  --tint-warning-strong: rgba(var(--pal-amber-500-rgb), 0.3);
  --tint-danger-subtle: rgba(var(--pal-red-500-rgb), 0.06);
  --tint-danger-soft: rgba(var(--pal-red-500-rgb), 0.12);
  --tint-danger-strong: rgba(var(--pal-red-500-rgb), 0.3);
  --tint-info-subtle: rgba(var(--pal-blue-500-rgb), 0.06);
  --tint-info-soft: rgba(var(--pal-blue-500-rgb), 0.12);
  --tint-info-strong: rgba(var(--pal-blue-500-rgb), 0.3);
  --tint-neutral-subtle: rgba(var(--pal-slate-400-rgb), 0.06);
  --tint-neutral-soft: rgba(var(--pal-slate-400-rgb), 0.12);
  --tint-neutral-strong: rgba(var(--pal-slate-400-rgb), 0.3);
  --tint-accent-subtle: rgba(var(--pal-violet-600-rgb), 0.06);
  --tint-accent-soft: rgba(var(--pal-violet-600-rgb), 0.12);
  --tint-accent-strong: rgba(var(--pal-violet-600-rgb), 0.3);
  /* Белое и тёмное «вообще» (10.10.2026): блик и тень поверх чего угодно,
     осветление/затемнение в color-mix, белый текст на цветной заливке.
     Одинаковы в обеих темах. */
  --highlight-rgb: var(--pal-white-rgb);
  --shade-rgb: var(--pal-slate-900-rgb);
  --mix-highlight: var(--pal-white);
  --mix-shade: var(--pal-black);
  --text-on-accent: var(--pal-white);
  /* Тройки каналов для свечений и полупрозрачных подложек по смыслу —
     `rgba(var(--accent-rgb), 0.2)`. Значения те же, что были оттенком. */
  --ink-rgb: var(--pal-black-rgb);
  --shade-deep-rgb: var(--pal-slate-950-rgb);
  --accent-rgb: var(--pal-violet-600-rgb);
  --accent-strong-rgb: var(--pal-violet-700-rgb);
  --accent-soft-rgb: var(--pal-periwinkle-300-rgb);
  --info-tint-rgb: var(--pal-blue-500-rgb);
  --info-strong-rgb: var(--pal-blue-600-rgb);
  --success-tint-rgb: var(--pal-emerald-500-rgb);
  --success-strong-rgb: var(--pal-emerald-600-rgb);
  --live-rgb: var(--pal-green-600-rgb);
  --neutral-tint-rgb: var(--pal-slate-400-rgb);
  --neutral-strong-rgb: var(--pal-slate-600-rgb);
  --danger-tint-rgb: var(--pal-red-500-rgb);
  --legacy-info-glow-rgb: var(--pal-legacy-007bff-rgb);
  /* Кольцо фокуса полей ввода и кнопок. */
  --focus-ring: 0 0 0 3px rgba(var(--focus-ring-color-rgb), 0.24);
  /* Кольцо фокуса поля с ошибкой. */
  --focus-ring-danger: 0 0 0 3px rgba(var(--pal-red-500-rgb), 0.18);
}

html[data-theme="dark"] {
  --overlay-backdrop: rgba(var(--pal-black-rgb), 0.6);
  --overlay-backdrop-soft: rgba(var(--pal-black-rgb), 0.45);
}

/* ==========================================================================
   4. Токены каркаса и карточки документа (перенесены из app-shell.css и
   documents_review.css 10.10.2026 — токены живут только здесь).
   ========================================================================== */
:root {
  --sidebar-width: 240px;
  --sidebar-width-collapsed: 68px;
  --topbar-height: 56px;
  --review-surface: var(--surface-tertiary);
  --review-surface-elevated: var(--surface-secondary);
  --review-border: var(--border-color);
  --review-tabbar-bg: var(--review-surface-elevated);
  --review-panel-bg: var(--review-surface);
  /* Ширина правой колонки по умолчанию. 520 px было мало: строка полей
     «Номер · Дата · Период · Сумма · Договор-основание» рассыпалась в
     столбик, а заголовок раздела переносился на две строки. Правая
     колонка — та, в которой печатают, ей и место. 18.08.2026 */
  --review-split-right: 660px;
}

html[data-theme="dark"] {
  --review-surface: var(--surface-primary);
  --review-surface-elevated: var(--surface-tertiary);
  --review-border: var(--border-color);
  --review-tabbar-bg: var(--review-surface-elevated);
  --review-panel-bg: var(--review-surface);
}

/* ==========================================================================
   6. РОЛИ КОМПОНЕНТОВ ПО ТЕМЕ — бывшие правила `[data-theme="dark"] .x`
   из постраничных CSS (10.10.2026). Компонент теперь берёт одну
   переменную, а тёмное значение живёт здесь. Где пара «день/ночь»
   совпала с общей ролью (`--surface-*`, `--text-*`, …), компонент
   получил её, а не свою переменную.
   ========================================================================== */
:root {
  /* из accounting.css */
  --acc-quick-filter-button-is-active-border: var(--button-primary-border);
  --acc-quick-filter-button-is-active-box-shadow: var(--button-primary-shadow);
  --acc-chain-state--ok-fg: var(--success-700);
  --acc-chain-state--warning-bg: color-mix(
    in srgb,
    var(--warning-500) 12%,
    var(--surface-secondary)
  );
  --acc-chain-state--warning-fg: var(--warning-700);
  --acc-chain-state--danger-bg: color-mix(
    in srgb,
    var(--danger-500) 12%,
    var(--surface-secondary)
  );
  --acc-accounting-modal-header--primary-bg: color-mix(
    in srgb,
    var(--accent) 8%,
    var(--surface-primary)
  );
  --acc-accounting-modal-header--primary-border: var(--border-color);
  --acc-manager-focus-pill-is-active-bg: var(--primary-100);
  --acc-manager-focus-pill-is-active-border: var(--primary-400);
  --acc-manager-focus-pill-is-active-fg: var(--primary-color);
  --acc-priority-pill--warning-fg: var(--warning-800);
  --acc-active-filter-chip-bg: var(--primary-100);
  --acc-filters-count-badge-border: var(--primary-300);
  --acc-active-filter-chip-border: var(--primary-300);
  /* из calendar.css */
  --cal-scale-btn-active-border: var(--button-primary-border);
  --cal-calendar-day-today-day-number-bg: var(--surface-active);
  --cal-calendar-day-today-day-number-fg: var(--primary-color);
  --cal-event-priority-badge-priority-high-fg: var(--danger-700);
  --cal-event-priority-badge-priority-medium-fg: var(--warning-700);
  --cal-event-priority-badge-priority-low-fg: var(--success-700);
  /* из documents_queue.css */
  --queue-brand-link-fg: var(--primary-600);
  --queue-brand-link-hover-fg: var(--primary-600);
  --queue-chain-link-fg: currentColor;
  --queue-chain-link-hover-fg: var(--primary-color);
  --queue-footnote-opacity: 1;
  --queue-docs-body-td-border-bottom: 1px solid var(--gray-400);
  --queue-quick-filter-button-is-active-border: var(--button-primary-border);
  --queue-finance-chainstate--warning-fg: var(--warning-800);
  --queue-finance-chainstate--danger-fg: var(--danger-700);
  --queue-status-progress-box-shadow: inset 0 1px 0
    rgba(var(--pal-white-rgb), 0.28);
  --queue-documents-queue-table-tr-is-selected-bg: rgba(
    var(--pal-blue-600-rgb),
    0.07
  );
  --queue-doc-name-footnote--awaiting-fg: var(--warning-700);
  --queue-docs-packet-part-row-td-bg: var(--surface-secondary);
  /* из documents_review.css */
  --review-ocr-lite-border: color-mix(
    in srgb,
    var(--border-color) 70%,
    var(--pal-white) 30%
  );
  --review-ocr-lite-bg: color-mix(
    in srgb,
    var(--surface-tertiary) 78%,
    var(--pal-white) 22%
  );
  --review-builder-tag-bg: var(--surface-secondary);
  --review-builder-card-bg: rgba(var(--pal-white-rgb), 0.84);
  --review-segment-divider-border: color-mix(
    in srgb,
    var(--color-primary) 25%,
    var(--review-border)
  );
  --review-page-img-border: var(--review-border);
  --review-tabbtn-bg: rgba(var(--pal-black-rgb), 0.02);
  --review-tabbtn-hover-bg: rgba(var(--pal-black-rgb), 0.06);
  --review-builder-panel-bg: var(--surface-primary);
  --review-loaded-siblings-panel-bg: var(--surface-secondary);
  --review-loaded-sibling-chip-bg: var(--surface-primary);
  --review-loaded-sibling-chip-fg: var(--text-secondary);
  --review-loaded-sibling-chip-hover-disabled-border: color-mix(
    in srgb,
    var(--color-primary) 45%,
    var(--review-border)
  );
  --review-loaded-sibling-chip--current-bg: var(--primary-50);
  --review-loaded-sibling-chipapproved-fg: var(--color-success);
  --review-loaded-segment-divider-bg: linear-gradient(
    90deg,
    color-mix(in srgb, var(--color-primary) 10%, var(--primary-50)) 0%,
    color-mix(in srgb, var(--color-primary) 12%, var(--primary-100)) 100%
  );
  --review-loaded-segment-dividerlink-hover-bg: color-mix(
    in srgb,
    var(--color-primary) 10%,
    transparent
  );
  --review-loaded-page-spinner-bg: color-mix(
    in srgb,
    var(--surface-primary) 75%,
    transparent
  );
  --review-loaded-page-slot-is-error-loaded-page-spinner-bg: color-mix(
    in srgb,
    var(--color-danger) 6%,
    var(--surface-primary)
  );
  --review-btn-danger-outline-border: var(--error-700);
  --review-btn-danger-outline-fg: var(--error-700);
  --review-btn-documents-review-btn-accent-orange-border: var(--warning-800);
  --review-btn-documents-review-btn-accent-orange-fg: var(--warning-800);
  --review-builder-carry-missing-fg: var(--warning-700);
  /* из ds-components.css */
  --ds-select-arrow-icon: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23475569' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  --ds-date-input-icon: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23475569' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'/%3E%3Cline x1='16' y1='2' x2='16' y2='6'/%3E%3Cline x1='8' y1='2' x2='8' y2='6'/%3E%3Cline x1='3' y1='10' x2='21' y2='10'/%3E%3C/svg%3E");
  --ds-text-success: var(--success-500);
  --ds-summary-tile--in-summary-value-fg: var(--success-500);
  --ds-finance-diagnosticsbadge--danger-fg: var(--error-700);
  --ds-finance-chainstate--ok-fg: var(--success-600);
  --ds-chain-state--warning-fg: var(--warning-800);
  --ds-text-brand-700-fg: color-mix(
    in srgb,
    var(--accent-interactive) 82%,
    var(--black)
  );
  /* из legacy-unified-compat.css */
  --legacy-app-header-bar-border: var(--app-header-bar-border);
  --legacy-workspace-action-link-bg: var(--workspace-action-link-bg);
  --legacy-workspace-action-link-border: var(--workspace-action-link-border);
  --legacy-workspace-action-link-fg: var(--workspace-action-link-text);
  --legacy-footer-link-fg: var(--footer-link-color);
  --legacy-text-secondary-theme-fg: var(--text-secondary-strong);
  --legacy-app-header-bar-bg: color-mix(
    in srgb,
    var(--surface-primary) 82%,
    transparent
  );
  --legacy-workspace-action-link-is-active-bg: color-mix(
    in srgb,
    var(--primary-color) 12%,
    var(--surface-primary)
  );
  --legacy-workspace-action-link-is-active-border: color-mix(
    in srgb,
    var(--primary-color) 28%,
    var(--border-color)
  );
  --legacy-workspace-action-link-is-active-fg: var(--primary-color);
  --legacy-footer-link-visited-fg: color-mix(
    in srgb,
    var(--secondary-900) 82%,
    var(--primary-700) 18%
  );
  /* из admin_monitoring.css, admin_boards.css */
  --mon-card-border: var(--gray-200);
  --mon-card-bg: linear-gradient(
    180deg,
    rgba(var(--highlight-rgb), 0.96),
    rgba(var(--pal-slate-50-rgb), 0.96)
  );
  --mon-title-fg: var(--secondary-900);
  --mon-subtitle-fg: var(--gray-500);
  --mon-meta-value-fg: var(--secondary-900);
  --mon-context-border: var(--gray-300);
  --mon-context-bg: rgba(var(--highlight-rgb), 0.65);
  --mon-context-fg: var(--gray-600);
  --mon-history-border: var(--tint-neutral-soft);
  --mon-history-bg: rgba(var(--highlight-rgb), 0.78);
  --mon-history-meta-fg: var(--gray-600);
  --boards-kanban-col-bg: var(--surface-secondary);
  /* из admin_dashboard.css */
  --admin-scope-bg-white: var(--pal-white);
  --admin-scope-bg-gray-50-half: color-mix(
    in srgb,
    var(--gray-50) 50%,
    transparent
  );
  --admin-scope-text-500: var(--text-muted);
  --admin-scope-border-100: var(--gray-100);
  --admin-scope-border-200: var(--gray-200);
  /* из ai_assistant.css */
  --ai-code-block-bg: var(--color-bg-subtle);
  --ai-code-inline-bg: rgba(var(--pal-black-rgb), 0.1);
  /* из login.css */
  --login-card-shadow: var(--shadow-lg);
  --login-link-button-shadow: none;
  --login-auth-invite-readonly-bg: var(--gray-legacy-e9);
  /* из portal_base.css */
  --portal-card-icon-primary-bg: var(--primary-50);
  --portal-card-icon-primary-fg: var(--primary-700);
  --portal-card-icon-info-bg: var(--info-50);
  --portal-card-icon-info-fg: var(--info-700);
  --portal-card-icon-border: transparent;
  --portal-sidebar-border: var(--border-color);
  --portal-sidebar-section-border: var(--border-color-subtle);
  --portal-top-bar-border: var(--glass-border);
  --portal-data-table-head-border: var(--border-color);
  --portal-data-table-row-border: var(--border-color);
  --portal-empty-state-bg: var(--surface-secondary);
  --portal-toolbar-bg: var(--surface-secondary);
  --portal-table-card-border: var(--card-border);
  --portal-card-icon-success-fg: var(--success-700);
  --portal-card-icon-warning-fg: var(--warning-700);
  --portal-card-icon-danger-fg: var(--danger-700);
  --portal-summary-card-emphasis-bg: linear-gradient(
    135deg,
    var(--primary-50),
    var(--card-bg)
  );
  --portal-summary-card-emphasis-border: var(--primary-100);
  --portal-theme-toggle-bg: var(--gray-50);
  --portal-theme-toggle-fg: var(--secondary-700);
  --portal-theme-toggle-border: 1px solid var(--gray-300);
  --portal-btn-secondary-fg: var(--slate-800);
  --portal-btn-secondary-border: 1px solid var(--button-secondary-border);
  --portal-btn-success-bg: var(--green-600);
  --portal-btn-success-fg: var(--text-inverse);
  --portal-btn-success-border: 1px solid var(--pal-green-700);
  --portal-badge-grid-button-status-badge-bg: var(--gray-100);
  --portal-badge-grid-button-status-badge-status-error-bg: var(--red-200);
  --portal-badge-grid-button-status-badge-status-error-fg: var(--danger-900);
  --portal-badge-grid-button-status-badge-status-error-border: var(--error-600);
  --portal-badge-grid-button-status-badge-status-needsrevie-bg: var(
    --warning-200
  );
  --portal-badge-grid-button-status-badge-status-needsrevie-fg: var(
    --warning-900
  );
  --portal-badge-grid-button-status-badge-status-processing-bg: var(--blue-100);
  --portal-badge-grid-button-status-badge-status-processing-fg: var(--blue-800);
  --portal-badge-grid-button-status-badge-status-processing-border: var(
    --blue-500
  );
  --portal-badge-grid-button-status-badge-status-queued-bg: var(--gray-200);
  --portal-badge-grid-button-status-badge-status-queued-fg: var(--slate-800);
  --portal-badge-grid-button-status-badge-status-queued-border: var(--gray-400);
  --portal-accountingfilterscount-bg: var(--indigo-50);
  --portal-accountingfilterscount-fg: var(--indigo-700);
  --portal-accountingfilterscount-border: 1px solid var(--indigo-200);
  --portal-skeleton-after-bg: linear-gradient(
    90deg,
    transparent 0%,
    rgba(var(--pal-white-rgb), 0.4) 50%,
    transparent 100%
  );
  --portal-sidebar-bg: linear-gradient(
    180deg,
    var(--surface-primary),
    var(--surface-secondary)
  );
  --portal-sidebar-header-bg: linear-gradient(
    180deg,
    rgba(var(--primary-500-rgb), 0.08),
    transparent
  );
  --portal-nav-link-hover-bg: var(--surface-hover);
  --portal-nav-link-active-bg: var(--primary-50);
  --portal-top-bar-bg: var(--glass-bg);
  --portal-data-table-thead-tr-bg: var(--surface-secondary);
  --portal-data-table-tbody-tr-bg: var(--surface-secondary);
  --portal-subnav-a-active-border: var(--primary-200);
  --portal-badge-grid-button-status-badge-bg-2: var(--slate-800);
  --portal-badge-grid-button-status-badge-border: var(--secondary-900);
  /* из tenant_portal.css */
  --tenant-card-icon-contracts-bg: var(--indigo-100);
  --tenant-card-icon-contracts-fg: var(--pal-indigo-800);
  --tenant-card-icon-invoices-bg: var(--warning-50);
  --tenant-card-icon-invoices-fg: var(--warning-800);
  --tenant-card-icon-balance-bg: var(--emerald-50);
  --tenant-card-icon-balance-fg: var(--success-500);
  --tenant-card-icon-payments-fg: var(--error-700);
  --tenant-badge-grid-button-status-badge-border: 1px solid var(--gray-300);
  --tenant-badge-grid-button-status-badge-bg: var(--gray-100);
  --tenant-badge-grid-button-status-badge-fg: var(--secondary-700);
  --tenant-badge-grid-button-status-badge-status-issued-bg: var(--orange-50);
  --tenant-badge-grid-button-status-badge-status-issued-fg: var(--orange-900);
  --tenant-badge-grid-button-status-badge-status-issued-border: var(
    --orange-700
  );
  --tenant-badge-grid-button-status-badge-status-overdue-bg: var(--danger-50);
  --tenant-badge-grid-button-status-badge-status-overdue-fg: var(--danger-900);
  --tenant-badge-grid-button-status-badge-status-overdue-border: var(
    --error-700
  );
  --tenant-badge-grid-button-status-badge-status-paid-bg: var(--emerald-50);
  --tenant-badge-grid-button-status-badge-status-paid-fg: var(--emerald-900);
  --tenant-badge-grid-button-status-badge-status-paid-border: var(
    --success-500
  );
  --tenant-badge-grid-button-status-badge-status-cancelled-fg: var(
    --secondary-700
  );
  --tenant-badge-grid-button-status-badge-status-cancelled-border: var(
    --gray-400
  );
  --tenant-badge-grid-button-status-badge-status-draft-bg: var(--gray-50);
  --tenant-badge-grid-button-status-badge-status-draft-fg: var(--slate-800);
  --tenant-badge-grid-button-status-badge-status-partpaid-bg: var(--blue-50);
  --tenant-badge-grid-button-status-badge-status-partpaid-fg: var(--blue-900);
  --tenant-badge-grid-button-status-badge-status-partpaid-border: var(
    --blue-500
  );
  --tenant-badge-grid-button-status-badge-status-active-fg: var(
    --secondary-900
  );
  --tenant-badge-grid-button-status-badge-status-active-border: var(--gray-500);
  --tenant-badge-grid-button-status-badge-status-pending-fg: var(--warning-900);
  --tenant-badge-grid-button-status-badge-status-pending-border: var(
    --warning-600
  );
  --tenant-badge-grid-button-status-badge-status-processing-bg: var(--info-100);
  --tenant-badge-grid-button-status-badge-status-processing-fg: var(--blue-900);
  --tenant-badge-grid-button-status-badge-status-processing-border: var(
    --blue-500
  );
  --tenant-btn-ghost-fg: var(--slate-800);
  --tenant-btn-ghost-border: 1px solid var(--button-secondary-border);
  --tenant-flex-space-x-2-px-4-py-2-bg: var(--indigo-600);
  --tenant-flex-space-x-2-px-4-py-2-fg: var(--text-inverse);
  --tenant-flex-space-x-2-px-4-py-2-border: 1px solid var(--indigo-700);
  --tenant-chat-section-btn-btn-success-bg: var(--green-600);
  --tenant-chat-section-btn-btn-success-fg: var(--text-inverse);
  --tenant-chat-section-btn-btn-success-border: 1px solid var(--pal-green-700);
  --tenant-btn-btn-success-bg: var(--pal-green-700);
  --tenant-btn-btn-success-fg: var(--text-inverse);
  --tenant-btn-btn-success-border: 1px solid var(--dark-success-600);
  --tenant-btn-btn-danger-bg: var(--error-700);
  --tenant-btn-btn-danger-fg: var(--text-inverse);
  --tenant-btn-btn-danger-border: 1px solid var(--red-800);
  /* из user_settings.css */
  --settings-user-settings-page-input-bg: var(--text-inverse);
  --settings-user-settings-page-input-border: 1px solid var(--gray-400);
  --settings-user-settings-page-input-accent-fg: var(--blue-600);
  --settings-user-settings-page-btn-secondary-border: 1px solid var(--gray-500);
  --settings-user-settings-page-btn-secondary-disabled-bg: var(--gray-100);
  --settings-user-settings-page-filter-control-border: var(--gray-400);
}

html[data-theme="dark"] {
  /* из accounting.css */
  --acc-quick-filter-button-is-active-border: var(--primary-400);
  --acc-quick-filter-button-is-active-box-shadow: 0 10px 22px
    color-mix(in srgb, var(--primary-500) 40%, transparent);
  --acc-chain-state--ok-fg: var(--success-400);
  --acc-chain-state--warning-bg: color-mix(
    in srgb,
    var(--warning-500) 35%,
    var(--surface-secondary)
  );
  --acc-chain-state--warning-fg: var(--warning-400);
  --acc-chain-state--danger-bg: color-mix(
    in srgb,
    var(--danger-500) 35%,
    var(--surface-secondary)
  );
  --acc-accounting-modal-header--primary-bg: color-mix(
    in srgb,
    var(--accent) 22%,
    var(--surface-primary)
  );
  --acc-accounting-modal-header--primary-border: var(--primary-500);
  --acc-manager-focus-pill-is-active-bg: var(--primary-900);
  --acc-manager-focus-pill-is-active-border: var(--primary-500);
  --acc-manager-focus-pill-is-active-fg: var(--primary-300);
  --acc-priority-pill--warning-fg: var(--warning-400);
  --acc-active-filter-chip-bg: var(--pal-slate-800);
  --acc-filters-count-badge-border: var(--primary-500);
  --acc-active-filter-chip-border: var(--pal-slate-600);
  /* из calendar.css */
  --cal-scale-btn-active-border: var(--button-primary-border);
  --cal-calendar-day-today-day-number-bg: var(--accent-interactive);
  --cal-calendar-day-today-day-number-fg: var(--text-inverse);
  --cal-event-priority-badge-priority-high-fg: color-mix(
    in srgb,
    var(--error-400) 92%,
    var(--pal-white)
  );
  --cal-event-priority-badge-priority-medium-fg: color-mix(
    in srgb,
    var(--warning-400) 95%,
    var(--pal-white)
  );
  --cal-event-priority-badge-priority-low-fg: color-mix(
    in srgb,
    var(--success-400) 92%,
    var(--pal-white)
  );
  /* из documents_queue.css */
  --queue-brand-link-fg: var(--primary-color);
  --queue-brand-link-hover-fg: var(--primary-400);
  --queue-chain-link-fg: var(--primary-color);
  --queue-chain-link-hover-fg: var(--primary-400);
  --queue-footnote-opacity: 0.92;
  --queue-docs-body-td-border-bottom: 1px solid var(--gray-600);
  --queue-quick-filter-button-is-active-border: var(--button-primary-border);
  --queue-finance-chainstate--warning-fg: var(--warning-500);
  --queue-finance-chainstate--danger-fg: var(--error-400);
  --queue-status-progress-box-shadow: inset 0 1px 0
    rgba(var(--pal-white-rgb), 0.06);
  --queue-documents-queue-table-tr-is-selected-bg: rgba(
    var(--pal-blue-500-rgb),
    0.12
  );
  --queue-doc-name-footnote--awaiting-fg: var(--warning-400);
  --queue-docs-packet-part-row-td-bg: rgba(var(--pal-white-rgb), 0.03);
  /* из documents_review.css */
  --review-ocr-lite-border: color-mix(
    in srgb,
    var(--border-color) 82%,
    var(--pal-white) 18%
  );
  --review-ocr-lite-bg: color-mix(
    in srgb,
    var(--surface-secondary) 78%,
    var(--pal-white) 12%
  );
  --review-builder-tag-bg: rgba(var(--pal-slate-900-rgb), 0.72);
  --review-builder-card-bg: rgba(var(--pal-slate-900-rgb), 0.72);
  --review-segment-divider-border: color-mix(
    in srgb,
    var(--color-primary) 40%,
    var(--review-border)
  );
  --review-page-img-border: color-mix(
    in srgb,
    var(--review-border) 70%,
    var(--surface-inverse)
  );
  --review-tabbtn-bg: rgba(var(--pal-white-rgb), 0.03);
  --review-tabbtn-hover-bg: rgba(var(--pal-white-rgb), 0.06);
  --review-builder-panel-bg: linear-gradient(
    135deg,
    rgba(var(--pal-violet-600-rgb), 0.14),
    rgba(var(--pal-slate-800-rgb), 0.94)
  );
  --review-loaded-siblings-panel-bg: var(--review-surface-elevated);
  --review-loaded-sibling-chip-bg: var(--review-surface-elevated);
  --review-loaded-sibling-chip-fg: var(--text-primary);
  --review-loaded-sibling-chip-hover-disabled-border: var(--color-primary);
  --review-loaded-sibling-chip--current-bg: color-mix(
    in srgb,
    var(--color-primary) 18%,
    var(--review-surface)
  );
  --review-loaded-sibling-chipapproved-fg: var(--color-success);
  --review-loaded-segment-divider-bg: linear-gradient(
    90deg,
    color-mix(in srgb, var(--color-primary) 20%, var(--review-surface)) 0%,
    color-mix(in srgb, var(--color-primary) 24%, var(--review-surface-elevated))
      100%
  );
  --review-loaded-segment-dividerlink-hover-bg: color-mix(
    in srgb,
    var(--color-primary) 15%,
    transparent
  );
  --review-loaded-page-spinner-bg: color-mix(
    in srgb,
    var(--review-surface) 80%,
    transparent
  );
  --review-loaded-page-slot-is-error-loaded-page-spinner-bg: color-mix(
    in srgb,
    var(--color-danger) 10%,
    var(--review-surface)
  );
  --review-btn-danger-outline-border: var(--error-400);
  --review-btn-danger-outline-fg: var(--error-400);
  --review-btn-documents-review-btn-accent-orange-border: var(--warning-400);
  --review-btn-documents-review-btn-accent-orange-fg: var(--warning-400);
  --review-builder-carry-missing-fg: var(--warning-400);
  /* из ds-components.css */
  --ds-select-arrow-icon: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='14' height='14' viewBox='0 0 24 24' fill='none' stroke='%23cbd5e1' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  --ds-date-input-icon: url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%23cbd5e1' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Crect x='3' y='4' width='18' height='18' rx='2'/%3E%3Cline x1='16' y1='2' x2='16' y2='6'/%3E%3Cline x1='8' y1='2' x2='8' y2='6'/%3E%3Cline x1='3' y1='10' x2='21' y2='10'/%3E%3C/svg%3E");
  --ds-text-success: var(--success-400);
  --ds-summary-tile--in-summary-value-fg: var(--emerald-400);
  --ds-finance-diagnosticsbadge--danger-fg: var(--error-400);
  --ds-finance-chainstate--ok-fg: var(--emerald-400);
  --ds-chain-state--warning-fg: var(--warning-400);
  --ds-text-brand-700-fg: var(--violet-300);
  /* из legacy-unified-compat.css */
  --legacy-app-header-bar-border: color-mix(
    in srgb,
    var(--border-color-strong) 60%,
    transparent
  );
  --legacy-workspace-action-link-bg: color-mix(
    in srgb,
    var(--surface-secondary) 90%,
    transparent
  );
  --legacy-workspace-action-link-border: color-mix(
    in srgb,
    var(--button-secondary-border) 72%,
    transparent
  );
  --legacy-workspace-action-link-fg: var(--text-primary);
  --legacy-footer-link-fg: color-mix(
    in srgb,
    var(--text-primary) 86%,
    var(--text-inverse) 14%
  );
  --legacy-text-secondary-theme-fg: color-mix(
    in srgb,
    var(--text-primary) 86%,
    var(--text-inverse) 14%
  );
  --legacy-app-header-bar-bg: color-mix(
    in srgb,
    var(--surface-primary) 72%,
    transparent
  );
  --legacy-workspace-action-link-is-active-bg: color-mix(
    in srgb,
    var(--primary-color) 22%,
    var(--surface-primary)
  );
  --legacy-workspace-action-link-is-active-border: color-mix(
    in srgb,
    var(--primary-color) 42%,
    var(--button-secondary-border)
  );
  --legacy-workspace-action-link-is-active-fg: var(--violet-200);
  --legacy-footer-link-visited-fg: color-mix(
    in srgb,
    var(--text-primary) 82%,
    var(--primary-300) 18%
  );
  /* из admin_monitoring.css, admin_boards.css */
  --mon-card-border: var(--secondary-700);
  --mon-card-bg: linear-gradient(
    180deg,
    rgba(var(--pal-gray-cool-900-rgb), 0.96),
    rgba(var(--pal-gray-cool-800-rgb), 0.96)
  );
  --mon-title-fg: var(--gray-50);
  --mon-subtitle-fg: var(--gray-400);
  --mon-meta-value-fg: var(--gray-100);
  --mon-context-border: var(--gray-600);
  --mon-context-bg: rgba(var(--shade-rgb), 0.4);
  --mon-context-fg: var(--gray-300);
  --mon-history-border: rgba(var(--pal-gray-cool-600-rgb), 0.8);
  --mon-history-bg: rgba(var(--shade-rgb), 0.55);
  --mon-history-meta-fg: var(--gray-300);
  --boards-kanban-col-bg: var(--slate-800);
  /* из admin_dashboard.css */
  --admin-scope-bg-white: var(--surface-primary);
  --admin-scope-bg-gray-50-half: var(--surface-secondary);
  --admin-scope-text-500: var(--text-secondary);
  --admin-scope-border-100: var(--border-color);
  --admin-scope-border-200: var(--border-color);
  /* из ai_assistant.css */
  --ai-code-block-bg: rgba(var(--pal-white-rgb), 0.1);
  --ai-code-inline-bg: rgba(var(--pal-white-rgb), 0.1);
  /* из login.css */
  --login-card-shadow: var(--shadow-sm);
  --login-link-button-shadow: var(--shadow-sm);
  --login-auth-invite-readonly-bg: var(--surface-secondary);
  /* из portal_base.css */
  --portal-card-icon-primary-bg: var(--surface-tertiary);
  --portal-card-icon-primary-fg: var(--text-secondary);
  --portal-card-icon-info-bg: var(--surface-tertiary);
  --portal-card-icon-info-fg: var(--text-secondary);
  --portal-card-icon-border: var(--border-color-subtle);
  --portal-sidebar-border: var(--gray-800);
  --portal-sidebar-section-border: var(--gray-800);
  --portal-top-bar-border: var(--border-color);
  --portal-data-table-head-border: var(--gray-700);
  --portal-data-table-row-border: var(--gray-800);
  --portal-empty-state-bg: var(--slate-800);
  --portal-toolbar-bg: var(--slate-800);
  --portal-table-card-border: var(--gray-800);
  --portal-card-icon-success-fg: var(--success-400);
  --portal-card-icon-warning-fg: var(--warning-400);
  --portal-card-icon-danger-fg: var(--danger-400);
  --portal-summary-card-emphasis-bg: linear-gradient(
    135deg,
    var(--blue-900),
    var(--slate-800)
  );
  --portal-summary-card-emphasis-border: var(--blue-900);
  --portal-theme-toggle-bg: var(--slate-800);
  --portal-theme-toggle-fg: var(--gray-100);
  --portal-theme-toggle-border: 1px solid var(--gray-600);
  --portal-btn-secondary-fg: var(--gray-100);
  --portal-btn-secondary-border: 1px solid var(--button-secondary-border);
  --portal-btn-success-bg: var(--green-500);
  --portal-btn-success-fg: var(--success-50);
  --portal-btn-success-border: 1px solid var(--success-500);
  --portal-badge-grid-button-status-badge-bg: var(--slate-800);
  --portal-badge-grid-button-status-badge-status-error-bg: var(--danger-100);
  --portal-badge-grid-button-status-badge-status-error-fg: var(--red-200);
  --portal-badge-grid-button-status-badge-status-error-border: var(--error-500);
  --portal-badge-grid-button-status-badge-status-needsrevie-bg: var(
    --warning-100
  );
  --portal-badge-grid-button-status-badge-status-needsrevie-fg: var(
    --warning-200
  );
  --portal-badge-grid-button-status-badge-status-processing-bg: var(--blue-900);
  --portal-badge-grid-button-status-badge-status-processing-fg: var(--blue-200);
  --portal-badge-grid-button-status-badge-status-processing-border: var(
    --blue-500
  );
  --portal-badge-grid-button-status-badge-status-queued-bg: var(--slate-800);
  --portal-badge-grid-button-status-badge-status-queued-fg: var(--info-50);
  --portal-badge-grid-button-status-badge-status-queued-border: var(--gray-500);
  --portal-accountingfilterscount-bg: var(--indigo-100);
  --portal-accountingfilterscount-fg: var(--primary-800);
  --portal-accountingfilterscount-border: 1px solid var(--indigo-300);
  --portal-skeleton-after-bg: linear-gradient(
    90deg,
    transparent 0%,
    rgba(var(--pal-white-rgb), 0.08) 50%,
    transparent 100%
  );
  --portal-sidebar-bg: linear-gradient(
    180deg,
    var(--gray-900),
    var(--gray-800)
  );
  --portal-sidebar-header-bg: linear-gradient(
    180deg,
    var(--blue-900),
    var(--gray-900)
  );
  --portal-nav-link-hover-bg: var(--gray-800);
  --portal-nav-link-active-bg: var(--blue-900);
  --portal-top-bar-bg: var(--slate-800);
  --portal-data-table-thead-tr-bg: var(--gray-800);
  --portal-data-table-tbody-tr-bg: var(--slate-800);
  --portal-subnav-a-active-border: var(--gray-700);
  --portal-badge-grid-button-status-badge-bg-2: var(--gray-600);
  --portal-badge-grid-button-status-badge-border: var(--gray-400);
  /* из tenant_portal.css */
  --tenant-card-icon-contracts-bg: var(--gray-300);
  --tenant-card-icon-contracts-fg: var(--secondary-900);
  --tenant-card-icon-invoices-bg: var(--warning-100);
  --tenant-card-icon-invoices-fg: var(--warning-200);
  --tenant-card-icon-balance-bg: var(--success-100);
  --tenant-card-icon-balance-fg: var(--green-200);
  --tenant-card-icon-payments-fg: var(--red-200);
  --tenant-badge-grid-button-status-badge-border: 1px solid var(--gray-600);
  --tenant-badge-grid-button-status-badge-bg: var(--slate-800);
  --tenant-badge-grid-button-status-badge-fg: var(--gray-100);
  --tenant-badge-grid-button-status-badge-status-issued-bg: var(--warning-100);
  --tenant-badge-grid-button-status-badge-status-issued-fg: var(--warning-200);
  --tenant-badge-grid-button-status-badge-status-issued-border: var(
    --warning-500
  );
  --tenant-badge-grid-button-status-badge-status-overdue-bg: var(--danger-100);
  --tenant-badge-grid-button-status-badge-status-overdue-fg: var(--red-200);
  --tenant-badge-grid-button-status-badge-status-overdue-border: var(
    --error-500
  );
  --tenant-badge-grid-button-status-badge-status-paid-bg: var(--success-100);
  --tenant-badge-grid-button-status-badge-status-paid-fg: var(--green-200);
  --tenant-badge-grid-button-status-badge-status-paid-border: var(--green-500);
  --tenant-badge-grid-button-status-badge-status-cancelled-fg: var(--info-50);
  --tenant-badge-grid-button-status-badge-status-cancelled-border: var(
    --gray-500
  );
  --tenant-badge-grid-button-status-badge-status-draft-bg: var(--secondary-900);
  --tenant-badge-grid-button-status-badge-status-draft-fg: var(--info-50);
  --tenant-badge-grid-button-status-badge-status-partpaid-bg: var(--gray-300);
  --tenant-badge-grid-button-status-badge-status-partpaid-fg: var(
    --secondary-900
  );
  --tenant-badge-grid-button-status-badge-status-partpaid-border: var(
    --gray-500
  );
  --tenant-badge-grid-button-status-badge-status-active-fg: var(
    --secondary-900
  );
  --tenant-badge-grid-button-status-badge-status-active-border: var(--gray-500);
  --tenant-badge-grid-button-status-badge-status-pending-fg: var(--warning-200);
  --tenant-badge-grid-button-status-badge-status-pending-border: var(
    --warning-500
  );
  --tenant-badge-grid-button-status-badge-status-processing-bg: var(--blue-200);
  --tenant-badge-grid-button-status-badge-status-processing-fg: var(--blue-900);
  --tenant-badge-grid-button-status-badge-status-processing-border: var(
    --blue-500
  );
  --tenant-btn-ghost-fg: var(--gray-100);
  --tenant-btn-ghost-border: 1px solid var(--button-secondary-border);
  --tenant-flex-space-x-2-px-4-py-2-bg: var(--indigo-100);
  --tenant-flex-space-x-2-px-4-py-2-fg: var(--primary-800);
  --tenant-flex-space-x-2-px-4-py-2-border: 1px solid var(--indigo-300);
  --tenant-chat-section-btn-btn-success-bg: var(--green-500);
  --tenant-chat-section-btn-btn-success-fg: var(--success-50);
  --tenant-chat-section-btn-btn-success-border: 1px solid var(--success-500);
  --tenant-btn-btn-success-bg: var(--green-200);
  --tenant-btn-btn-success-fg: var(--success-100);
  --tenant-btn-btn-success-border: 1px solid var(--success-600);
  --tenant-btn-btn-danger-bg: var(--red-200);
  --tenant-btn-btn-danger-fg: var(--danger-100);
  --tenant-btn-btn-danger-border: 1px solid var(--red-800);
  /* из user_settings.css */
  --settings-user-settings-page-input-bg: var(--secondary-900);
  --settings-user-settings-page-input-border: 1px solid var(--gray-600);
  --settings-user-settings-page-input-accent-fg: var(--blue-500);
  --settings-user-settings-page-btn-secondary-border: 1px solid var(--gray-600);
  --settings-user-settings-page-btn-secondary-disabled-bg: var(--secondary-900);
  --settings-user-settings-page-filter-control-border: var(--gray-500);
}

/* Роли, одинаковые в обеих темах: бумага при печати и подложка
   всплывающей подсказки `[data-tooltip]` (10.10.2026). */
:root {
  --print-paper: var(--pal-white);
  --print-ink: var(--pal-black);
  --print-ink-muted: var(--pal-legacy-555555);
  --print-rule: var(--pal-legacy-cccccc);
  --print-rule-soft: var(--pal-legacy-dddddd);
  --tooltip-bg: var(--pal-gray-legacy-333);
}

/* ==========================================================================
   5. ПЕЧАТЬ — тема всегда светлая (перенесено из unified-bundle.css).
   ========================================================================== */
@media print {
  /* ── печать: тема всегда светлая ──────────────────────────────────────
     Замер 18.08.2026: печатные правила задавали белый фон только `body`,
     а карточки и плитки сохраняли тёмную заливку и светлый текст. Браузер
     по умолчанию фон не печатает — на бумаге получался белый текст на
     белом листе, то есть пустая страница. Сбрасываем сами токены: всё,
     что построено на них (а после уборки этого месяца — почти всё),
     становится печатным без правил на каждый компонент. */
  :root,
  [data-theme="dark"],
  html[data-theme="dark"] {
    --surface-primary: var(--text-inverse);
    --surface-secondary: var(--text-inverse);
    --surface-tertiary: var(--text-inverse);
    --surface-hover: var(--text-inverse);
    --card-bg: var(--text-inverse);
    --bg-primary: var(--text-inverse);
    --bg-secondary: var(--text-inverse);
    --text-primary: var(--black);
    --text-secondary: var(--gray-legacy-222);
    --text-tertiary: var(--gray-legacy-444);
    --text-muted: var(--gray-legacy-444);
    --border-color: var(--gray-legacy-999);
    --border-color-strong: var(--gray-legacy-666);
    --card-border: var(--gray-legacy-999);
    --card-shadow: none;
    --shadow-sm: none;
    --shadow-md: none;
    --shadow-lg: none;
    --accent-text: var(--black);
    --link-color: var(--black);
    /* Статусные цвета как текст: на бумаге они остаются различимыми по
       оттенку, но читаются и в чёрно-белой печати. Светлые «тёмнотемные»
       значения (var(--success-800) и подобные) на белом листе исчезают. */
    --status-success-text: var(--success-100);
    --status-error-text: var(--danger-100);
    --status-warning-text: var(--warning-100);
    --status-info-text: var(--blue-900);
    /* Цвета категорий как текст: в тёмной теме это светлые оттенки
       (var(--blue-200) и подобные), на белом листе они пропадают. */
    --category-1-text: var(--blue-800);
    --category-2-text: var(--teal-800);
    --category-3-text: var(--violet-900);
  }
}

/* Меньше движения (a11y, 20.10.2026): одно общее правило вместо точечных.
   variables.css грузится первым на всех страницах, включая вход и кабинет. */
@media (prefers-reduced-motion: reduce) {
  *,
  *::before,
  *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}
