/* ============================================================
   Общие компоненты приложения «Час пик»: основа страницы и классы, которые
   строят шаблоны и JavaScript (.btn, .card, .rd-input, .status-pill, .tag,
   шторки, модалки, пикеры, .seg …). Подключается перед skin.css
   (см. templates/_styles.html); skin.css — палитра (роли --ui-*), иконки,
   графика — идёт последним и переписывает вид этих классов.

   Здесь:
     1. основа: сброс, шрифт, фокус, reduced-motion;
     2. старые имена переменных (--ink, --surface, --border …) как алиасы на
        роли --ui-*: страницы, написанные до перехода, перекрашиваются сами;
     3. компоненты — их строит JavaScript, и переписывать разметку там нечем;
     4. роли, нужные именно этому приложению (теги баланса, статус
        «просрочено»), — поверх ролей палитры, без литералов.
   ============================================================ */

/* ── Шрифт ──
   Inter подключён self-host (вариативный 400–700, один файл на сабсет); цифры
   везде табличные (font-feature-settings ниже). Заголовки — Manrope (skin.css). */
@font-face{font-family:'Inter';font-style:normal;font-weight:400 700;font-display:swap;
  src:url('/static/fonts/inter-cyrillic.woff2') format('woff2');
  unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116;}
@font-face{font-family:'Inter';font-style:normal;font-weight:400 700;font-display:swap;
  src:url('/static/fonts/inter-cyrillic-ext.woff2') format('woff2');
  unicode-range:U+0460-052F,U+1C80-1C88,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F;}
@font-face{font-family:'Inter';font-style:normal;font-weight:400 700;font-display:swap;
  src:url('/static/fonts/inter-latin.woff2') format('woff2');
  unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+2074,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD;}
@font-face{font-family:'Inter';font-style:normal;font-weight:400 700;font-display:swap;
  src:url('/static/fonts/inter-latin-ext.woff2') format('woff2');
  unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF;}

/* ── Старые имена → роли палитры ── */
:root{
  --bg:var(--ui-bg); --surface:var(--ui-surface); --surface-2:var(--ui-bg); --surface-3:var(--ui-bg);
  --ink:var(--ui-ink); --heading:var(--ui-heading);
  /* Три уровня приглушённого текста (ink-2, muted) вместо четырёх старых. */
  --text-2:var(--ui-ink-2); --muted:var(--ui-ink-2); --faint:var(--ui-muted); --faint-2:var(--ui-muted);
  --border:var(--ui-line); --border-input:var(--ui-line); --divider:var(--ui-line); --divider-2:var(--ui-line);
  --dashed:var(--ui-line-strong); --border-ghost:var(--ui-line);

  /* Статусы: текст + своя подложка. «Готово к загрузке» — бренд,
     «загружено» — good, «ещё нет» — нейтраль. */
  --ok-bg:var(--ui-good-50); --ok-text:var(--ui-good); --ok-dot:var(--ui-good);
  --ready-bg:var(--ui-primary-50); --ready-text:var(--ui-primary); --ready-dot:var(--ui-primary);
  --filled-border:color-mix(in srgb,var(--ui-primary) 40%,transparent);
  --neutral-bg:var(--ui-sunken); --neutral-text:var(--ui-ink-2); --neutral-dot:var(--ui-line-strong);

  /* Роли приложения поверх ролей палитры.
     «Просрочено» и необратимое — crit; предупреждение, структура, подсказка — warn
     (crit — для отказа, но в рабочем инструменте просроченный срок — отказ). */
  --danger:var(--ui-crit); --danger-2:var(--ui-crit); --danger-bg:var(--ui-crit-50);
  --struct-bg:var(--ui-warn-50); --struct-text:var(--ui-warn); --struct-dot:var(--ui-warn);
  --new-bg:var(--ui-primary-50); --new-text:var(--ui-primary);
  /* Фиолетовый — серия 4 скина (текст — тёмный --sk-av3) на своей 12-процентной подложке. */
  --code-bg:color-mix(in srgb,var(--sk-av3) 12%,var(--ui-surface));
  --code-text:var(--sk-av3); --code-dot:var(--sk-s4);
  --multi-bg:var(--ui-sunken); --multi-text:var(--ui-ink-2); --multi-dot:var(--sk-s6);
  --disabled-bg:var(--ui-sunken); --disabled-text:var(--ui-muted);

  --r-card:var(--ui-radius-card); --r-card-2:var(--ui-radius-m); --r-btn:var(--ui-radius-m);
  --r-input:var(--ui-radius-m); --r-pill:var(--ui-radius-pill);
  --font-ui:var(--ui-font); --font-mono:var(--ui-font);
  --shadow-drawer:var(--ui-shadow-drawer);
  --shadow-modal:var(--ui-shadow-float);
  --shadow-pop:var(--ui-shadow-float);
  --overlay:var(--ui-scrim);
}

/* ── Основа ── */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;background:var(--ui-bg)}
body{margin:0;background:var(--ui-bg);color:var(--ui-ink);font-family:var(--ui-font);font-size:15px;line-height:1.5;
  font-feature-settings:"tnum" 1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}
button,a,[role="button"]{touch-action:manipulation;-webkit-tap-highlight-color:transparent}
button,input,select,textarea{font:inherit;color:inherit}
button{cursor:pointer}
img,svg{display:block;max-width:100%}
:focus-visible{outline:2px solid var(--ui-focus);outline-offset:2px;border-radius:8px}
/* tabindex="-1" — цель для программного фокуса (<main>, панели), а не
   элемент, до которого доходят с клавиатуры: рамка вокруг целой страницы или
   панели ничего не подсказывает. Интерактивные элементы внутри остаются с рамкой. */
[tabindex="-1"]:focus,[tabindex="-1"]:focus-visible{outline:none}
/* Меньше движения — не значит без отклика. Анимации — одна мгновенная итерация
   (бесконечная в .01 мс мерцала бы, как у спиннера). Переходы цвета и
   прозрачности остаются, а шторки, модалки и панель не едут, а проявляются. */
@media (prefers-reduced-motion:reduce){
  *,*::before,*::after{animation-duration:.01ms!important;animation-iteration-count:1!important;scroll-behavior:auto!important}
  .drawer,.rd-modal,.modal,.ai-panel,.dz-orb,.toast{transform:none!important}
  .rd-side{transition-duration:0s!important}
}

*,*::before,*::after{margin:0;padding:0}
/* Под открытой модальной поверхностью страница не прокручивается. Правилом, а
   не скриптом: не зависит от того, чем панель закрыли — кнопкой, Escape или
   кликом по затемнению. */
body:has(dialog[open]){overflow:hidden}
/* Атрибут hidden должен скрывать всегда: display у .btn и подобных его перебивал
   (в шторке новой задачи торчала кнопка «Удалить»). */
[hidden]{display:none!important}
a{color:var(--ui-action)}
input,button,select,textarea{outline:none}
.mono{font-family:var(--ui-font);font-variant-numeric:tabular-nums}
.u-label{font-size:12px;letter-spacing:0;color:var(--ui-ink-2);font-weight:600}

/* ── Кнопки ──
   40 px на десктопе (рабочий инструмент плотнее клиентского продукта), 44 px
   под палец — цель касания не меньше 44 px. */
.btn{border:none;border-radius:var(--ui-radius-m);min-height:40px;padding:0 18px;font-size:14px;font-weight:700;
  line-height:1.2;display:inline-flex;align-items:center;justify-content:center;gap:8px;text-decoration:none;white-space:nowrap;
  transition:transform var(--ui-fast) ease-out,background-color var(--ui-fast) ease-out,box-shadow var(--ui-fast) ease-out,color var(--ui-fast) ease-out}
.btn:active:not(:disabled){transform:scale(0.98)}
.btn-primary{background:var(--ui-primary);color:var(--ui-on-primary);
  box-shadow:0 6px 18px -6px color-mix(in srgb,var(--ui-primary) 35%,transparent)}
.btn-primary:hover:not(:disabled){background:var(--ui-primary-hover)}
.btn-primary:active:not(:disabled){background:var(--ui-primary-pressed)}
.btn-ghost{background:var(--ui-sunken);color:var(--ui-heading)}
.btn-ghost:hover:not(:disabled){background:var(--ui-nav-hover)}
.btn:disabled,.btn.is-disabled{opacity:0.5;cursor:default;box-shadow:none}
@media (pointer:coarse){.btn{min-height:44px}}

/* ── Заголовок раздела ── 26 px на телефоне, крупнее от 768. */
.rd-h1{margin:0;font-size:28px;font-weight:700;letter-spacing:-0.01em;line-height:1.2;color:var(--ui-heading)}
@media (max-width:767px){.rd-h1{font-size:26px}}

/* ── Шапка страницы (templates/_page.html) ── раздел над заголовком, плашка периода, пояснение. */
.rd-head{display:flex;align-items:flex-end;justify-content:space-between;gap:16px 24px;flex-wrap:wrap;margin-bottom:4px}
.rd-head-main{min-width:0}
.rd-head-row{display:flex;align-items:center;gap:6px 14px;flex-wrap:wrap}
.rd-sub{margin:8px 0 0;font-size:15px;line-height:1.5;color:var(--ui-ink-2);max-width:68ch}
.rd-head-side{display:flex;align-items:center;gap:8px;flex-wrap:wrap}

/* Вкладки домена — фазы работы внутри раздела (источники → проверка →
   выгрузки). Второй уровень навигации: сайдбар несёт домены, страница — фазы.
   Язык вкладок — как у верхней навигации:
   активная — бренд и линия снизу. Прокручивается по горизонтали внутри себя:
   на 390 px три вкладки в строку не помещаются, а тянуть за собой прокрутку
   документа им нельзя. */
.rd-tabs{display:flex;gap:20px;margin:16px 0 0;box-shadow:inset 0 -1px 0 var(--ui-line);
  overflow-x:auto;scrollbar-width:none}
.rd-tabs::-webkit-scrollbar{display:none}
.rd-tabs a{position:relative;flex:0 0 auto;display:flex;align-items:center;min-height:var(--ui-touch);padding:0 2px;
  font-size:14px;font-weight:500;color:var(--ui-ink-2);text-decoration:none;white-space:nowrap;transition:color var(--ui-fast)}
.rd-tabs a::after{content:"";position:absolute;inset:auto 0 0;height:2px;border-radius:999px;background:transparent}
.rd-tabs a:hover{color:var(--ui-heading)}
.rd-tabs a.active{font-weight:600;color:var(--ui-primary)}
.rd-tabs a.active::after{background:var(--ui-primary)}

/* ── Карточки ── форма вместо линий: подложка и мягкая тень, без рамки. */
.card{background:var(--ui-surface);border-radius:var(--ui-radius-card);box-shadow:var(--ui-shadow-card)}

/* ── Поля ── утоплены в фон, на фокусе светлеют и получают кольцо бренда. */
.rd-input{width:100%;min-height:40px;font-size:14px;padding:0 14px;border:0;
  border-radius:var(--ui-radius-m);background:var(--ui-sunken);color:var(--ui-ink)}
.rd-input:focus{background:var(--ui-surface);box-shadow:inset 0 0 0 1px var(--ui-primary)}
.rd-input:disabled{opacity:0.5;cursor:default}
.rd-input[aria-invalid="true"],.rd-input.input-error{box-shadow:inset 0 0 0 1px var(--ui-warn)}
textarea.rd-input{padding-block:10px;line-height:1.5;min-height:0;resize:vertical}
.rd-input.mono{text-align:right;font-size:14px}
/* Список: своя стрелка вместо нативной. Относится ко всем
   <select> приложения: голый select в Safari и Chrome выглядел по-разному. */
select,select.rd-input{appearance:none;-webkit-appearance:none;cursor:pointer;min-height:40px;padding:0 36px 0 14px;
  border:0;border-radius:var(--ui-radius-m);background-color:var(--ui-sunken);color:var(--ui-ink);font-size:14px;
  background-image:linear-gradient(45deg,transparent 50%,var(--ui-ink-2) 50%),linear-gradient(135deg,var(--ui-ink-2) 50%,transparent 50%);
  background-position:calc(100% - 19px) 50%,calc(100% - 14px) 50%;background-size:5px 5px;background-repeat:no-repeat}
select:focus{background-color:var(--ui-surface);box-shadow:inset 0 0 0 1px var(--ui-primary)}
select:disabled{opacity:0.5;cursor:default}
@media (pointer:coarse){.rd-input,select{min-height:44px}}
/* Под пальцем поле не мельче 16 px: иначе iPhone увеличивает страницу при фокусе. */
@media (pointer:coarse){input:not([type=checkbox]):not([type=radio]),select,textarea{font-size:16px}}

/* ── Сегменты ── выбор из 2–5, активный — белая пилюля с тенью. */
.seg{display:inline-flex;gap:4px;padding:4px;background:var(--ui-sunken);border-radius:var(--ui-radius-pill)}
.seg button{border:0;background:transparent;border-radius:var(--ui-radius-pill);min-height:36px;padding:0 16px;
  font-size:14px;font-weight:500;color:var(--ui-ink-2);white-space:nowrap;
  transition:color var(--ui-fast),background-color var(--ui-fast)}
.seg button:hover{color:var(--ui-heading)}
.seg button.on,.seg button[aria-pressed="true"]{background:var(--ui-surface);color:var(--ui-heading);font-weight:700;box-shadow:var(--ui-shadow-card)}
.seg button:disabled{cursor:default;opacity:.5}

/* ── Статус-пилюли ── */
.status-pill{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;line-height:1.2;
  padding:4px 10px;border-radius:var(--ui-radius-pill)}
.status-pill .dot{width:6px;height:6px;border-radius:50%;flex:none}
.status-pill.ok{background:var(--ok-bg);color:var(--ok-text)} .status-pill.ok .dot{background:var(--ok-dot)}
.status-pill.ready{background:var(--ready-bg);color:var(--ready-text)} .status-pill.ready .dot{background:var(--ready-dot)}
.status-pill.neutral{background:var(--neutral-bg);color:var(--neutral-text)} .status-pill.neutral .dot{background:var(--neutral-dot)}
/* Просроченный срок: контрольная дата периода прошла, а реестры не собраны. */
.status-pill.late{background:var(--danger-bg);color:var(--danger-2)} .status-pill.late .dot{background:var(--danger)}
/* Плашка, которая ещё и кнопка захода на портал или криптораздел АТС: «Реестры»,
   «Штрафы», «Агрегатор спроса». */
.status-pill.portal{cursor:pointer}
.status-pill.portal:hover{background:var(--struct-bg);color:var(--struct-text)}
.status-pill.portal:hover .dot{background:var(--struct-dot)}


/* ── Маркеры-пилюли (баланс) ── */
.tag{display:inline-flex;align-items:center;gap:6px;font-size:12px;font-weight:700;padding:3px 10px;border-radius:var(--ui-radius-pill)}
.tag .dot{width:6px;height:6px;border-radius:50%}
.tag.struct{background:var(--struct-bg);color:var(--struct-text)} .tag.struct .dot{background:var(--struct-dot)}
.tag.code{background:var(--code-bg);color:var(--code-text)} .tag.code .dot{background:var(--code-dot)}
.tag.warn{background:var(--danger-bg);color:var(--danger-2)} .tag.warn .dot{background:var(--danger)}
.tag.new{background:var(--new-bg);color:var(--new-text)}
.tag.multi{background:var(--multi-bg);color:var(--multi-text);white-space:nowrap} .tag.multi .dot{background:var(--multi-dot)}

/* ── Чекбокс 18px ── */
.checkbox{width:18px;height:18px;border-radius:5px;background:var(--ui-surface);box-shadow:inset 0 0 0 1px var(--ui-muted);
  display:flex;align-items:center;justify-content:center;flex:none;transition:background-color var(--ui-fast)}
.checkbox.on{background:var(--ui-primary);box-shadow:none}
.checkbox .tick{width:4px;height:8px;border-right:2px solid var(--ui-on-primary);border-bottom:2px solid var(--ui-on-primary);
  transform:rotate(45deg);margin-top:-2px;opacity:0}
.checkbox.on .tick{opacity:1}

/* ── Шеврон (CSS-уголок) ── */
.chev{width:8px;height:8px;border-right:2px solid var(--ui-muted);border-bottom:2px solid var(--ui-muted);
  transform:rotate(45deg);transition:transform var(--ui-base);flex:none}
.chev.open{transform:rotate(-135deg)}

/* ── Оверлей + шторка ── */
/* Всплывающие окна растут из своей кнопки: scale(.97) от угла, где кнопка
   (transform-origin задаёт каждое окно), а не из центра и не просто проявляются. */
@keyframes rdPop{from{opacity:0;transform:scale(.97)}}
/* Вход и выход одним путём: close() не прячет поверхность рывком — display и
   overlay переключаются в конце перехода, пока шторка уезжает туда, откуда
   пришла. Открытие на полпути разворачивает переход с текущего положения, а
   уходящая поверхность клики уже не ловит. Обе стороны — ease-out (ease-in
   медлит в первый, самый заметный миг); вход --ui-base, выход быстрее —
   --ui-fast: правило без [open] задаёт выход, с [open] — вход. Браузер без
   allow-discrete закрывает мгновенно, как раньше. ⌘K (skin.css) не анимируется. */
.drawer-overlay,.rd-modal-overlay,.modal-overlay{
  transition:display var(--ui-fast) allow-discrete,overlay var(--ui-fast) allow-discrete}
:is(.drawer-overlay,.rd-modal-overlay,.modal-overlay):not([open]){pointer-events:none}
:is(.drawer-overlay,.rd-modal-overlay,.modal-overlay)::backdrop{background:var(--overlay);opacity:0;
  transition:opacity var(--ui-fast) var(--ui-ease-out),display var(--ui-fast) allow-discrete,overlay var(--ui-fast) allow-discrete}
:is(.drawer-overlay,.rd-modal-overlay,.modal-overlay)[open]::backdrop{opacity:1;transition-duration:var(--ui-base)}
@starting-style{:is(.drawer-overlay,.rd-modal-overlay,.modal-overlay)[open]::backdrop{opacity:0}}
/* Поверхность — нативный <dialog>: сбрасываем рамку, отступы и ограничения
   размера из UA-стилей, затемнение уезжает в ::backdrop. */
.drawer-overlay{position:fixed;inset:0;z-index:50;display:none;border:0;padding:0;margin:0;
  width:100%;height:100%;max-width:none;max-height:none;background:transparent;overflow:hidden}
.drawer-overlay[open]{display:block}
.drawer{position:absolute;top:0;right:0;bottom:0;max-width:94vw;background:var(--ui-bg);
  border-radius:var(--ui-radius-card) 0 0 var(--ui-radius-card);
  box-shadow:var(--shadow-drawer);display:flex;flex-direction:column;transform:translateX(48px);opacity:0;
  transition:transform var(--ui-fast) var(--ui-ease-out),opacity var(--ui-fast) var(--ui-ease-out)}
.drawer-overlay[open] .drawer{transform:none;opacity:1;transition-duration:var(--ui-base)}
@starting-style{.drawer-overlay[open] .drawer{transform:translateX(48px);opacity:0}}
.drawer-head{display:flex;align-items:flex-start;justify-content:space-between;gap:12px;padding:24px 28px 18px;
  background:var(--ui-surface);border-radius:var(--ui-radius-card) 0 0 0;box-shadow:inset 0 -1px 0 var(--ui-line)}
.drawer-head .title{font-size:22px;font-weight:700;letter-spacing:-0.01em;color:var(--ui-heading)}
.drawer-head .sub{font-size:13px;color:var(--ui-ink-2);margin-top:3px}
/* Закрыть: иконка в круге 40 px. */
.drawer-x{width:40px;height:40px;flex:none;display:inline-grid;place-items:center;padding:0;border-radius:var(--ui-radius-pill);border:0;
  background:transparent;font-size:16px;color:var(--ui-ink-2);transition:background-color var(--ui-fast),color var(--ui-fast)}
.drawer-x:hover{background:var(--ui-nav-hover);color:var(--ui-heading)}
.drawer-body{flex:1;overflow:auto;padding:22px 28px}
.drawer-foot{display:flex;align-items:center;justify-content:flex-end;gap:10px;padding:16px 28px;
  background:var(--ui-surface);box-shadow:inset 0 1px 0 var(--ui-line)}
@media (max-width:767px){
  .drawer-head,.drawer-body,.drawer-foot{padding-left:16px;padding-right:16px}
}

/* ── Модалка (профиль) ── */
.rd-modal-overlay{position:fixed;inset:0;z-index:70;display:none;align-items:center;justify-content:center;
  border:0;padding:0;margin:0;width:100%;height:100%;max-width:none;max-height:none;background:transparent}
.rd-modal-overlay[open]{display:flex}
.rd-modal{position:relative;width:440px;max-width:calc(100vw - 32px);background:var(--ui-surface);border-radius:var(--ui-radius-card);
  box-shadow:var(--shadow-modal);overflow:hidden}
/* Модалка проявляется и чуть вырастает, уходит тем же путём (см. «Оверлей»). */
.rd-modal,.modal{opacity:0;transform:scale(.97);
  transition:opacity var(--ui-fast) var(--ui-ease-out),transform var(--ui-fast) var(--ui-ease-out)}
:is(.rd-modal-overlay,.modal-overlay)[open] :is(.rd-modal,.modal){opacity:1;transform:none;transition-duration:var(--ui-base)}
@starting-style{:is(.rd-modal-overlay,.modal-overlay)[open] :is(.rd-modal,.modal){opacity:0;transform:scale(.97)}}

/* ── Месяц-пикер ── */
.mp-pop{position:absolute;background:var(--ui-surface);border-radius:var(--ui-radius-card);
  box-shadow:var(--shadow-pop);padding:12px;z-index:400;transform-origin:top left;animation:rdPop var(--ui-fast) var(--ui-ease-out)}
.mp-yr{display:flex;align-items:center;justify-content:space-between;margin-bottom:10px}
/* Цвет задан явно: пикер может жить внутри панели со своим цветом текста. */
/* Стрелки года — общая иконка chevron, повёрнутая влево и вправо. */
:is(.mp-yr,.mp-year-row)>button:first-child .ico{transform:rotate(90deg)}
:is(.mp-yr,.mp-year-row)>button:last-child .ico{transform:rotate(-90deg)}
.mp-yr b{font-size:14px;font-weight:700;color:var(--ui-heading)}
.mp-yr button{width:32px;height:32px;border-radius:var(--ui-radius-pill);border:0;background:transparent;
  display:flex;align-items:center;justify-content:center;color:var(--ui-ink-2)}
.mp-yr button:hover{background:var(--ui-nav-hover);color:var(--ui-heading)}
.mp-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:4px}
.mp-cell{border:0;background:transparent;color:var(--ui-ink);border-radius:var(--ui-radius-s);min-height:36px;padding:0;
  font-size:13px;font-weight:600}
.mp-cell:hover{background:var(--ui-nav-hover)}
.mp-cell.selected{background:var(--ui-primary);color:var(--ui-on-primary)}
.mp-cell.current{background:var(--ui-primary-50);color:var(--ui-primary)}

/* ── Календарь (выбор дня) ──
   Тот же попап, что у выбора месяца, только сеткой по неделям. Нужен там, где
   день выбирают из ограниченного списка: длинный <select> на полтораста
   отчётных дат листают, а не читают, и «когда была прошлая пятница» по нему
   не понять. Логика — static/js/date-picker.js. */
.cal-pop{width:260px;padding:12px}
.cal-week{display:grid;grid-template-columns:repeat(7,1fr);gap:2px;margin-bottom:4px}
.cal-week span{text-align:center;font-size:11px;font-weight:700;color:var(--ui-ink-2)}
.cal-grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
.cal-cell{border:0;background:transparent;color:var(--ui-ink);
  border-radius:var(--ui-radius-s);min-height:32px;padding:0;font-size:13px;font-weight:600;
  font-variant-numeric:tabular-nums}
.cal-cell:not(:disabled):hover{background:var(--ui-nav-hover)}
.cal-cell:disabled{color:var(--ui-muted);opacity:0.5;cursor:default}
.cal-cell.selected{background:var(--ui-primary);color:var(--ui-on-primary)}
.cal-cell.today{background:var(--ui-primary-50);color:var(--ui-primary)}
.cal-cell.empty{visibility:hidden}
/* Кнопка-поле: выглядит как .rd-input, ведёт себя как кнопка попапа. */
button.rd-input{cursor:pointer;display:flex;align-items:center;
  justify-content:space-between;gap:10px;text-align:left}
button.rd-input:hover{background:var(--ui-nav-hover)}

/* ── Фильтры и таблицы отчётов (Отчёты, Маржинальность) ── общее для обеих страниц. */
.controls-card{padding:20px 24px;margin-top:24px;margin-bottom:20px}
.controls-row{display:flex;align-items:flex-end;gap:12px 16px;flex-wrap:wrap}
.ctrl-group{display:flex;flex-direction:column;gap:6px;position:relative}
.ctrl-label{font-size:13px;font-weight:600;color:var(--ui-ink-2)}
.mp-wrap{position:relative;display:inline-block}
.mp-trigger{min-height:44px;padding:0 14px;border:0;border-radius:var(--ui-radius-m);background:var(--ui-sunken);
  font-family:inherit;font-size:14px;font-weight:600;color:var(--ui-heading);cursor:pointer;display:flex;align-items:center;
  gap:8px;user-select:none;white-space:nowrap;min-width:164px;transition:background-color var(--ui-fast)}
.mp-trigger:hover{background:var(--ui-nav-hover)}
/* Попап месяца выпадает поверх карточки таблицы, которая идёт ниже по DOM. */
.ctrl-group .mp-pop{z-index:400}
.mp-dropdown{position:absolute;top:calc(100% + 8px);left:0;z-index:400;background:var(--ui-surface);border-radius:var(--ui-radius-card);
  box-shadow:var(--ui-shadow-float);padding:12px;min-width:244px;transform-origin:top left;animation:rdPop var(--ui-fast) var(--ui-ease-out)}
.mp-year-row{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}
.mp-year-nav{width:32px;height:32px;border-radius:var(--ui-radius-pill);border:0;background:transparent;cursor:pointer;
  display:flex;align-items:center;justify-content:center;font-size:16px;color:var(--ui-ink-2)}
.mp-year-nav:hover{background:var(--ui-nav-hover);color:var(--ui-heading)}
.mp-year-val{font-size:14px;font-weight:700;color:var(--ui-heading)}
.mp-months{display:grid;grid-template-columns:repeat(3,1fr);gap:4px}
.mp-month{min-height:36px;border-radius:var(--ui-radius-s);border:0;background:none;font-family:inherit;font-size:13px;
  font-weight:600;color:var(--ui-ink);cursor:pointer;text-align:center}
.mp-month:hover{background:var(--ui-nav-hover)}
/* Реестры периода закрыты на 100 %. */
.mp-month.full{background:var(--ui-good-50);color:var(--ui-good)}
.mp-month.full:hover{background:color-mix(in srgb,var(--ui-good) 16%,var(--ui-surface))}
.mp-month.selected{background:var(--ui-primary);color:var(--ui-on-primary)}
/* Переключатель показателя («Объём» / «Стоимость»): выбранный — тихая подложка
   бренда, а не сплошная заливка: две ярко-синие плашки рядом с главной кнопкой
   спорили с ней за внимание. */
.metric-toggle-group{display:flex;gap:6px}
.metric-toggle{min-height:44px;padding:0 16px;border-radius:var(--ui-radius-m);border:0;background:var(--ui-sunken);
  font-family:inherit;font-size:14px;font-weight:600;color:var(--ui-ink-2);cursor:pointer;
  transition:background-color var(--ui-fast),color var(--ui-fast);display:flex;align-items:center;gap:6px}
.metric-toggle:hover{background:var(--ui-nav-hover);color:var(--ui-heading)}
.metric-toggle.on{background:var(--ui-primary-50);color:var(--ui-primary);box-shadow:inset 0 0 0 1px var(--ui-primary)}
/* Общий :focus-visible ставит радиус 8px — рамка фокуса и обводка выбранного
   переключателя расходились по форме углов (14px) и давали «кривую» двойную линию. */
.metric-toggle:focus-visible{border-radius:var(--ui-radius-m);outline-offset:3px}
.filter-row{display:flex;gap:8px;flex-wrap:wrap;margin-top:16px;padding-top:16px;border-top:1px solid var(--ui-line)}
.ms-wrap{position:relative}
.ms-trigger{min-height:36px;padding:0 14px;border:0;border-radius:var(--ui-radius-pill);background:var(--ui-sunken);font-family:inherit;
  font-size:13px;font-weight:600;color:var(--ui-heading);cursor:pointer;display:flex;align-items:center;gap:6px;white-space:nowrap;
  transition:background-color var(--ui-fast)}
.ms-trigger:hover{background:var(--ui-nav-hover)}
.ms-trigger.has-value{background:var(--ui-primary-50);color:var(--ui-primary)}
.ms-badge{background:var(--ui-primary);color:var(--ui-on-primary);border-radius:99px;padding:0 6px;font-size:12px;font-weight:700;
  min-width:18px;height:18px;display:flex;align-items:center;justify-content:center}
.ms-dropdown{display:none;position:absolute;top:calc(100% + 8px);left:0;z-index:300;background:var(--ui-surface);border-radius:var(--ui-radius-card);
  box-shadow:var(--ui-shadow-float);padding:10px;min-width:240px;max-width:340px;transform-origin:top left;animation:rdPop var(--ui-fast) var(--ui-ease-out)}
.ms-dropdown.open{display:block}
.ms-search{width:100%;min-height:36px;padding:0 12px;border:0;border-radius:var(--ui-radius-s);background:var(--ui-sunken);
  font-family:inherit;font-size:14px;margin-bottom:6px;outline:none}
.ms-search:focus{background:var(--ui-surface);box-shadow:inset 0 0 0 1px var(--ui-primary)}
.ms-list{max-height:220px;overflow-y:auto;display:flex;flex-direction:column;gap:1px}
.ms-item{display:flex;align-items:center;gap:10px;min-height:36px;padding:0 8px;border-radius:var(--ui-radius-s);cursor:pointer}
.ms-item:hover{background:var(--ui-bg)}
.ms-item input[type=checkbox]{width:16px;height:16px;accent-color:var(--ui-primary);cursor:pointer;flex-shrink:0}
.ms-item span{font-size:14px;font-weight:500;color:var(--ui-ink);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.ms-empty{font-size:13px;color:var(--ui-ink-2);text-align:center;padding:8px}
.ms-actions{display:flex;justify-content:flex-end;margin-top:6px;padding-top:6px;border-top:1px solid var(--ui-line)}
.ms-clear{font-size:13px;font-weight:600;color:var(--ui-crit);background:none;border:none;cursor:pointer;padding:6px 4px}
.table-card{padding:0;overflow:hidden}
.table-toolbar{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:20px 24px 14px}
.table-toolbar-title{font-size:18px;font-weight:700;color:var(--ui-heading)}
.table-toolbar-meta{font-size:14px;color:var(--ui-ink-2)}
.table-toolbar-right{display:flex;align-items:center;gap:14px}
.fs-btn{width:40px;height:40px;border:0;border-radius:var(--ui-radius-pill);background:transparent;cursor:pointer;display:flex;
  align-items:center;justify-content:center;color:var(--ui-ink-2);flex-shrink:0;transition:background-color var(--ui-fast),color var(--ui-fast)}
.fs-btn:hover{background:var(--ui-nav-hover);color:var(--ui-heading)}
.toggle-chevron{display:inline-block;font-size:12px;margin-right:7px;color:var(--ui-muted);transition:transform var(--ui-base);cursor:pointer}
.toggle-chevron.open{transform:rotate(90deg)}
tr.hidden{display:none}
.no-data{display:flex;flex-direction:column;align-items:center;justify-content:center;height:280px;color:var(--ui-ink-2);gap:8px}
.no-data p{font-size:15px;font-weight:600;color:var(--ui-heading)}
.no-data small{font-size:14px}
.spinner{display:flex;align-items:center;justify-content:center;height:240px;color:var(--ui-ink-2);font-size:14px;gap:10px}
@keyframes spin{to{transform:rotate(360deg)}}
.spin-ico{animation:spin 1s linear infinite;width:20px;height:20px;border:2.5px solid var(--ui-line);border-top-color:var(--ui-primary);border-radius:50%;display:inline-block}

/* ── Сверка с ЦФР005 (Авансовые платежи, Окончательный платеж) ──
   Сгруппированная таблица и плашки-баннеры сверки: общие для двух страниц,
   раньше были скопированы в оба шаблона. Таблица без вертикальной сетки,
   разделители только между строками. */
.rd-banners{display:flex;gap:12px;flex-wrap:wrap;margin-top:24px}
.rd-banners:empty{display:none}
.bn{flex:1 1 280px;border-radius:var(--ui-radius-m);background:var(--ui-surface);box-shadow:var(--ui-shadow-card);
  padding:16px 20px;font-size:14px;line-height:1.5;color:var(--ui-ink-2)}
.bn b{display:block;font-size:15px;font-weight:700;color:var(--ui-heading);margin-bottom:4px}
.bn.good{background:var(--ui-good-50);box-shadow:none;color:var(--ui-ink)} .bn.good b{color:var(--ui-good)}
.bn.bad{background:var(--ui-crit-50);box-shadow:none;color:var(--ui-ink)} .bn.bad b{color:var(--ui-crit)}
.bn.wait{background:var(--ui-sunken);box-shadow:none}
/* Плашка аванса с зафиксированными долями — кнопка сброса фиксации. Отдельной
   кнопки нет намеренно: позиций у аванса больше двадцати, и кнопка в каждой
   строке захламила бы таблицу, а сбрасывают фиксацию всегда целиком. */
.bn-fixed{cursor:pointer;transition:box-shadow var(--ui-fast)}
.bn-fixed:hover{box-shadow:var(--ui-shadow-float)}
:is(.sum-card,.fin-card){padding:0;overflow:hidden;margin-top:24px}
:is(.sum-scroll,.fin-scroll){overflow-x:auto}
:is(.sum-card,.fin-card) .rd-table{border-collapse:collapse;width:100%;font-size:14px;font-variant-numeric:tabular-nums}
:is(.sum-card,.fin-card) .rd-table th,:is(.sum-card,.fin-card) .rd-table td{border:0;border-top:1px solid var(--ui-line);padding:11px 14px;white-space:nowrap}
:is(.sum-card,.fin-card) .rd-table thead th{background:var(--ui-surface);border-top:0;font-weight:500;font-size:13px;color:var(--ui-ink-2);text-align:center}
:is(.sum-card,.fin-card) .rd-table thead tr:first-child th:first-child{text-align:left}
:is(.sum-card,.fin-card) .rd-table td:first-child{text-align:left;font-weight:600;color:var(--ui-heading)}
/* Окончательный платёж: десять колонок, суммы до 16 знаков. Все числа должны
   попадать на страницу без прокрутки, поэтому: подпись позиции переносится
   (штрафные позиции длинные — «КОМ бНЦЗ — штраф за неготовность…»), шапка
   тоже, а шрифт и поля подстраиваются под ширину карточки (единицы cqw от
   контейнера): на широком экране — 13px, на узком мельче, но не ниже 10px.
   Поля в em, чтобы вся таблица сжималась пропорционально. */
.fin-card{container-type:inline-size}
.fin-card .rd-table{font-size:clamp(10px,1.02cqw,13px)}
.fin-card .rd-table th,.fin-card .rd-table td{padding:.8em .6em}
.fin-card .rd-table th:first-child,.fin-card .rd-table td:first-child{padding-left:1.1em}
.fin-card .rd-table th:last-child,.fin-card .rd-table td:last-child{padding-right:1.1em}
.fin-card .rd-table td:first-child{white-space:normal;min-width:11em}
.fin-card .rd-table thead th{white-space:normal;line-height:1.3}
/* Вертикальные границы между смысловыми блоками таблицы */
#sum-table tbody td:is(:nth-child(2),:nth-child(6)),#sum-table thead tr:first-child th:nth-child(n+2),#sum-table thead tr:last-child th:nth-child(4n+1),
#fin-table tbody td:is(:nth-child(2),:nth-child(3),:nth-child(4),:nth-child(8)),#fin-table thead tr:first-child th:is(:nth-child(2),:nth-child(3),:nth-child(4),:nth-child(7)),
#fin-table thead tr:last-child th:is(:nth-child(1),:nth-child(3)){border-left:2px solid var(--ui-line-strong)}
.fin-card .rd-table tr.sep td{border-top:3px solid var(--ui-line-strong)}
.fin-card .rd-table .fin-sub{font-size:.85em;font-weight:400;color:var(--ui-ink-2)}
:is(.sum-card,.fin-card) .rd-table td.n{text-align:right}
:is(.sum-card,.fin-card) .rd-table td.n.ok{color:var(--ui-good)}
:is(.sum-card,.fin-card) .rd-table td.n.warn{color:var(--ui-crit);font-weight:700}
:is(.sum-card,.fin-card) .rd-table td.muted{color:var(--ui-ink-2);font-style:italic;font-weight:400}
/* Стоимость и авансы — основания остатка, а не он сам: приглушены. */
:is(.sum-card,.fin-card) .rd-table td.src{color:var(--ui-ink-2)}
/* Списание расхождения: подогнанная сумма ОСТ подсвечена, клик по ней снимает
   согласованное списание, клик по Δ — списывает. Отдельных кнопок не заводим. */
:is(.sum-card,.fin-card) .rd-table td.manual,:is(.sum-card,.fin-card) .rd-table td.adjusted{background:var(--ui-warn-50)}
:is(.sum-card,.fin-card) .rd-table td.adjusted,:is(.sum-card,.fin-card) .rd-table td.cancelable{cursor:pointer}
:is(.sum-card,.fin-card) .rd-table td.delta-writable{cursor:pointer;text-decoration:underline dotted}
:is(.sum-card,.fin-card) .rd-table tr.grp td{background:var(--ui-bg);font-weight:700;font-size:13px;color:var(--ui-ink-2)}
:is(.sum-card,.fin-card) .rd-table tr.tot td{background:var(--ui-primary-50);font-weight:700;color:var(--ui-heading)}
:is(.sum-card,.fin-card) .rd-table tr.sub td{background:var(--ui-bg);font-weight:400;color:var(--ui-ink-2)}
:is(.sum-card,.fin-card) .rd-table tr.sub td:first-child{font-weight:400}
:is(.sum-card,.fin-card) .rd-table input.pct{width:76px;min-height:32px;font-size:14px;padding:0 8px;border:0;border-radius:var(--ui-radius-s);
  background:var(--ui-sunken);text-align:right}
:is(.sum-card,.fin-card) .rd-table input.pct:focus{background:var(--ui-surface);box-shadow:inset 0 0 0 1px var(--ui-primary)}
:is(.sum-unmapped,.fin-unmapped){padding:20px 24px}
:is(.sum-unmapped,.fin-unmapped):empty{display:none}
:is(.sum-unmapped,.fin-unmapped) h3{font-size:15px;font-weight:700;color:var(--ui-heading);margin-bottom:8px}
:is(.sum-unmapped,.fin-unmapped) ul{list-style:none;display:flex;flex-direction:column;gap:6px;font-size:14px;color:var(--ui-ink-2)}

/* ── Тосты ── */
#rd-toast-c{position:fixed;bottom:24px;right:24px;z-index:4000;display:flex;flex-direction:column;gap:8px;max-width:calc(100vw - 32px)}
.toast{padding:12px 18px;background:var(--ui-heading);color:var(--ui-on-primary);border-radius:var(--ui-radius-m);font-size:14px;font-weight:600;
  box-shadow:var(--ui-shadow-float);
  transition:opacity var(--ui-base) var(--ui-ease-out),transform var(--ui-base) var(--ui-ease-out)}
/* Переход, а не ключевые кадры: несколько тостов подряд не начинают заново.
   Уходит быстрее, чем пришёл (.out ставит rdToast и убирает тост после него). */
@starting-style{.toast{opacity:0;transform:translateY(8px)}}
.toast.out{opacity:0;transform:translateY(8px);transition-duration:var(--ui-fast)}
.toast.success{background:var(--ui-good);color:var(--ui-good-50)}
.toast.error{background:var(--ui-crit);color:var(--ui-crit-50)}
.toast-act{margin-left:16px;padding:0;border:0;background:none;color:inherit;font:inherit;font-weight:700;
  text-decoration:underline;cursor:pointer}
.toast-act:hover{text-decoration-thickness:2px}

/* ── Аккордеоны разделов ── */
.accordion-list { display: flex; flex-direction: column; gap: 14px; margin-top: 22px; }
.acc-head { display: flex; align-items: center; gap: 16px; padding: 16px 22px; cursor: pointer;
  width: 100%; border: none; background: none; text-align: left; font-family: inherit; }
.acc-title { font-size: 16px; font-weight: 700; color: var(--ui-heading); flex: 1; }
.acc-counter { font-size: 13px; color: var(--ui-ink-2); }
.acc-mini { width: 90px; height: 6px; background: var(--ui-data-track); border-radius: var(--r-pill); overflow: hidden; }
.acc-mini-fill { height: 100%; width: 0; background: var(--ui-gradient-brand); border-radius: var(--r-pill); transition: width .3s ease-out; }
.accordion-body { display: none; }
.accordion-item.open .accordion-body { display: block; }
.accordion-item.open .acc-head .chev { transform: rotate(-135deg); }

/* ── Строка сектора. Колонки объявляет страница: у Реестров их четыре, у Авансов три. ── */
.sector-thead { display: grid; padding: 10px 22px;
  box-shadow: inset 0 1px 0 var(--ui-line); font-size: 12px; font-weight: 500; color: var(--ui-ink-2); }
.sector-row { display: grid; align-items: center;
  padding: 13px 22px; box-shadow: inset 0 1px 0 var(--ui-line); cursor: pointer; width: 100%;
  text-align: left; background: none; border: 0; font-family: inherit; transition: background-color var(--ui-fast); }
.sector-row:hover { background: var(--ui-bg); }
.sector-name { font-size: 14px; font-weight: 600; color: var(--ui-heading); }
.sector-zones { font-size: 12px; color: var(--ui-ink-2); margin-top: 2px; }
/* Штрафы: в колонке статуса по пилюле на каждый тип штрафа сектора. */
.fine-status { display: flex; flex-direction: column; gap: 4px; align-items: flex-start; }
.sector-by { font-size: 12px; color: var(--ui-ink-2); margin-top: 1px; display: flex; align-items: center; gap: 6px; }
.uploader-name { font-size: 12px; color: var(--ui-ink-2); }
.avatar { width: 34px; height: 34px; border-radius: 50%; display: flex; align-items: center;
  justify-content: center; font-size: 13px; font-weight: 700; color: var(--ui-on-primary); flex-shrink: 0; }
.avatar-sm { width: 22px; height: 22px; font-size: 11px; font-weight: 700; }

/* ── Карточки услуг ── */
.services-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; padding: 20px 22px; }
.service-card { border-radius: var(--r-card-2); padding: 16px 18px; background: var(--ui-bg); }
.service-card.filled { box-shadow: inset 0 0 0 1px var(--filled-border); background: var(--ui-surface); }
.service-card-head { display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px; }
.service-card-title { font-size: 14px; font-weight: 600; color: var(--ui-heading); }
.svc-flag { font-size: 12px; font-weight: 600; color: var(--ui-ink-2); }

/* ── Тело шторки загрузки ── */
.period-info {
  background: var(--ui-surface); border-radius: var(--r-input);
  padding: 10px 14px; font-size: 13px; color: var(--ui-ink-2); margin-bottom: 18px;
}
.zone-group { margin-bottom: 20px; }
.zone-title { font-size: 12px; font-weight: 700; color: var(--ui-ink-2); margin-bottom: 8px; }
/* Сохранённое состояние зоны — над таблицей выбора файлов, чтобы «что уже
   лежит в БД» и «что выбрано для отправки» нельзя было спутать. */
.zone-saved { font-size: 12px; font-weight: 600; color: var(--ready-text); background: var(--ready-bg);
  border-radius: var(--r-input); padding: 7px 11px; margin-bottom: 8px; }
.zone-saved.none { color: var(--ui-ink-2); background: var(--neutral-bg); font-weight: 400; }
/* Добавка УИРП: подпись под полем — откуда число или почему его нет (6.10). */
.uirp-extra-note { font-size: 12px; color: var(--ui-ink-2); margin-top: 5px; }
.rd-input.uirp-extra[readonly] { background: var(--ui-bg); cursor: default; }
/* Заголовок типа штрафа: над его ценовыми зонами. Черта — только между блоками,
   поэтому правило висит на заголовке, следующем за зонами предыдущего типа. */
.fine-type-title { font-size: 14px; font-weight: 700; color: var(--ui-heading); margin-bottom: 10px; }
.zone-group + .fine-type-title { margin-top: 26px; padding-top: 20px;
  border-top: 1px solid var(--ui-line); }
.registry-table { background: var(--ui-surface); border-radius: var(--r-card-2); overflow: hidden; }
.registry-table-head {
  display: grid; grid-template-columns: 90px 1fr 150px; gap: 10px;
  padding: 9px 14px; background: var(--ui-bg);
  font-size: 12px; font-weight: 500; color: var(--ui-ink-2);
}
.registry-row {
  display: grid; grid-template-columns: 90px 1fr 150px; gap: 10px; align-items: center;
  padding: 11px 14px; border-top: 1px solid var(--ui-line); background: var(--ui-surface);
}
.registry-row:first-of-type { border-top: none; }
.registry-name { font-size: 13px; font-weight: 600; color: var(--ui-heading); }
.filename-cell { font-size: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; color: var(--ui-ink-2); }
.code-valid { color: var(--ready-text); background: var(--ready-bg); padding: 0 2px; border-radius: 3px; }
.code-invalid { color: var(--danger); background: var(--danger-bg); padding: 0 2px; border-radius: 3px; }
.code-placeholder { color: var(--ui-muted); }
.status-loaded { display: flex; align-items: center; gap: 5px; font-size: 13px; font-weight: 600; color: var(--ready-text); }
.status-unloaded { font-size: 13px; color: var(--ui-ink-2); }
.status-invalid { display: flex; align-items: center; gap: 5px; font-size: 13px; font-weight: 600; color: var(--danger); }
.drop-zone {
  border: 2px dashed var(--ui-line-strong); border-radius: var(--ui-radius-card); min-height: 320px;
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  text-align: center; margin-top: 16px; cursor: pointer; transition: border-color var(--ui-fast), background-color var(--ui-fast);
}
.drop-zone.drag-over { border-color: var(--ui-primary); background: var(--ui-primary-50); }
.drop-zone-text { font-size: 14px; color: var(--ui-ink-2); }

/* ── Шторка загрузки и попапы пополнения справочников ──
   Механизм один на все страницы, где грузят реестры (partials/upload_modals.html,
   static/js/uploads.js), поэтому и стили общие: пока они лежали в index.html,
   вторая такая страница осталась бы без них. */
.drawer-warning {
  background: var(--struct-bg); border-radius: var(--r-input);
  padding: 10px 14px; font-size: 13px; color: var(--struct-text); margin-right: auto;
}

/* ── Toast (страничные тосты; контейнер, вид — из .toast выше) ── */
#toast-container {
  position: fixed; bottom: 26px; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 8px; z-index: 999;
  pointer-events: none; max-width: calc(100vw - 32px);
}

/* ── Modal (новые договоры / потребители) ── теперь на ролях палитры: раньше это
   был единственный экран в старой синей палитре. */
.modal-overlay {
  position: fixed; inset: 0; z-index: 5000;
  display: none; align-items: center; justify-content: center;
  padding: 24px; border: 0; margin: 0;
  width: 100%; height: 100%; max-width: none; max-height: none; background: transparent;
}
.modal-overlay[open] { display: flex; }
.modal {
  background: var(--ui-surface);
  border-radius: var(--ui-radius-card); box-shadow: var(--ui-shadow-float);
  width: 100%; max-width: 640px; max-height: 86vh;
  display: flex; flex-direction: column; padding: 22px 24px 20px;
}
.modal-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.modal-head h3 { font-size: 20px; font-weight: 700; letter-spacing: -0.01em; color: var(--ui-heading); margin: 0; }
.modal-sub { margin: 6px 0 16px; font-size: 13px; color: var(--ui-ink-2); line-height: 1.5; }
.cm-grid { display: grid; grid-template-columns: 1fr 150px 120px; gap: 10px; align-items: center; }
.cm-grid-head {
  font-size: 12px; font-weight: 500; color: var(--ui-ink-2);
  padding: 0 2px 8px; border-bottom: 1px solid var(--ui-line);
}
.cm-list { overflow-y: auto; margin-top: 8px; display: flex; flex-direction: column; gap: 8px; padding-right: 2px; }
.cm-row { display: grid; grid-template-columns: 1fr 150px 120px; gap: 10px; align-items: center; }
.cm-name { font-size: 13px; color: var(--ui-ink); font-family: var(--ui-font); white-space: normal; word-break: break-all; line-height: 1.35; cursor: pointer; }
.cm-name:hover { color: var(--ui-action); text-decoration: underline; }
.cm-type { padding: 0 32px 0 10px; font-size: 13px; font-family: inherit; width: 100%; }
.cm-code-field { border-radius: var(--ui-radius-s); background: var(--ui-sunken); }
.cm-code-field:focus-within { background: var(--ui-surface); box-shadow: inset 0 0 0 1px var(--ui-primary); }
.cm-code-field.input-error { box-shadow: inset 0 0 0 1px var(--ui-warn); }
.cm-code { width: 100%; border: none; background: transparent; outline: none; font-family: inherit; font-size: 13px; text-align: center; min-height: 36px; padding: 0 10px; color: var(--ui-ink); }
.modal-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 18px; }
.cons-grid { display: grid; grid-template-columns: 1fr 110px 90px; gap: 10px; align-items: center; }
.cons-row  { display: grid; grid-template-columns: 1fr 110px 90px; gap: 10px; align-items: center; }
.cons-code { font-size: 13px; color: var(--ui-ink-2); }
.gtp-grid { display: grid; grid-template-columns: 110px 1fr 90px; gap: 10px; align-items: center; }
.gtp-row  { display: grid; grid-template-columns: 110px 1fr 90px; gap: 10px; align-items: center; }
/* Пять колонок в стандартные 640px не помещаются: окну АОУ — своя ширина. */
#aou-modal .modal { max-width: 900px; }
.aou-grid { display: grid; grid-template-columns: 150px 1fr 150px 1fr 1fr; gap: 10px; align-items: center; }
.aou-row  { display: grid; grid-template-columns: 150px 1fr 150px 1fr 1fr; gap: 10px; align-items: center; }
/* Кнопки окон — те же .btn: 40 px, радиус 12, brand для главной. */
.modal-action-btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px; min-height: 40px; padding: 0 16px;
  font-size: 14px; font-weight: 700; font-family: inherit; border-radius: var(--ui-radius-m);
  cursor: pointer; border: none;
  transition: background-color var(--ui-fast) ease-out, transform var(--ui-fast) ease-out;
}
.modal-action-btn:active:not(:disabled) { transform: scale(0.98); }
.modal-action-btn.secondary { background: var(--ui-sunken); color: var(--ui-heading); }
.modal-action-btn.secondary:hover { background: var(--ui-nav-hover); }
.modal-action-btn.primary { background: var(--ui-primary); color: var(--ui-on-primary); }
.modal-action-btn.primary:hover { background: var(--ui-primary-hover); }
.modal-action-btn:disabled { opacity: .5; cursor: default; }
.card-remove {
  flex-shrink: 0; width: 32px; height: 32px;
  display: inline-flex; align-items: center; justify-content: center;
  border: none; background: transparent; border-radius: var(--ui-radius-pill);
  color: var(--ui-ink-2); font-size: 1.1rem; cursor: pointer;
}
.card-remove:hover { background: var(--ui-crit-50); color: var(--ui-crit); }

/* ── Подпись поля ── */
.field-label{display:block;margin-bottom:6px;font-size:14px;font-weight:700;color:var(--ui-heading)}

/* ── Баннер: сообщение над содержимым ── иконка + 1–2 строки. */
.banner{display:flex;align-items:flex-start;gap:12px;margin-bottom:16px;padding:16px;border-radius:var(--ui-radius-m);
  font-size:14px;background:var(--ui-primary-50);color:var(--ui-ink)}
.banner>svg{width:20px;height:20px;flex:none;margin-top:2px}
.banner>p{margin:0}
.banner--warn{background:var(--ui-warn-50);color:var(--ui-warn)}

/* ── Скелетон: загрузка по форме будущего блока ── */
.skeleton{border-radius:12px;background:color-mix(in srgb,var(--ui-line) 70%,transparent);animation:sk-pulse 2s cubic-bezier(.4,0,.6,1) infinite}
@keyframes sk-pulse{50%{opacity:.5}}

/* Отчёты-деревья с месяцами в столбцах: «Динамика отклонений», «Динамика цен». */
/* Шапка месяцев остаётся на экране: у длинного дерева без неё не понять, какой это столбец. */
.dv-wrap{overflow:auto;max-height:calc(100vh - 48px)}
/* Столбцы месяцев равной ширины: одинаковый разряд стоит друг под другом в любой строке. */
.dv-table{border-collapse:separate;border-spacing:0;table-layout:fixed;width:100%;font-size:14px;line-height:1.3;white-space:nowrap}
.dv-table th,.dv-table td{box-sizing:border-box;background:var(--ui-surface)}
.dv-table th{position:sticky;top:0;z-index:3;padding:10px 14px;vertical-align:bottom;font-size:13px;font-weight:600;color:var(--ui-heading);text-align:right;box-shadow:inset 0 -1px 0 var(--ui-line-strong)}
.dv-table th small{display:block;font-size:12px;font-weight:400;color:var(--ui-muted)}
/* По верху, а не по центру: в базовом столбце нет второй строки, и цена при центровке прыгала бы относительно соседних. */
.dv-table td{padding:9px 14px;vertical-align:top;box-shadow:inset 0 -1px 0 var(--ui-line)}
.dv-table th:first-child,.dv-table td:first-child{position:sticky;left:0;z-index:2;width:290px;text-align:left;overflow:hidden;text-overflow:ellipsis}
.dv-table th:first-child{z-index:4;box-shadow:inset -1px 0 0 var(--ui-line-strong),inset 0 -1px 0 var(--ui-line-strong)}
.dv-table td:first-child{box-shadow:inset -1px 0 0 var(--ui-line-strong),inset 0 -1px 0 var(--ui-line)}
.dv-table td.dv-cell{text-align:right;font-variant-numeric:tabular-nums}
.dv-table td.dv-none{color:var(--ui-muted)}
/* Базовый месяц — точка отсчёта, а не один из столбцов динамики. */
.dv-table th:nth-child(2),.dv-table td:nth-child(2){background:var(--ui-bg);box-shadow:inset -1px 0 0 var(--ui-line),inset 0 -1px 0 var(--ui-line)}
/* Изменение: отрицательный правый отступ оставляет цифры в одну линию и с заливкой, и без. */
.dv-table td.dv-cell small{display:block;width:fit-content;margin:2px -6px 0 auto;padding:0 6px;border-radius:6px;font-size:12px;font-weight:500;color:var(--ui-muted)}
.dv-table td.dv-cell small.up{color:var(--ui-crit)}
.dv-table td.dv-cell small.down{color:var(--ui-good)}
.dv-table td.dv-cell small.up.big{background:var(--ui-crit-50);font-weight:600}
.dv-table td.dv-cell small.down.big{background:var(--ui-good-50);font-weight:600}
/* Уровни дерева различаются весом и тоном, нижние строки плотнее и без линий — читаются одним блоком. */
.dv-l0 td,.dv-l0 td:nth-child(2){background:var(--ui-sunken);font-weight:700;color:var(--ui-heading)}
.dv-l1 td{font-weight:600;color:var(--ui-heading)}
.dv-l2 td{font-weight:500;color:var(--ui-ink)}
.dv-l3 td{padding-top:5px;padding-bottom:5px;font-weight:400;color:var(--ui-ink-2);box-shadow:none}
.dv-l3 td:first-child{box-shadow:inset -1px 0 0 var(--ui-line-strong)}
.dv-l3 td:nth-child(2){box-shadow:inset -1px 0 0 var(--ui-line)}
.dv-table tbody tr:hover td{background:var(--ui-sunken)}
.dv-unit{margin-left:6px;font-size:12px;font-weight:500;color:var(--ui-ink-2)}
.dv-note{margin:0;padding:0 24px 14px;font-size:13px;color:var(--ui-ink-2)}
.dv-toggle{all:unset;cursor:pointer;display:inline-flex;align-items:center;gap:6px}
.dv-toggle:focus-visible{outline:2px solid var(--ui-primary);outline-offset:2px;border-radius:4px}
