/* Blanc de Blancs — панель управленческого учёта
   components.css — компоненты. Требует tokens.css (подключать первым). */

/* ═══ База ═══ */
*,*::before,*::after{box-sizing:border-box}
html{-webkit-text-size-adjust:100%;scrollbar-gutter:stable}
body{margin:0;font-family:var(--font-sans);font-size:var(--text-base);line-height:var(--lh-normal);color:var(--text);background:var(--c-canvas);font-variant-numeric:tabular-nums;-webkit-font-smoothing:antialiased}
h1,h2,h3,h4,h5,p,figure,dl,dd,ul,ol{margin:0}
ul,ol{padding:0;list-style:none}
a{color:var(--link);text-decoration:none}
a:hover{color:var(--link-hover);text-decoration:underline}
button{font:inherit;color:inherit;background:none;border:0}
input,select,textarea,button{font-family:inherit}
svg{display:block}
img{max-width:100%;display:block}
:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px;border-radius:var(--radius-xs)}
::selection{background:var(--c-brand-100)}
hr{border:0;border-top:1px solid var(--border);margin:var(--space-4) 0}
@media (prefers-reduced-motion:reduce){*{animation-duration:.01ms!important;transition-duration:.01ms!important}}

/* ═══ Типографика ═══ */
.h1{font-family:var(--font-serif);font-size:var(--text-2xl);font-weight:var(--fw-bold);line-height:var(--lh-tight);color:var(--text-strong)}
.h2{font-family:var(--font-serif);font-size:var(--text-xl);font-weight:var(--fw-semibold);line-height:var(--lh-snug);color:var(--text-strong)}
.h3{font-size:var(--text-md);font-weight:var(--fw-semibold);color:var(--text-strong)}
.eyebrow{font-size:var(--text-xs);font-weight:var(--fw-semibold);letter-spacing:.06em;text-transform:uppercase;color:var(--text-muted)}
.muted{color:var(--text-muted)}
.small{font-size:var(--text-sm)}
.xs{font-size:var(--text-xs)}
.num,.money{font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1}
.money{white-space:nowrap}
.pos{color:var(--income)}
.neg{color:var(--expense)}
.warn{color:var(--discrepancy)}
.strong{font-weight:var(--fw-semibold);color:var(--text-strong)}
.mono{font-family:var(--font-mono)}

/* ═══ Раскладка ═══ */
.container{width:100%;max-width:var(--container);margin-inline:auto;padding-inline:var(--space-5)}
.container--wide{max-width:var(--container-wide)}
/* Свёрнутое меню отдаёт 16rem−4.5rem=11.5rem (184 px) контенту. Без этого правила они уходили
   в пустые поля по бокам центрированного контейнера — на 1920 со свёрнутым меню было заметно
   свободное место и слева, и справа. 100+11.5=111.5rem. */
.app-shell.is-collapsed .container--wide{max-width:111.5rem}
.main{padding-block:var(--space-6) var(--space-12)}
.stack{display:flex;flex-direction:column;gap:var(--space-4)}
.stack.gap-2{gap:var(--space-2)}.stack.gap-3{gap:var(--space-3)}.stack.gap-6{gap:var(--space-6)}.stack.gap-8{gap:var(--space-8)}
.cluster{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-3)}
.cluster.gap-2{gap:var(--space-2)}
.between{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3)}
.grid{display:grid;gap:var(--space-4)}
.page-head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-4);flex-wrap:wrap;margin-bottom:var(--space-5)}
.page-head .h1{margin-bottom:.1em}

/* ═══ Топбар (десктоп) ═══ */
.topbar{position:sticky;top:0;z-index:40;display:flex;align-items:center;gap:var(--space-6);height:var(--topbar-h);padding-inline:var(--space-5);background:var(--topbar-bg);color:var(--topbar-fg);box-shadow:var(--shadow-sm);backdrop-filter:saturate(1.2) blur(6px)}
.brand{display:inline-flex;align-items:center;gap:var(--space-2);color:#fff;font-weight:var(--fw-bold);letter-spacing:-.01em}
.brand:hover{text-decoration:none;color:#fff}
.brand__mark{display:grid;place-items:center;width:1.7rem;height:1.7rem;border-radius:var(--radius-sm);background:var(--c-brand-600);color:#fff;font-weight:var(--fw-bold);font-size:1rem}
.brand__sub{font-weight:var(--fw-regular);font-size:var(--text-sm);color:var(--c-slate-400);padding-left:var(--space-3);margin-left:var(--space-1);border-left:1px solid rgba(255,255,255,.18)}
.topbar__nav{display:flex;gap:var(--space-1);flex:1}
.topbar__nav a{color:rgba(255,255,255,.72);padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);font-weight:var(--fw-medium);font-size:var(--text-sm)}
.topbar__nav a:hover{color:#fff;background:rgba(255,255,255,.09);text-decoration:none}
.topbar__nav a.is-active{color:#fff;background:rgba(255,255,255,.14)}
.userbox{display:flex;align-items:center;gap:var(--space-3);margin-left:auto}
.userbox__id{display:flex;flex-direction:column;line-height:1.15;text-align:right}
.userbox__name{font-size:var(--text-sm);font-weight:var(--fw-medium)}
.userbox__role{font-size:var(--text-xs);color:rgba(255,255,255,.6)}
.icon-btn{display:grid;place-items:center;width:2rem;height:2rem;border-radius:var(--radius-sm);color:rgba(255,255,255,.8);cursor:pointer}
.icon-btn:hover{background:rgba(255,255,255,.12);color:#fff}
.icon-btn svg{width:18px;height:18px}

/* ═══ Нижняя навигация (мобайл) ═══ */
.bottom-nav{display:none}
@media (max-width:767px){
  .topbar__nav{display:none}
  .userbox__id{display:none}
  .bottom-nav{position:fixed;left:0;right:0;bottom:0;z-index:40;display:grid;grid-auto-flow:column;grid-auto-columns:1fr;height:var(--bottomnav-h);background:var(--c-surface);border-top:1px solid var(--border);padding-bottom:env(safe-area-inset-bottom);box-shadow:0 -2px 10px rgba(16,21,31,.06)}
  .bottom-nav a{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:2px;color:var(--text-muted);font-size:.6875rem;font-weight:var(--fw-medium)}
  .bottom-nav a:hover{text-decoration:none}
  .bottom-nav a svg{width:22px;height:22px}
  .bottom-nav a.is-active{color:var(--c-brand-600)}
  .has-bottom-nav{padding-bottom:calc(var(--bottomnav-h) + var(--space-6))}
}

/* ═══ Кнопки ═══ */
.btn{--_bg:var(--c-surface);--_fg:var(--text);--_bd:var(--border-strong);display:inline-flex;align-items:center;justify-content:center;gap:var(--space-2);height:2.5rem;padding-inline:var(--space-4);border:1px solid var(--_bd);border-radius:var(--radius-sm);background:var(--_bg);color:var(--_fg);font-size:var(--text-sm);font-weight:var(--fw-semibold);cursor:pointer;white-space:nowrap;transition:background .12s,border-color .12s,box-shadow .12s,color .12s}
.btn:hover{text-decoration:none}
.btn svg{width:1.05em;height:1.05em}
.btn:disabled,.btn[aria-disabled="true"]{opacity:.45;cursor:not-allowed;pointer-events:none}
.btn--primary{--_bg:var(--c-brand-600);--_fg:#fff;--_bd:var(--c-brand-600)}
.btn--primary:hover{--_bg:var(--c-brand-700);--_bd:var(--c-brand-700)}
.btn--secondary{--_bg:var(--c-surface);--_fg:var(--c-brand-700);--_bd:var(--c-brand-200)}
.btn--secondary:hover{--_bg:var(--c-brand-50)}
.btn--ghost{--_bg:transparent;--_bd:transparent;--_fg:var(--text-muted)}
.btn--ghost:hover{--_bg:var(--c-slate-100);--_fg:var(--text)}
.btn--danger{--_bg:var(--c-neg-600);--_fg:#fff;--_bd:var(--c-neg-600)}
.btn--danger:hover{--_bg:var(--c-neg-700);--_bd:var(--c-neg-700)}
.btn--sm{height:2rem;padding-inline:var(--space-3);font-size:var(--text-xs)}
.btn--lg{height:2.875rem;padding-inline:var(--space-6);font-size:var(--text-base)}
.btn--block{display:flex;width:100%}
.btn--icon{padding-inline:0;width:2.5rem}
.btn--icon.btn--sm{width:2rem}
.topbar .btn--ghost{--_fg:rgba(255,255,255,.8)}
.topbar .btn--ghost:hover{--_bg:rgba(255,255,255,.12);--_fg:#fff}

/* ═══ Формы ═══ */
.field{display:flex;flex-direction:column;gap:var(--space-2)}
.field.row{flex-direction:row;align-items:center;gap:var(--space-3)}
.label{font-size:var(--text-sm);font-weight:var(--fw-medium);color:var(--text-strong)}
.label .req{color:var(--c-neg-600)}
.label .opt{color:var(--text-muted);font-weight:var(--fw-regular)}
.hint{font-size:var(--text-xs);color:var(--text-muted)}
.input,.select,.textarea{width:100%;height:2.5rem;padding:0 var(--space-3);border:1px solid var(--border-strong);border-radius:var(--radius-sm);background:var(--c-surface);color:var(--text);font-size:var(--text-base);transition:border-color .12s,box-shadow .12s}
.textarea{height:auto;min-height:4.75rem;padding:var(--space-2) var(--space-3);line-height:var(--lh-normal);resize:vertical}
.input::placeholder,.textarea::placeholder{color:var(--c-slate-400)}
.input:hover,.select:hover,.textarea:hover{border-color:var(--c-slate-400)}
.input:focus,.select:focus,.textarea:focus{outline:none;border-color:var(--border-focus);box-shadow:var(--shadow-focus)}
.input:disabled,.select:disabled,.textarea:disabled,.input[readonly]{background:var(--c-slate-50);color:var(--text-muted);cursor:not-allowed}
.input[readonly]{cursor:default}
.select{appearance:none;-webkit-appearance:none;padding-right:var(--space-8);background-image: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='%23697182' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right var(--space-3) center;background-size:16px}
.field.is-error .input,.field.is-error .select,.input[aria-invalid="true"],.select[aria-invalid="true"]{border-color:var(--c-neg-500);box-shadow:0 0 0 3px rgba(213,52,42,.16)}
.error-text{font-size:var(--text-xs);color:var(--c-neg-700);display:flex;gap:.3em;align-items:center}
.error-text svg{width:.95em;height:.95em}
.input--sm{height:2rem;font-size:var(--text-sm);padding-inline:var(--space-2)}
/* поле суммы */
.amount{position:relative;display:flex;align-items:center}
.amount>.input{text-align:right;font-variant-numeric:tabular-nums;font-weight:var(--fw-medium);padding-right:1.9rem}
.amount__cur{position:absolute;right:var(--space-3);color:var(--text-muted);pointer-events:none;font-size:var(--text-sm)}
.amount.amount--sm>.input{padding-right:1.5rem}
.amount.amount--sm .amount__cur{right:var(--space-2)}

/* чекбокс / радио / переключатель */
.check{display:inline-flex;align-items:flex-start;gap:var(--space-2);cursor:pointer;font-size:var(--text-sm);color:var(--text)}
.check input{width:1.1rem;height:1.1rem;margin:.08rem 0 0;accent-color:var(--c-brand-600);flex:none;cursor:pointer}
.check input:disabled{cursor:not-allowed}
.check.is-disabled{color:var(--text-muted);cursor:not-allowed}
.switch{position:relative;display:inline-flex;align-items:center;gap:var(--space-2);cursor:pointer;font-size:var(--text-sm)}
.switch input{position:absolute;opacity:0;width:2.4rem;height:1.4rem;margin:0;cursor:pointer}
.switch__track{width:2.4rem;height:1.4rem;border-radius:var(--radius-full);background:var(--c-slate-300);position:relative;transition:background .15s;flex:none}
.switch__track::after{content:"";position:absolute;top:2px;left:2px;width:1rem;height:1rem;border-radius:50%;background:#fff;box-shadow:var(--shadow-sm);transition:transform .15s}
.switch input:checked+.switch__track{background:var(--c-brand-600)}
.switch input:checked+.switch__track::after{transform:translateX(1rem)}
.switch input:focus-visible+.switch__track{box-shadow:var(--shadow-focus)}

/* клавиша */
.kbd{display:inline-block;min-width:1.5em;padding:.12em .45em;border:1px solid var(--border-strong);border-bottom-width:2px;border-radius:var(--radius-xs);background:var(--c-surface);font-family:var(--font-mono);font-size:.78em;line-height:1.4;color:var(--text-strong);text-align:center;white-space:nowrap}

/* ═══ Карточки / панели ═══ */
.card{background:var(--c-surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:var(--space-5);box-shadow:var(--shadow-sm)}
.panel{background:var(--c-surface);border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);overflow:hidden}
.panel__head{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);padding:var(--space-4) var(--space-5);border-bottom:1px solid var(--border)}
.panel__title{font-size:var(--text-md);font-weight:var(--fw-semibold);color:var(--text-strong)}
.panel__body{padding:var(--space-5)}
.panel__body.flush{padding:0}
.panel__foot{padding:var(--space-4) var(--space-5);border-top:1px solid var(--border);background:var(--c-surface-2)}
.section-title{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-xs);font-weight:var(--fw-semibold);text-transform:uppercase;letter-spacing:.05em;color:var(--text-muted);margin-bottom:var(--space-3)}
.section-title .line{flex:1;height:1px;background:var(--border)}

/* ═══ KPI-карточки ═══ */
.cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(15rem,1fr));gap:var(--space-4)}
/* KPI-плитка с предупреждающим акцентом (итерация 5): значение на границе/выше цели.
   Составной селектор .kpi.kpi--warn — чтобы перебить базовое правило .kpi (та же специфичность, определено ниже). */
.kpi.kpi--warn{border-color:var(--c-warn-100);background:var(--c-warn-50)}
.kpi.kpi--warn .kpi__value{color:var(--c-warn-700)}
/* Раскладка «3 в ряд → 1 колонка на мобильном» (итерация 5, обязательства отчёта) */
.cols-3{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--space-4)}
@media (max-width:820px){.cols-3{grid-template-columns:1fr}}
.kpi{display:flex;flex-direction:column;gap:var(--space-2);background:var(--c-surface);border:1px solid var(--border);border-radius:var(--radius-lg);padding:var(--space-5);box-shadow:var(--shadow-sm)}
.kpi__label{font-size:var(--text-sm);color:var(--text-muted);font-weight:var(--fw-medium)}
.kpi__value{font-size:var(--text-2xl);font-weight:var(--fw-bold);line-height:1;color:var(--text-strong);font-variant-numeric:tabular-nums;letter-spacing:-.02em}
.kpi__value .cur{font-size:.55em;font-weight:var(--fw-semibold);color:var(--text-muted);margin-left:.2em}
.kpi__meta{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-sm);flex-wrap:wrap;color:var(--text-muted)}
.delta{display:inline-flex;align-items:center;gap:.15em;font-weight:var(--fw-semibold);font-variant-numeric:tabular-nums}
.delta--up{color:var(--income)}
.delta--down{color:var(--expense)}
.delta--flat{color:var(--text-muted)}
.delta__arrow{font-size:.8em;line-height:1}
/* Дельта «по смыслу» (итерация 5, Отчёт учредителю): цвет = хорошо/плохо/внимание
   НЕЗАВИСИМО от знака и направления стрелки — рост расхода красный при стрелке вверх.
   Разводит семантику с .delta--up/down (те красят по знаку). */
.delta--good{color:var(--income)}
.delta--bad{color:var(--expense)}
.delta--warn{color:var(--discrepancy)}

/* прогресс план/факт */
.progress{position:relative;height:.5rem;border-radius:var(--radius-full);background:var(--c-slate-100);overflow:hidden}
.progress__fill{position:absolute;inset:0 auto 0 0;height:100%;border-radius:inherit;background:var(--c-brand-500);transition:width .6s ease}
.progress__fill.is-pos{background:var(--c-pos-500)}
.progress__fill.is-warn{background:var(--c-warn-500)}
.progress-row{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-3);font-size:var(--text-sm);margin-bottom:var(--space-2)}

/* ═══ Таблицы ═══ */
.table-wrap{width:100%;overflow-x:auto;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--c-surface);box-shadow:var(--shadow-sm)}
table.data{width:100%;border-collapse:collapse;font-size:var(--text-sm)}
table.data th,table.data td{padding:var(--space-3) var(--space-4);text-align:left;border-bottom:1px solid var(--border);vertical-align:middle}
table.data thead th{position:sticky;top:0;z-index:1;background:var(--c-surface-2);font-size:var(--text-xs);font-weight:var(--fw-semibold);text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);white-space:nowrap}
table.data tbody tr:hover{background:var(--c-surface-2)}
table.data .num,table.data th.num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}
table.data tbody tr:last-child td{border-bottom:0}
table.data tr.is-total td{border-top:2px solid var(--border-strong);font-weight:var(--fw-bold);color:var(--text-strong);background:var(--c-surface-2)}
table.data tr.is-subtotal td{font-weight:var(--fw-semibold);background:var(--c-surface-2)}
table.data caption{text-align:left;padding:var(--space-3) var(--space-4);font-weight:var(--fw-semibold);color:var(--text-strong)}
.table--zebra tbody tr:nth-child(even){background:var(--c-surface-2)}
/* Липкая первая колонка (итерация 5, PnL × 12 месяцев): широкая таблица скроллится, статья закреплена слева */
.table--sticky1 th:first-child,.table--sticky1 td:first-child{position:sticky;left:0;z-index:2;background:var(--c-surface);text-align:left;will-change:transform}
.table--sticky1 thead th:first-child{z-index:3}
.table--sticky1 tr.is-total td:first-child,.table--sticky1 tr.is-subtotal td:first-child{background:var(--c-surface-2)}
.table--sticky1 tbody tr:hover td:first-child{background:var(--c-surface-2)}
.table--compact th,.table--compact td{padding:var(--space-2) var(--space-3)}
/* #108 часть 2: табель — 32–35 колонок по дням, 2861 px, ни в какой контейнер не влезет.
   Стикинг даёт .table--sticky1 (итерация 5, PnL) — в разметке табеля класс просто не стоял,
   а в моём макете держался инлайн-стилями на каждой ячейке. Здесь инлайн-хак становится
   правилом: плотной таблице нужны ещё две вещи, которых PnL не требовал, — гарантированная
   ширина колонки имени (иначе на скролле ФИО сжимается) и шов, чтобы уезжающие колонки
   не «прилипали» к имени без границы. Сужено до .table--dense: PnL (.data.table--sticky1)
   не затрагивается, его принятый вид остаётся прежним. */
.table--dense.table--sticky1 th:first-child,
.table--dense.table--sticky1 td:first-child{min-width:11rem;box-shadow:1px 0 0 var(--border)}
/* Строка-заголовок подразделения растянута colspan'ом. Фон обязателен — иначе сквозь ячейку
   видно уезжающие дни. Сама ячейка «прилипнуть» не может: она шириной во всю строку, и left:0
   ей не даёт запаса для сдвига — при прокрутке название группы уезжает вместе с днями.
   Поэтому липким делаем СОДЕРЖИМОЕ: <span> внутри ячейки. Правило безвредно, если span'а нет
   (в разметке прода название лежит текстом — нужно обернуть, одна правка на строку). */
.table--dense.table--sticky1 td[colspan]{background:var(--c-brand-50);color:var(--c-brand-700);box-shadow:none}
.table--dense.table--sticky1 td[colspan] > span,
.table--dense.table--sticky1 th[colspan] > span{position:sticky;left:var(--space-3);display:inline-block}
.cell-muted{color:var(--text-muted)}

/* ═══ Табличный ввод (кассовый день) ═══ */
table.entry{width:100%;border-collapse:collapse;font-size:var(--text-sm)}
table.entry thead th{background:var(--c-surface-2);font-size:var(--text-xs);font-weight:var(--fw-semibold);text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);text-align:left;padding:var(--space-2) var(--space-2);border-bottom:1px solid var(--border);white-space:nowrap}
table.entry th.num{text-align:right}
table.entry td{padding:.2rem .3rem;border-bottom:1px solid var(--border)}
table.entry td.rownum{width:2.2rem;text-align:center;color:var(--text-muted);font-size:var(--text-xs)}
/* Заголовок «№» наследовал text-align:left от table.entry thead th, а сама колонка — узкая
   и центрированная (не денежная величина, не нуждается в выравнивании по разрядам): «№» стоял
   у левого края ячейки, а цифры под ним — по центру. Оба выровнены по центру колонки. */
table.entry.entry--grid thead th{text-align:center}
table.entry td.amount-cell{width:9.5rem}
table.entry td.del-cell{width:2rem;text-align:center}
/* #292 · Импортные строки (source <> 'manual') — только для чтения: подложка говорит, что
   строка пришла извне и правке не поддаётся, а источник называет плашка в колонке суммы
   (.src--excel). Перенос принятого решения дизайнера (слой #188 итерации 18) — до него
   класс жил в разметке без единого правила. Курсив отклонён: табличные цифры в нём
   теряют разрядку. */
tr.imported-row>td{background:var(--c-surface-2)}
table.entry tr.imported-row:hover>td{background:var(--c-surface-2)}
/* #302 · Вторая ось различимости импортной строки (ответ дизайнера на замер ADV_292 П3).
   Заливка остаётся — она группирует строки, — но одна признаком быть не может: на карточке
   она даёт 1,05:1, а темнее нельзя, табличные цифры теряют разрядку. Признак — маркер в левой
   кромке первой ячейки: присутствие формы, а не оттенок, поэтому читается в ч/б и при
   дальтонизме. Замер: --c-slate-500 = 4,90:1 в светлой теме, 6,08:1 в тёмной при пороге 3:1
   для графических объектов; токен меняется вместе с темой, отдельного правила для dark нет.
   Цвет нейтральный намеренно: pos/neg/warn закреплены за денежной семантикой. */
tr.imported-row>td:first-child{box-shadow:inset 3px 0 0 var(--c-slate-500)}
/* #299 · Плашка источника под суммой — только в импортных строках. Колонку не расширяем
   (9,5rem подобраны под шесть колонок, на 375 запаса нет), плашку не сокращаем до иконки
   (слово «Excel» — единственное объяснение нередактируемости строки), седьмую колонку не
   вводим (сетка общая для экранов ввода). .src становится блочной, встаёт под сумму и
   прижимается вправо — длина суммы больше ни на что не влияет. Замер до правки: «Excel»
   резался до «Ex» на суммах от пяти знаков. Цена: импортные строки выше ручных на строку
   текста (21 px), одинаково для всех. */
tr.imported-row>td.amount-cell{white-space:normal}
tr.imported-row>td.amount-cell .src{display:flex;width:max-content;margin-left:auto;margin-top:2px}
.grid-input{width:100%;height:2.2rem;border:1px solid transparent;border-radius:var(--radius-sm);background:transparent;padding:0 var(--space-2);font-size:var(--text-sm);color:var(--text)}
.grid-input:hover{border-color:var(--border)}
.grid-input:focus{outline:none;border-color:var(--border-focus);box-shadow:var(--shadow-focus);background:var(--c-surface)}
select.grid-input{appearance:none;-webkit-appearance:none;padding-right:1.5rem;background-image: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='%23697182' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right .35rem center;background-size:14px}
.amount-cell .grid-input{text-align:right;font-variant-numeric:tabular-nums;font-weight:var(--fw-medium)}
.del-btn{width:1.6rem;height:1.6rem;display:grid;place-items:center;border-radius:var(--radius-sm);color:var(--text-muted);cursor:pointer;opacity:0;transition:opacity .1s,background .1s,color .1s}
table.entry tr:hover .del-btn,.del-btn:focus-visible{opacity:1}
.del-btn:hover{background:var(--c-neg-50);color:var(--c-neg-600)}
.del-btn svg{width:15px;height:15px}
.entry-foot td{padding:var(--space-2) var(--space-3);border-top:2px solid var(--border-strong);font-weight:var(--fw-semibold);background:var(--c-surface-2)}
.entry-foot .num{text-align:right;font-variant-numeric:tabular-nums;color:var(--text-strong)}

/* ═══ Бейджи ═══ */
.badge{display:inline-flex;align-items:center;gap:.35em;height:1.5rem;padding:0 .6em;border-radius:var(--radius-full);font-size:var(--text-xs);font-weight:var(--fw-semibold);white-space:nowrap;border:1px solid transparent;line-height:1}
.badge--neutral{background:var(--c-slate-100);color:var(--c-slate-700)}
.badge--brand{background:var(--c-brand-50);color:var(--c-brand-700)}
.badge--pos{background:var(--c-pos-50);color:var(--c-pos-700)}
.badge--neg{background:var(--c-neg-50);color:var(--c-neg-700)}
.badge--warn{background:var(--c-warn-50);color:var(--c-warn-700)}
.badge--info{background:var(--c-info-50);color:var(--c-info-700)}
.badge--card{background:color-mix(in srgb, var(--pay-card) 12%, transparent);color:var(--pay-card)}
.badge--cash{background:color-mix(in srgb, var(--pay-cash) 14%, transparent);color:var(--pay-cash)}
.pay-card{color:var(--pay-card)}
.pay-cash{color:var(--pay-cash)}
.badge__dot{width:.5em;height:.5em;border-radius:50%;background:currentColor}

/* бейдж сверки */
.recon{display:inline-flex;align-items:center;gap:var(--space-2);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);font-weight:var(--fw-semibold);font-size:var(--text-base);border:1px solid transparent;font-variant-numeric:tabular-nums}
.recon--ok{background:var(--c-pos-50);color:var(--c-pos-700);border-color:var(--c-pos-100)}
.recon--off{background:var(--c-warn-50);color:var(--c-warn-700);border-color:var(--c-warn-100)}
.recon__icon{width:1.4rem;height:1.4rem;border-radius:50%;display:grid;place-items:center;color:#fff;font-size:.9rem;font-weight:var(--fw-bold);flex:none;line-height:1}
.recon--ok .recon__icon{background:var(--c-pos-600)}
.recon--off .recon__icon{background:var(--c-warn-500)}
.recon--lg{font-size:var(--text-md);padding:var(--space-3) var(--space-4);width:100%;justify-content:center}
.recon--lg .recon__icon{width:1.6rem;height:1.6rem;font-size:1rem}

/* ═══ Алерты / тосты ═══ */
.alert{display:flex;gap:var(--space-3);padding:var(--space-3) var(--space-4);border-radius:var(--radius-md);border:1px solid transparent;font-size:var(--text-sm)}
.alert__icon{flex:none;width:1.25rem;height:1.25rem;margin-top:.05rem}
.alert__body{display:flex;flex-direction:column;gap:2px;min-width:0}
.alert__title{font-weight:var(--fw-semibold)}
.alert--info{background:var(--c-info-50);border-color:var(--c-info-100);color:var(--c-info-700)}
.alert--success{background:var(--c-pos-50);border-color:var(--c-pos-100);color:var(--c-pos-700)}
.alert--warn{background:var(--c-warn-50);border-color:var(--c-warn-100);color:var(--c-warn-700)}
.alert--danger{background:var(--c-neg-50);border-color:var(--c-neg-100);color:var(--c-neg-700)}
.toast-stack{position:fixed;right:var(--space-4);bottom:var(--space-4);z-index:80;display:flex;flex-direction:column;gap:var(--space-2);max-width:22rem}
@media (max-width:767px){.toast-stack{left:var(--space-4);right:var(--space-4);bottom:calc(var(--bottomnav-h) + var(--space-3));max-width:none}}
.toast{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3) var(--space-4);border-radius:var(--radius-md);background:var(--c-slate-900);color:#fff;box-shadow:var(--shadow-lg);font-size:var(--text-sm);font-weight:var(--fw-medium);animation:toast-in .25s ease}
.toast--success{background:var(--c-pos-700)}
.toast--danger{background:var(--c-neg-700)}
[data-theme="dark"] .toast{background:#2a3446}
@keyframes toast-in{from{opacity:0;transform:translateY(10px)}to{opacity:1;transform:none}}

/* ═══ Графики — вынесены в charts.css (полноценный класс компонентов) ═══ */

/* ═══ Кассовый день · раскладка ═══ */
/* Плашка «Сверка кассы» была 21rem — непропорционально широкой рядом с основной колонкой.
   Сужена на 30% (21×0.7=14.7rem): её контролы (суммы, два инпута, кнопки) не нуждаются
   в такой ширине, а освободившееся отдано «Расходам» напрямую, без изменения токенов. */
.cashday{display:grid;grid-template-columns:minmax(0,1fr) 14.7rem;gap:var(--space-5);align-items:start}
.cashday__main{display:flex;flex-direction:column;gap:var(--space-5);min-width:0}
.recon-rail{position:sticky;top:calc(var(--topbar-h) + var(--space-5));display:flex;flex-direction:column;gap:var(--space-4)}
@media (max-width:1023px){.cashday{grid-template-columns:1fr}.recon-rail{position:static}}
/* «Выручка» уменьшена вдвое, «Вносится вручную» вынесена из неё в свой блок той же высоты,
   в освободившейся половине — вместе с «Сверкой кассы» в рейке получаются три блока сводки
   по кассе. Ниже 900px — обратно в один столбец, тесно делить пополам не даёт смысла. */
.cashday-revenue-row{display:grid;grid-template-columns:1fr 1fr;gap:var(--space-5);align-items:start}
@media (max-width:900px){.cashday-revenue-row{grid-template-columns:1fr}}

/* ═══ Справочник счёта / контрагента (rich select на <details>, работает без JS) ═══ */
.picker{position:relative;display:inline-block}
.picker>summary{list-style:none;display:flex;align-items:center;gap:var(--space-2);height:2.5rem;padding:0 var(--space-3);border:1px solid var(--border-strong);border-radius:var(--radius-sm);background:var(--c-surface);cursor:pointer;font-size:var(--text-base);min-width:14rem}
.picker>summary::-webkit-details-marker{display:none}
.picker>summary::after{content:"";margin-left:auto;flex:none;width:16px;height:16px;background: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='%23697182' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E") center/16px no-repeat}
.picker[open]>summary{border-color:var(--border-focus);box-shadow:var(--shadow-focus)}
.picker__value{display:inline-flex;align-items:center;gap:var(--space-2);min-width:0;overflow:hidden;white-space:nowrap;text-overflow:ellipsis}
.picker__menu{position:absolute;z-index:30;top:calc(100% + 4px);left:0;min-width:18rem;max-height:19rem;overflow:hidden auto;background:var(--c-surface);border:1px solid var(--border);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);padding:var(--space-1)}
.picker__grouphead{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-xs);font-weight:var(--fw-semibold);text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);padding:var(--space-3) var(--space-2) var(--space-1)}
.picker__opt{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2);border-radius:var(--radius-sm);cursor:pointer;font-size:var(--text-sm);position:relative}
.picker__opt:hover{background:var(--c-surface-2)}
.picker__opt input{position:absolute;width:1px;height:1px;opacity:0}
.picker__opt input:focus-visible+.picker__label{outline:2px solid var(--border-focus);outline-offset:2px;border-radius:var(--radius-xs)}
.picker__label{display:inline-flex;align-items:center;gap:var(--space-2);flex:1;min-width:0}
.picker__opt .picker__label>.grp{margin-left:auto;flex:none}
.picker__name{flex:1;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.picker__opt:has(input:checked){background:var(--c-brand-50)}
.picker__opt:has(input:checked)::after{content:"";margin-left:auto;flex:none;width:16px;height:16px;background: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='%232b4fc4' stroke-width='2.5' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='20 6 9 17 4 12'/%3E%3C/svg%3E") center/16px no-repeat}
/* #096: поле поиска в пикере + пустой результат. .picker__opts — прокручиваемая область
   под зафиксированным поиском (поиск не уезжает при скролле 553 опций). */
.picker__search{position:sticky;top:0;z-index:1;background:var(--c-surface);padding:var(--space-2);border-bottom:1px solid var(--border)}
.picker__search-input{width:100%;height:2.25rem;padding:0 var(--space-2);border:1px solid var(--border-strong);border-radius:var(--radius-sm);font-size:var(--text-sm);background:var(--c-surface)}
.picker__search-input:focus{outline:none;border-color:var(--border-focus);box-shadow:var(--shadow-focus)}
.picker__opts{padding:var(--space-1)}
.picker__empty{padding:var(--space-3) var(--space-2);text-align:center}

/* Метка счёта (банк): цветной моно-квадрат + короткое имя (+опц. локальная иконка) */
.acct{display:inline-flex;align-items:center;gap:.5em;min-width:0}
.acct__mark{width:1.3rem;height:1.3rem;border-radius:4px;background:var(--acct-color,var(--acct-default));color:#fff;display:grid;place-items:center;font-size:.72rem;font-weight:var(--fw-bold);flex:none}
.acct__icon{width:1.3rem;height:1.3rem;border-radius:4px;object-fit:contain;flex:none}
.acct__name{font-weight:var(--fw-medium);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}

/* Группа контрагентов: цветная плашка + пиктограмма */
.grp{display:inline-flex;align-items:center;gap:.4em;font-size:var(--text-xs);color:var(--text-muted);white-space:nowrap}
.grp__ic{width:1.15rem;height:1.15rem;border-radius:4px;display:grid;place-items:center;color:#fff;flex:none;background:var(--grp,var(--c-slate-400))}
.grp__ic svg{width:.78rem;height:.78rem}
.grp--alcohol{--grp:var(--grp-alcohol)}
.grp--food{--grp:var(--grp-food)}
.grp--services{--grp:var(--grp-services)}
.grp--rent{--grp:var(--grp-rent)}
.grp--utilities{--grp:var(--grp-utilities)}
.grp--payroll{--grp:var(--grp-payroll)}
.grp--household{--grp:var(--grp-household)}
.grp--aggregators{--grp:var(--grp-aggregators)}
.grp--taxes{--grp:var(--grp-taxes)}
.grp--transport{--grp:var(--grp-transport)}
.grp--repair{--grp:var(--grp-repair)}
.grp--other{--grp:var(--grp-other)}

/* Бейдж источника данных (нейтральный, цветовой код точкой). Без чужих логотипов. */
.src{display:inline-flex;align-items:center;gap:.35em;height:1.3rem;padding:0 .45em;border-radius:var(--radius-xs);background:var(--c-slate-100);color:var(--c-slate-600);font-size:.6875rem;font-weight:var(--fw-semibold);letter-spacing:.02em;white-space:nowrap;border:1px solid var(--border);font-variant-numeric:normal}
.src__dot{width:.45em;height:.45em;border-radius:50%;background:var(--src,var(--c-slate-400));flex:none}
.src--1c{--src:var(--src-1c)}
.src--sbis{--src:var(--src-sbis)}
.src--bank{--src:var(--src-bank)}
.src--manual{--src:var(--src-manual)}
.src--excel{--src:var(--src-excel)}
.src__ic{width:.95rem;height:.95rem;object-fit:contain;border-radius:2px;flex:none}

/* ═══ История · журнал улучшений (лента) ═══ */
.changelog{position:relative;display:flex;flex-direction:column;gap:var(--space-6);padding-left:var(--space-6);margin:0}
.changelog::before{content:"";position:absolute;left:.35rem;top:.5rem;bottom:.5rem;width:2px;background:var(--border)}
.change{position:relative}
.change::before{content:"";position:absolute;left:calc(-1 * var(--space-6) + .05rem);top:.4rem;width:.7rem;height:.7rem;border-radius:50%;background:var(--c-brand-500);border:2px solid var(--c-surface);box-shadow:0 0 0 2px var(--border)}
.change__date{font-size:var(--text-xs);color:var(--text-muted);font-variant-numeric:tabular-nums}
.change__title{font-size:var(--text-md);font-weight:var(--fw-semibold);color:var(--text-strong);margin:.15em 0 .3em;letter-spacing:-.01em}
.change__desc{color:var(--text);max-width:68ch;text-wrap:pretty}
.change__tags{display:flex;gap:var(--space-2);margin-top:var(--space-3);flex-wrap:wrap}

/* ═══ Утилиты ═══ */
.right{text-align:right}.center{text-align:center}.nowrap{white-space:nowrap}
.divider{height:1px;background:var(--border);border:0}
.tag{display:inline-flex;align-items:center;gap:.3em;padding:.12em .5em;border-radius:var(--radius-sm);background:var(--c-slate-100);color:var(--c-slate-700);font-size:var(--text-xs);font-weight:var(--fw-medium)}
.sr-only{position:absolute!important;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}
.dl-figures{display:grid;grid-template-columns:1fr auto;gap:var(--space-2) var(--space-6);font-size:var(--text-sm);align-items:baseline}
.dl-figures dt{color:var(--text-muted)}
.dl-figures dd{margin:0;text-align:right;font-variant-numeric:tabular-nums;font-weight:var(--fw-medium);color:var(--text-strong);white-space:nowrap}
.dl-figures .rule{grid-column:1 / -1;height:1px;background:var(--border);margin:var(--space-1) 0}
.dl-figures .big dt,.dl-figures .big dd{font-size:var(--text-md);font-weight:var(--fw-bold);color:var(--text-strong)}

/* ═══ Вход ═══ */
.auth{min-height:100dvh;display:grid;place-items:center;padding:var(--space-5);background:var(--c-canvas)}
.auth__card{width:100%;max-width:24rem;background:var(--c-surface);border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-lg);padding:var(--space-8) var(--space-8) var(--space-6)}
.auth__brand{display:flex;flex-direction:column;align-items:center;gap:var(--space-3);margin-bottom:var(--space-6);text-align:center}
.auth__brand .brand__mark{width:2.75rem;height:2.75rem;font-size:1.5rem}
.auth__brand h1{font-size:var(--text-lg);color:var(--text-strong)}
.auth__foot{margin-top:var(--space-6);text-align:center;font-size:var(--text-xs);color:var(--text-muted)}

/* ═══ Навигация 2.0 (#029): sidebar + мобильный оффканвас + табы разделов ═══ */
.app-shell{display:flex;align-items:stretch;min-height:100dvh}
.nav-toggle-checkbox{position:absolute;opacity:0;width:1px;height:1px;pointer-events:none}
.sidebar{flex:none;width:var(--sidebar-w);position:sticky;top:0;height:100dvh;display:flex;flex-direction:column;background:var(--sidebar-bg);color:#fff;z-index:var(--z-sidebar);transition:width .15s ease,background .15s ease}
.sidebar__top{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-4) var(--space-4) var(--space-3);flex:none}
.sidebar__brand{display:flex;align-items:center;gap:var(--space-2);min-width:0;color:#fff;font-weight:var(--fw-bold);flex:1}
.sidebar__brand:hover{color:#fff;text-decoration:none}
.sidebar__brand-text{display:flex;flex-direction:column;line-height:1.2;overflow:hidden;white-space:nowrap}
.sidebar__brand-text small{font-size:var(--text-xs);font-weight:var(--fw-regular);color:rgba(255,255,255,.55)}
.sidebar__collapse-btn{flex:none;width:1.75rem;height:1.75rem;display:grid;place-items:center;border-radius:var(--radius-sm);color:rgba(255,255,255,.65);cursor:pointer}
.sidebar__collapse-btn:hover{background:rgba(255,255,255,.1);color:#fff}
.sidebar__collapse-btn svg{width:16px;height:16px;transition:transform .15s}
.sidebar .brand__mark{background:var(--accent-bordo)}
.sidebar__nav{flex:1;overflow-y:auto;padding:var(--space-2) var(--space-3);display:flex;flex-direction:column;gap:1px}
.sidebar__link{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);color:rgba(255,255,255,.78);font-size:var(--text-sm);font-weight:var(--fw-medium);position:relative;white-space:nowrap}
.sidebar__link:hover{background:var(--sidebar-hover-bg);color:#fff;text-decoration:none}
.sidebar__link .nav-ic{width:19px;height:19px;flex:none}
.sidebar__link span{overflow:hidden;text-overflow:ellipsis}
.sidebar__link .sidebar__count{margin-left:auto}
.sidebar__link.is-active{background:var(--sidebar-active-bg);color:#fff}
.sidebar__link.is-active::before{content:"";position:absolute;left:-.75rem;top:.4rem;bottom:.4rem;width:3px;border-radius:0 3px 3px 0;background:var(--accent-bordo)}
.sidebar__link.is-soon{color:rgba(255,255,255,.35);cursor:default}
.sidebar__link.is-soon:hover{background:none;color:rgba(255,255,255,.35)}
.sidebar__settings{flex:none;padding:var(--space-2) var(--space-3);border-top:1px solid rgba(255,255,255,.1)}
.sidebar__user{flex:none;padding:var(--space-3);border-top:1px solid rgba(255,255,255,.1);display:flex;align-items:center;gap:var(--space-2)}
.sidebar__user .userbox__id{overflow:hidden}
.sidebar__user .userbox__name{color:#fff}
.sidebar__user .userbox__role{color:rgba(255,255,255,.55)}
.sidebar__user .icon-btn{color:rgba(255,255,255,.75)}
.sidebar__user .icon-btn:hover{background:rgba(255,255,255,.12);color:#fff}
.sidebar__user .btn--ghost{--_fg:rgba(255,255,255,.75)}
.sidebar__user .btn--ghost:hover{--_bg:rgba(255,255,255,.12);--_fg:#fff}
.sidebar__swatches{display:flex;gap:5px}
.swatch-btn{width:15px;height:15px;border-radius:50%;background:var(--sw);border:2px solid rgba(255,255,255,.3);cursor:pointer;padding:0;flex:none}
.swatch-btn.is-active{border-color:#fff}
.app-shell.is-collapsed .sidebar__swatches{display:none}
.app-main{flex:1;min-width:0;display:flex;flex-direction:column}
.mobile-topbar{display:none}
.offcanvas-scrim{display:none}

/* свёрнутый sidebar (десктоп, запоминается в localStorage — #app.js) */
.app-shell.is-collapsed .sidebar{width:var(--sidebar-w-collapsed)}
.app-shell.is-collapsed .sidebar__brand-text,.app-shell.is-collapsed .sidebar__link span:not(.sr-only),.app-shell.is-collapsed .sidebar__user .userbox__id{display:none}
.app-shell.is-collapsed .sidebar__link{justify-content:center}
.app-shell.is-collapsed .sidebar__link.is-active::before{left:-.6rem}
.app-shell.is-collapsed .sidebar__collapse-btn svg{transform:rotate(180deg)}
.app-shell.is-collapsed .sidebar__top{justify-content:center}
.app-shell.is-collapsed .sidebar__brand{flex:none}

@media (max-width:1023px){
  .app-shell{display:block}
  .sidebar{position:fixed;left:0;top:0;bottom:0;width:min(80vw,19rem);transform:translateX(-100%);transition:transform .2s ease;box-shadow:var(--shadow-lg)}
  .app-shell.is-collapsed .sidebar{width:min(80vw,19rem)}
  .app-shell.is-collapsed .sidebar__brand-text,.app-shell.is-collapsed .sidebar__link span:not(.sr-only){display:flex}
  .app-shell.is-collapsed .sidebar__link{justify-content:flex-start}
  .nav-toggle-checkbox:checked ~ .sidebar{transform:translateX(0)}
  .nav-toggle-checkbox:checked ~ .offcanvas-scrim{opacity:1;pointer-events:auto}
  .offcanvas-scrim{display:block;position:fixed;inset:0;background:rgba(6,10,20,.5);opacity:0;pointer-events:none;transition:opacity .2s ease;z-index:calc(var(--z-offcanvas) - 1)}
  .mobile-topbar{display:flex;align-items:center;gap:var(--space-3);height:var(--topbar-h);padding-inline:var(--space-4);background:var(--topbar-bg);color:#fff;position:sticky;top:0;z-index:30}
  .mobile-topbar__burger{display:grid;place-items:center;width:2.25rem;height:2.25rem;color:#fff;cursor:pointer;border-radius:var(--radius-sm)}
  .mobile-topbar__burger:hover{background:rgba(255,255,255,.12)}
  .mobile-topbar__burger svg{width:22px;height:22px}
  .mobile-topbar .brand{color:#fff;font-size:var(--text-sm);flex:1}
  .mobile-topbar .icon-btn{color:rgba(255,255,255,.85)}
  .sidebar__collapse-btn{display:none}
}
@media (min-width:1024px){ .has-bottom-nav .bottom-nav{display:none} }

/* ═══ Табы разделов (Платежи · Отчёты · Настройки · Табель — #029) ═══ */
.tabbar{display:flex;gap:var(--space-1);border-bottom:1px solid var(--border);margin-bottom:var(--space-5);overflow-x:auto}
.tabbar a{padding:var(--space-3) var(--space-4);font-size:var(--text-sm);font-weight:var(--fw-medium);color:var(--text-muted);border-bottom:2px solid transparent;white-space:nowrap;margin-bottom:-1px;flex:none}
.tabbar a:hover{color:var(--text);text-decoration:none}
.tabbar a.is-active{color:var(--c-brand-600);border-bottom-color:var(--c-brand-600);font-weight:var(--fw-semibold)}
.tabbar a.is-soon{color:var(--c-slate-400);cursor:default;pointer-events:none}

/* ═══ Drill-down (#064): статья → месяцы → дни → операции; работает без JS (<details>), мобильный аккордеон — та же разметка ═══ */
.drilldown{border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--c-surface);box-shadow:var(--shadow-sm);overflow:hidden}
.drilldown__row{border-bottom:1px solid var(--border)}
.drilldown__row:last-child{border-bottom:0}
.drilldown__row>summary{display:grid;grid-template-columns:1.25rem 1fr 8rem 8rem;align-items:center;gap:var(--space-3);padding:var(--space-3) var(--space-4);cursor:pointer;list-style:none;font-size:var(--text-sm)}
.drilldown__row>summary::-webkit-details-marker{display:none}
.drilldown__row>summary:hover{background:var(--c-surface-2)}
.drilldown__row[open]>summary{background:var(--c-surface-2);border-bottom:1px solid var(--border);font-weight:var(--fw-semibold)}
.drilldown__chevron{width:1rem;height:1rem;color:var(--text-muted);transition:transform .15s}
.drilldown__row[open]>summary .drilldown__chevron{transform:rotate(90deg)}
.drilldown__body{background:var(--c-surface-2)}
.drilldown__body .drilldown__row>summary{padding-left:calc(var(--space-4) + 1.25rem)}
.drilldown__body .drilldown__body .drilldown__row>summary{padding-left:calc(var(--space-4) + 2.5rem)}
.drilldown__body .drilldown__body .drilldown__body .drilldown__row>summary{padding-left:calc(var(--space-4) + 3.75rem)}
.drilldown__leaf{display:grid;grid-template-columns:1.25rem 1fr 8rem 8rem;gap:var(--space-3);padding:var(--space-2) var(--space-4);font-size:var(--text-sm);color:var(--text-muted);border-bottom:1px solid var(--border)}
.drilldown__leaf:last-child{border-bottom:0}
.drilldown .num{text-align:right;font-variant-numeric:tabular-nums}
@media (max-width:600px){.drilldown__row>summary,.drilldown__leaf{grid-template-columns:1.1rem 1fr auto}}

/* ═══ Tooltip (#077, итерация 3): чисто CSS через attr(data-tip), без JS. На фокусе (клавиатура)
   и наведении одинаково; дублируйте текст в aria-label для читалок экрана (они тоолтип не увидят). ═══ */
[data-tip]{position:relative;cursor:default}
[data-tip]::after{content:attr(data-tip);position:absolute;left:50%;bottom:calc(100% + 7px);transform:translateX(-50%);background:#171d2b;color:#fff;font-size:var(--text-xs);font-weight:var(--fw-medium);padding:.4em .65em;border-radius:var(--radius-sm);white-space:nowrap;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .12s,visibility .12s;z-index:60;box-shadow:var(--shadow-md)}
[data-tip]::before{content:"";position:absolute;left:50%;bottom:calc(100% + 2px);transform:translateX(-50%);border:5px solid transparent;border-top-color:#171d2b;opacity:0;visibility:hidden;pointer-events:none;transition:opacity .12s,visibility .12s;z-index:60}
[data-tip]:hover::after,[data-tip]:hover::before,[data-tip]:focus-visible::after,[data-tip]:focus-visible::before{opacity:1;visibility:visible}
[data-tip-below]::after{bottom:auto;top:calc(100% + 7px)}
[data-tip-below]::before{bottom:auto;top:calc(100% + 2px);border-top-color:transparent;border-bottom-color:#171d2b}

/* ═══ Ставка официальная/неофициальная (#076, итерация 3): трёхпозиционный переключатель, чистый CSS ═══ */
.rate-toggle{display:inline-flex;gap:2px;padding:3px;background:var(--c-surface-2);border:1px solid var(--border);border-radius:var(--radius-md)}
.rate-toggle label{padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);font-size:var(--text-sm);font-weight:var(--fw-medium);color:var(--text-muted);cursor:pointer;white-space:nowrap}
.rate-toggle label:hover{color:var(--text)}
#rm-official:checked~.rate-toggle label[for="rm-official"],#rm-both:checked~.rate-toggle label[for="rm-both"],#rm-unofficial:checked~.rate-toggle label[for="rm-unofficial"]{background:var(--c-surface);color:var(--c-brand-700);box-shadow:var(--shadow-sm)}
.rv{display:none}
.rv--total{display:none}
#rm-official:checked~.table-wrap .rv--official{display:inline}
#rm-both:checked~.table-wrap .rv--official,#rm-both:checked~.table-wrap .rv--unofficial{display:inline}
#rm-unofficial:checked~.table-wrap .rv--unofficial{display:inline}
.rate-cell{display:flex;flex-direction:column;align-items:flex-end;line-height:1.5;gap:1px}
.rate-cell .rv--unofficial{color:var(--text-muted);font-size:.92em}

/* ═══ График смен (#077, итерация 3): сетка по подразделениям, цвет ячейки = слот прихода ═══ */
.sched-table{width:100%;border-collapse:collapse;font-size:var(--text-xs)}
.sched-table th,.sched-table td{padding:2px;text-align:center;vertical-align:middle}
.sched-table thead th{position:sticky;top:0;z-index:2;background:var(--c-surface-2);font-weight:var(--fw-semibold);color:var(--text-muted);padding:var(--space-2) 2px}
/* will-change:transform на закреплённых колонках (namecol/poscol и их аналоги ниже) — просьба
   форсировать отдельный композитный слой. На статичном скролле (после остановки) слой уже
   и так корректно перекрывает соседние ячейки (проверено), но во время самого скролла браузер
   иногда досчитывает слой с опозданием на один-два кадра — в это окно фон/пунктир соседней
   ячейки на кадр показывается поверх. will-change заранее выделяет слой, кадра рассинхронизации
   не остаётся. */
.sched-table th.sched-namecol,.sched-table td.sched-namecol{position:sticky;left:0;z-index:1;background:var(--c-surface);text-align:left;padding:var(--space-2) var(--space-3);min-width:11rem;font-size:var(--text-sm);will-change:transform}
.sched-table thead th.sched-namecol{z-index:3;background:var(--c-surface-2)}
.sched-daynum{font-variant-numeric:tabular-nums;display:block}
.sched-daydot{display:inline-block;width:6px;height:6px;border-radius:50%;margin-top:3px}
.sched-daydot.is-good{background:var(--coverage-good)}
.sched-daydot.is-short{background:var(--coverage-short)}
.sched-cell{width:1.85rem;height:1.6rem;border-radius:4px;display:inline-flex;align-items:center;justify-content:center;vertical-align:middle;font-size:.68rem;font-weight:var(--fw-bold)}
.sched-cell--empty{background:transparent}
.sched-cell--open{background:var(--slot-open-bg);color:var(--slot-open-fg)}
.sched-cell--kitchen{background:var(--slot-kitchen-bg);color:var(--slot-kitchen-fg)}
.sched-cell--rest{background:var(--slot-rest-bg);color:var(--slot-rest-fg)}
.sched-cell--vacation{background:var(--kind-vacation-bg);color:var(--kind-vacation-fg)}
.sched-cell--sick{background:var(--kind-sick-bg);color:var(--kind-sick-fg)}
.sched-cell--dayoff{background:var(--kind-dayoff-bg);color:var(--kind-dayoff-fg)}
.sched-cell--trial{background:var(--kind-trial-bg);color:var(--kind-trial-fg);background-image:repeating-linear-gradient(135deg,transparent 0 3px,rgba(0,0,0,.06) 3px 6px)}
.sched-cell--absent{background:var(--kind-absent-neutral-bg);color:var(--kind-absent-neutral-fg)}
.sched-cell--absent-unexcused{background:var(--kind-absent-unexcused-bg);color:var(--kind-absent-unexcused-fg)}
.sched-cell--proposed{outline:2px dashed var(--c-brand-500);outline-offset:-2px}
.sched-cell.is-probation{box-shadow:inset 0 0 0 1.5px var(--kind-probation)}
.sched-cell-wrap{position:relative;display:inline-flex}
.sched-status-dot{position:absolute;top:-2px;right:-2px;width:8px;height:8px;border-radius:50%;box-shadow:0 0 0 1.5px var(--c-surface);cursor:default}
.sched-status-dot.is-approved{background:var(--coverage-good)}
.sched-status-dot.is-rejected{background:var(--c-neg-600)}
/* colspan ломает position:sticky у ячейки (проверено: с colspan = 33 ячейка едет вместе
со скроллом, будто position:static, хотя computed-style показывает sticky) — закрепляем
только первую (не colspan) ячейку строки, фон/цвет/жирность — на все, ряд читается
сплошной плашкой как раньше. */
.sched-deptrow td{background:var(--c-brand-50);font-weight:var(--fw-bold);color:var(--c-brand-700);text-align:left}
.sched-deptrow td:first-child{position:sticky;left:0;z-index:1;padding:var(--space-2) var(--space-3)!important;will-change:transform}
/* трассировка строки по клику: ячейка ФИО — реальная <button> (она же sticky — доступна
   с любой точки горизонтального скролла), вся строка обводится сверху/снизу, пока фокус внутри
   неё. :focus-within вместо чекбокс-приёма (:has(:checked)) — тот не пересчитывался в проверке
   на скролле/клике надёжно, фокус — стандартный и предсказуемый механизм. Box-shadow, а не
   фон — фон уже занят выходными/праздниками/зеброй/закреплёнными колонками на каждой ячейке. */
.row-pin-label{all:unset;display:block;width:100%;cursor:pointer;font:inherit;color:inherit;text-align:inherit}
.table--dense.table--sticky1 tbody tr:focus-within td,
.table--dense.table--sticky1 tbody tr:focus-within th,
.sched-table tbody tr:focus-within td{box-shadow:inset 0 2px 0 var(--c-brand-600),inset 0 -2px 0 var(--c-brand-600)!important}
.reason-head,.reason-peer{display:none}
.sched-legend{display:flex;flex-wrap:wrap;gap:var(--space-5)}
.sched-legend__group{display:flex;flex-direction:column;gap:var(--space-2)}
.sched-legend__title{font-size:var(--text-xs);font-weight:var(--fw-semibold);color:var(--text-muted);text-transform:uppercase;letter-spacing:.04em}
.sched-legend__items{display:flex;flex-wrap:wrap;gap:var(--space-3)}
.sched-legend__item{display:inline-flex;align-items:center;gap:.4em;font-size:var(--text-sm)}
.sched-legend__swatch{width:1.1rem;height:1.1rem;border-radius:4px;flex:none}

/* переключатель «вид руководителя / вид коллеги» — радио вне .panel, реагируем через ~ на весь блок ниже */
.viewmode{display:inline-flex;gap:2px;padding:3px;background:var(--c-surface-2);border:1px solid var(--border);border-radius:var(--radius-md)}
.viewmode label{padding:var(--space-2) var(--space-3);border-radius:var(--radius-sm);font-size:var(--text-sm);font-weight:var(--fw-medium);color:var(--text-muted);cursor:pointer;white-space:nowrap}
#vm-head:checked~.viewmode-row .viewmode label[for="vm-head"],#vm-peer:checked~.viewmode-row .viewmode label[for="vm-peer"]{background:var(--c-surface);color:var(--c-brand-700);box-shadow:var(--shadow-sm)}
#vm-head:checked~.panel .reason-head{display:inline-flex}
#vm-peer:checked~.panel .reason-peer{display:inline-flex}

/* ═══ Модерация замен (#077 §6) ═══ */
.diff-old{color:var(--text-muted);text-decoration:line-through}
.diff-new{color:var(--text-strong);font-weight:var(--fw-semibold)}
.diff-arrow{color:var(--text-muted);margin:0 .5em}

/* ═══ Виджет отпуска (#077 §7) ═══ */
.vacation-widget{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-4);border-radius:var(--radius-lg);background:var(--kind-vacation-bg);color:var(--kind-vacation-fg);border:1px solid var(--kind-vacation-fg);border-color:color-mix(in srgb, var(--kind-vacation-fg) 30%, transparent)}
.vacation-widget__icon{flex:none;width:2.25rem;height:2.25rem;display:grid;place-items:center;border-radius:50%;background:var(--c-surface)}
.vacation-widget__icon svg{width:1.15rem;height:1.15rem}
.vacation-widget__body{display:flex;flex-direction:column;gap:1px}
.vacation-widget__title{font-weight:var(--fw-semibold)}
.vacation-widget__meta{font-size:var(--text-sm);opacity:.85}
.vac-overview__row{display:grid;grid-template-columns:9rem 1fr;gap:var(--space-3);align-items:center;font-size:var(--text-sm);margin-bottom:var(--space-2)}
.vac-overview__bar{position:relative;height:1.5rem;background:var(--c-surface-2);border-radius:var(--radius-sm);overflow:hidden}
.vac-overview__seg{position:absolute;top:0;bottom:0;background:var(--kind-vacation-fg);border-radius:var(--radius-sm);display:flex;align-items:center;justify-content:center;font-size:.65rem;color:#fff;font-weight:var(--fw-semibold);white-space:nowrap;overflow:hidden;padding:0 4px}
.vac-overview__seg.is-overlap{background:var(--c-warn-500)}

/* ═══ Матрица прав (#078, /settings/permissions) ═══ */
.rbac-matrix-wrap{overflow:auto;border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--c-surface);box-shadow:var(--shadow-sm)}
.rbac{border-collapse:collapse;font-size:var(--text-xs)}
.rbac th,.rbac td{border-bottom:1px solid var(--border);padding:var(--space-2);vertical-align:middle}
.rbac thead th{position:sticky;top:0;z-index:2;background:var(--c-surface-2);font-weight:var(--fw-semibold);text-align:center;white-space:nowrap}
.rbac th.rbac-rescol,.rbac td.rbac-rescol{position:sticky;left:0;z-index:1;background:var(--c-surface);text-align:left;min-width:11rem;padding-inline:var(--space-3)}
.rbac thead th.rbac-rescol{z-index:3;background:var(--c-surface-2)}
.rbac-sectionrow td{position:sticky;left:0;background:var(--c-brand-50);color:var(--c-brand-700);font-weight:var(--fw-bold);font-size:var(--text-xs);text-transform:uppercase;letter-spacing:.04em;padding:var(--space-2) var(--space-3)}
.rbac-cell{display:flex;flex-direction:column;align-items:center;gap:3px;min-width:4.75rem}
.rbac-rw{display:flex;gap:7px}
.rbac-rw label{display:flex;align-items:center;gap:2px;font-size:.66rem;color:var(--text-muted);cursor:pointer}
.rbac-rw input{width:.9rem;height:.9rem;accent-color:var(--c-brand-600);cursor:pointer}
.rbac-scope{font-size:.66rem;height:1.35rem;padding:0 .3em;border:1px solid var(--border-strong);border-radius:var(--radius-xs);background:var(--c-surface);color:var(--text-muted)}
.rbac-cell.is-locked{opacity:.55}
.rbac-cell.is-locked .rbac-rw label,.rbac-cell.is-locked .rbac-scope{cursor:not-allowed}
.rbac-lock{color:var(--text-muted);display:inline-flex}
.rbac-lock svg{width:11px;height:11px}
.rbac-warnflag{color:var(--c-warn-500);font-weight:var(--fw-bold);font-size:.85rem;line-height:1}

/* ═══ Хаб «Настройки» ═══ */
.hub-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(15rem,1fr));gap:var(--space-4)}
.hub-card{display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-5);background:var(--c-surface);border:1px solid var(--border);border-radius:var(--radius-lg);box-shadow:var(--shadow-sm);text-decoration:none;color:inherit;transition:border-color .12s,box-shadow .12s,transform .12s}
.hub-card:hover{border-color:var(--c-brand-200);box-shadow:var(--shadow-md);text-decoration:none;color:inherit;transform:translateY(-1px)}
.hub-card__icon{width:2.25rem;height:2.25rem;border-radius:var(--radius-md);background:var(--c-brand-50);color:var(--c-brand-700);display:grid;place-items:center;flex:none}
.hub-card__icon svg{width:1.2rem;height:1.2rem}
.hub-card__title{font-weight:var(--fw-semibold);color:var(--text-strong)}
.hub-card__desc{font-size:var(--text-sm);color:var(--text-muted)}

/* ═══ Состояние «нет данных» — таблицы (график/.chart уже имеет своё в charts.css) ═══ */
.table-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-3);padding:var(--space-12) var(--space-5);color:var(--text-muted);text-align:center}
.table-empty svg{width:2rem;height:2rem;opacity:.5}
.table-empty__title{font-weight:var(--fw-semibold);color:var(--text)}

/* ═══ Селектор периода (#082, итерация 4): переиспользуемый компонент шапки экрана.
   Клик по подписи месяца открывает нативный <input type="month"> (оверлей opacity:0,
   без сторонних библиотек). Границы данных — обычный disabled на крайних кнопках. ═══ */
.period-nav{display:inline-flex;align-items:center;gap:var(--space-2)}
.period-nav__btn{width:2rem;height:2rem;flex:none;display:grid;place-items:center;border-radius:var(--radius-sm);border:1px solid var(--border-strong);background:var(--c-surface);color:var(--text);cursor:pointer}
.period-nav__btn:hover{background:var(--c-surface-2)}
.period-nav__btn:disabled{opacity:.35;cursor:not-allowed;pointer-events:none}
.period-nav__btn svg{width:16px;height:16px}
.period-nav__label{position:relative;display:inline-flex}
.period-nav__current{display:inline-flex;align-items:center;gap:.35em;height:2rem;padding:0 var(--space-3);border-radius:var(--radius-sm);font-weight:var(--fw-semibold);color:var(--text-strong);font-size:var(--text-sm);white-space:nowrap;border:1px solid transparent}
.period-nav__label:hover .period-nav__current{background:var(--c-surface-2)}
.period-nav__current.is-open{background:var(--c-surface);border-color:var(--border-focus);box-shadow:var(--shadow-focus)}
.period-nav__current.is-current{color:var(--c-brand-700)}
.period-nav__dot{display:none;width:.4em;height:.4em;border-radius:50%;background:var(--c-brand-600);flex:none}
.period-nav__current.is-current .period-nav__dot{display:inline-block}
.period-nav__chevron{width:13px;height:13px;color:var(--text-muted);flex:none}
.period-nav__input{position:absolute;inset:0;opacity:0;cursor:pointer;width:100%;border:0}
.period-nav__popover{position:absolute;top:calc(100% + 6px);left:0;z-index:30;min-width:15rem;padding:var(--space-3);background:var(--c-surface);border:1px solid var(--border);border-radius:var(--radius-md);box-shadow:var(--shadow-lg);font-size:var(--text-xs);color:var(--text-muted)}
@media (max-width:479px){.period-nav__current{padding:0 var(--space-2);font-size:var(--text-xs)}}

/* ═══ Сводка задолженности по ФОТ (#082, итерация 4): список сотрудник → долг, drill по месяцам.
   <details>/<summary>, без JS, разворачивается по клику. ═══ */
.debtlist{border:1px solid var(--border);border-radius:var(--radius-lg);background:var(--c-surface);box-shadow:var(--shadow-sm);overflow:hidden}
.debtrow{border-bottom:1px solid var(--border)}
.debtrow:last-child{border-bottom:0}
.debtrow>summary{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3) var(--space-4);cursor:pointer;list-style:none}
.debtrow>summary::-webkit-details-marker{display:none}
.debtrow>summary:hover{background:var(--c-surface-2)}
.debtrow[open]>summary{background:var(--c-surface-2);border-bottom:1px solid var(--border)}
.debtrow__chevron{width:1rem;height:1rem;color:var(--text-muted);transition:transform .15s;flex:none}
.debtrow[open]>summary .debtrow__chevron{transform:rotate(90deg)}
.debtrow__name{flex:1;min-width:0}
.debtrow__amount{font-variant-numeric:tabular-nums;font-weight:var(--fw-bold);white-space:nowrap;font-size:var(--text-md)}
.debtrow__amount.is-zero{color:var(--text-muted);font-weight:var(--fw-regular);font-size:var(--text-base)}
.debtrow__amount.is-notable{color:var(--expense)}
.debtrow__body{background:var(--c-surface-2)}
.debtleaf{display:flex;justify-content:space-between;gap:var(--space-3);padding:var(--space-2) var(--space-4) var(--space-2) calc(var(--space-4) + 1.25rem);font-size:var(--text-sm);color:var(--text-muted);border-bottom:1px solid var(--border)}
.debtleaf:last-child{border-bottom:0}
.debtlist__total{display:flex;justify-content:space-between;align-items:center;padding:var(--space-3) var(--space-4);background:var(--c-surface-2);border-top:2px solid var(--border-strong);font-weight:var(--fw-bold);color:var(--text-strong)}

/* ═══ Журнал посещений (#083, итерация 4): метрика визитов, мини-heatmap, статус давности ═══ */
.visits-count{display:inline-flex;align-items:center;justify-content:center;min-width:2.4rem;height:1.7rem;padding:0 .55em;border-radius:var(--radius-full);background:var(--c-brand-50);color:var(--c-brand-700);font-weight:var(--fw-bold);font-variant-numeric:tabular-nums;font-size:var(--text-sm)}
.visits-count.is-zero{background:var(--c-slate-100);color:var(--text-muted);font-weight:var(--fw-regular)}
.lastvisit.is-stale{color:var(--c-warn-700);font-weight:var(--fw-semibold)}
.lastvisit.is-never{color:var(--text-muted)}
.heatmap30{display:inline-flex;gap:1px;vertical-align:middle}
.heatmap30 span{width:5px;height:13px;border-radius:1px;background:var(--c-slate-100);display:inline-block}
.heatmap30 span.lvl-1{background:var(--c-brand-200)}
.heatmap30 span.lvl-2{background:var(--c-brand-400)}
.heatmap30 span.lvl-3{background:var(--c-brand-700)}
[data-theme="dark"] .heatmap30 span{background:var(--c-slate-200)}

/* \u2550\u2550\u2550 \u0422\u0430\u0431\u0435\u043b\u044c: \u043c\u0430\u0440\u043a\u0435\u0440 \u00ab\u043e\u0442\u043f\u0443\u0441\u043a\u00bb \u0432 \u044f\u0447\u0435\u0439\u043a\u0435 (\u0438\u0442\u0435\u0440\u0430\u0446\u0438\u044f 2) \u2550\u2550\u2550 */
.ts-vacation{background:repeating-linear-gradient(135deg,var(--c-brand-50) 0 4px,transparent 4px 8px);color:var(--c-brand-700);font-weight:var(--fw-semibold);text-align:center;font-size:.7em}

/* ═══ Печатные формы как класс (#3.4): акт оплаты, отчёт смены — А4, поля исполнителя пустые ═══ */
.print-sheet{display:none}
.act{max-width:180mm;margin:0 auto;font-size:13px;line-height:1.5;color:#000}
.act__title{font-size:16px;font-weight:var(--fw-bold);text-align:center;margin-bottom:2px}
.act__legal{text-align:center;color:#333;margin-bottom:18px;font-size:12px}
.act__row{display:flex;gap:var(--space-2);margin-bottom:10px}
.act__row .lbl{flex:none;color:#333}
.act__row .val{flex:1;border-bottom:1px solid #000;min-height:1.3em;padding-bottom:1px}
.act__blank{border-bottom:1px solid #000;display:inline-block;min-width:8em}
.act__sig{display:flex;justify-content:space-between;gap:var(--space-8);margin-top:34px}
.act__sig div{flex:1;text-align:center;border-top:1px solid #000;padding-top:4px;font-size:11px;color:#333}
.act__foot{margin-top:22px;font-size:10.5px;color:#555}

/* ═══ Печать (отчёты, акты) ═══ */
@media print{
  .topbar,.bottom-nav,.toast-stack,.no-print,.sidebar,.mobile-topbar,.offcanvas-scrim,.tabbar,.nav-toggle-checkbox{display:none!important}
  .app-shell{display:block}
  body{background:#fff;color:#000}
  .main{padding:0}
  .card,.panel,.table-wrap{box-shadow:none;border-color:#c9c9c9;break-inside:avoid}
  a{color:inherit;text-decoration:none}
  .screen-only{display:none!important}
  .print-sheet{display:block}
  .money.pos,.money.neg,.pos,.neg,.warn,.grp__ic,.src__dot,.badge{print-color-adjust:exact;-webkit-print-color-adjust:exact}
  @page{margin:16mm}
}
@media not print{ .print-only{display:none!important} }

/* #030-B (sess_007, вводная Георгия): плотная сетка табеля — ФИО над должностью,
   строки ужаты ~30% (padding 8px→2px, line-height 1.15). Аддитивно к дизайн-системе. */
.table--dense th,.table--dense td{padding:1px var(--space-3)!important;line-height:1.05!important}
.cell-emp__name{display:block;font-size:1.3em;line-height:1.15}
.cell-emp__pos{display:block;font-size:1em;color:var(--text-muted);line-height:1.2;font-weight:var(--fw-regular)}
/* #165B: multihead — один sticky-контейнер (flex+gap), не два независимых sticky span. */
.is-multihead__sticky{position:sticky;left:var(--space-3);display:flex;gap:var(--space-2);align-items:baseline;background:inherit}
.is-multihead__sticky .cell-emp__name,.is-multihead__sticky .cell-emp__pos{display:inline}
/* #165C: Ставка — выравнивание вправо (как числовые колонки). */
.table--dense.table--sticky1 td:not([colspan]):nth-last-child(2){text-align:right}
/* совмещение: подстроки назначений вдвое ниже; заголовок с ФИО — обычной высоты (вводная Георгия sess_007) */
.table--dense tr.is-sub td{padding:1px var(--space-3);line-height:1;font-size:.92em}
/* экранный предпросмотр печатного бланка — «лист бумаги» (белый и в тёмной теме) */
.sheet-preview{background:#fff;color:#000;border:1px solid var(--border);border-radius:var(--radius-md);box-shadow:var(--shadow-sm);padding:28px 32px;margin-bottom:var(--space-3)}
@media print{.sheet-preview{display:none}}
/* #077-A fix: дизайнерский .sched-daynum{display:block} на <th> разваливал таблицу
   (дни столбиком — дефект и в исходном макете schedule.html). th остаётся ячейкой. */
.sched-table th.sched-daynum{display:table-cell}
/* #077-B: ячейка с открытой заявкой (proposed) — пунктирная рамка (из макета) */
.sched-cell.is-proposed{outline:2px dashed var(--c-brand-500);outline-offset:-2px}

/* ═══ База договоров (#088, итерация 6): условия-бейджи, файлы, пояснения, аудит ═══ */
/* Условия-бейджи — компактные плашки условий прямо в строке реестра. Нейтральная шкала:
   условия договора НЕ денежная семантика (pos/neg/warn зарезервированы за деньгами). */
.terms{display:flex;flex-wrap:wrap;gap:.3rem}
.term-badge{display:inline-flex;align-items:center;gap:.3em;height:1.4rem;padding:0 .5em;border-radius:var(--radius-xs);border:1px solid var(--border);background:var(--c-surface-2);color:var(--text);font-size:.6875rem;font-weight:var(--fw-semibold);white-space:nowrap;line-height:1;font-variant-numeric:tabular-nums}
.term-badge--delay{background:var(--c-brand-50);color:var(--c-brand-700);border-color:var(--c-brand-100)}
.term-badge--prepay{background:var(--c-info-50);color:var(--c-info-700);border-color:var(--c-info-100)}
.term-badge--perpetual{background:var(--c-slate-100);color:var(--c-slate-700)}
.term-badge--none{background:transparent;color:var(--text-muted);border-style:dashed}

/* Подсветка истечения срока действия (строка реестра) */
tr.ctr-expiring td{background:var(--c-warn-50)}
tr.ctr-expired td{background:var(--c-slate-50);color:var(--text-muted)}
tr.ctr-expired td a{color:var(--text-muted)}

/* Файлы документа: скан PDF, фото страниц */
.ctr-files{display:grid;grid-template-columns:repeat(auto-fill,minmax(16rem,1fr));gap:var(--space-3)}
.ctr-file{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3);border:1px solid var(--border);border-radius:var(--radius-md);background:var(--c-surface)}
.ctr-file__ic{flex:none;width:2.25rem;height:2.75rem;border-radius:var(--radius-xs);display:grid;place-items:center;background:var(--c-slate-100);color:var(--c-slate-600);font-size:.625rem;font-weight:var(--fw-bold);letter-spacing:.02em;text-transform:uppercase}
.ctr-file__ic--img{background:var(--c-brand-50);color:var(--c-brand-700)}
.ctr-file__body{min-width:0;flex:1;display:flex;flex-direction:column;gap:2px}
.ctr-file__name{font-size:var(--text-sm);font-weight:var(--fw-medium);color:var(--text-strong);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.ctr-file__meta{font-size:var(--text-xs);color:var(--text-muted)}
.ctr-file--add{border-style:dashed;justify-content:center;color:var(--text-muted);cursor:pointer;font-size:var(--text-sm);font-weight:var(--fw-medium)}
.ctr-file--add:hover{border-color:var(--c-brand-400);color:var(--c-brand-700);background:var(--c-brand-50)}

/* Условие + автопояснение бытовым языком */
.ctr-term{display:flex;flex-direction:column;gap:var(--space-1);padding:var(--space-3) 0;border-bottom:1px solid var(--border)}
.ctr-term:last-child{border-bottom:0}
.ctr-term__row{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-3)}
.ctr-term__name{font-size:var(--text-sm);color:var(--text-muted)}
.ctr-term__value{font-size:var(--text-md);font-weight:var(--fw-semibold);color:var(--text-strong);font-variant-numeric:tabular-nums;white-space:nowrap}
.ctr-term__explain{font-size:var(--text-sm);color:var(--text-muted);text-wrap:pretty}

/* Компактный блок «Договоры» в карточке контрагента */
.ctr-mini{display:flex;flex-wrap:wrap;align-items:center;gap:var(--space-2)}
.ctr-mini__empty{font-size:var(--text-sm);color:var(--text-muted)}

/* Аудит-строка карточек */
.audit-line{display:flex;flex-wrap:wrap;gap:var(--space-1) var(--space-4);font-size:var(--text-xs);color:var(--text-muted);padding-top:var(--space-3);border-top:1px solid var(--border);margin-top:var(--space-4)}

/* ═══ Drill статьи → контрагенты в PnL-таблицах (итерация 5, дозаказ): чистый CSS через :has(),
   без JS. Каждая раскрываемая статья — отдельный <tbody class="pnl-group"> с чекбоксом в summary-строке. ═══ */
.pnl-detail{display:none}
.pnl-group:has(.pnl-exp__cb:checked) .pnl-detail{display:table-row}
.pnl-exp{display:inline-flex;align-items:center;gap:.4em;cursor:pointer}
.pnl-exp__cb{position:absolute;opacity:0;width:1px;height:1px}
.pnl-exp__chevron{width:.9rem;height:.9rem;color:var(--text-muted);transition:transform .15s;flex:none}
.pnl-group:has(.pnl-exp__cb:checked) .pnl-exp__chevron{transform:rotate(90deg)}
.pnl-exp__cb:focus-visible + .pnl-exp__chevron{outline:2px solid var(--border-focus);outline-offset:2px;border-radius:2px}
.pnl-detail td{background:var(--c-surface-2)}
.pnl-detail td:first-child{padding-left:2.75rem;color:var(--text-muted);font-weight:var(--fw-regular)}
.table--sticky1 .pnl-detail td:first-child{background:var(--c-surface-2)}
.pnl-detail--link td{padding-left:2.75rem}
.pnl-detail--link a{font-weight:var(--fw-medium)}

/* ═══ Модель выручки (итерация 7): группы потоков, налоговая база, кошелёк «в пути», сверка ═══ */

/* — Точка потока выручки (легенды, расшифровки) — */
.flow-dot{width:.55em;height:.55em;border-radius:50%;background:var(--flow,var(--c-slate-400));flex:none;display:inline-block}
.flow--cash-fisc{--flow:var(--flow-cash-fisc)}
.flow--cash-nonfisc{--flow:var(--flow-cash-nonfisc)}
.flow--card{--flow:var(--flow-card)}
.flow--qr{--flow:var(--flow-qr)}
.flow--agg{--flow:var(--flow-agg)}
.flow--house{--flow:var(--flow-house)}

/* — Группы полей выручки в форме кассового дня (details/summary, работает без JS) — */
.rev-group{border:1px solid var(--border);border-radius:var(--radius-md);background:var(--c-surface);margin-bottom:var(--space-3)}
.rev-group>summary{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3) var(--space-4);cursor:pointer;list-style:none;border-radius:var(--radius-md)}
.rev-group>summary::-webkit-details-marker{display:none}
.rev-group>summary:hover{background:var(--c-surface-2)}
.rev-group[open]>summary{border-bottom:1px solid var(--border);border-radius:var(--radius-md) var(--radius-md) 0 0}
.rev-group__chevron{width:1rem;height:1rem;color:var(--text-muted);transition:transform .15s;flex:none}
.rev-group[open]>summary .rev-group__chevron{transform:rotate(90deg)}
.rev-group__name{font-weight:var(--fw-semibold);color:var(--text-strong)}
.rev-group__count{font-size:var(--text-xs);color:var(--text-muted)}
.rev-group__subtotal{margin-left:auto;font-variant-numeric:tabular-nums;font-weight:var(--fw-semibold);color:var(--text-strong);white-space:nowrap}
.rev-group__subtotal.is-empty{color:var(--text-muted);font-weight:var(--fw-regular)}
.rev-group__body{padding:var(--space-4);display:grid;grid-template-columns:repeat(auto-fit,minmax(13rem,1fr));gap:var(--space-4)}
.rev-field__head{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap}
.rev-total{display:flex;align-items:baseline;justify-content:space-between;gap:var(--space-3);padding:var(--space-4);border-radius:var(--radius-md);background:var(--c-surface-2);border:1px solid var(--border-strong)}
.rev-total__label{font-weight:var(--fw-semibold);color:var(--text-strong)}
.rev-total__value{font-size:var(--text-xl);font-weight:var(--fw-bold);color:var(--text-strong);font-variant-numeric:tabular-nums}
.rev-tax-hint{font-size:var(--text-sm);color:var(--text-muted);margin-top:var(--space-2)}
@media (max-width:767px){
  .rev-group__body{grid-template-columns:1fr}
  .rev-total{position:sticky;bottom:calc(var(--bottomnav-h) + var(--space-2));z-index:20;box-shadow:var(--shadow-lg)}
}

/* — Налоговая база УСН: три показателя + стопка-полоса — */
.taxsplit{display:grid;grid-template-columns:repeat(auto-fit,minmax(9rem,1fr));gap:var(--space-4)}
.taxsplit__item{display:flex;flex-direction:column;gap:2px}
.taxsplit__label{font-size:var(--text-sm);color:var(--text-muted);display:flex;align-items:center;gap:.35em}
.taxsplit__value{font-size:var(--text-lg);font-weight:var(--fw-bold);color:var(--text-strong);font-variant-numeric:tabular-nums}
.taxsplit__item--undef .taxsplit__value{color:var(--text-muted)}
.taxbar{display:flex;height:.6rem;border-radius:var(--radius-full);overflow:hidden;background:var(--c-slate-100);margin:var(--space-3) 0}
.taxbar__seg{height:100%}
.taxbar__seg--base{background:var(--c-brand-600)}
.taxbar__seg--out{background:var(--c-slate-400)}
.taxbar__seg--undef{background:repeating-linear-gradient(135deg,var(--c-slate-300) 0 4px,var(--c-slate-100) 4px 8px)}

/* — Кошелёк «Агрегаторы (в пути)»: это не деньги на счету — читается иначе — */
.kpi--transit{border-style:dashed;border-color:var(--transit-bd);background:var(--c-surface-2)}
.kpi--transit .kpi__value{color:var(--text)}
.kpi--transit.is-zero .kpi__value{color:var(--text-muted)}
.transit-mark{display:inline-flex;align-items:center;gap:.35em;font-size:var(--text-xs);font-weight:var(--fw-semibold);color:var(--text-muted);text-transform:uppercase;letter-spacing:.04em}
.transit-mark svg{width:.95rem;height:.95rem}

/* — Сверка СБИС ↔ касса: подсветка строк дня — */
tr.rec-off td{background:var(--c-warn-50)}
tr.rec-big td{background:var(--c-neg-50)}

/* — Эскиз сопоставления платежа агрегатора — */
.mtc{display:grid;grid-template-columns:1fr auto 1fr;gap:var(--space-4);align-items:start}
.mtc__col{border:1px solid var(--border);border-radius:var(--radius-md);background:var(--c-surface);overflow:hidden}
.mtc__head{padding:var(--space-3) var(--space-4);border-bottom:1px solid var(--border);background:var(--c-surface-2);font-weight:var(--fw-semibold);font-size:var(--text-sm)}
.mtc__row{display:flex;align-items:center;justify-content:space-between;gap:var(--space-3);padding:var(--space-2) var(--space-4);border-bottom:1px solid var(--border);font-size:var(--text-sm)}
.mtc__row:last-child{border-bottom:0}
.mtc__row.is-picked{background:var(--c-brand-50)}
.mtc__link{align-self:center;color:var(--text-muted);font-size:var(--text-xs);text-align:center;padding-inline:var(--space-2)}
.mtc__link svg{width:1.5rem;height:1.5rem;margin:0 auto .25em}
@media (max-width:820px){.mtc{grid-template-columns:1fr}.mtc__link{transform:rotate(90deg)}}

/* ═══ Справочники и реестр документов (итерация 8) ═══ */

/* — Четыре новые группы контрагентов (палитра выросла с 12 до 15, см. CHANGES) — */
.grp--meat{--grp:var(--grp-meat)}
.grp--fish{--grp:var(--grp-fish)}
.grp--produce{--grp:var(--grp-produce)}
.grp--market{--grp:var(--grp-market)}

/* — Фильтр-чипы групп: цвет группы + счётчик. Состояние «выбрано» — через :has(:checked), без JS — */
.chipbar{display:flex;flex-wrap:wrap;gap:var(--space-2)}
.chip-f{display:inline-flex;align-items:center;gap:.4em;height:1.9rem;padding:0 .6em;border:1px solid var(--border);border-radius:var(--radius-full);background:var(--c-surface);color:var(--text);font-size:var(--text-xs);font-weight:var(--fw-medium);cursor:pointer;white-space:nowrap;user-select:none}
.chip-f:hover{background:var(--c-surface-2)}
.chip-f__dot{width:.55em;height:.55em;border-radius:50%;background:var(--grp,var(--c-slate-400));flex:none}
.chip-f__count{color:var(--text-muted);font-variant-numeric:tabular-nums}
.chip-f:has(input:checked){background:var(--c-brand-50);border-color:var(--c-brand-400);color:var(--c-brand-700);font-weight:var(--fw-semibold)}
.chip-f:has(input:checked) .chip-f__count{color:var(--c-brand-600)}
.chip-f:has(input:focus-visible){box-shadow:var(--shadow-focus)}
@media (max-width:640px){.chipbar{flex-wrap:nowrap;overflow-x:auto;padding-bottom:var(--space-1);scrollbar-width:thin}}

/* — Инлайн-редактирование строки: раскрывается под строкой, прокрутка не теряется (CSS-only) — */
.rowedit__form{display:none}
.rowedit:has(.rowedit__cb:checked) .rowedit__form{display:table-row}
.rowedit__cb{position:absolute;opacity:0;width:1px;height:1px}
.rowedit__btn{display:inline-flex;align-items:center;gap:.35em;height:1.6rem;padding:0 .5em;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--c-surface);color:var(--text-muted);font-size:var(--text-xs);font-weight:var(--fw-medium);cursor:pointer;white-space:nowrap}
.rowedit__btn:hover{border-color:var(--c-brand-400);color:var(--c-brand-700);background:var(--c-brand-50)}
.rowedit:has(.rowedit__cb:checked) .rowedit__btn{background:var(--c-brand-50);border-color:var(--c-brand-400);color:var(--c-brand-700)}
.rowedit:has(.rowedit__cb:checked)>tr:first-child>td{background:var(--c-surface-2)}
.rowedit__form>td{background:var(--c-surface-2);padding:var(--space-4)}
.rowedit__grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(11rem,1fr));gap:var(--space-4);margin-bottom:var(--space-4)}

/* — Происхождение документа: три состояния, различимы иконкой, не только цветом — */
.orig{display:inline-flex;align-items:center;gap:.35em;height:1.4rem;padding:0 .5em;border-radius:var(--radius-xs);border:1px solid var(--border);font-size:.6875rem;font-weight:var(--fw-semibold);white-space:nowrap;line-height:1}
.orig svg{width:.85rem;height:.85rem;flex:none}
.orig--ecp{background:var(--c-info-50);color:var(--c-info-700);border-color:var(--c-info-100)}
.orig--paper{background:var(--c-slate-100);color:var(--text)}
.orig--manual{background:transparent;color:var(--text-muted);border-style:dashed}

/* — Предпросмотр файла: ожидание конвертации и «файл не приложен» — */
.prev{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--space-3);padding:var(--space-10) var(--space-5);border:1px solid var(--border);border-radius:var(--radius-md);background:var(--c-surface-2);text-align:center}
.prev--none{border-style:dashed;background:transparent}
.prev__title{font-weight:var(--fw-semibold);color:var(--text)}
.prev__hint{font-size:var(--text-sm);color:var(--text-muted);max-width:34ch;text-wrap:pretty}
.spin{width:1.6rem;height:1.6rem;border-radius:50%;border:2px solid var(--c-slate-300);border-top-color:var(--c-brand-600);animation:spin .8s linear infinite}
@keyframes spin{to{transform:rotate(360deg)}}
@media (prefers-reduced-motion:reduce){.spin{animation-duration:2.4s}}

/* — Пагинация длинных справочников — */
.pager{display:flex;align-items:center;gap:var(--space-2);flex-wrap:wrap}
.pager__info{color:var(--text-muted);font-size:var(--text-sm);margin-right:auto}
.pager__btn{min-width:2rem;height:2rem;padding:0 .5em;display:inline-flex;align-items:center;justify-content:center;border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--c-surface);color:var(--text);font-size:var(--text-sm);font-variant-numeric:tabular-nums;cursor:pointer}
.pager__btn:hover{background:var(--c-surface-2)}
.pager__btn.is-current{background:var(--c-brand-600);border-color:var(--c-brand-600);color:#fff;font-weight:var(--fw-semibold)}
.pager__btn:disabled{opacity:.4;cursor:not-allowed}
.pager__gap{color:var(--text-muted);padding-inline:.2em}

/* — Банковские счета: карточка счёта, закрытые — приглушены, без иконки — нейтральная заглушка — */
.acctcard{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-4);border:1px solid var(--border);border-radius:var(--radius-md);background:var(--c-surface)}
.acctcard.is-closed{background:var(--c-surface-2);border-style:dashed}
.acctcard.is-closed .acctcard__name{color:var(--text-muted)}
.acctcard__logo{width:2.5rem;height:2.5rem;border-radius:var(--radius-sm);object-fit:contain;flex:none;background:var(--c-surface-2)}
.acctcard__logo--none{display:grid;place-items:center;background:var(--c-slate-100);color:var(--c-slate-500)}
.acctcard__logo--none svg{width:1.3rem;height:1.3rem}
.acctcard__body{min-width:0;flex:1;display:flex;flex-direction:column;gap:2px}
.acctcard__name{font-weight:var(--fw-semibold);color:var(--text-strong)}
.acctcard__meta{font-size:var(--text-xs);color:var(--text-muted);font-variant-numeric:tabular-nums}

/* — Тёмная тема: пара «фон --c-slate-100 + текст --c-slate-600…900» (итерация 8).
   Шкалу slate-600…900 НЕ инвертируем: в этой системе она же служит тёмной поверхностью
   хрома (--sidebar-bg / --topbar-bg), инверсия делала сайдбар белым по белому.
   Поэтому перечисляем всех консьюмеров пары — их в системе ровно пять. → 5,69:1 каждый. */
[data-theme="dark"] .badge--neutral,
[data-theme="dark"] .src,
[data-theme="dark"] .tag,
[data-theme="dark"] .term-badge--perpetual,
[data-theme="dark"] .shift--idle,
[data-theme="dark"] .ctr-file__ic{color:var(--c-slate-500)}

/* — Полоса вкладок: overflow-x:auto поднимает вторую ось в auto, и 1px вертикального
   переполнения рисует паразитный скроллбар (на 12 вкладках он перекрывал последнюю). — */
.tabbar{overflow-y:hidden}

/* ═══ Итерация 8.1: список справочника — мобильные карточки, метки полноты, фильтр-дропдаун ═══ */

/* — Метки полноты карточки: «есть» — брендовая заливка, «нет» — пунктирный контур.
   Зелёный НЕ используется: pos/neg/warn закреплены за денежной семантикой.
   Состояние читается без цвета — по заливке против пунктира (дальтонизм, ч/б печать). — */
.cmarks{display:inline-flex;gap:.25rem;flex:none}
.cmark{display:inline-flex;align-items:center;height:1.25rem;padding:0 .4em;border-radius:var(--radius-xs);font-size:.625rem;font-weight:var(--fw-bold);letter-spacing:.02em;line-height:1;white-space:nowrap;border:1px solid transparent}
.cmark--on{background:var(--c-brand-600);color:#fff}
/* — Тёмная тема: `--c-brand-600` из тёмного (#003f80) становится светлым (#5b9be6),
   поэтому белый текст на брендовой заливке перестаёт читаться (2,89:1). Перечисляем всех
   консьюмеров «текст поверх brand-600»: заливка остаётся брендовой, текст становится тёмным.
   Декоративные заливки без текста (.switch__track, .period-nav__dot, .taxbar__seg--base,
   .heatmap30) не затронуты. → ≈5,9:1 — */
[data-theme="dark"] .cmark--on,
[data-theme="dark"] .pager__btn.is-current,
[data-theme="dark"] .brand__mark{color:var(--c-canvas)}
/* #293 · Второй куст тех же консьюмеров: в тёмной теме светлеют и --c-pos-600 (#157a4a →
   #4cc389), и --c-neg-600 (#bf2a20 → #ef7a70), поэтому белый текст поверх них рассыпается
   так же. Замер WCAG до → после: .recon__icon «Сошлось» 2,22 → 8,35; .btn--primary
   2,89 → 6,41; .btn--danger 2,73 → 6,78 (норма 4,5:1 — не проходил ни один).
   У кнопок переопределяется --_fg, а не color: color проиграл бы каскаду .btn.
   Правило принято в дизайне и потеряно при пересборке базы от main — это перенос. */
[data-theme="dark"] .recon__icon,
[data-theme="dark"] .acct__mark,
[data-theme="dark"] .vac-overview__seg{color:var(--c-canvas)}
[data-theme="dark"] .btn--primary,
[data-theme="dark"] .btn--danger{--_fg:var(--c-canvas)}

.cmark--off{background:transparent;color:var(--text-muted);border-color:var(--border-strong);border-style:dashed}

/* — Неизвестная отсрочка: договор есть, условия не извлечены — сигнал к действию — */
.delay-unknown{display:inline-flex;align-items:center;gap:.25em;color:var(--c-warn-700);font-weight:var(--fw-semibold);cursor:help;border-bottom:1px dotted currentColor}

/* — Панель фильтров: дропдауны со счётчиками внутри опций + сводка активного фильтра — */
.filterbar{display:flex;flex-wrap:wrap;gap:var(--space-4);align-items:flex-end}
.filterbar__field{display:flex;flex-direction:column;gap:var(--space-1);min-width:13rem}
.filterbar__summary{font-size:var(--text-sm);color:var(--text-muted);padding-bottom:.55rem}
.filterbar__summary strong{color:var(--text-strong);font-variant-numeric:tabular-nums}

/* — Мобильный список контрагентов: карточка-ссылка вместо таблицы, без горизонтального скролла — */
.cplist{display:none}
.cprow{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3) var(--space-4);border-bottom:1px solid var(--border);color:inherit;text-decoration:none}
.cprow:last-child{border-bottom:0}
.cprow:hover{background:var(--c-surface-2);text-decoration:none;color:inherit}
.cprow.is-off{opacity:.6}
.cprow__body{min-width:0;flex:1;display:flex;flex-direction:column;gap:2px}
.cprow__name{font-weight:var(--fw-semibold);color:var(--text-strong);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.cprow__meta{font-size:var(--text-xs);color:var(--text-muted);display:flex;align-items:center;gap:.35em;flex-wrap:wrap}
.cprow__meta .flow-dot{width:.5em;height:.5em}
.cprow__sep{opacity:.5}
.cprow__chev{width:1rem;height:1rem;color:var(--text-muted);flex:none}
@media (max-width:767px){
  .cplist{display:block}
  .cplist ~ .table-wrap{display:none}
}

/* — Логотип банка-начертания (итерация 8.1): широкие лого 5:1 в квадрат не влезают.
   Фиксируем высоту, ширину отдаём содержимому. Светлая подложка держит чёрные
   начертания (ОТП, Россельхозбанк) читаемыми и в тёмной теме — перекрашивать
   чужие логотипы нельзя. — */
.acctcard__logo--mark{width:auto;height:1.5rem;max-width:7.5rem;padding:.2rem .35rem;background:#fff;
  border:1px solid var(--border);border-radius:var(--radius-xs);box-sizing:content-box;object-fit:contain}
@media (max-width:479px){.acctcard__logo--mark{max-width:5.5rem}}

/* ═══ #098 Оживление: иконки разделов, кошельки на «Обзоре», сдержанные эффекты ═══ */

/* — Плашка иконки раздела в хабе «Настройки». Заливка — фиксированный токен раздела,
   глиф белый: тот же приём, что у .grp__ic, он единственный держит AA в обеих темах
   (мягкая тонированная подложка в тёмной теме проваливается по контрасту). — */
.hub-card__icon[class*="plate--"]{background:var(--plate);color:#fff;border-radius:var(--radius-sm);
  width:2.25rem;height:2.25rem;display:grid;place-items:center;flex:none}
.hub-card__icon[class*="plate--"] svg{width:1.25rem;height:1.25rem}
.plate--password{--plate:var(--grp-services)}
.plate--counterparties{--plate:var(--grp-food)}
.plate--contracts{--plate:var(--grp-rent)}
.plate--accounts{--plate:var(--grp-utilities)}
.plate--users{--plate:var(--grp-payroll)}
.plate--pnl{--plate:var(--grp-taxes)}
.plate--channels{--plate:var(--grp-aggregators)}
.plate--staffing{--plate:var(--grp-transport)}
.plate--activity{--plate:var(--grp-alcohol)}
.plate--permissions{--plate:var(--accent-bordo)}

/* — Кошелёк на «Обзоре»: логотип банка / символ кассы / символ «деньги в дороге» — */
.kpi__head{display:flex;align-items:center;gap:var(--space-2);margin-bottom:var(--space-1)}
.kpi__mark{width:1.75rem;height:1.75rem;border-radius:var(--radius-xs);flex:none;display:grid;place-items:center;
  background:var(--c-surface-2);border:1px solid var(--border);object-fit:contain;color:var(--text-muted)}
.kpi__mark svg{width:1.05rem;height:1.05rem}
.kpi__mark--transit{border-style:dashed;border-color:var(--transit-bd);background:transparent}

/* Логотипы источников: до трёх, дальше «+N» */
.kpi__srcs{display:inline-flex;align-items:center;gap:.25rem;margin-left:auto;flex:none}
.kpi__srcs img{width:1.25rem;height:1.25rem;border-radius:var(--radius-xs);object-fit:contain;background:#fff;border:1px solid var(--border)}
.kpi__srcmore{display:inline-flex;align-items:center;height:1.25rem;padding:0 .35em;border-radius:var(--radius-xs);
  background:var(--c-slate-100);color:var(--text-muted);font-size:.625rem;font-weight:var(--fw-bold);font-variant-numeric:tabular-nums}

/* Исторический кошелёк: действующий и архивный */
.kpi--archived{background:var(--c-surface-2);border-style:dashed}
.kpi--archived .kpi__value{color:var(--text-muted)}

/* Служебные плитки: меньше и легче, чтобы не спорили с деньгами */
.kpi--service{padding:var(--space-3) var(--space-4)}
.kpi--service .kpi__value{font-size:var(--text-md);font-weight:var(--fw-semibold);color:var(--text)}
.kpi--service .kpi__label{font-size:var(--text-xs)}

/* — Сдержанные эффекты: подъём на наведении, видимый фокус, мгновенный отклик на нажатие — */
.card,.kpi,.hub-card,.gcard,.acctcard{transition:transform .14s ease,box-shadow .14s ease,border-color .14s ease}
a.hub-card:hover,a.gcard:hover,a.acctcard:hover{transform:translateY(-2px);box-shadow:var(--shadow-md);border-color:var(--c-brand-200)}
a.hub-card:active,a.gcard:active,a.acctcard:active{transform:translateY(0);box-shadow:var(--shadow-sm);transition-duration:0s}
a.hub-card:focus-visible,a.gcard:focus-visible,a.acctcard:focus-visible{outline:2px solid var(--border-focus);outline-offset:2px;box-shadow:var(--shadow-focus)}
.quick-actions{display:flex;flex-wrap:wrap;gap:var(--space-3)}
.quick-actions .btn{transition:transform .14s ease,box-shadow .14s ease}
.quick-actions .btn:hover{transform:translateY(-1px);box-shadow:var(--shadow-sm)}
.quick-actions .btn:active{transform:translateY(0);transition-duration:0s}
@media (prefers-reduced-motion:reduce){
  .card,.kpi,.hub-card,.gcard,.acctcard,.quick-actions .btn{transition:none}
  a.hub-card:hover,a.gcard:hover,a.acctcard:hover,.quick-actions .btn:hover{transform:none}
}

/* ═══ #099 блок 6: путь наверх — хлебные крошки (итерация 9) ═══
   Крошки ВЫТЕСНЯЮТ кнопку «Назад: …» — путь наверх ровно один способ (обоснование в CHANGES).
   Стоят над заголовком, в потоке page-head, глубина максимум три звена. */
.crumbs{display:flex;align-items:center;gap:.35rem;flex-wrap:nowrap;min-width:0;
  font-size:var(--text-xs);color:var(--text-muted);margin-bottom:var(--space-1)}
.crumbs a{color:var(--text-muted);text-decoration:none;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:14rem}
.crumbs a:hover{color:var(--link);text-decoration:underline}
.crumbs__sep{flex:none;opacity:.55}
.crumbs__here{color:var(--text);font-weight:var(--fw-medium);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}
.crumbs__back{display:none;flex:none;align-items:center;gap:.25rem;color:var(--text-muted);text-decoration:none;white-space:nowrap}
.crumbs__back svg{width:.9rem;height:.9rem;flex:none}
.crumbs__back:hover{color:var(--link)}

/* Мобильный: цепочка не помещается — остаётся только родитель со стрелкой (это те же крошки,
   схлопнутые до одного звена, а не второй компонент: разметка одна, лишнее скрыто). */
@media (max-width:640px){
  .crumbs a:not(.crumbs__back),.crumbs__sep,.crumbs__here{display:none}
  .crumbs a.crumbs__back{display:inline-flex}
  .crumbs{margin-bottom:var(--space-2)}
}

/* Верхний уровень раздела: крошки вырождаются в одно звено — вместо них подпись-ориентир. */
.page-kicker{display:flex;align-items:center;gap:.4rem;font-size:var(--text-xs);color:var(--text-muted);margin-bottom:var(--space-1)}
.page-kicker__ic{width:.95rem;height:.95rem;flex:none}

/* Пункт «скоро»: недоступен, но виден — состав раздела не меняется по мере готовности. */
.hub-card.is-soon{opacity:.65;pointer-events:none;border-style:dashed}
.hub-card__soon{margin-left:auto;flex:none}
.hub-card.is-soon .hub-card__icon[class*="plate--"]{background:var(--c-slate-400)}

/* ═══ #099 блоки 1–5: строка ввода кассового дня, сворачивание, пикер, мобильный ═══ */

/* — Блок 1. Осознанная сетка строки расхода. table-layout:fixed отдаёт ширины нам, а не браузеру.
   Ширины — фиксированные доли: все колонки растут вместе с контейнером. Меньше всего дано
   «Описанию»: у него нет измеримого требования — текст длиннее любой колонки и сидит под
   многоточием по замыслу. Селекты и контрагент — наоборот: «Касса (наличные)» должна быть
   читаема целиком, ошибка в счёте стоит денег. — */
/* min-width — пол читаемости: ниже него таблица не сжимается, а прокручивается.
   Проценты выше этого пола растягивают колонки по контейнеру (965 px при открытом меню,
   ~1149 px при свёрнутом), ниже — работают от самого пола, поэтому названия не режутся.
   Сжатия «на время открытого пикера» больше нет: в макете четвёртая строка стоит open
   для демонстрации, :has() был бы включён всегда и пол читаемости не действовал бы. */
/* #108: состав колонок изменился — «Счёт» убран (в кассовом дне ведутся только наличные,
   банк приходит из выписки). Осталось шесть колонок в утверждённом порядке:
   № · Сумма · Категория · Получатель · Описание · кнопки строки.

   Проценты (набор #099) заменены на ФИКСИРОВАННЫЕ ширины пяти колонок + auto у «Описания».
   Причина — арифметика реального экрана, а не вкусовщина: при развёрнутом меню на 1280
   контент-колонка кассового дня даёт ~628 px (1280 − сайдбар 256 − паддинги контейнера 40 −
   рейка сверки 336 − зазор 20). Проценты сжимали бы ВСЕ колонки пропорционально, и «Категория»
   с «Получателем» теряли бы читаемость там, где она нужнее всего. Фиксированные ширины держат
   опознание значения на любой ширине, а весь остаток забирает «Описание» — единственная
   колонка со свободным текстом, который пользователь только что набрал сам.

   Ширины — измеренная потребность (текст шрифтом страницы + хром контрола), не глазом:
     col-num  2rem     = 32 px — два разряда номера строки, правое выравнивание;
     col-sum  6.25rem  = 100 px — «126 920,50» (73) + паддинги инпута (16) + поля ячейки; шапка
                                  «Сумма, ₽» (58, nowrap) тоже укладывается;
     col-cat  11.5rem  = 184 px — селект: поля ячейки 10 + паддинг 8 + стрелка 20 + текст 146,
                                  чего хватает на «Коммунальные услуги» (145) — самую частую длинную;
     col-cp   10rem    = 160 px — пикер: поля 10 + паддинги 16 + стрелка 16 + зазор 8 + текст 110,
                                  хватает на «ООО «Ромашка»» (108) и «Мосэнергосбыт» (95);
     col-del  3.9rem   = 62 px — ДВЕ кнопки строки: дискетка 26 + корзина 26 + поля ячейки;
     col-desc auto     — весь остаток контейнера.

   Пол min-width:33.7rem (539 px) — это ровно сумма пяти фиксированных колонок, то есть скролл
   включается только когда «Описанию» не осталось ничего. Ориентир 47rem из заявки (752 px)
   не подошёл бы: контент-колонка на 1280 с развёрнутым меню — 611 px по замеру (не 626),
   752 > 611, и таблица продолжила бы скроллиться. Проверено замером, поэтому пол снижен дальше. */
table.entry.entry--grid{table-layout:fixed;width:100%;min-width:33.7rem}
.entry--grid col.col-num{width:2rem}
.entry--grid col.col-sum{width:6.25rem}
.entry--grid col.col-cat{width:11.5rem}
.entry--grid col.col-cp{width:10rem}
.entry--grid col.col-desc{width:auto}
.entry--grid col.col-del{width:3.9rem}
/* Класс сохранён намеренно: колонки «Счёт» в кассовом дне больше нет, но состав классов
   проверяется приёмкой, а правило безвредно — при шести <col> оно ни к чему не применяется. */
.entry--grid col.col-acct{width:0}
/* «Сумма» (число, выровненное вправо) стояла вплотную к «Категории» (селект от левого края) —
   зазор был всего 2×4,8 px паддинга ячейки. Увеличен адресно на этой границе, а не по всей
   таблице — остальные колонки уже разделены текстовыми контролами и так читаются нормально. */
.entry--grid td.amount-cell{padding-right:1.25rem}
.entry--grid td{overflow:hidden}
/* ...но не у ячейки с раскрытым пикером: overflow:hidden обрезал бы его меню по краю ячейки. */
.entry--grid td:has(.picker[open]){overflow:visible}
/* Селекты не сжимаются ниже читаемости названия */
/* Хром селекта в сетке жмётся: стрелке хватает 1.25rem, освободившиеся 4 px уходят названию. */
.entry--grid select.grid-input{min-width:100%;text-overflow:ellipsis;padding-right:1.25rem}
.entry--grid .picker{display:block;width:100%}
/* Прод жёстко держит min-width:14rem на summary пикера — в сетке ширину задаёт колонка */
.entry--grid .picker>summary{min-width:0;width:100%;padding-inline:var(--space-2)}
/* Длинные названия обрезаются многоточием осознанно: полное значение видно в раскрытом списке —
   .picker__menu держит min-width:18rem (288 px) и шире колонки, а раскрытый <select> рисуется
   попапом по натуральной ширине. Опознание в закрытом состоянии + полный текст при выборе. */
.entry--grid .payroll-type-select{margin-top:var(--space-1)}

/* — #108: последняя колонка. Две кнопки строки в один ряд: дискетка (сохранение строки, #104)
   и корзина. Дискетка видна ВСЕГДА — это индикатор состояния строки, а не действие по наведению;
   корзина остаётся на hover, как в принятом поведении .del-btn. Состояние «сохранено» кодируется
   двумя осями: форма иконки (дискета → галка) и цвет, — не цветом в одиночку. — */
.entry--grid td.del-cell{text-align:center;white-space:nowrap}
.entry--grid td.del-cell .del-btn,.entry--grid td.del-cell .line-save-btn{display:inline-grid;vertical-align:middle}
.line-save-btn{width:1.6rem;height:1.6rem;display:grid;place-items:center;border:0;background:transparent;
  border-radius:var(--radius-sm);color:var(--text-muted);cursor:pointer;padding:0}
.line-save-btn:hover{background:var(--c-surface-2);color:var(--text-strong)}
.line-save-btn.is-saved{color:var(--c-pos-600)}
.line-save-btn svg{width:16px;height:16px}

/* — Блок 2 (#099, пересчитан под #108). Свёрнутое меню отдаёт контенту ~184 px. Отдельный набор
   ширин больше не нужен: «Описание» на auto забирает остаток само. Но там, где места много,
   двум колонкам опознания не жалко добавить — длинные названия категорий и контрагентов
   перестают обрезаться. Порог 1200 px оставлен прежним. — */
@media (min-width:1200px){
  .app-shell.is-collapsed .entry--grid col.col-cat{width:12rem}
  .app-shell.is-collapsed .entry--grid col.col-cp{width:12rem}
}
/* От 1440 px рабочая область (100rem) даёт кассе 771–1204 px, и «Описание» уже не голодает —
   поэтому две колонки опознания забирают своё: категория показывает «Прочие запланированные»
   (160), получатель — плейсхолдер «— без контрагента —» (136), который в базовом наборе
   не влезал. Ниже порога приоритет обратный: место нужнее «Описанию».
   Порог 1400, а не 1440: окно 1440 с вертикальной полосой прокрутки даёт вьюпорт ~1425,
   и правило на 1440 в него уже не попадало — проверено замером (та же грабля, что с 1200/1280). */
@media (min-width:1400px){
  .entry--grid col.col-cat{width:13.25rem}
  .entry--grid col.col-cp{width:12rem}
  /* Граница Категория→Получатель: колонка шире базовой на 0.75rem, и весь этот прирост
     уходит в правый паддинг ячейки, а не в селект: читаемое место внутри не сужается,
     только растёт зазор до «Получателя». Сужено до ≥ 1400 — на базовом размере у col-cat
     запаса почти нет (2 px против «Незапланированные расходы»), добавлять паддинг там —
     обрезать текст. */
  .entry--grid td.col-cat{padding-right:.75rem}
}
/* На 1920 (и шире) «Описание» забирало весь остаток контейнера — сотни лишних пустых px
   после набранного текста. Первая попытка — max-width на самом .entry--grid — отката: у
   .table-wrap своя карточка (рамка+тень), и узкая таблица внутри неё выглядела второй,
   вложенной коробкой. Теперь ограничен сам инпут строки описания: у поля есть max-width,
   а остаток ячейки — прозрачный фон таблицы без рамки, то есть визуально это просто воздух
   строки, а не вторая коробка внутри первой. */
.entry--grid td.col-desc .grid-input{max-width:26rem}

/* — Блок 3. Обрезка списка контрагента. Причина: .panel{overflow:hidden} режет
   абсолютное .picker__menu. Точечно снимаем переполнение только у панели с открытым пикером —
   меню открывается полностью даже в последней строке. Выносить в слой поверх интерфейса
   не стал: это потребовало бы JS для позиционирования, а JS в поставку не идёт. — */
/* .table-wrap — клип-бокс по ОБЕИМ осям: overflow-x:auto приводит overflow-y:visible к auto,
   поэтому «только по вертикали» не работает. Раскрываем обе оси — но это безопасно ровно там,
   где таблица укладывается в контент-область и горизонтальный скролл не нужен. От 1280 px это
   так при любом состоянии меню (965 / ~1149 px против пола 912 px), поэтому снятие переполнения
   ограничено этой шириной. Ниже — обёртка остаётся скролл-боксом: список контрагента
   подрезается по её краю и доступен прокруткой (JS для слоя поверх интерфейса не кладём).
   Порог 1200, а не 1280: хром при открытом меню съедает 312 px, значит пол 880 px выполнен уже
   от 1192 px вьюпорта — и ревью-просмотрщик в режиме 1280 даёт iframe шириной 1278 px (рамка). */
@media (min-width:1200px){
  .panel:has(.picker[open]){overflow:visible}
  .panel:has(.picker[open]) .table-wrap{overflow:visible}
}
/* Строка с открытым пикером поднимается над соседями */
.entry--grid tr:has(.picker[open]){position:relative;z-index:31}
/* Меню в последней строке раскрывается вверх, если снизу нет места */
.picker--up[open] .picker__menu{top:auto;bottom:calc(100% + 4px)}

/* — Блок 4. Мобильный кассовый день: строка ввода — карточка, а не таблица. — */
.entry-cards{display:none}
.entry-card{border:1px solid var(--border);border-radius:var(--radius-md);padding:var(--space-3);
  background:var(--c-surface);display:flex;flex-direction:column;gap:var(--space-2)}
.entry-card + .entry-card{margin-top:var(--space-3)}
.entry-card__top{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2)}
.entry-card__num{font-size:var(--text-xs);color:var(--text-muted)}
.entry-card__sum{font-variant-numeric:tabular-nums;font-weight:var(--fw-bold);font-size:var(--text-md);color:var(--text-strong)}
.entry-card__row{display:flex;flex-direction:column;gap:2px}
.entry-card__k{font-size:var(--text-xs);color:var(--text-muted)}
.entry-card__v{font-size:var(--text-sm);color:var(--text)}
.entry-card__desc{font-size:var(--text-sm);color:var(--text);text-wrap:pretty}
/* Палец, а не курсор. Три тап-зоны в карточной/мобильной подаче подняты до 44 px.
   Всё — суженными селекторами, без правок самих прод-классов: в десктопном сайдбаре
   те же .icon-btn остаются 32 px — там мышь и это нормальная плотность.
   У .btn в проде жёсткая height:2.5rem — поэтому задаём height, а не только min-height. */
.entry-cards .btn{height:2.75rem;min-height:2.75rem}
@media (max-width:1023px){
  .mobile-topbar .mobile-topbar__burger{width:2.75rem;height:2.75rem}
  .mobile-topbar .icon-btn{width:2.75rem;height:2.75rem}
}

@media (max-width:767px){
  .entry-cards{display:block}
  .entry-cards ~ .table-wrap{display:none}
  /* Панель «Клавиатура» — Tab/Enter/Ctrl+S на телефоне не существует */
  .keys-panel{display:none}
  /* Сверка кассы — главный контроль дня — поднимается наверх */
  .cashday--mobile-order{display:flex;flex-direction:column}
  /* #291: сняты .order-expense и .order-income — их классов нет в разметке вовсе. Замер по
     остальным двум: .cashday--mobile-order стоит на <form>, её прямые дети — .cashday__main
     и aside.recon-rail, поэтому дочерний селектор не попадает и в .order-revenue тоже; но
     этот класс в разметке живёт, и снятие правила разошлось бы с макетом — оставлено
     до ответа дизайнера (та же структура и у него). Порядок держат правила ниже. */
  .cashday--mobile-order > .order-recon{order:1}
  .cashday--mobile-order > .order-revenue{order:2}
}

/* — Блок 5. Одна навигационная модель на мобильном: bottom-nav основная, оффканвас
   показывает только то, чего в ней нет. Пересекающиеся пункты в оффканвасе скрыты. — */
@media (max-width:1023px){
  .sidebar__link.is-in-bottomnav{display:none}
  .sidebar__nav::before{content:"Не вошло в нижнее меню";display:block;
    font-size:var(--text-xs);color:rgba(255,255,255,.45);padding:var(--space-2) var(--space-3) var(--space-1)}
}

/* ═══ #099 доп.: «Выручка» как выгрузка из СБИС + ручной ввод отдельно ═══
   Правила только через модификаторы — принятые .rev-group / .rev-group__body не переопределяем. */

/* Шапка синхронизации: источник, время, ручная кнопка «Обновить из СБИС» */
.rev-sync{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;
  padding:var(--space-3) var(--space-5);border-bottom:1px solid var(--border);background:var(--c-surface-2)}
.rev-sync__when{font-size:var(--text-xs);color:var(--text-muted);font-variant-numeric:tabular-nums}
.rev-sync__btn{margin-left:auto;flex:none}

/* Автоматическая группа: поля только читаются — подаём списком, а не сеткой полей ввода.
   Заодно уходит рваный ряд: у списка одна колонка, высота подписи не влияет на соседей. */
.rev-group--auto .rev-group__body{display:block;padding-top:0}
.rev-line{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-2) 0;border-bottom:1px solid var(--border)}
.rev-line:last-child{border-bottom:0}
.rev-line__name{display:flex;align-items:center;gap:var(--space-2);min-width:0;flex:1;font-size:var(--text-sm)}
.rev-line__val{font-variant-numeric:tabular-nums;font-weight:var(--fw-semibold);color:var(--text-strong);white-space:nowrap}
.rev-line__val.is-neg{color:var(--expense)}
.rev-line__note{flex-basis:100%;font-size:var(--text-xs);color:var(--text-muted);margin:0}

/* Ручная группа: остаётся полями ввода, но ряд выровнен по верху — подписи разной высоты
   больше не сдвигают соседей. */
.rev-group--manual .rev-group__body{align-items:start}
.rev-group--manual .rev-field__head{min-height:1.35rem;display:flex;align-items:center;gap:var(--space-2)}

/* Признак происхождения на уровне группы, чтобы не повторять плашку у каждой строки */
.rev-group__src{display:inline-flex;align-items:center;gap:.3em;margin-left:var(--space-2);flex:none}

/* Ручная группа: не растягиваем поля бесконечно — максимум три в ряд */
/* Три поля — три колонки, без фантомной пустой дорожки от auto-fit */
.rev-group--manual .rev-group__body{grid-template-columns:repeat(3,minmax(0,18rem))}
@media (max-width:900px){.rev-group--manual .rev-group__body{grid-template-columns:repeat(2,minmax(0,18rem))}}
@media (max-width:600px){.rev-group--manual .rev-group__body{grid-template-columns:minmax(0,1fr)}}

/* — #108, вне рамки заявки: мобильный порядок блока 4 (#099) при текущей разметке прода.
   .cashday--mobile-order стоит на <form>, а её прямые дети — .cashday__main и aside.recon-rail;
   принятые правила .order-* висят на панелях ВНУТРИ main и до прямых детей не достают, поэтому
   «Сверка кассы» уезжала вниз. Две строки возвращают принятый порядок без правки разметки.
   Если порядок решено менять иначе — эти две строки удаляются без последствий. — */
@media (max-width:767px){
  .cashday--mobile-order > .recon-rail{order:1}
  .cashday--mobile-order > .cashday__main{order:2}
  /* align-items:start у .cashday нужен рейке на десктопе (карточка не тянется на всю высоту),
     но в мобильной колонке он же не даёт ей растянуться по ширине: рейка вставала 259 px
     против 319 px у панелей. В колоночной раскладке возвращаем растяжение. */
  .cashday--mobile-order{align-items:stretch}
}


/* ═══ Пакет 2 (продолжение #108/#105, принято 29.07): плотность строк табеля/графика, дни
   недели, тип дня календаря, закреплённые колонки итогов табеля, архив в штатном, bottom-nav ═══ */

/* часть 1 — должность в отдельной колонке, мелким шрифтом, вместо строки под ФИО (вдвое ниже
   строка). Модификатор поверх .cell-emp__pos — сам класс не трогаем, им пользуется стек #030-B. */
.cell-emp__pos--col{white-space:nowrap}
.cell-emp__pos--mobile{display:none}

/* зебра по строкам сотрудников — класс на строку: заголовки подразделений и подытоги сбивают
   чётность, nth-child зебрил бы вперемешку с ними. */
.is-alt{background:var(--c-surface-2)}
.table--dense.table--sticky1 tr.is-alt td:first-child{background:var(--c-surface-2)}
.sched-table tr.is-alt td.sched-namecol{background:var(--c-surface-2)}

/* часть 2 — дни недели под числами месяца: вторая строка шапки, той же плотности что первая.
   top второй строки = высота первой (число + её паддинг/рамка), посчитанная тем же font-size. */
/* часть 2 — день недели под числом внутри ТОЙ ЖЕ ячейки шапки, второй строки нет: две отдельные sticky-строки
   шапки требовали точного top второй под высоту первой — в живом превью расхождение с реальной
   высотой давало разъезжающиеся ряды чисел (скриншот пользователя). Исправлено слиянием в ОДНУ
   строку: число и буквы дня внутри одной ячейки (две короткие строки текста) — одна sticky-строка
   вместо двух, баг класса снят целиком и высота шапки падает примерно вдвое, как просил заказчик. */
.hdr-wd{display:block;font-size:.68em;font-weight:var(--fw-regular);color:var(--text-muted);line-height:1.05;text-transform:none!important}

/* часть 3 — тип дня в календарной колонке: ось независимая от kind ячейки графика (та про
   запись сотрудника в этот день, эта про саму дату). Второй канал — не только цвет: выходной
   читается по паре букв (сб/вс) в подзаголовке; праздник — штриховкой (приём .sched-cell--trial,
   перенесённый на колонку целиком); предпраздничный — подчёркиванием числа/буквы пунктиром.
   Праздник, выпавший на выходной (9 мая 2026 — суббота), в разметке получает is-holiday ВМЕСТО
   is-weekend — конфликта приоритета в CSS нет; для отпуска на такой день компаунд-селектор
   ниже специфичнее обеих частей по отдельности, отпуск остаётся читаемым поверх. */
/* #151 D1: маркеры выходного/праздника — НЕПРОЗРАЧНЫЙ background-color + узор через
   background-image. Раньше полупрозрачный background с !important затирал фон thead th
   (липкая шапка просвечивала: под числом читалась строка данных). Теперь thead th.is-weekend
   сохраняет непрозрачный фон + узор поверх — шапка не просвечивает. */
.is-weekend{background-color:color-mix(in srgb, var(--c-slate-600) 10%, var(--c-surface-2))!important;background-image:repeating-linear-gradient(135deg,transparent 0 4px,color-mix(in srgb, var(--c-slate-600) 6%, transparent) 4px 8px)!important}
.is-holiday{background-color:color-mix(in srgb, var(--c-brand-100, var(--c-brand-50)) 30%, var(--c-surface-2))!important;background-image:repeating-linear-gradient(135deg,transparent 0 4px,color-mix(in srgb, var(--text) 8%, transparent) 4px 8px)!important}
/* border-bottom пунктиром на ячейке при border-collapse:collapse красится отдельным слоем
   разрешения границ таблицы — этот слой у сеточных таблиц может визуально рисоваться поверх
   position:sticky колонок (ФИО/Должность) при горизонтальной прокрутке, в обход обычного
   порядка отрисовки контента ячейки. Псевдоэлемент внутри ячейки — обычный слой контента,
   подчиняется тому же порядку, что и остальное содержимое (уже проверено: там sticky-колонки
   корректно перекрывают соседние ячейки). */
/* border-bottom пунктиром на ячейке при border-collapse:collapse красится отдельным слоем
   разрешения границ таблицы — этот слой у сеточных таблиц может визуально рисоваться поверх
   position:sticky колонок (ФИО/Должность) при горизонтальной прокрутке, в обход обычного
   порядка отрисовки контента ячейки. Заменено на фоновый паттерн (обычный слой контента,
   тот же порядок отрисовки, что у остального содержимого ячейки — sticky-колонки его корректно
   перекрывают). Псевдоэлементы `::before/::after` заняты подсказкой при наведении (не годятся). */
.is-preholiday{
  border-bottom:0!important;
  background-image:linear-gradient(to right, var(--c-info-700) 50%, transparent 50%)!important;
  background-size:6px 2px!important;
  background-position:bottom!important;
  background-repeat:repeat-x!important;
}
td.ts-vacation.is-weekend,td.ts-vacation.is-holiday{background:repeating-linear-gradient(135deg,var(--c-brand-50) 0 4px,transparent 4px 8px)!important}
.sched-legend__swatch.is-weekend,.sched-legend__swatch.is-holiday{width:1.1rem;height:1.1rem;border-radius:3px;display:inline-block}

/* ═══ Итерация 12 (#121): «Итого за месяц», подсказка-иконка, «Выплачено» тотал+журнал,
   типы дня расширены (отгул/прогул/смотровой в табеле), «Не могу выйти» — 3 состояния ═══ */

/* часть 1 — подсказка под иконку вместо 3-строчного текста рядом с заголовком (п.4 ТЗ_121).
   Существующий [data-tip] (CSS-тултип, см. выше) — без нового механизма; иконка — обычная
   focusable-кнопка, поэтому «по тапу» работает тем же :focus-visible, что и на десктопе. */
.hint-icon{width:1.4rem;height:1.4rem;border-radius:50%;border:1px solid var(--border-strong);color:var(--text-muted);display:grid;place-items:center;cursor:help;flex:none;background:none}
.hint-icon svg{width:.8rem;height:.8rem}
.hint-icon:hover,.hint-icon:focus-visible{color:var(--c-brand-700);border-color:var(--c-brand-200)}

/* часть 2 — «Выплачено»: тотал + разбивка мелким + журнал по клику (details/summary, без JS).
   Способ платежа (badge--cash/card) теперь свойство СТРОКИ журнала, не месячной ячейки —
   у месяца способа не существует, если платили и так, и так (§5 ТЗ_121). */
.payout-cell{display:block;text-align:right}
.payout-cell>summary{list-style:none;cursor:pointer;display:flex;flex-direction:column;align-items:flex-end;gap:1px}
.payout-cell>summary::-webkit-details-marker{display:none}
.payout-cell>summary:hover .payout-cell__total{text-decoration:underline;text-decoration-style:dotted}
.payout-cell__breakdown{font-size:var(--text-xs);color:var(--text-muted);font-weight:var(--fw-regular);white-space:nowrap}
.payout-journal{margin-top:var(--space-2);padding-top:var(--space-2);border-top:1px dashed var(--border);display:flex;flex-direction:column;gap:var(--space-2);text-align:left}
.payout-journal__row{display:flex;align-items:center;gap:var(--space-2);font-size:var(--text-xs);white-space:nowrap}
.payout-journal__date{color:var(--text-muted)}
.payout-journal__sum{font-weight:var(--fw-medium);margin-left:auto}

/* часть 3 — новые типы дня в табеле (letter-код в ячейке вместо часов, приём .ts-vacation).
   Своя заливка на каждый тип — второй канал (буква) уже есть у всех, дополнительно смотровой
   получает ту же штриховку, что в графике (.sched-cell--trial), прогул — отдельную, гуще и под
   другим углом, чтобы не спутать со смотровым. */
.ts-sick{background:var(--kind-sick-bg);color:var(--kind-sick-fg);font-weight:var(--fw-semibold);text-align:center;font-size:.7em}
.ts-dayoff-used{background:color-mix(in srgb, var(--c-info-700) 16%, var(--c-surface));color:var(--c-info-700);font-weight:var(--fw-semibold);text-align:center;font-size:.7em}
.ts-trial{background:var(--kind-trial-bg);color:var(--kind-trial-fg);background-image:repeating-linear-gradient(135deg,transparent 0 3px,rgba(0,0,0,.06) 3px 6px);font-weight:var(--fw-semibold);text-align:center;font-size:.7em}
.ts-absent-unexcused{background:var(--c-slate-200);color:var(--c-slate-800);background-image:repeating-linear-gradient(45deg,transparent 0 3px,color-mix(in srgb, var(--c-slate-900) 22%, transparent) 3px 6px);font-weight:var(--fw-semibold);text-align:center;font-size:.7em}

/* часть 4 — «Не могу выйти» (unavailable, §7 ТЗ_121): переиспользует --kind-dayoff — токен уже
   был подписан «важная дата — не может выйти» при заведении в пакете 2, буквально та же
   сущность. Три состояния — второй канал у каждого (форма, не только цвет):
   заявлено — пунктирная рамка (тот же язык, что .sched-cell--proposed для заявок графика);
   учтено — сплошная заливка (как остальные kind-* в графике);
   сдвинуто — заливка слота смены СВЕРХУ + маленький флаг в углу (приём .sched-status-dot,
   уже используемый для одобрения/отклонения замен) — видно и то, что смена стоит, и то, что
   она стоит НАПЕРЕКОР просьбе. */
.sched-cell--unavail-requested{background:transparent;border:1.5px dashed var(--kind-dayoff-fg);color:var(--kind-dayoff-fg);box-sizing:border-box}
.sched-cell--unavail-approved{background:var(--kind-dayoff-bg);color:var(--kind-dayoff-fg)}
.sched-status-dot.is-overridden{background:var(--kind-dayoff-fg)}
/* значок наличия комментария у дня (§7: «в ячейке — значок наличия комментария») — маленькая
   точка в углу ячейки, отдельная позиция от status-dot (тот в углу справа сверху), не спорит
   цветом ни с одним из kind-* — нейтральный slate. */
.has-note{position:relative}
.has-note::after{content:"";position:absolute;left:1px;bottom:1px;width:4px;height:4px;border-radius:50%;background:var(--c-slate-500)}

/* часть 5 — отгул (уже полученное право на отсутствие, TZ §6) — мягкий информационный тон,
   отдельный и от «не могу выйти» (то заявка, это факт), и от отпуска/больничного/смотрового.
   color-mix от существующего --c-info-700 (тот же приём, что у предпраздничного маркера),
   без нового токена. */
.sched-cell--dayoff-used{background:color-mix(in srgb, var(--c-info-700) 16%, var(--c-surface));color:var(--c-info-700)}

/* часть 6 — прогул (TZ §6, #129) — единственный «проблемный» тип; денежная семантика neg/warn
   занята под деньги (правило проекта), поэтому не красный/жёлтый — тёмно-серая штриховка под
   другим углом и гуще, чем у смотрового, буква видна на просвет. */
.sched-cell--absent-unexcused{background:var(--c-slate-200);color:var(--c-slate-800);background-image:repeating-linear-gradient(45deg,transparent 0 3px,color-mix(in srgb, var(--c-slate-900) 22%, transparent) 3px 6px)}

/* часть 8 — граф смен sess_016 (§10 ТЗ_121): ячейка — час цифрой, фон = категория времени
   (открытие/день/вечер), план/факт различаются НЕ цветом (открытие/день/вечер — это только план;
   факту категория не нужна, он показывает отработанные часы, а не время прихода) — факт жирным
   без заливки (унаследовано от базового .sched-cell — у него уже font-weight:bold, заливки не
   было и не будет, если не навесить .sched-cell--open/--kitchen/--rest). .sched-cell--fact —
   явное имя для читаемости кода, свойств не добавляет сверх базового. */
.sched-cell--fact{color:var(--text-strong)}
/* --slot-open — категория «открытие», единственная с усиленным начертанием (просьба «выделить
   сильнее прочих» — туда мало кто хочет). Средствами, не цветом: жирная рамка вместо обычной. */
.sched-cell--open{box-shadow:inset 0 0 0 1.5px var(--slot-open-fg)}

/* сегодня — вертикальная граница между планом и фактом, а не подсветка всей колонки (кроме
   заголовка, где полоса плюс жирный номер — иначе на 31 узкой колонке границу не найти взглядом) */
.is-today{box-shadow:inset 2px 0 0 var(--c-brand-600),inset -2px 0 0 var(--c-brand-600)}
thead .is-today{background:var(--c-brand-50)!important;color:var(--c-brand-700)}
thead .is-today .sched-daynum{font-weight:var(--fw-bold)}
/* автофокус на сегодня без JS: якорь на заголовке сегодняшнего дня + переходы С ДРУГИХ экранов
   на #today-col (переход в пределах самого графика не нужен — на нём уже находишься). Нативная
   навигация по фрагменту сама скроллит нужный скролл-контейнер (.table-wrap), в т.ч. по горизонтали
   — без scrollIntoView и вообще без единой строчки JS. scroll-margin — компенсация на ширину
   закреплённых слева колонок (Сотрудник+Должность), чтобы якорь не встал вплотную под них. */
#today-col{scroll-margin-left:19rem;scroll-margin-top:3rem}

/* часть 9 — итог дня против штатного минимума (§10.4): две строки под сеткой, число человек
   в смене этот день по группе, недокомплект — тот же язык, что уже даёт --coverage-short
   (сеть #077 «комплект дня», не новая палитра). */
.sched-covrow td.sched-namecol{font-weight:var(--fw-semibold);color:var(--text-muted);font-size:var(--text-xs)}
.sched-cov{font-weight:var(--fw-bold);color:var(--coverage-good)}
.sched-cov.is-short{color:var(--coverage-short);background:color-mix(in srgb, var(--coverage-short) 12%, transparent)}

/* норма против плана у сотрудника (§10.5) — переиспользует существующий .delta язык (тот же,
   что в KPI и в дельтах отчёта учредителя): стрелка вверх/вниз, не только цвет. */
.sched-namecol .delta__arrow{margin-left:2px}

/* часть 10 — печать графика и табеля, ЧБ (§10.8). Вся цветовая кодировка (категории времени,
   3 состояния заявки, типы дня) на сером принтере превращается в неразличимые оттенки — второй
   язык: буквы/цифры (уже есть в разметке — час, letter-коды типов дня), рамки и штриховка
   (уже есть у праздника/смотрового/прогула), жирность (план/факт). print-color-adjust:exact —
   иначе Chrome по умолчанию не печатает фоновые паттерны/цвета вовсе, и вторая половина кодировки
   пропадает без предупреждения. */
@media print{
  .sidebar,.mobile-topbar,.bottom-nav,.page-head .cluster,.hint-icon,.rate-toggle,footer{display:none!important}
  .app-shell{display:block}
  .app-main{padding:0}
  .container,.container--wide{max-width:none;padding:0}
  .panel{box-shadow:none;border:1px solid #000}
  .table-wrap{overflow:visible!important;max-height:none!important}
  *{-webkit-print-color-adjust:exact;print-color-adjust:exact;color-adjust:exact}
  .sched-cell--open{box-shadow:inset 0 0 0 2px #000}
  .sched-cell--kitchen{box-shadow:inset 0 0 0 1px #000}
  .sched-cell--rest{border:1px dashed #000}
  .sched-cell--fact{text-decoration:underline}
  .is-today{box-shadow:none;border-left:2px solid #000;border-right:2px solid #000}
  .sched-cov.is-short{outline:1px solid #000;font-weight:var(--fw-bold)}
  .sched-cov.is-short::after{content:" !"}
  table.data,.sched-table{font-size:9px}
  /* #153: печать показывает точное значение ВМЕСТО округлённого (не рядом).
     font-size:0 гасит исходный текст, ::after возвращает точное из data-tip своим размером.
     Начисло (has-note--formula) — число остаётся (оно точное), формула не нужна. */
  .has-note{font-size:0}
  .has-note::after{content:attr(data-tip);font-size:9px;position:static;width:auto;height:auto;border-radius:0;background:none}
  .has-note--formula{font-size:inherit}
  .has-note--formula::after{content:none}
}
@page{size:A4;margin:10mm}
.print-footer{display:none}
@media print{.print-footer{display:block;position:fixed;bottom:0;left:0;right:0;font-size:8px;color:#000;border-top:1px solid #000;padding-top:2mm}}

/* часть 4 — справа закреплена группа Часы·Ставка·Начислено (табель). Колспан-строки (заголовки
   подразделений, «Итого по подразделению») исключены явно: объединённая ячейка — не три
   отдельных, сцепление её ломает. thead.wd-row НЕ исключается: в разметке у неё те же 3 пустые
   ячейки-заглушки в конце строки, что и у первой шапки — если не закрепить и их, при scrollLeft:0
   пустые заглушки остаются на своём естественном месте (за пределами видимой области), а часы/
   ставка/начислено первой строки уже спозиционированы sticky и перекрывают середину календаря —
   из-за этого вторая строка «уезжала» и показывала на 5-6 дней больше первой в одном и том же
   видимом окне. */
/* мобильный отчёт: слевая (ФИО, 11rem) и правая (Часы+Ставка+Начислено, 18rem) закреплённые
   группы вместе — 29rem (464px), на 375–390 это больше всего экрана: середине с
   календарём не остаётся места, обе закреплённые части наезжают друг на друга. Правая
   группа включается только от 768px — на узких экранах Остаётся только левая закреплённая колонка
   (как в итерации 10 до этого пакета) — Часы/Ставка/Начислено прокручиваются вместе с днями,
   как и было. Внутри медиа-запроса же — z-index:3 у ЛЮБОй ячейки шапки (не только у
   закреплённых углов): без этого тело строки (z-index:2 у правой закреплённой группы) при
   вертикальной прокрутке на мгновение оказывалось выше обычных (не закреплённых) ячеек шапки
   (z-index:1 из базового table.data thead th) — строки таблицы визуально «наезжали» на шапку при скролле. */
@media (min-width:768px){
.table--dense.table--sticky1 thead th{z-index:3;border-bottom:2px solid var(--border-strong)}
/* закреплённые угловые ячейки шапки (ФИО слева, Часы/Ставка/Начислено справа) должны быть
   выше обычных дневных — при одинаковом z-index:3 у всех более поздние по DOM дневные ячейки
   при горизонтальной прокрутке накрывали закреплённый заголовок «Сотрудник» (шапка «наезжает»
   на своё же имя колонки). */
.table--dense.table--sticky1 thead th:first-child,
.table--dense.table--sticky1 thead th:nth-last-child(-n+3){z-index:4}
.table--dense.table--sticky1 tbody td:not([colspan]):nth-last-child(-n+3){position:sticky;background:var(--c-surface);z-index:2}
.table--dense.table--sticky1 thead th:nth-last-child(-n+3){position:sticky;background:var(--c-surface)}
.table--dense.table--sticky1 tbody td:not([colspan]):last-child,
.table--dense.table--sticky1 thead th:last-child{right:0;min-width:6rem}
.table--dense.table--sticky1 tbody td:not([colspan]):nth-last-child(2),
.table--dense.table--sticky1 thead th:nth-last-child(2){right:7.5rem;min-width:6.5rem}
.table--dense.table--sticky1 tbody td:not([colspan]):nth-last-child(3),
.table--dense.table--sticky1 thead th:nth-last-child(3){right:14rem;min-width:4rem;box-shadow:-3px 0 0 var(--border)}
.table--dense.table--sticky1 tr.is-subtotal td:not([colspan]):nth-last-child(-n+3),
.table--dense.table--sticky1 tr.is-total td:not([colspan]):nth-last-child(-n+3){background:var(--c-surface-2)}
.table--dense.table--sticky1 tbody tr:hover td:not([colspan]):nth-last-child(-n+3){background:var(--c-surface-2)}
.table--dense.table--sticky1 tr.is-alt td:not([colspan]):nth-last-child(-n+3){background:var(--c-surface-2)}
}
/* колонка должности ужата на ~20%: текст в разметке сокращён до «повар г/ц»/«х/ц»/
   «совм. должностей» и т.п. — max-width держит колонку узкой даже если где-то 1-2 слова не сократили. */
.col-pos{max-width:7rem;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
/* стройный ряд в колонке ставки: число или «оклад» — всё по правому краю, табулярные цифры. */
.col-rate{text-align:right!important;font-variant-numeric:tabular-nums;white-space:nowrap}

/* график смен — тот же принцип плотности что и табель (часть 1): должность в свою колонку,
   компактный паддинг вместо унаследованного var(--space-2) (тот был рассчитан на 2-строчный
   стек, которого больше нет). Сам .sched-namecol не удаляется — только паддинг/интерлиньяж. */
.sched-table td.sched-namecol,.sched-table th.sched-namecol{padding:2px var(--space-3);line-height:1.15}
.sched-table thead th{padding:2px;line-height:1.15;border-bottom:2px solid var(--border-strong)}
/* Должность в графике уезжала за экран при горизонтальном скролле — была не закреплена, только
   ФИО. Закрепляем второй колонкой слева — точно так же, как справа закреплены часы/ставка/
   начислено в табеле. */
.sched-table td.sched-poscol,.sched-table th.sched-poscol{position:sticky;left:11rem;z-index:1;background:var(--c-surface);box-shadow:1px 0 0 var(--border);min-width:7rem;will-change:transform}
.sched-table thead th.sched-poscol{z-index:3;background:var(--c-surface-2)}
.sched-table tr.is-alt td.sched-poscol{background:var(--c-surface-2)}

/* часть 5 — архивные сотрудники (штатное расписание): приглушённый стиль, из данных не
   удаляются — на них ссылаются назначения и выплаты. */
.is-archived{opacity:.65}
/* подсказка при наведении на выходной/праздник/предпраздничный — имя праздника уже лежит в
   title, просто показываем его крупнее и стилизованно (чистый CSS, без JS). */
.is-holiday[title],.is-preholiday[title]{position:relative;cursor:help}
.is-holiday[title]:hover::after,.is-preholiday[title]:hover::after{content:attr(title);position:absolute;bottom:100%;left:50%;transform:translateX(-50%);margin-bottom:4px;padding:.4em .6em;background:var(--c-slate-900);color:#fff;font-size:var(--text-xs);font-weight:var(--fw-regular);white-space:nowrap;border-radius:var(--radius-sm);box-shadow:var(--shadow-md);z-index:20;pointer-events:none}
.is-holiday[title]:hover::before,.is-preholiday[title]:hover::before{content:"";position:absolute;bottom:100%;left:50%;transform:translateX(-50%);margin-bottom:-1px;border:4px solid transparent;border-top-color:var(--c-slate-900);z-index:20;pointer-events:none}
/* колонка «Сотрудник» в табеле сужена на ~20% (11rem→8.8rem) по просьбе заказчика. */
.table--dense.table--sticky1 td:first-child,.table--dense.table--sticky1 th:first-child{min-width:8.8rem}
/* мобильный альбомный/книжный режим табеля и графика: переключатель ширины в просмотрщике
   симулирует поворот телефона шириной, а не через orientation — реальный поворот телефона
   тоже меняет именно ширину вьюпорта, а не какой-то отдельный признак, поэтому брейкпоинт по
   ширине здесь надёжнее (и проверяется в _review.html, где нет отдельного тумблера ориентации).
   ≤430px — книжная (узкий телефон, 360/390 из просмотрщика): календарь (дни 1–31) не помещается
   и не читается — прячем его, оставляем Сотрудник·Должность·Часы·Ставка·Начислено (табель) /
   Сотрудник·Должность (график). 431–1023px — альбомная (телефон лёжа/планшет, 768/900 из
   просмотрщика) — полная сетка с календарём, как на десктопе. Диапазон children 3..33 — ровно
   31 день, считая от Сотрудник(1)/Должность(2); в графике после дней столбцов итогов нет —
   диапазон тот же. */
@media (max-width:430px){
  .table--dense.table--sticky1 tr:not(:has([colspan])) > :nth-child(n+3):nth-child(-n+33),
  .sched-table tr:not(:has([colspan])) > :nth-child(n+3):nth-child(-n+33){display:none;width:0!important;padding:0!important;border:0!important}
  /* итог дня/минимум (sched-covrow, §10.4) — цифры по дням, без календаря рядом с ними
     бессмысленны: на этой ширине сам календарь уже скрыт правилом выше, но строку целиком
     ничего не гасило — оставались две висящие подписи-ярлыка без единой цифры. */
  .sched-covrow{display:none}
  .table--dense.table--sticky1,.sched-table{min-width:0}
  .table-wrap{overflow-x:hidden}
  /* должность переезжает под ФИО, как было в исходном стеке (.cell-emp__name/.cell-emp__pos) —
     колонка «Должность» прячется — теперь и в шапке: .col-pos добавлен на заголовочный <th>,
     раньше шапка и тело прятались двумя разными правилами (позиционным tr>:nth-child(2) для
     тела, thead th:nth-child(2) для шапки), а у строки «Итого по подразделению» (colspan=33)
     в начале всего 4 ячейки — и вторая по счёту там «Часы», а не «Должность»: позиционный
     селектор ошибочно обнулял итоговые часы отдела. Один классовый селектор на оба ряда снимает
     и раскол шапка/тело, и совпадение по случайной позиции у строк с colspan.
     Строки-подстроки совмещения (is-sub, без ФИО в первой ячейке) — их подпись роли теперь тоже
     дублируется в первую ячейку через .cell-emp__pos--mobile (разметка), как у обычных строк;
     без этого дубля строка на мобильном показывала бы только цифры без подписи, что к чему. */
  .col-pos{display:none}
  .cell-emp__pos--mobile{display:block!important}
  /* убираем единицы измерения из каждой ячейки — заголовок «Должность» уже снят выше вместе со
     всей колонкой; «₽/ч»/копейки дублируют то, что теперь сказано один раз в заголовке «Ставка,
     р/ч» и в легенде суммы; так на один экран влезают ФИО · Часы · Ставка · Начислено без
     прокрутки. */
  .unit-suffix,.cents-suffix{display:none}
  .mobile-hide-portrait{display:none}
  /* без 30 скрытых дневных колонок освобождается место, но авторазметка игнорирует % ширины
     колонок (Начислено уезжало за экран, нужен был горизонтальный скролл) — переводим таблицу
     на table-layout:fixed и задаём всем 4 видимым колонкам точные %, чтобы они гарантированно
     суммировались в 100% и Часы/Ставка/Начислено помещались без скролла. */
  .table--dense.table--sticky1{table-layout:fixed;width:100%}
  .table--dense.table--sticky1 td:first-child,.table--dense.table--sticky1 th:first-child{min-width:0;width:38%;white-space:normal;overflow:hidden}
  /* thead th здесь НЕ получает position:static — только сброс правого офсета (right:auto).
     Комбинированный tbody+thead селектор с общим position:static!important (как было) гасил
     ГОРИЗОНТАЛЬНОЕ прилипание к правому краю (нужно) заодно с ВЕРТИКАЛЬНЫМ (thead th{position:
     sticky;top:0} из базового правила) — на скролле ВНИЗ шапка Часы/Ставка/Начислено уезжала
     вместе с телом (не липла к верху), и в её место наезжали числа первой строки: в шапке
     читалось только «Сотрудник» (единственная ячейка, у которой position не трогали). */
  .table--dense.table--sticky1 tbody td:not([colspan]):nth-last-child(3){width:17%;right:auto!important;position:static!important;box-shadow:none!important}
  .table--dense.table--sticky1 thead th:nth-last-child(3){width:17%;right:auto!important;box-shadow:none!important}
  .table--dense.table--sticky1 tbody td:not([colspan]):nth-last-child(2){width:22%;right:auto!important;position:static!important}
  .table--dense.table--sticky1 thead th:nth-last-child(2){width:22%;right:auto!important}
  .table--dense.table--sticky1 tbody td:not([colspan]):last-child{width:23%;right:auto!important;position:static!important}
  .table--dense.table--sticky1 thead th:last-child{width:23%;right:auto!important}
  .cell-emp__pos--mobile{font-size:.75em;white-space:normal;overflow-wrap:break-word;max-width:100%}
  .cell-emp__name{font-size:1.15em;overflow:hidden;text-overflow:ellipsis;max-width:100%}
  /* график смен на этой ширине — один столбец (Сотрудник; должность и дни уже скрыты выше).
     Без явной ширины авторазметка держит колонку по содержимому и оставляет пустую полосу
     справа во всю ширину панели. */
  .sched-table{width:100%}
  .sched-table td.sched-namecol,.sched-table th.sched-namecol{width:100%}
  .container--wide,.container{padding-inline:var(--space-2)}
}
/* «Сотрудники и назначения»: колонки по подразделениям вместо одной длинной простыни —
   почти целиком помещается на экран. auto-fit сам схлопывается в 1 колонку на мобильном. */
.staff-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(14rem,1fr));gap:0 var(--space-6)}
.staff-grid__col{min-width:0}
.staff-grid__col h3{margin-bottom:var(--space-3);padding-bottom:var(--space-2);border-bottom:1px solid var(--border)}
/* три отдельные таблицы (Зал/Кухня/Управление) без общей ширины колонок расходились по факту
   разной длины текста в «Должности» и сумм — визуально не в ряд между блоками. table-layout:fixed
   + одинаковые <colgroup> во всех трёх выравнивают колонки друг под другом независимо от
   содержимого; «Должность» без явной ширины забирает весь остаток. Последняя колонка (Действия)
   сужена под сами кнопки и прижата к правому краю (это и есть правый край таблицы/блока), а не
   растянута на остаток — раньше лишняя ширина доставалась ей, и кнопки повисали слева с пустым
   местом справа. Заголовок «Действия» и сами кнопки центрированы одной осью.*/
.staff-rate-table{table-layout:fixed}
.staff-rate-table col.col-type{width:9rem}
.staff-rate-table col.col-norm{width:5rem}
.staff-rate-table col.col-base{width:8.5rem}
.staff-rate-table col.col-trial{width:5rem}
.staff-rate-table col.col-actions{width:13rem}
.staff-rate-table th.actions-head,.staff-rate-table td:last-child{text-align:center}

/* часть 6 — .bottom-nav фиксированной панелью перекрывала контент на любом промежуточном
   экране прокрутки: padding у .has-bottom-nav спасает только конец документа (position:fixed
   всегда перекрывает то, что попадает под неё, независимо от места на странице). Один из трёх
   вариантов ТЗ — нав на этом брейкпоинте переведена в обычный поток, показывается один раз, в
   конце страницы, как обычная секция; перекрытия больше нет ни на одном экране прокрутки.
   Дублирующий доступ к разделам остаётся всегда — через гамбургер в .mobile-topbar
   (position:sticky, не уезжает). */
@media (max-width:767px){
  .bottom-nav{position:static;box-shadow:none}
}


/* — #168: таблица норм на 375 — «Обед»/«Вечер» были за краем (scrollW 499 против 317).
   Сжатие, а не второй слой: один набор инпутов (двойные имена в POST недопустимы).
   Заголовок «День целиком» переносится в две строки, колонка сходится к ширине инпута. — */
.norms-table .norm-num{width:4.5rem}
@media (max-width:767px){
  .norms-table .data th,.norms-table .data td{padding:var(--space-1);white-space:normal}
  .norms-table .norm-num{width:3rem}
}
/* — #185: поставка дизайнера §175 (iter-11). Итоговые колонки табеля отделены от массива,
   высота без двойной прокрутки, кегль при свёрнутом меню. Перенесён блоком из
   design/components_delivery_175.css (комментарий «Высота блока» → конец поставки,
   без --debug-подсветки). Файлы дизайнера целиком не копировать — база отстаёт от прода (#161/#129).
   ponytail: перенос блоком как есть, без пересочинения — потолок: правки дизайнера здесь
   не разделить на «принять часть»; чинить точечно можно только следующим циклом с замерами. — */

/* --- Высота блока (вопрос A из #176): рамок по вертикали нет вовсе. Блок таблицы = высота своих
   строк: уволили сотрудников — ужался, добавили — вырос; внутреннего скролла данных нет ни при
   каком числе строк, прокручивает страница. Правило явное (а не «просто убрали инлайн max-height»),
   чтобы лимит не вернулся случайно: max-height снят, высота не задаётся ни в px, ни от вьюпорта.
   Горизонтальная прокрутка календаря остаётся (overflow-x у .table-wrap). --- */
.table-wrap--auto{max-height:none!important;height:auto!important}

/* --- Фон/иерархия/шапка — на всех ширинах (включая 375, там эти 3 колонки видны). --- */
.ts-table.table--dense.table--sticky1{table-layout:fixed;font-size:var(--text-xs)}
/* Заголовки Часы·Ставка·Начислено: перенос в 2 строки, по центру (§3 ТЗ). База — тон глубже
   обычной шапки (surface-2), чтобы блок читался отдельным «прибором», а не продолжением
   календаря; Начислено темнее/жирнее Часов и Ставки — им иерархия внутри блока (§2.3 ТЗ). */
.ts-table.table--dense.table--sticky1 thead th:nth-last-child(-n+3){white-space:normal;text-align:center!important;
  line-height:var(--lh-tight);padding-top:4px!important;padding-bottom:4px!important;
  background:var(--c-slate-100);font-weight:var(--fw-bold)}
.ts-table.table--dense.table--sticky1 thead th:nth-last-child(2),
.ts-table.table--dense.table--sticky1 thead th:nth-last-child(3){color:var(--text);font-weight:var(--fw-semibold)}
.ts-table.table--dense.table--sticky1 thead th:last-child{color:var(--text-strong)}
/* Граница массива/итогов — сплошная и жирнее прежнего пунктира-тени (1px→2px, border-strong),
   держится на самой sticky-колонке — видна на любой позиции горизонтальной прокрутки (§2.1 ТЗ).
   Мобильный ≤430px её уже гасит box-shadow:none!important (там и календаря не видно — нечего
   отделять), не трогаем. */
.ts-table.table--dense.table--sticky1 thead th:nth-last-child(3),
.ts-table.table--dense.table--sticky1 tbody tr>:not([colspan]):nth-last-child(3){box-shadow:-2px 0 0 var(--border-strong)}
/* Базовый тон блока на обычных строках (не зебра/подытог/итог/hover — у них уже есть свой тон,
   не спорим с принятым #121). Зебра/подытог/итог внутри блока не трогаем — они и так темнее. */
.ts-table.table--dense.table--sticky1 tbody tr:not(.is-alt):not(.is-subtotal):not(.is-total):not(:hover)>:not([colspan]):nth-last-child(-n+3){
  background:var(--c-slate-50)}
/* Зебра/подытог/итог/hover внутри блока — на тон глубже базового (slate-100 против slate-50),
   иначе зебра-полоса «гаснет» именно в этих 3 колонках (surface-2 у зебры вне блока светлее
   нашего базового тона блока — приняли бы за баг). Без привязки к ширине — тон не зависит от
   sticky-механики (та начинается только с 768px). */
.ts-table.table--dense.table--sticky1 tbody tr.is-alt>:not([colspan]):nth-last-child(-n+3),
.ts-table.table--dense.table--sticky1 tbody tr:hover>:not([colspan]):nth-last-child(-n+3){background:var(--c-slate-100)}
/* Иерархия строк итогов (§2.4 ТЗ): база .data tr.is-subtotal/is-total делает жирными ВСЕ ячейки
   строки одинаково — Часы/Ставка возвращены к обычному весу, Начислено остаётся/усиливается
   единственным акцентом строки. */
.ts-table.table--dense.table--sticky1 tbody tr.is-subtotal>:not([colspan]):nth-last-child(-n+3),
.ts-table.table--dense.table--sticky1 tbody tr.is-total>:not([colspan]):nth-last-child(-n+3){font-weight:var(--fw-regular);color:var(--text);background:var(--c-slate-100)}
.ts-table.table--dense.table--sticky1 tbody tr.is-subtotal>:not([colspan]):last-child,
.ts-table.table--dense.table--sticky1 tbody tr.is-total>:not([colspan]):last-child{font-weight:var(--fw-bold);color:var(--text-strong);font-size:1.08em}
/* Колонка живёт по строкам сотрудников (6 цифр). Семизначный «Итого за месяц» из уравнения
   колонки выведен: не расширяет её, а вытекает влево поверх СВОЕЙ ЖЕ пустой соседней ячейки
   «Ставка» (в итоге ставки нет). colspan не нужен и ломает sticky (#170 C): ячейка обычная,
   закрепление работает как у всех, число просто рисуется поверх пустого места слева —
   Начислено идёт последним в DOM, значит поверх соседа. */
.ts-table.table--dense.table--sticky1 tbody tr.is-total>:not([colspan]):last-child{padding-left:0!important;overflow:visible}

/* --- Ширины колонок — обязательные числа §3 ТЗ (утверждено #170 D), только ≥431px. --- */
@media (min-width:431px){
  .ts-table.table--dense.table--sticky1 thead th:first-child,.ts-table.table--dense.table--sticky1 tbody tr>:first-child{width:150px}
  .ts-table.table--dense.table--sticky1 thead th.col-pos,.ts-table.table--dense.table--sticky1 tbody tr>.col-pos{width:104px;max-width:104px}
  .ts-table.table--dense.table--sticky1 thead tr>:nth-child(n+3):nth-child(-n+33),
  .ts-table.table--dense.table--sticky1 tbody tr>:nth-child(n+3):nth-child(-n+33){width:26px}
  /* Начислено 82 (паддинг 8+8, контент 66) · Ставка 62 (4+4, контент 54, «₽/ч» в ячейке) ·
     Часы 42 (5+5, контент 32) — числа из #170 D, менять только с обоснованием (правило ТЗ §5). */
  .ts-table.table--dense.table--sticky1 thead th:last-child,.ts-table.table--dense.table--sticky1 tbody tr>:not([colspan]):last-child{width:72px;padding-left:8px!important;padding-right:8px!important}
  .ts-table.table--dense.table--sticky1 thead th:nth-last-child(2),.ts-table.table--dense.table--sticky1 tbody tr>:not([colspan]):nth-last-child(2){width:62px;padding-left:4px!important;padding-right:4px!important}
  .ts-table.table--dense.table--sticky1 thead th:nth-last-child(3),.ts-table.table--dense.table--sticky1 tbody tr>:not([colspan]):nth-last-child(3){width:42px;padding-left:5px!important;padding-right:5px!important}
}
/* --- Закрепление справа — офсеты 0·82·144 (сумма фактических ширин, #170 A: щель = дефект),
   на той же ширине, что и раньше был весь механизм закрепления (≥768px). --- */
@media (min-width:768px){
  .ts-table.table--dense.table--sticky1 thead th:nth-last-child(-n+3),
  .ts-table.table--dense.table--sticky1 tbody tr>:not([colspan]):nth-last-child(-n+3){position:sticky;z-index:2}
  .ts-table.table--dense.table--sticky1 thead th:nth-last-child(-n+3){z-index:4;background:var(--c-slate-100)}
  .ts-table.table--dense.table--sticky1 tbody tr>:not([colspan]):nth-last-child(-n+3){background:var(--c-surface)}
  .ts-table.table--dense.table--sticky1 thead th:last-child,.ts-table.table--dense.table--sticky1 tbody tr>:not([colspan]):last-child{right:0}
  .ts-table.table--dense.table--sticky1 thead th:nth-last-child(2),.ts-table.table--dense.table--sticky1 tbody tr>:not([colspan]):nth-last-child(2){right:72px}
  .ts-table.table--dense.table--sticky1 thead th:nth-last-child(3),.ts-table.table--dense.table--sticky1 tbody tr>:not([colspan]):nth-last-child(3){right:134px}
  /* Тон блока задан выше без привязки к ширине; здесь только базовый surface для обычных
     строк — чтобы под sticky на ≥768 не просвечивал календарь. */
  .ts-table.table--dense.table--sticky1 tbody tr>:not([colspan]):nth-last-child(-n+3){background:var(--c-surface)}
}

/* --- #176 B: меню свёрнуто → освободившиеся ~190px тратим на кегль (решение Георгия), не на
   воздух. Второй, более крупный набор размеров — только при .is-collapsed, только там, где сама
   раскладка сайдбара существует (≥768px). Один и тот же .ts-table, правила глушат друг друга по
   специфичности (доп. классы), а не !important — переключение мгновенное, без прыжка контента
   (числа те же самые ячейки, просто шире/крупнее). --- */
@media (min-width:768px){
  .app-shell.is-collapsed .ts-table.table--dense.table--sticky1{font-size:var(--text-sm)}
  .app-shell.is-collapsed .ts-table.table--dense.table--sticky1 thead th:first-child,
  .app-shell.is-collapsed .ts-table.table--dense.table--sticky1 tbody tr>:first-child{width:164px}
  .app-shell.is-collapsed .ts-table.table--dense.table--sticky1 thead th.col-pos,
  .app-shell.is-collapsed .ts-table.table--dense.table--sticky1 tbody tr>.col-pos{width:114px;max-width:114px}
  .app-shell.is-collapsed .ts-table.table--dense.table--sticky1 thead tr>:nth-child(n+3):nth-child(-n+33),
  .app-shell.is-collapsed .ts-table.table--dense.table--sticky1 tbody tr>:nth-child(n+3):nth-child(-n+33){width:28px}
  .app-shell.is-collapsed .ts-table.table--dense.table--sticky1 thead th:last-child,
  .app-shell.is-collapsed .ts-table.table--dense.table--sticky1 tbody tr>:not([colspan]):last-child{width:78px;padding-left:8px!important;padding-right:8px!important;right:0}
  .app-shell.is-collapsed .ts-table.table--dense.table--sticky1 thead th:nth-last-child(2),
  .app-shell.is-collapsed .ts-table.table--dense.table--sticky1 tbody tr>:not([colspan]):nth-last-child(2){width:68px;padding-left:5px!important;padding-right:5px!important;right:78px}
  .app-shell.is-collapsed .ts-table.table--dense.table--sticky1 thead th:nth-last-child(3),
  .app-shell.is-collapsed .ts-table.table--dense.table--sticky1 tbody tr>:not([colspan]):nth-last-child(3){width:46px;padding-left:5px!important;padding-right:5px!important;right:146px}
}

/* #190 круг 5 (D2): карточки мероприятий — свой класс, не мобильный .entry-cards.
   .entry-cards скрыт на десктопе (display:none, @media<768 display:block) —
   мероприятия были невидимы на 1280/900. Свой класс всегда видим. */
.banquet-cards{display:block}
.banquet-cards .entry-card{margin-bottom:var(--space-3)}
/* Круг 6 (D3 косметика): строка правки на мобильных — причина под значением. */
.rev-line.is-edited{flex-wrap:wrap}
.rev-line.is-edited .rev-line__val{width:100%;text-align:left}

/* #167 (S3): точка-признак неподтверждённого больничного в графике. */
.sched-cell__dot{font-weight:700;opacity:.7;margin-left:1px}

/* ═══ #184 · Мобильная навигация: одна модель на телефоне, скрим без ловушки кликов ═══
   Три симптома заявки — три независимых правила. Ни одно принятое правило не переписано
   и не переименовано: перекрытие идёт ниже по файлу той же специфичностью (порядком).

   1) «Боковое меню открывается, но пункты неактивны» (реально — только 768–1023).
      .sidebar лежит на z-index:var(--z-sidebar)=40, .offcanvas-scrim — на
      calc(var(--z-offcanvas) - 1)=69. Панель физически ПОД скримом, и клик забирает
      скрим (он же закрывает меню — оттого «пункт не нажимается, меню просто закрылось»).
      Лечится одной строкой: на брейкпоинте офканваса панель встаёт над скримом.

   2) «Нижнее меню не зафиксировано и уезжает на длинном скролле» (≤767).
      Причина не в прыжке вьюпорта: в «пакете 2, часть 6» нав намеренно выведена из fixed
      в поток ради #125 (перекрывала контент) и живёт в конце документа. Решение
      постановщика — A: fixed возвращается ВМЕСТЕ с отступом контента, а не вместо него.
      Побочно чинится .rev-total (строка 821 прода): она уже сейчас липнет к
      bottom:calc(var(--bottomnav-h) + var(--space-2)), то есть прод рассчитан на
      закреплённую панель — при position:static резерв висел над пустотой.

   3) «В нижнем меню нет элементов управления панелью» (≤767).
      Модель A: нижняя панель — единственная навигация телефона. Офканвас на ≤767
      выключается целиком (симптом 1 на этой ширине исчезает вместе с элементом),
      пятая кнопка «Ещё» открывает лист с управлением и разделами, не вошедшими
      в четвёрку. Лист — чекбокс-хак, ровно как принятый #nav-toggle: JS не нужен.
      Свотчи цвета сайдбара в лист НЕ переносятся: на ≤767 сайдбара больше нет,
      настройка потеряла предмет (на десктопе остаётся как была).
   ═══ */

/* — часть 1: панель офканваса над скримом — */
@media (max-width:1023px){
  .sidebar{z-index:var(--z-offcanvas)}
}

/* — часть 2: нижняя панель снова закреплена, контент получает резерв под неё.
     Отступ — на <body class="has-bottom-nav">, поэтому резерв появляется в конце
     документа и ничего не перекрывается ни на одном экране прокрутки. — */
@media (max-width:767px){
  .bottom-nav{position:fixed;box-shadow:0 -2px 10px rgba(16,21,31,.06)}
  .has-bottom-nav{padding-bottom:calc(var(--bottomnav-h) + env(safe-area-inset-bottom, 0px) + var(--space-6))}
}

/* — часть 3а: офканвас на телефоне выключен. Гамбургер убран, чтобы не осталось
     кнопки, открывающей ничего; сам чекбокс #nav-toggle оставлен в разметке —
     на 768–1023 он рабочий. — */
@media (max-width:767px){
  .sidebar,.offcanvas-scrim,.mobile-topbar__burger{display:none}
}

/* — часть 3б: пятая кнопка «Ещё». Живёт в .bottom-nav рядом со ссылками, поэтому
     повторяет их подачу: .bottom-nav a стилизован по тегу, а не по классу. — */
.bnav-more{display:none}
@media (max-width:767px){
  .bottom-nav .bnav-more{display:flex;flex-direction:column;align-items:center;justify-content:center;
    gap:2px;color:var(--text-muted);font-size:.6875rem;font-weight:var(--fw-medium);
    cursor:pointer;-webkit-tap-highlight-color:transparent}
  .bottom-nav .bnav-more svg{width:22px;height:22px}
  .nav-more-checkbox:checked ~ .app-main .bottom-nav .bnav-more{color:var(--c-brand-600)}
}

/* — часть 3в: сам лист. Скрим на 69, лист на 70 — та же пара уровней, что у офканваса,
     так что лист перекрывает нижнюю навигацию (40), а не воюет с ней. — */
.nav-more-checkbox{position:absolute;opacity:0;width:1px;height:1px;pointer-events:none}
.moresheet,.moresheet-scrim{display:none}
@media (max-width:767px){
  .moresheet-scrim{display:block;position:fixed;inset:0;background:rgba(6,10,20,.5);
    opacity:0;pointer-events:none;transition:opacity .2s ease;z-index:calc(var(--z-offcanvas) - 1)}
  .nav-more-checkbox:checked ~ .moresheet-scrim{opacity:1;pointer-events:auto}
  .moresheet{display:flex;flex-direction:column;position:fixed;left:0;right:0;bottom:0;
    z-index:var(--z-offcanvas);max-height:min(84dvh,34rem);
    background:var(--c-surface);border-top:1px solid var(--border);
    border-radius:var(--radius-lg) var(--radius-lg) 0 0;box-shadow:var(--shadow-lg);
    transform:translateY(101%);transition:transform .2s ease;
    padding-bottom:env(safe-area-inset-bottom, 0px)}
  .nav-more-checkbox:checked ~ .moresheet{transform:none}
}
.moresheet__head{display:flex;align-items:center;gap:var(--space-3);flex:none;
  padding:var(--space-3) var(--space-4);border-bottom:1px solid var(--border)}
.moresheet__title{font-size:var(--text-md);font-weight:var(--fw-semibold);color:var(--text-strong);flex:1}
.moresheet__close{display:grid;place-items:center;width:2.75rem;height:2.75rem;margin-right:calc(var(--space-2) * -1);
  border-radius:var(--radius-sm);color:var(--text-muted);cursor:pointer;flex:none}
.moresheet__close:hover{background:var(--c-slate-100);color:var(--text)}
.moresheet__close svg{width:20px;height:20px}
.moresheet__body{overflow-y:auto;padding:var(--space-4);display:flex;flex-direction:column;gap:var(--space-4);
  -webkit-overflow-scrolling:touch}
.moresheet__group{display:flex;flex-direction:column;gap:1px}
.moresheet__link{display:flex;align-items:center;gap:var(--space-3);min-height:2.75rem;
  padding:var(--space-2) var(--space-2);border-radius:var(--radius-sm);
  color:var(--text);font-size:var(--text-base);font-weight:var(--fw-medium)}
.moresheet__link:hover{background:var(--c-slate-100);text-decoration:none;color:var(--text)}
.moresheet__link .nav-ic{width:20px;height:20px;flex:none;color:var(--text-muted)}
.moresheet__link .badge{margin-left:auto}
.moresheet__link .moresheet__chev{width:18px;height:18px;flex:none;margin-left:auto;color:var(--text-muted)}
.moresheet__link .badge ~ .moresheet__chev{margin-left:var(--space-2)}
.moresheet__row{display:flex;align-items:center;gap:var(--space-3);min-height:2.75rem;padding:var(--space-2)}
.moresheet__row .switch{margin-left:auto}
.moresheet__rowtxt{display:flex;flex-direction:column;line-height:1.25;min-width:0}
.moresheet__rowtxt small{font-size:var(--text-xs);color:var(--text-muted)}
.moresheet__user{display:flex;align-items:center;gap:var(--space-3);padding:var(--space-3);
  border:1px solid var(--border);border-radius:var(--radius-md);background:var(--c-surface-2)}
.moresheet__user .userbox__name{color:var(--text-strong)}
.moresheet__user .userbox__role{color:var(--text-muted)}
.moresheet__ava{display:grid;place-items:center;width:2.25rem;height:2.25rem;flex:none;
  border-radius:var(--radius-full);background:var(--c-slate-200);color:var(--text-strong);
  font-weight:var(--fw-bold);font-size:var(--text-sm)}
.moresheet__user .btn{margin-left:auto}
.moresheet__ver{font-size:var(--text-xs);color:var(--text-muted);text-align:center;padding-bottom:var(--space-2)}

/* — часть 4: подпись «Не вошло в нижнее меню» в офканвасе — только там, где это правда.
     Принятый блок 5 вешает её и на 768–1023, где нижней панели не видно вовсе, а дубли
     пунктов там не скрываются (класс is-in-bottomnav навешивает JS по matchMedia ≤767) —
     то есть подпись стояла над полным списком. На ≤767 офканваса больше нет, и весь
     блок 5 остаётся без предмета. — */
@media (min-width:768px) and (max-width:1023px){
  .sidebar__link.is-in-bottomnav{display:flex}
  .sidebar__nav::before{content:none}
}

/* ==========================================================================
   #340: История лентой — колонка, точки по категориям, переключатель вида.
   Аддитивный блок: существующие .changelog/.change (строки 394–401) не тронуты.
   ========================================================================== */

/* Колонка контента как в макете: на 1280 лента не растягивается на всю ширину. */
.history-timeline{max-width:52rem}

/* Точка на линии — цвет по категории записи (токены #332, обе темы покрыты). */
.change--new::before{background:var(--hist-new)}
.change--fix::before{background:var(--hist-fix)}
.change--bug::before{background:var(--hist-bug)}
.change--internal::before{background:var(--hist-internal)}

/* Переключатель «Лентой / Карточками» — ссылки-сегменты в шапке страницы. */
.view-switch{display:inline-flex;border:1px solid var(--border);border-radius:var(--radius-md);overflow:hidden}
.view-switch a{padding:.375rem .75rem;font-size:var(--text-sm);color:var(--text-muted);text-decoration:none}
.view-switch a:hover{color:var(--link)}
.view-switch a.is-active{background:var(--c-brand-500);color:var(--c-white)}
.view-switch a + a{border-left:1px solid var(--border)}

/* ═══════════════════════════════════════════════════════════════════════════
   #338: перенос принятой дельты дизайн-системы iteration-20 (пакет дефектов).
   Аддитивно: ни один существующий селектор не переименован и не удалён.
   ═══════════════════════════════════════════════════════════════════════════ */

/* П.1. Денежная семантика в списке цифр. `.dl-figures dd` (0,1,1) перебивал
   `.pos`/`.neg`/`.warn` (0,1,0) — «Приход/Расход наличными» в сверке кассы были
   нейтральными при дословно верной разметке. Сужаем до dd; базовое правило целое.
   Крупная строка перечислена вторым селектором: `.dl-figures .big dd` — это 0,2,1,
   без неё цветной итог сверки снова ушёл бы в --text-strong. */
.dl-figures dd.pos,.dl-figures .big dd.pos{color:var(--income)}
.dl-figures dd.neg,.dl-figures .big dd.neg{color:var(--expense)}
.dl-figures dd.warn,.dl-figures .big dd.warn{color:var(--discrepancy)}

/* П.2. Подвал таблицы расходов, две строки. «Итого расходов» остаётся жирным на
   линии 2 px; «в том числе наличными» подано как уточнение — вес regular, линия
   1 px, подпись приглушена, сумма medium обычным цветом (цифру всё равно читают).
   Две оси помимо цвета: пара различима и в ч/б печати. */
.entry-foot .entry-foot__sub td{border-top:1px solid var(--border);
  font-weight:var(--fw-regular);color:var(--text-muted)}
.entry-foot .entry-foot__sub .num{font-weight:var(--fw-medium);color:var(--text)}

/* П.5. Узкая шапка панели с двумя кнопками. Базовый .panel__head — одна строка со
   space-between; две кнопки на ~347 px сжимаются до нечитаемых и рвут заголовок.
   По модификатору шапка разваливается на две строки: заголовок сверху, кнопки ниже
   во всю ширину равными долями, каждая ≥44 px (порог касания).
   Порог считается по ширине САМОЙ панели, а не вьюпорта: узкая шапка бывает и на
   1280 — сайдбар плюс рейка сжимают панель до тех же ~350 px. Контейнер объявлен
   через :has — только у панелей, чья шапка взяла модификатор. Вьюпортный медиа-
   запрос оставлен вторым контуром для браузеров без @container. */
.panel:has(> .panel__head--wrap){container-type:inline-size}
@container (max-width:479px){
  .panel__head--wrap{flex-wrap:wrap;align-items:flex-start}
  .panel__head--wrap > .cluster{flex:1 0 100%;gap:var(--space-2)}
  .panel__head--wrap > .cluster > .btn{flex:1 1 0;min-height:2.75rem;justify-content:center}
  .panel__head--wrap > .cluster > .btn--sm{padding-inline:var(--space-2)}
}
@media (max-width:479px){
  .panel__head--wrap{flex-wrap:wrap;align-items:flex-start}
  .panel__head--wrap > .cluster{flex:1 0 100%;gap:var(--space-2)}
  .panel__head--wrap > .cluster > .btn{flex:1 1 0;min-height:2.75rem;justify-content:center}
  .panel__head--wrap > .cluster > .btn--sm{padding-inline:var(--space-2)}
}

/* ═══════════════════════════════════════════════════════════════════════════
   \u0418\u0442\u0435\u0440\u0430\u0446\u0438\u044f 21 · \u0436\u0438\u0432\u043e\u0439 \u043a\u0430\u0441\u0441\u043e\u0432\u044b\u0439 \u0434\u0435\u043d\u044c (#334), \u043a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044c \u0434\u043d\u0435\u0439 (#335),
   \u043a\u043d\u043e\u043f\u043a\u0430 \u00ab\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435\u00bb (#336). \u0410\u0434\u0434\u0438\u0442\u0438\u0432\u043d\u043e, \u043d\u043e\u0432\u044b\u0445 \u0446\u0432\u0435\u0442\u043e\u0432 \u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432 \u043a\u043d\u043e\u043f\u043e\u043a \u043d\u0435\u0442.
   ═══════════════════════════════════════════════════════════════════════════ */

/* — \u041a\u0430\u043d\u0430\u043b 1 \u00ab\u0446\u0438\u0444\u0440\u0430 \u043f\u0440\u043e\u043c\u0435\u0436\u0443\u0442\u043e\u0447\u043d\u0430\u044f\u00bb: \u043f\u043b\u0430\u0448\u043a\u0430 \u0441\u0442\u0430\u0442\u0443\u0441\u0430 \u0441\u043c\u0435\u043d\u044b. \u0421\u0442\u043e\u0438\u0442 \u0432 \u0441\u0442\u0440\u043e\u043a\u0435
     .rev-sync — \u0442\u0430 \u0436\u0435 \u0433\u0435\u043e\u043c\u0435\u0442\u0440\u0438\u044f, \u0447\u0442\u043e \u0443 \u043f\u043b\u0430\u0448\u043a\u0438 \u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a\u0430 \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 C,
     \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u043c\u0435\u0436\u0434\u0443 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438 \u043d\u0435 \u0441\u0434\u0432\u0438\u0433\u0430\u0435\u0442 \u043f\u0430\u043d\u0435\u043b\u044c \u043d\u0438 \u043d\u0430 \u043f\u0438\u043a\u0441\u0435\u043b\u044c. — */
.rev-sync--live{background:var(--c-info-50);border-bottom-color:var(--c-info-100)}
.shift{display:inline-flex;align-items:center;gap:.4em;height:1.4rem;padding:0 .5em;
  border-radius:var(--radius-xs);background:var(--c-info-100);color:var(--c-info-700);
  font-size:.6875rem;font-weight:var(--fw-semibold);white-space:nowrap}
.shift__dot{width:.5em;height:.5em;border-radius:50%;background:currentColor;flex:none}
.shift--idle{background:var(--c-slate-100);color:var(--c-slate-700)}
/* Тёмная тема: пара «фон --c-slate-100 + текст --c-slate-700» давала 1,41:1 — шкала slate
   не инвертируется. `.shift--idle` внесён в перечисление консьюмеров выше (стр. ~946). */
.shift--idle .shift__dot{border-radius:1px}
.shift--stale{background:var(--c-warn-50);color:var(--c-warn-700)}
.shift--stale .shift__dot{background:transparent;border:1.5px solid currentColor;box-sizing:border-box}

/* — \u041a\u0430\u043d\u0430\u043b 2: \u043e\u0444\u043e\u0440\u043c\u043b\u0435\u043d\u0438\u0435 \u0441\u0430\u043c\u0438\u0445 \u0447\u0438\u0441\u0435\u043b. \u0417\u043d\u0430\u043a ≈ \u043f\u0435\u0440\u0435\u0434 \u0441\u0443\u043c\u043c\u043e\u0439 \u0438 \u043f\u0443\u043d\u043a\u0442\u0438\u0440\u043d\u0430\u044f \u043b\u0438\u043d\u0438\u044f
     \u043f\u043e\u0434 \u043d\u0435\u0439 — \u0434\u0432\u0430 \u043d\u0435\u0446\u0432\u0435\u0442\u043e\u0432\u044b\u0445 \u0441\u0438\u0433\u043d\u0430\u043b\u0430: \u0432\u044b\u0436\u0438\u0432\u0430\u044e\u0442 \u0432 \u0447/\u0431 \u043f\u0435\u0447\u0430\u0442\u0438 \u0438 \u043f\u0440\u0438 \u0434\u0430\u043b\u044c\u0442\u043e\u043d\u0438\u0437\u043c\u0435.
     \u0426\u0432\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u0441\u0438\u043b\u0438\u0432\u0430\u0435\u0442. \u0414\u0435\u043d\u0435\u0436\u043d\u0443\u044e \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0443 pos/neg \u043d\u0435 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u0435\u043c. — */
.money--live{border-bottom:1px dashed var(--c-info-700);padding-bottom:1px}
.money--live::before{content:"≈\00a0";color:var(--c-info-700);font-weight:var(--fw-medium)}
.rev-total__value.money--live,.dl-figures dd.money--live{border-bottom-width:2px}

/* \u041f\u0440\u043e\u0447\u0435\u0440\u043a \u0432\u043c\u0435\u0441\u0442\u043e \u043d\u0443\u043b\u044f \u0432 B \u0438 D: \u043d\u043e\u043b\u044c \u0443\u0442\u0432\u0435\u0440\u0436\u0434\u0430\u0435\u0442 \u00ab\u043f\u043e\u0441\u0447\u0438\u0442\u0430\u043b\u0438, \u0432\u044b\u0448\u043b\u043e 0\u00bb. */
.rev-line__val--wait{color:var(--text-muted)}

/* — \u041a\u043d\u043e\u043f\u043a\u0430 \u00ab\u041e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435\u00bb (#336): \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0438\u0434 \u00ab\u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u043f\u043e\u043b\u0451\u0442\u0435\u00bb,
     \u0440\u0430\u0437\u043c\u0435\u0440 \u0438 \u043f\u0430\u043b\u0438\u0442\u0440\u0430 \u043f\u0440\u0435\u0436\u043d\u0438\u0435 (btn--secondary btn--sm). — */
.rev-sync__btn.is-loading{pointer-events:none;opacity:.75}
.rev-sync__btn.is-loading::before{content:"";width:.85em;height:.85em;flex:none;
  border:2px solid currentColor;border-right-color:transparent;border-radius:50%;
  margin-right:.4em;animation:bdb-spin .8s linear infinite}
@keyframes bdb-spin{to{transform:rotate(1turn)}}
@media (prefers-reduced-motion:reduce){.rev-sync__btn.is-loading::before{animation-duration:2.4s}}

/* — \u041a\u0430\u043b\u0435\u043d\u0434\u0430\u0440\u044c \u0434\u043d\u0435\u0439 (#335). \u0422\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 — \u0441\u0442\u0440\u043e\u043a\u0430 \u0434\u0430\u0442\u044b \u0432 .page-kicker.
     \u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u044f\u0447\u0435\u0439\u043a\u0438 \u043a\u043e\u0434\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0434\u0432\u0443\u043c\u044f \u043e\u0441\u044f\u043c\u0438 \u0441\u0440\u0430\u0437\u0443 — \u0437\u0430\u043b\u0438\u0432\u043a\u0430/\u043a\u0430\u0439\u043c\u0430 \u0418 \u0444\u043e\u0440\u043c\u0430
     \u043c\u0430\u0440\u043a\u0435\u0440\u0430 (\u0441\u043f\u043b\u043e\u0448\u043d\u0430\u044f \u0442\u043e\u0447\u043a\u0430 · \u043f\u043e\u043b\u0430\u044f · \u043a\u0432\u0430\u0434\u0440\u0430\u0442 · \u043d\u0435\u0442), \u0430 \u043d\u0435 \u043e\u0434\u043d\u0438\u043c \u0446\u0432\u0435\u0442\u043e\u043c. — */
.daypick{display:inline-flex;align-items:center;gap:.25rem}
.daypick__step{display:inline-grid;place-items:center;width:1.5rem;height:1.5rem;flex:none;
  border-radius:var(--radius-xs);color:var(--text-muted);text-decoration:none;line-height:1}
.daypick__step:hover{background:var(--c-slate-100);color:var(--text-strong)}
.daypick__box{position:relative}
.daypick__now{display:inline-flex;align-items:center;gap:.3rem;padding:.15rem .4rem;
  border-radius:var(--radius-xs);cursor:pointer;color:var(--text-strong);list-style:none;
  font-weight:var(--fw-semibold);font-variant-numeric:tabular-nums}
.daypick__now::-webkit-details-marker{display:none}
.daypick__now:hover{background:var(--c-slate-100)}
.daypick__chev{width:.8rem;height:.8rem;flex:none;transition:transform .12s}
.daypick__box[open] .daypick__chev{transform:rotate(180deg)}
.daypick__layer{position:absolute;z-index:40;top:calc(100% + var(--space-2));left:0;
  width:360px;max-width:calc(100vw - var(--space-8));padding:var(--space-4);
  background:var(--c-surface);border:1px solid var(--border);border-radius:var(--radius-lg);
  box-shadow:var(--shadow-md,0 10px 28px rgba(2,18,69,.16));font-size:var(--text-sm);color:var(--text)}
.daypick__nav{display:flex;align-items:center;justify-content:space-between;gap:var(--space-2);
  margin-bottom:var(--space-3)}
.daypick__month{display:flex;align-items:baseline;gap:.4rem;font-weight:var(--fw-semibold);color:var(--text-strong)}
.daypick__grid{display:grid;grid-template-columns:repeat(7,1fr);gap:2px}
.daypick__wd{height:1.5rem;display:grid;place-items:center;font-size:var(--text-xs);color:var(--text-muted)}
.dp{height:2.25rem;display:grid;place-items:center;align-content:center;gap:2px;
  border:1px solid transparent;border-radius:var(--radius-sm);text-decoration:none;
  font-variant-numeric:tabular-nums;line-height:1.05;color:var(--text)}
.dp:hover{border-color:var(--border-strong)}
.dp__mark{width:.35rem;height:.35rem;border-radius:50%;background:transparent}
.dp--sbis{background:var(--c-info-50);color:var(--c-info-700);font-weight:var(--fw-medium)}
.dp--sbis .dp__mark{background:var(--c-info-700)}
.dp--closed{border-style:dashed;border-color:var(--border-strong)}
.dp--closed .dp__mark{width:.4rem;height:.4rem;border:1px solid var(--text-muted)}
.dp--draft{background:var(--c-slate-100)}
.dp--draft .dp__mark{background:var(--text-muted);border-radius:1px}
.dp--empty{color:var(--text-muted);pointer-events:none}
.dp.is-today{border:2px solid var(--c-brand-600);font-weight:var(--fw-bold);color:var(--text-strong)}
.daypick__legend{display:grid;gap:var(--space-1);margin-top:var(--space-3);padding-top:var(--space-3);
  border-top:1px solid var(--border);font-size:var(--text-xs);color:var(--text-muted)}
.daypick__legend > span{display:flex;align-items:center;gap:.45rem}
.daypick__legend .dp{height:1.4rem;width:2rem;flex:none;font-size:var(--text-xs)}

/* — \u0413\u0440\u0430\u0431\u043b\u044f #099 \u043f.3: \u0441\u043b\u043e\u0439 \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u0430\u0432\u0438\u0441\u0435\u0442\u044c \u043e\u0442 \u043f\u0440\u0435\u0434\u043a\u043e\u0432 \u0441 overflow. \u041d\u0430 \u0443\u0437\u043a\u043e\u0439 \u0448\u0438\u0440\u0438\u043d\u0435
     \u043e\u043d \u043d\u0435 absolute, \u0430 \u0432 \u043f\u043e\u0442\u043e\u043a\u0435: \u043e\u0431\u0440\u0435\u0437\u0430\u0442\u044c \u0435\u0433\u043e \u0442\u043e\u0433\u0434\u0430 \u043d\u0435\u0447\u0435\u043c, \u0438 \u043d\u0430 375 \u043e\u043d \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442 \u0432\u0441\u044e
     \u0448\u0438\u0440\u0438\u043d\u0443 layout, \u0430 \u043d\u0435 360 px. — */
@media (max-width:767px){
  .page-kicker--daypick{flex-wrap:wrap}
  .daypick{display:flex;width:100%;flex-wrap:nowrap}
  .daypick__box{position:static;flex:1 1 auto;min-width:0}
  .daypick__layer{position:static;width:auto;max-width:none;min-width:0;margin-top:var(--space-2);
    margin-inline:-3rem}
  .daypick__grid{min-width:0}
  /* Порог касания 44 px на всех трёх органах управления. Стрелки и дата растут до
     2.75rem, а слой ровно на их ширину расширяется отрицательным margin-inline:
     3rem = 2.75rem стрелка + .25rem gap с каждой стороны. Иначе 44-пиксельные
     стрелки съедали бы 96 px строки и ячейка падала до 31 px — то есть порог
     на стрелках ломал бы порог в сетке. Итог на 375: слой = вся ширина .daypick
     (357 px), контент 323 px, ячейка (323 − 12) / 7 = 44,5 px. */
  .daypick__step{width:2.75rem;height:2.75rem}
  .daypick__now{min-height:2.75rem}
  .dp{min-height:2.75rem}
}


/* #334 возврат п.5: число финансового итога не должно рваться переносом строки. */
.rev-total .rev-total__value{white-space:nowrap}

/* ── #119 · Свод кассы по месяцу — перенос блока из components_delivery_119.css (iteration-13, принят sess_020) ── */
/* ═══ ТЗ_119 / #119 — свод кассы по месяцу (`/cash-month`) ═══
   Новый экран. Строки = дни, внизу «Итого». 26 колонок в пяти смысловых группах не выживают
   в один ряд (в Excel их 30+), поэтому группы сворачиваются: свёрнутая группа не исчезает,
   а сжимается в ОДНУ итоговую колонку — месяц продолжает читаться, ширина падает втрое.
   Механика — чекбокс-хак + `:has()` (JS в поставке нет): чекбоксы живут в чипах над таблицей
   (`.chipbar`/`.chip-f` — принятый компонент), заголовки групп в шапке — `<label for>` на те же
   чекбоксы, поэтому свернуть можно и из шапки, и из чипа.
   Своя таблица (`.cm-table`), а НЕ модификатор принятого `.table--dense.table--sticky1`:
   у табеля 33 однотипные узкие колонки-дни, здесь 26 разноширинных денежных — общие правила
   ширин/офсетов пришлось бы переопределять почти целиком. Ни одно правило табеля не тронуто. */

.cm-table{width:100%;border-collapse:separate;border-spacing:0;table-layout:fixed;
  font-size:var(--text-xs);font-variant-numeric:tabular-nums;font-feature-settings:"tnum" 1;
  /* Ширины закреплённых справа колонок — переменными, а НЕ двумя числами: офсет закрепления
     обязан равняться фактической ширине соседа (#170 A: щель = дефект), а копия числа
     рассинхронизируется при первой же правке ширины — именно так и получилась щель 2px,
     когда «Откл.» стал 72 при офсете 74. Теперь и width, и right читают одно значение. */
  --cm-w-dev:72px; --cm-w-st:92px}
.cm-table th,.cm-table td{padding:7px 6px;line-height:var(--lh-tight);text-align:right;
  white-space:nowrap;vertical-align:middle;border-bottom:1px solid var(--border);width:70px}
/* Ширины (числа — в CHANGES §3): дата 50 · деньги 70 · излишки 52 · остаток счёта 78 ·
   итоговая колонка свёрнутой группы 70 · план-заглушка 34 · статус 92 · отклонение 72.
   Сумма состояния по умолчанию — 930px при самой узкой рабочей области 965 (1280, меню
   открыто, вертикальная полоса страницы на месте): не «в размер», а с запасом 35px.
   Подгонка суммы ВПЛОТНУЮ к рабочей области — источник ложной полосы прокрутки: ширина
   области зависит от рендера сайдбара, жёлоба прокрутки (в проде `scrollbar-gutter:stable`)
   и паддинга контейнера, поэтому равенство держаться не может. Остаток при `table-layout:
   fixed` раскладывается по колонкам пропорционально — запас не оставляет пустого места.
   Минимумы по содержимому проверены: 7-значная сумма («2 746 917») — 50px + 12px паддинга
   = 62 ≤ 70; «Остаток счёта» 7-значный с запасом на жирный итог — 78. */
.cm-table .cm-day{width:50px;text-align:left}
.cm-table .cm-surplus{width:52px}
.cm-table .cm-acct{width:78px}
.cm-table .cm-s--cash,.cm-table .cm-s--bank,.cm-table .cm-s--exp{width:70px}
.cm-table .cm-plan{width:34px;text-align:center}
.cm-table .cm-st{width:var(--cm-w-st);text-align:left}
.cm-table .cm-dev{width:var(--cm-w-dev)}

/* — Шапка в два уровня: строка групп (тон глубже) + строка колонок. Заголовки колонок
   переносятся в две строки, поэтому `white-space:normal` только здесь. — */
.cm-table thead .cm-grouprow th{background:var(--c-slate-100);color:var(--text-strong);
  font-weight:var(--fw-bold);text-align:center;padding:5px 6px;border-bottom:1px solid var(--border-strong);
  /* Страховка: подпись группы длиннее своей колонки не выносится на соседа, а обрезается
     в своей ячейке. Дефект ловился дважды (заглушка «План» 2px, свёрнутые группы до 12px):
     при `white-space:nowrap` и видимом overflow текст уезжает поверх соседних данных ровно
     в тех состояниях, где остатка ширины на пропорциональную раскладку нет. Подписи
     свёрнутых групп при этом сокращены до «Нал.» / «Б/н» / «Расх.» — полное имя стоит
     строкой ниже («Нал. конец», «Выручка б/н», «Расход всего»), так что смысл не теряется. */
  overflow:hidden}
.cm-table thead .cm-headrow th{background:var(--c-surface-2);color:var(--text);font-weight:var(--fw-semibold);
  white-space:normal;text-align:right;padding:4px 6px;border-bottom:2px solid var(--border-strong);vertical-align:bottom}
.cm-table thead .cm-headrow th.cm-day,.cm-table thead .cm-headrow th.cm-st{text-align:left}
.cm-table thead .cm-headrow th.cm-plan{text-align:center}

/* — Переключатель группы: и в шапке таблицы, и в чипе над ней (один и тот же чекбокс). — */
.cm-gtoggle{display:inline-flex;align-items:center;gap:.3em;cursor:pointer;user-select:none;
  padding:1px 4px;border-radius:var(--radius-xs);color:inherit}
.cm-gtoggle:hover{background:var(--c-slate-200)}
.cm-gcaret{width:.7rem;height:.7rem;flex:none;transition:transform .15s}
.cm-scope:has(#cmg-cash:checked) .cm-gcaret--cash,
.cm-scope:has(#cmg-bank:checked) .cm-gcaret--bank,
.cm-scope:has(#cmg-exp:checked) .cm-gcaret--exp{transform:rotate(90deg)}
/* Раскрыто → скрыта итоговая колонка группы; свёрнуто → скрыты подробные. */
.cm-scope:not(:has(#cmg-cash:checked)) .cm-c--cash{display:none}
.cm-scope:has(#cmg-cash:checked) .cm-s--cash{display:none}
.cm-scope:not(:has(#cmg-bank:checked)) .cm-c--bank{display:none}
.cm-scope:has(#cmg-bank:checked) .cm-s--bank{display:none}
.cm-scope:not(:has(#cmg-exp:checked)) .cm-c--exp{display:none}
.cm-scope:has(#cmg-exp:checked) .cm-s--exp{display:none}
.cm-groups{display:flex;align-items:center;gap:var(--space-3);flex-wrap:wrap;padding:var(--space-3) var(--space-5);border-bottom:1px solid var(--border);background:var(--c-surface-2)}
.cm-groups__label{font-size:var(--text-xs);color:var(--text-muted);font-weight:var(--fw-semibold);text-transform:uppercase;letter-spacing:.04em}
.chip-f.is-soon{opacity:.6;border-style:dashed;pointer-events:none}

/* — Зебра/hover: фон непрозрачный, иначе под закреплёнными колонками просвечивают данные. — */
.cm-table tbody tr:nth-child(even) td{background:var(--c-surface-2)}
.cm-table tbody tr:nth-child(odd) td{background:var(--c-surface)}
.cm-table tbody tr:hover td{background:var(--c-slate-50)}

/* — Дата: ссылка на дневной экран занимает всю ячейку (клик по строке целиком без JS
   не сделать — исполнителю нужен `data-href` на `<tr>`, отмечено в CHANGES). — */
.cm-table td.cm-day{padding:0;font-weight:var(--fw-semibold);color:var(--text-strong)}
.cm-daylink{display:flex;align-items:baseline;gap:.3em;padding:7px 6px;color:inherit;text-decoration:none}
.cm-daylink:hover{text-decoration:underline;color:var(--link)}
.cm-daylink small{font-weight:var(--fw-regular);color:var(--text-muted);font-size:.85em}

/* — Отклонение — главный сигнал экрана. Ноль тих (серый, без заливки), не-ноль кричит
   (заливка + цвет + знак + стрелка: цвет НЕ единственный канал), «—» = пересчёта не было. — */
.cm-table td.cm-dev{font-weight:var(--fw-semibold)}
.cm-table tbody tr td.cm-dev--short{background:var(--c-neg-50);color:var(--expense)}
.cm-table tbody tr td.cm-dev--over{background:var(--c-warn-50);color:var(--discrepancy)}
.cm-table td.cm-dev--zero{color:var(--text-muted);font-weight:var(--fw-regular)}
.cm-devmark{font-size:.85em;margin-left:.15em}
.cm-z{color:var(--text-muted)}

/* — Статус дня. Денежную семантику pos/neg/warn не перехватываем (правило проекта):
   проведён — нейтральный бейдж с замком, не свёрнут — информационный с часами,
   черновик — пунктирная кайма с карандашом. Второй канал у каждого — иконка. — */
.cm-stbadge{max-width:100%}
.cm-stbadge svg{width:.8rem;height:.8rem;flex:none}
.cm-stbadge--draft{border-style:dashed;border-color:var(--border-strong);background:transparent;color:var(--text-muted)}

/* — Черновик: в итоги не входит, поэтому помечен не только бейджем — вся строка уходит
   в штриховку и приглушённый текст (видно и в ч/б печати). — */
.cm-table tbody tr.cm-row--draft td{color:var(--text-muted);
  background-image:repeating-linear-gradient(135deg,transparent 0 5px,color-mix(in srgb,var(--c-slate-400) 16%,transparent) 5px 7px)}
.cm-table tbody tr.cm-row--future td{color:var(--text-muted)}
.cm-table tbody tr.cm-row--today td.cm-day{box-shadow:inset 3px 0 0 var(--c-brand-500)}

/* — Итого. Остатки не суммируются (сумма остатков — бессмыслица): в этих клетках перенос
   с подписью «на дату», отсюда две строки и своя высота у итоговой строки. — */
.cm-table tbody tr.cm-row--total td{background:var(--c-slate-100);font-weight:var(--fw-bold);
  color:var(--text-strong);border-top:2px solid var(--border-strong);border-bottom:0}
.cm-carry{display:flex;flex-direction:column;align-items:flex-end;line-height:1.1}
.cm-carry small{font-weight:var(--fw-regular);color:var(--text-muted);font-size:.8em}
.cm-table tbody tr.cm-row--total td.cm-dev--short{background:var(--c-neg-100);color:var(--expense)}

/* — Заглушка группы «План» (§6 ТЗ: бюджета в панели нет — #042). Место занято, данных нет:
   штриховка + серый, колонка не раскрывается. — */
.cm-table .cm-plan{background-image:repeating-linear-gradient(135deg,transparent 0 3px,color-mix(in srgb,var(--c-slate-400) 14%,transparent) 3px 5px);color:var(--text-muted)}
.cm-table thead .cm-plan{color:var(--text-muted)}

/* — Закрепление: дата слева, «Статус» и «Откл.» справа (офсеты 0 и 74 = ширина «Откл.»).
   Только ≥768px — ниже таблицы нет вовсе, там карточки дней. — */
@media (min-width:768px){
  .cm-table thead th.cm-day,.cm-table tbody td.cm-day{position:sticky;left:0;z-index:2}
  .cm-table thead th.cm-day{z-index:5;background:var(--c-slate-100)}
  .cm-table thead .cm-headrow th.cm-day{background:var(--c-surface-2)}
  .cm-table .cm-st{position:sticky;right:var(--cm-w-dev);z-index:2;box-shadow:-2px 0 0 var(--border-strong)}
  .cm-table .cm-dev{position:sticky;right:0;z-index:2}
  .cm-table thead .cm-st,.cm-table thead .cm-dev{z-index:5;background:var(--c-slate-100)}
  .cm-table thead .cm-headrow .cm-st,.cm-table thead .cm-headrow .cm-dev{background:var(--c-surface-2)}
  .cm-table thead .cm-gh--status{position:sticky;right:0;z-index:5;background:var(--c-slate-100);box-shadow:-2px 0 0 var(--border-strong)}
}

/* — Мобильный (≤767): таблица месяца не превращается в горизонтальную простыню, вместо неё
   карточка на день. Структура данных та же (правило проекта), плотность другая: на лице
   карточки — дата, статус, отклонение, выручка и наличные на конец; `<details>` открывает
   полную раскладку по трём группам. Правка параметров дня остаётся на дневном экране. — */
.cmlist{display:none}
@media (max-width:767px){
  .cm-scope .table-wrap{display:none}
  .cm-scope .cm-groups{display:none}
  .cmlist{display:flex;flex-direction:column;gap:var(--space-2);padding:var(--space-3)}
}
.cmcard{border:1px solid var(--border);border-radius:var(--radius-md);background:var(--c-surface);overflow:hidden}
.cmcard>summary{display:grid;grid-template-columns:auto 1fr auto;gap:var(--space-1) var(--space-3);
  align-items:center;padding:var(--space-3);min-height:44px;cursor:pointer;list-style:none}
.cmcard>summary::-webkit-details-marker{display:none}
.cmcard__date{font-size:var(--text-md);font-weight:var(--fw-bold);color:var(--text-strong);white-space:nowrap}
.cmcard__date small{font-size:var(--text-xs);font-weight:var(--fw-regular);color:var(--text-muted);margin-left:.25em}
.cmcard__dev{justify-self:end;font-weight:var(--fw-semibold);font-variant-numeric:tabular-nums;
  padding:2px 8px;border-radius:var(--radius-sm);white-space:nowrap}
.cmcard__dev--short{background:var(--c-neg-50);color:var(--expense)}
.cmcard__dev--over{background:var(--c-warn-50);color:var(--discrepancy)}
.cmcard__dev--zero,.cmcard__dev--none{color:var(--text-muted);font-weight:var(--fw-regular)}
.cmcard__facts{grid-column:1/-1;display:flex;flex-wrap:wrap;gap:var(--space-1) var(--space-4);
  font-size:var(--text-xs);color:var(--text-muted);font-variant-numeric:tabular-nums}
.cmcard__facts b{color:var(--text);font-weight:var(--fw-semibold)}
.cmcard__body{border-top:1px solid var(--border);background:var(--c-surface-2);padding:var(--space-3)}
.cmcard--draft{border-style:dashed}
.cmcard--draft>summary{background-image:repeating-linear-gradient(135deg,transparent 0 5px,color-mix(in srgb,var(--c-slate-400) 14%,transparent) 5px 7px)}
.cmcard--future>summary{color:var(--text-muted)}
.cmcard--total{border-color:var(--border-strong);background:var(--c-slate-100)}
.cm-dl{display:grid;grid-template-columns:1fr auto;gap:2px var(--space-3);margin:0;font-size:var(--text-sm)}
.cm-dl dt{color:var(--text-muted)}
.cm-dl dd{margin:0;text-align:right;font-variant-numeric:tabular-nums;color:var(--text)}
.cm-dl__head{grid-column:1/-1;margin:var(--space-3) 0 var(--space-1);font-size:var(--text-xs);
  text-transform:uppercase;letter-spacing:.04em;color:var(--text-muted);font-weight:var(--fw-bold)}
.cm-dl__head:first-child{margin-top:0}
.cmcard__link{display:inline-flex;align-items:center;gap:.35em;min-height:44px;font-weight:var(--fw-semibold)}

/* — Сводка месяца в шапке панели: не отдельный блок KPI, а строка в `.panel__head` —
   иначе таблица уезжает вниз, а задача экрана — месяц целиком на одном экране. — */
.cm-sum{display:flex;flex-wrap:wrap;gap:var(--space-2) var(--space-5);font-size:var(--text-xs);color:var(--text-muted)}
.cm-sum__i{display:flex;align-items:baseline;gap:.35em}
.cm-sum__v{font-size:var(--text-sm);font-weight:var(--fw-bold);color:var(--text-strong);font-variant-numeric:tabular-nums}
.cm-sum__v--short{color:var(--expense)}
.cm-legend{display:flex;flex-wrap:wrap;gap:var(--space-2) var(--space-4);align-items:center;
  padding:var(--space-3) var(--space-5);border-top:1px solid var(--border);font-size:var(--text-xs);color:var(--text-muted)}
.cm-legend b{color:var(--text);font-weight:var(--fw-semibold)}

/* — Отладочная подсветка (только `cash-month-debug.html`, в поставку не идёт): внешний
   контур = граница ячейки/бокса, внутренний пунктир = граница контента (inset = паддинг).
   `position:relative` на всех ячейках безопасен: правила закрепления выше специфичнее
   (`.cm-table thead th.cm-day` против `.cm-table--debug th`) и `sticky` не теряется. — */
.cm-table--debug th,.cm-table--debug td{outline:1px solid rgba(191,42,32,.75);outline-offset:-1px;position:relative}
.cm-table--debug th::after,.cm-table--debug td::after{content:'';position:absolute;inset:7px 6px;
  border:1px dashed rgba(31,94,155,.85);pointer-events:none}
.cm-table--debug thead .cm-headrow th::after{inset:4px 6px}
.cm-table--debug thead .cm-grouprow th::after{inset:5px 6px}
.cmlist--debug .cmcard>summary,.cmlist--debug .cmcard__body{outline:1px solid rgba(191,42,32,.75);outline-offset:-1px;position:relative}
.cmlist--debug .cmcard>summary::after,.cmlist--debug .cmcard__body::after{content:'';position:absolute;inset:12px;
  border:1px dashed rgba(31,94,155,.85);pointer-events:none}

/* — Строка-размерник. При `table-layout:fixed` ширины колонок берутся ТОЛЬКО из первой строки
   таблицы, а первая строка здесь — строка групп с colspan: её 6 ячеек делили бы всю ширину
   между 26 колонками (замер до правки: деньги по 24px, «Дата» 146px). Поэтому первой идёт
   служебная строка из 26 пустых ячеек с теми же классами ширин и групп: она задаёт сетку,
   сворачивается вместе со своей группой и не занимает высоты (`visibility:hidden` оставляет
   ячейку в раскладке, `display:none` — нет, поэтому именно visibility). — */
.cm-table thead tr.cm-sizer th{height:0;padding:0;border:0;line-height:0;font-size:0;visibility:hidden}

/* — Пустые маркеры («—», будущий день, заглушка «План») сначала были на `--c-slate-400`:
   замер в тёмной теме дал 3,33:1 и 3,75:1 — ниже AA. В этой системе slate-400 — цвет
   декоративных заливок (точки, метки источников), не текста. Переведены на `--text-muted`
   (тёмная 6,86:1 · светлая 5,31:1); «отступать назад» им теперь даёт сам знак «—», а не
   слабый контраст. — */

/* — Мобильный: шапка панели с четырьмя числами месяца на 360px зажимала заголовок в столбик
   («Май / 2026 · / дни / месяца»). Заголовок получает всю строку, сводка встаёт под ним.
   Селектор сужен до `.cm-scope` — общий `.panel__head` принятых экранов не трогаем. — */
@media (max-width:767px){
  .cm-scope .panel__head{flex-wrap:wrap}
  .cm-scope .panel__title{flex:1 0 100%}
}

/* ═══ #361 · Бейдж источника с датой подтверждения (.srcd) ═══════════════════════
   Элемент дизайн-системы: «метка источника + дата подтверждения». Метка — произвольная
   строка («1С», «СБИС», «Excel», «банк»): ни класса, ни картинки с привязкой к системе.
   Чип переиспользует принятый .src (нейтральная плашка + точка цветом источника):
   ни одно правило .src / .src__dot НЕ переопределяется — новые свойства висят
   на собственных классах .srcd*. Раскрытие даты — без JS: скрытый чекбокс + <label>.
   Ограничение переиспользования: .srcd нельзя класть внутрь элемента с transform /
   will-change:transform / filter — такой предок становится содержащим блоком для
   position:fixed и мобильный лист перестанет быть на весь экран (например
   .table--sticky1 td:first-child — там will-change:transform). */
.srcd{position:relative;display:inline-flex;vertical-align:middle}
/* чекбокс скрыт через display:none — не фокусируется, таб-стопов в списке не прибавляет (§4 ТЗ) */
.srcd__tgl{display:none}
/* 18.4px: ниже line-box строки таблицы (13px × 1.45 = 18.85px) — высота строки не растёт */
.srcd__chip{position:relative;height:1.15rem;cursor:pointer;user-select:none}
/* Необязательный знак источника внутри чипа. Появляется вместо точки .src__dot там, где знак
   существует (1С, СБИС, Excel); у источников без знака — ручной ввод, «банк» вообще — остаётся
   точка. Контракт элемента от этого не меняется: и то и другое — «метка источника + дата»,
   класс к системе не привязан, чужие цвета не перекрашиваются. .src__ic не переопределяется:
   его 15,2 px в чипе 18,4 px занимают 83 % высоты, здесь нужен свой размер. */
.srcd__ic{width:13px;height:13px;object-fit:contain;flex:none}
.srcd__tip{position:absolute;z-index:60;top:calc(100% + 4px);left:0;display:none;
  max-width:min(15.5rem,62vw);padding:6px 10px;border:1px solid var(--border-strong);
  border-radius:var(--radius-sm);background:var(--c-slate-900);color:#fff;box-shadow:var(--shadow-md);
  font-size:var(--text-xs);font-weight:var(--fw-medium);line-height:1.35;white-space:nowrap}
.srcd--right .srcd__tip{left:auto;right:0}
/* Заливка слоя (--c-slate-900) роль между темами не меняет — белый текст на ней жив в обеих
   (15,76:1), в перечислительное правило добавлять нечего. Но в тёмной теме слой и полотно
   почти сливаются (1,17:1), поэтому граница берётся светлее: #6b7791 к #1c2330 — 3,1:1. */
[data-theme="dark"] .srcd__tip{border-color:var(--c-slate-400)}
.srcd__x{display:none}
.srcd__scrim{display:none}
@media (hover:hover){
  .srcd:hover .srcd__tip{display:block}
  .srcd:hover .srcd__chip{background:var(--c-slate-200)}
}
.srcd__tgl:checked ~ .srcd__tip{display:block}
.srcd__tgl:checked ~ .srcd__chip{box-shadow:0 0 0 2px var(--c-brand-600)}
.srcd__tgl:checked ~ .srcd__scrim{display:block;position:fixed;inset:0;z-index:55;background:transparent}
/* тап крупнее видимого чипа: 44×44 от центра (§4). Только на тач-указателе — на мыши
   невидимая зона ловила бы наведение в стороне от бейджа. */
@media (pointer:coarse){
  .srcd__chip::after{content:"";position:absolute;left:50%;top:50%;width:44px;height:44px;transform:translate(-50%,-50%)}
}
/* Мобильный: слой уходит из потока таблицы в фиксированный лист над нижней навигацией —
   overflow-x:auto таблицы его не обрезает, краёв вьюпорта у него нет по построению. */
@media (max-width:767px){
  .srcd__tip{position:fixed;top:auto;left:var(--space-3);right:var(--space-3);
    bottom:calc(var(--bottomnav-h) + env(safe-area-inset-bottom, 0px) + var(--space-3));
    max-width:none;white-space:normal;padding:var(--space-3) var(--space-4);
    font-size:var(--text-sm);box-shadow:var(--shadow-lg);
    display:none;align-items:center;gap:var(--space-3)}
  .srcd__tgl:checked ~ .srcd__tip{display:flex}
  .srcd__x{display:flex;align-items:center;justify-content:center;flex:none;margin-left:auto;
    width:32px;height:32px;margin-right:-6px;border-radius:var(--radius-sm);
    font-size:var(--text-lg);line-height:1;color:#fff;cursor:pointer}
  .srcd__x:hover{background:rgba(255,255,255,.14)}
}

/* Первый носитель — список операций «Банк». Всё внутри блока .bank-ops. */
/* у двух последних строк слой раскрывается вверх: вниз его обрезал бы .table-wrap
   (overflow-x:auto поднимает вторую ось в auto). :not(:first-child) — чтобы в таблице
   из одной-двух строк слой не ушёл вверх за верхнюю границу. */
.bank-ops tbody tr:nth-last-child(-n+2):not(:first-child) .srcd__tip{top:auto;bottom:calc(100% + 4px)}
@media (max-width:767px){
  .bank-ops tbody tr:nth-last-child(-n+2):not(:first-child) .srcd__tip{top:auto;
    bottom:calc(var(--bottomnav-h) + env(safe-area-inset-bottom, 0px) + var(--space-3))}
}



/* ═══ #361 · итерация 23 · знак вместо подписи, ряд знаков под суммой ═══════════
   Правка заказчика: метка подтверждает сумму операции, а не дату, и несёт только
   знак системы — подпись («1С», «СБИС», выписка банка) уходит в слой, который
   раскрывается по наведению и тапу. Знак банка при этом уезжает из колонки «Счёт»
   в тот же ряд: источник строки и подтверждения стоят рядом, под суммой.
   Все правила — на новых модификаторах; принятые .src, .src__dot, .srcd__chip
   не переопределяются. Вторая ось состояния сохранена: у каждого знака своя форма
   и свой текст в слое — цвет не единственный носитель смысла. */
.srcd__chip--mark{width:1.15rem;padding:0;gap:0;justify-content:center}
.srcd__chip--mark .srcd__ic{width:14px;height:14px}
@media (hover:hover){
  .srcd:hover .srcd__chip--mark{box-shadow:inset 0 0 0 1px var(--c-slate-500)}
}
.srcd__tgl:checked ~ .srcd__chip--mark{box-shadow:0 0 0 2px var(--c-brand-600)}
/* Белая подложка знака держится в обеих темах намеренно: чужие логотипы не перекрашиваются
   (1С — жёлтый круг, СБИС — синяя птица, знаки банков), а на тёмном полотне их светлые
   контуры теряются. Белого текста в чипе нет — в перечислительное правило тёмной темы
   добавлять нечего. */

.bank-ops__marks{display:flex;align-items:center;gap:4px}
/* Тач: три знака в ряд с зоной 44×44 у каждого перекрывались бы, и тап уходил бы соседу.
   Знак 28 px + шаг 16 px → центры ровно в 44 px, зоны стыкуются без нахлёста (§4 ТЗ). */
@media (pointer:coarse){
  .bank-ops__marks{gap:16px}
  .bank-ops__marks .srcd__chip--mark{width:28px;height:28px}
  .bank-ops__marks .srcd__chip--mark .srcd__ic{width:18px;height:18px}
}

/* Регрессия переноса: .srcd--right теперь стоит на каждом знаке в списке (колонка «Сумма»
   крайняя правая), и его правило .srcd--right .srcd__tip{left:auto;right:0} (0,2,0) перебивало
   мобильное .srcd__tip{left/right:var(--space-3)} (0,1,0) — фиксированный лист прижимался к
   правому краю вьюпорта и вылезал за него на 8 px. Возвращаем лист в мобильные границы
   правилом той же специфичности; десктопное поведение модификатора не тронуто. */
@media (max-width:767px){
  .srcd--right .srcd__tip{left:var(--space-3);right:var(--space-3)}
}

/* Знак 1С — широкое начертание: логотип прислан вектором (fill задан атрибутом на путях,
   классов st0/st1 без правил в нём нет), растровый 1c.png в 14 px размывался. Широкие
   логотипы в системе живут на светлой подложке отдельным начертанием (как .acctcard__logo--mark),
   квадратные знаки — как есть; поэтому чип 1С шире квадратного, высота ряда та же. */
.srcd__chip--wide{width:auto;padding:0 3px}
.srcd__ic--wide{width:auto;height:11px}
@media (pointer:coarse){
  .bank-ops__marks .srcd__chip--wide{width:auto;padding:0 5px}
  .bank-ops__marks .srcd__chip--wide .srcd__ic--wide{width:auto;height:16px}
}

/* Правка заказчика: 18,4 px знаки не читались — логотип 14 px даёт слишком мелкую деталь
   (жёлтый круг 1С, птица СБИС, буквы банков). Знак поднят до 24 px, логотип до 18 px,
   широкое начертание 1С — до 14 px по высоте; шаг ряда 6 px. Ряд знаков — вторая строка
   в ячейке суммы, поэтому высота строки растёт на ~6 px, ширина колонки не меняется. */
.srcd__chip--mark{width:1.5rem;height:1.5rem}
.srcd__chip--mark .srcd__ic{width:18px;height:18px}
.srcd__chip--wide{width:auto;padding:0 4px}
.srcd__chip--wide .srcd__ic--wide{width:auto;height:14px}
.bank-ops__marks{gap:6px}
@media (pointer:coarse){
  .bank-ops__marks{gap:14px}
  .bank-ops__marks .srcd__chip--mark{width:30px;height:30px}
  .bank-ops__marks .srcd__chip--mark .srcd__ic{width:22px;height:22px}
  .bank-ops__marks .srcd__chip--wide{width:auto;padding:0 6px}
  .bank-ops__marks .srcd__chip--wide .srcd__ic--wide{width:auto;height:18px}
}

/* Птичка СБИС — вектор, вырезанный из присланного логотипа (три пути, цвета атрибутом:
   #0c94ff и #0b6fbd). Начертание высокое и узкое (220 × 309), поэтому в квадратном чипе
   его масса меньше остальных знаков — тянем по высоте, ширина идёт по пропорции. */
/* специфичность как у .srcd__chip--mark .srcd__ic (0,2,0) — иначе квадрат 18 px перебивает */
.srcd__chip--mark .srcd__ic--tall{width:auto;height:20px}
@media (pointer:coarse){
  .bank-ops__marks .srcd__chip--mark .srcd__ic--tall{width:auto;height:25px}
}

/* ── #361 · развилка подачи знаков (кадры-варианты, ждут решения заказчика) ──
   Вариант A: знаки в своей колонке — строка одноэтажная, знаки в общей вертикали. */
.bank-ops__conf{white-space:nowrap}
.bank-ops__conf .bank-ops__marks{justify-content:flex-start}

/* Решение по развилке: знаки живут в своей колонке «Подтверждено» (перед «Суммой»), а в покое
   де-акцентированы — полная оправа возвращается на строке под курсором, при фокусе и на
   раскрытом слое. Де-акцент общий для всех знаков сразу: состояние им не кодируется.
   Гасим НЕ логотип, а оправу: opacity съедала контраст самих знаков (у светло-синего СБИС при
   полном цвете всего 3,14:1 — запаса нет, при .6 выходило 1,99:1, ниже порога 3:1 для
   нетекстовых элементов), а перекрашивать чужие логотипы правила запрещают. Поэтому в покое
   у знака нет белой подложки и рамки — только логотип в полном цвете; оправа возвращается
   на строке под курсором, при фокусе и на раскрытом слое. В тёмной теме подложка остаётся
   всегда: без неё цветные логотипы на тёмном полотне теряют контраст.
   ВАЖНО: оправа НЕ задана в базовом правиле .srcd__chip--mark (0,1,0) — иначе её приходилось бы
   гасить более поздним правилом той же темы, и любая следующая правка размера чипа возвращала
   подложку обратно (так и случилось на приёмке: базовый литерал background:#fff перебивал
   де-акцент). Теперь подложка появляется ТОЛЬКО перечисленными состояниями. */
.bank-ops__conf .srcd__chip--mark{background:transparent;box-shadow:none;
  transition:background .12s ease,box-shadow .12s ease}
/* Вне колонки подтверждения (карточка контракта элемента, §5 кадра краёв) знак — предмет
   спецификации, а не строка списка: де-акцентировать его нечем и не за чем. Оправа там
   постоянная. Правило 0,2,0 перебивает серую плашку принятого .src (--c-slate-100):
   без него птица СБИС садилась на #e5e9f0 (2,9:1 против 3,14:1 на белом), а hover-рамка
   .srcd:hover рисовала кольцо без подложки под ним. */
.card .srcd__chip--mark{background:#fff;box-shadow:inset 0 0 0 1px var(--border)}
@media (hover:hover){
  .bank-ops tbody tr:hover .bank-ops__conf .srcd__chip--mark,
  .bank-ops__conf .srcd:focus-within .srcd__chip--mark,
  .bank-ops__conf .srcd__tgl:checked ~ .srcd__chip--mark{background:#fff;
    box-shadow:inset 0 0 0 1px var(--border)}
}
/* тач-указатель и тёмная тема: оправа всегда */
@media (pointer:coarse){
  .bank-ops__conf .srcd__chip--mark{background:#fff;box-shadow:inset 0 0 0 1px var(--border)}
}
[data-theme="dark"] .bank-ops__conf .srcd__chip--mark{background:#fff;
  box-shadow:inset 0 0 0 1px var(--border)}

/* Заказчик убрал из строки «ИНН» и «Счёт» (ИНН смотрят в карточке контрагента, номер счёта
   при двух-трёх счетах строку только перегружал; сам счёт остался знаком банка в колонке
   «Подтверждено» и в тексте слоя). Остались: Дата · Контрагент · Назначение · Подтверждено · Сумма.
   Сумма теперь выделена не только цветом (pos/neg), но и начертанием — 15 px, 600, табличные
   цифры: в ч/б печати и при дальтонизме порядок величин читается без цвета. */
.bank-ops__sum{font-size:0.9375rem;font-weight:600;font-variant-numeric:tabular-nums;letter-spacing:-.01em}

/* Ширины колонок списка: «Дата», «Подтверждено» и «Сумма» — строго по содержимому (width:1%
   при table-layout:auto = «сожмись до контента»), свободное место достаётся «Контрагенту»
   и «Назначению», где информации в разы больше. Раньше auto-раскладка раздавала излишек
   всем колонкам пропорционально, и при закрытой боковой панели «Подтверждено» и «Дата»
   набирали лишние ~50 и ~55 px. Колонок во всех кадрах пять, порядок один и тот же. */
.bank-ops th:nth-child(1),.bank-ops td:nth-child(1),
.bank-ops th:nth-child(4),.bank-ops td:nth-child(4),
.bank-ops th:nth-child(5),.bank-ops td:nth-child(5){width:1%;white-space:nowrap}
.bank-ops th:nth-child(2),.bank-ops td:nth-child(2){width:24%}
.bank-ops th:nth-child(3),.bank-ops td:nth-child(3){width:auto}
/* строка-заглушка пустого списка занимает всю ширину — переносы ей нужны */
.bank-ops td[colspan]{white-space:normal;width:auto}

/* ── Мобильная подача списка (≤767): таблица → карточки в две строки ──────────
   Заказчик: горизонтальный скролл на телефоне не годится. Разметка та же самая — строку
   переводим в grid и раскладываем ячейки по областям: слева дата и под ней сумма,
   в середине контрагент и под ним назначение, знаки подтверждения — третьей колонкой
   во всю высоту карточки. Порядок колонок во всех кадрах один и тот же (5 ячеек),
   поэтому раскладка идёт по nth-child. Шапка скрыта: подписи колонок на карточке
   не нужны, смысл читается положением и начертанием. */
@media (max-width:767px){
  .bank-ops .table-wrap{overflow-x:visible;border:0;background:none}
  .bank-ops table{display:block;width:100%}
  .bank-ops thead{display:none}
  .bank-ops tbody{display:flex;flex-direction:column;gap:var(--space-3)}
  .bank-ops table.table--zebra tbody tr,.bank-ops tbody tr{display:grid;
    grid-template-columns:100px minmax(0,1fr);
    grid-template-areas:"date party" "sum purpose" "conf conf";
    column-gap:var(--space-4);row-gap:2px;padding:var(--space-3) var(--space-4);
    border:1px solid var(--border);border-radius:var(--radius-md);background:var(--c-surface)}
  .bank-ops tbody td{display:block;border:0;padding:0}
  .bank-ops tbody td:nth-child(1){grid-area:date;width:auto;white-space:nowrap;
    font-size:var(--text-xs);color:var(--text-muted)}
  .bank-ops tbody td:nth-child(2){grid-area:party;width:auto;font-weight:var(--fw-medium)}
  .bank-ops tbody td:nth-child(3){grid-area:purpose;width:auto;white-space:normal;
    font-size:var(--text-xs);color:var(--text-muted)}
  .bank-ops tbody td:nth-child(4){grid-area:conf;width:auto;margin-top:var(--space-2)}
  .bank-ops tbody td:nth-child(5){grid-area:sum;width:auto;text-align:left}
  /* знаки в карточке — горизонтальным рядом: столбик был выше двух строк текста и растягивал
     карточку (125 px против 69–87), высоту диктовало число знаков, а не содержимое. Шаг 14 px:
     на тач-указателе чип 30 px → центры ровно в 44 px, зоны тапа не перекрываются. */
  .bank-ops__conf .bank-ops__marks{flex-direction:row;gap:14px;align-items:center;justify-content:flex-start}
  /* строка-заглушка пустого списка — обычной карточкой */
  .bank-ops tbody tr:has(td[colspan]){display:block;text-align:center}
}

/* ── Мобильные плитки во всю ширину + ползунок поверх плиток (≤767) ────────────
   Заказчик: плитки должны занимать всю ширину экрана, а индикатор позиции — всплывать
   поверх них при прокрутке.
   1) Полное полотно: .bank-ops выходит из паддинга контейнера отрицательными полями,
      равными этому паддингу (--_bleed: space-5 на 480–767 и space-2 на ≤479 — так задано
      у .container в этих же границах). Приём «50% − 50vw» не подошёл: 100vw включает
      классический жёлоб прокрутки, и полотно уезжало влево на его ширину (замер: −5 px
      слева при 5 px обрезки справа).
   2) Плитка во всю ширину — это уже не карточка: боковые границы и радиус сняты,
      разделителем работает нижняя граница, зазор между плитками нулевой. Внутренний
      паддинг сохранён, содержимое к краю экрана не липнет.
   3) Ползунок: жёлоб убран, полоса рисуется поверх содержимого — 4 px, полупрозрачная,
      трек прозрачный. На тач-платформах оверлейная полоса по своей природе видна только
      во время прокрутки и гаснет сама; в настольном браузере она остаётся видимой —
      без JS состояние «сейчас скроллят» в CSS не читается, а JS в макеты не кладём. */
@media (max-width:767px){
  html{scrollbar-gutter:auto;scrollbar-width:thin;scrollbar-color:rgba(15,23,42,.3) transparent}
  html::-webkit-scrollbar{width:4px;background:transparent}
  html::-webkit-scrollbar-track{background:transparent}
  html::-webkit-scrollbar-thumb{background:rgba(15,23,42,.3);border-radius:999px}
  html[data-theme="dark"]{scrollbar-color:rgba(226,232,240,.34) transparent}
  html[data-theme="dark"]::-webkit-scrollbar-thumb{background:rgba(226,232,240,.34)}
  .app-main{overflow-x:clip}
  .bank-ops{--_bleed:var(--space-5);width:calc(100% + 2 * var(--_bleed));
    margin-inline:calc(-1 * var(--_bleed))}
  .bank-ops tbody{gap:0}
  .bank-ops table.table--zebra tbody tr,.bank-ops tbody tr{border-inline:0;border-top:0;
    border-radius:0;border-bottom:1px solid var(--border)}
  .bank-ops tbody tr:first-child{border-top:1px solid var(--border)}
}
/* ponytail: порог 430 = прод-медиа .container (components.css:1649), у дизайнера было 479 */
@media (max-width:430px){
  .bank-ops{--_bleed:var(--space-2)}
}
