/* FinKontur — стили общих компонентов (T95, инвариант I13, §6 01-ДИЗАЙН-СИСТЕМА.md).
   Партиалы Jinja — src/finkontur/app/templates/components/*.html, каждый компонент
   собран РОВНО из компонентных токенов tokens.css (никаких #hex/px вне них — правило
   гейта tools/design_check.py).

   Подключается ПОСЛЕДНИМ, после app.css (base.html): на экранах, ещё не переведённых
   на компоненты (T96), сохраняются старые классы app.css/dashboard.css (`.btn`,
   `.field`, `.pill`) — этот файл ТОЛЬКО добавляет новые классы (`.chip`, `.kpi`,
   `.banner`, `.error-summary`, `.empty-state`) и уточняет состояния существующих
   (`.field.err`, `.btn[disabled]`), не переопределяя структуру `.btn`/`.field` из
   app.css заново — совпадающие имена там и здесь описывают один и тот же компонент. */

/* ------------------------------------------------------------------ */
/* Кнопка §6.1 — варианты и состояния.                                  */
/* ВАЖНО: базовую коробку `.btn` (display/height/padding/border/radius) уже задаёт
   app.css — она держится на старых px-значениях (долг T92), но её МЕНЯТЬ здесь
   нельзя: components.css грузится ПОСЛЕ app.css на КАЖДОЙ странице (base.html),
   и переопределение общих свойств `.btn` задело бы все кнопки сайта, а не только
   пять переводимых экранов. Здесь — только варианты и состояния, которых в
   app.css ещё не было (`secondary`/`ghost`) или которые она недоопределяет
   (`disabled`, `busy`). `.btn-primary`/`.btn-danger` уже существуют в app.css —
   переопределяем в них только цвет (на семантический токен вместо `--model`),
   саму коробку не трогаем. */
/* ------------------------------------------------------------------ */
.btn-primary { background: var(--btn-primary-bg); border-color: var(--btn-primary-bg); color: var(--btn-primary-text); }
.btn-primary:hover { background: var(--btn-primary-bg-hover); border-color: var(--btn-primary-bg-hover); opacity: 1; }
.btn-secondary { background: var(--btn-secondary-bg); color: var(--btn-secondary-text); border-color: var(--btn-secondary-border); }
.btn-secondary:hover { border-color: var(--brand); }
.btn-ghost { background: transparent; color: var(--btn-ghost-text); border-color: transparent; }
.btn-ghost:hover { background: var(--surface-2); }
.btn[disabled], .btn.is-disabled { opacity: .55; cursor: not-allowed; }
.btn[disabled]:hover { border-color: inherit; }

/* Приёмка фазы 10: `.card a { color: var(--series-fact) }` из app.css сильнее
   (класс + элемент), чем `.btn-primary` (класс) — ссылка-кнопка внутри карточки
   красилась цветом ссылки: синий текст на синем фоне, надпись пропадала.
   Кнопка всегда берёт свои токены, где бы ни стояла. */
.card a.btn { color: var(--btn-secondary-text); }
.card a.btn-primary { color: var(--btn-primary-text); }
.card a.btn-danger { color: var(--btn-danger-text); }
.card a.btn-ghost { color: var(--btn-ghost-text); }
.btn.is-busy { opacity: .75; cursor: progress; }
.btn-sm { height: var(--control-h-sm); padding: 0 var(--space-3); font-size: var(--fs-caption); }

/* ------------------------------------------------------------------ */
/* Поле ввода §6.2 — ошибка и подсказка (структура .field — app.css).   */
/* ------------------------------------------------------------------ */
/* Кегль полей — токен --fs-control (16px на сенсорных, см. tokens.css): без этого
   поле берёт браузерные 13.33px, и Safari на iPhone зумит страницу при фокусе. */
input, select, textarea { font-family: inherit; font-size: var(--fs-control); }

.field.err input,
.field.err select,
.field.err textarea {
  border-color: var(--field-border-error);
}
.field-error-text { color: var(--neg); display: block; }
.field label { font-size: var(--field-label-size); font-weight: var(--fw-medium); color: var(--text-muted); }

/* Сводка ошибок формы §6.2 — role="alert" в разметке макроса. */
.error-summary {
  border: var(--border-w) solid var(--neg);
  background: var(--neg-bg);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin: 0 0 var(--space-4);
  color: var(--neg);
}
.error-summary:focus { outline: 2px solid var(--focus); outline-offset: 2px; }
.error-summary .error-list { margin: var(--space-2) 0 0; padding-left: var(--space-5); }
.error-summary .error-list a { color: inherit; }

/* ------------------------------------------------------------------ */
/* Плашка статуса §6.5 — пять закреплённых цветов, других не заводим.   */
/* ------------------------------------------------------------------ */
.chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: var(--chip-padding);
  border-radius: var(--chip-radius);
  font-size: var(--chip-font-size);
  font-weight: var(--fw-medium);
  white-space: nowrap;
}
.chip-draft { background: var(--surface-2); color: var(--text-muted); }
.chip-wait  { background: var(--warn-bg); color: var(--warn); }
.chip-ok    { background: var(--pos-bg); color: var(--pos); }
.chip-rev   { background: var(--neg-bg); color: var(--neg); }
.chip-model { background: var(--model-weak); color: var(--model); }

/* ------------------------------------------------------------------ */
/* KPI-плитка §6.4.                                                     */
/* ------------------------------------------------------------------ */
.kpi {
  display: block;
  background: var(--card-bg);
  border: var(--border-w) solid var(--card-border);
  border-radius: var(--card-radius);
  padding: var(--space-4);
  text-decoration: none;
  color: inherit;
}
a.kpi:hover { border-color: var(--brand); }
.kpi .k-label { font-size: var(--fs-caption); color: var(--kpi-label-color); }
.kpi .k-value {
  font-family: var(--font-num);
  font-variant-numeric: tabular-nums;
  font-size: var(--kpi-value-size);
  line-height: var(--lh-kpi);
  font-weight: var(--kpi-value-weight);
  margin: var(--space-1) 0;
}
.kpi .k-foot { font-size: var(--fs-caption); color: var(--kpi-lens-color); display: flex; gap: var(--space-2); flex-wrap: wrap; }
.kpi .delta-pos { color: var(--pos); }
.kpi .delta-neg { color: var(--neg); }
.kpi .k-na { color: var(--na); font-family: var(--font-sans); font-size: var(--fs-h2); font-variant-numeric: normal; }

/* ------------------------------------------------------------------ */
/* Баннер §6.6.                                                         */
/* ------------------------------------------------------------------ */
.banner {
  display: flex;
  gap: var(--space-3);
  align-items: center;
  justify-content: space-between;
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-md);
  font-size: var(--fs-small);
}
.banner-warn  { background: var(--warn-bg); color: var(--warn); }
.banner-neg   { background: var(--neg-bg); color: var(--neg); }
.banner-model { background: var(--model-weak); color: var(--model); }
.banner a { color: inherit; font-weight: var(--fw-medium); white-space: nowrap; display: inline-flex; align-items: center; gap: 4px; }
/* T101: ссылка «что сделать» и крестик закрытия — один блок у правого края. */
.banner-actions { display: inline-flex; align-items: center; gap: var(--space-2); flex: none; }
/* T101: `.banner { display: flex }` выше иначе перебивает встроенное правило браузера
   `[hidden] { display: none }` (тот же селектор по специфичности, но объявлен раньше) —
   без этой строки `el.hidden = true` (app.js, закрытие крестиком) ничего не прячет. */
.banner[hidden] { display: none; }

/* ------------------------------------------------------------------ */
/* Пустое состояние §6.3.                                               */
/* ------------------------------------------------------------------ */
.empty-state {
  padding: var(--space-6) var(--space-4);
  text-align: center;
  color: var(--text-muted);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
}
.empty-state-title { font-size: var(--fs-h3); font-weight: var(--fw-semibold); color: var(--text); }
.empty-state-reason { margin: 0; max-width: var(--measure); }

/* ------------------------------------------------------------------ */
/* Четыре состояния данных (I6) — .num уже задан в tokens.css.          */
/* ------------------------------------------------------------------ */
.amount-warn { color: var(--warn); }
[data-value-state="na"] { font-family: var(--font-sans); font-variant-numeric: normal; }

/* ------------------------------------------------------------------ */
/* Иконка §7 — инлайн SVG вместо текстовых стрелок/эмодзи.              */
/* ------------------------------------------------------------------ */
.icon { display: inline-block; vertical-align: -2px; flex: none; }
/* Приёмка фазы 10: на пульте действует правило графиков
   `.dashboard-scope svg { width: 100% }` — оно растягивало иконку внутри карточки
   до размера карточки (923 px вместо 14). Иконка всегда размером со свой атрибут,
   селектор такой же специфичности, но объявлен позже. */
.dashboard-scope svg.icon { width: auto; height: auto; display: inline-block; }

/* ------------------------------------------------------------------ */
/* Полоса доли §6.9 — вес строки внутри уже показанного столбца чисел.  */
/* Ширину задаёт сервер атрибутом style="width: N%" — это единственный  */
/* разрешённый инлайн-стиль (§11): считать долю в CSS нечем.            */
/* ------------------------------------------------------------------ */
.share-bar {
  display: block;
  height: var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--brand);
  min-width: var(--space-1);
}

/* ------------------------------------------------------------------ */
/* Панель вкладок экрана §6.10 (T103a) — «листы книги» внутри страницы. */
/* Разметку первой вкладки рисует сервер (templates/components/_tabbar.html), */
/* остальные добавляет static/tabs.js. Пока вкладка одна, полосы не видно —  */
/* без JS на экране не появляется ничего лишнего.                            */
/* ------------------------------------------------------------------ */
.tabbar {
  display: flex;
  align-items: stretch;
  gap: var(--space-1);
  margin-bottom: var(--space-3);
  border-bottom: var(--border-w) solid var(--border);
  /* XS и любая узкая ширина: полоса прокручивается ВНУТРИ себя, страница по
     горизонтали не прокручивается никогда (02-САЙТ-И-ЭКРАНЫ.md §8, правило 1). */
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
}
.tabbar[data-tab-count="1"] { display: none; }

.tabbar-item {
  display: inline-flex;
  align-items: center;
  flex: none;
  max-width: 24ch;
  border-bottom: 2px solid transparent;
  margin-bottom: calc(var(--border-w) * -1);
  border-radius: var(--radius-sm) var(--radius-sm) 0 0;
}
.tabbar-item:hover { background: var(--surface-2); }
.tabbar-item-active { background: var(--surface); border-bottom-color: var(--brand); }

.tabbar-tab {
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
  min-height: var(--nav-item-h);
  padding: 0 var(--space-3);
  max-width: 100%;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--text-muted);
  font: inherit;
  font-size: var(--fs-small);
}
.tabbar-item-active .tabbar-tab { color: var(--text); font-weight: var(--fw-medium); }
.tabbar-tab-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Несохранённый фильтр §6.10 — точка перед подписью, смысл продублирован в
   `title` кнопки (одним цветом состояние не кодируем, система §9). */
.tabbar-item-dirty .tabbar-tab-label::before {
  content: "";
  display: inline-block;
  width: var(--space-2);
  height: var(--space-2);
  margin-right: var(--space-2);
  border-radius: var(--radius-full);
  background: var(--warn);
}

.tabbar-close {
  display: inline-flex;
  align-items: center;
  padding: 0 var(--space-2) 0 0;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--text-muted);
}
.tabbar-close:hover { color: var(--neg); }

/* Панели вкладок: показана всегда ровно одна (tabs.js ставит `hidden`
   остальным), поэтому у контейнера нет своей раскладки — содержимое экрана
   ведёт себя так же, как без вкладок. */
.page-body[hidden] { display: none; }

/* Сенсорный ввод — тап-цель кнопок и плиток не меньше 44px (см. tokens.css). */
@media (pointer: coarse) {
  .btn { min-width: 44px; }
}

/* ------------------------------------------------------------------ */
/* Вкладки карточки §6.11 (T103b) — разделы ОДНОЙ записи (шаблон D): «Движения»/
/* «Закупки»/«Продажи»/«Эталон» у позиции, «Операции»/«Реквизиты» у контрагента. */
/* НЕ путать с .tabbar выше (открытые страницы) и .settings-tabs (соседние     */
/* экраны) — третий, независимый вид, докстринг 01-ДИЗАЙН-СИСТЕМА.md §6.11.    */
/* Без JS: группа радиокнопок вне видимой разметки + CSS ":checked ~" — тот же  */
/* приём, что чекбокс переключателя меню в base.html. Все разделы рендерятся   */
/* сразу, переключение только прячет/показывает CSS.                           */
/* ------------------------------------------------------------------ */
.card-tabs-input {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

.card-tabs-nav {
  display: flex;
  gap: var(--space-1);
  margin-bottom: var(--space-3);
  border-bottom: var(--border-w) solid var(--border);
  overflow-x: auto;
  overflow-y: hidden;
  scrollbar-width: thin;
}

.card-tab {
  display: inline-flex;
  align-items: center;
  flex: none;
  min-height: var(--nav-item-h);
  padding: 0 var(--space-3);
  border-bottom: 2px solid transparent;
  margin-bottom: calc(var(--border-w) * -1);
  color: var(--text-muted);
  font-size: var(--fs-small);
  cursor: pointer;
}
.card-tab:hover { color: var(--text); }

.card-tabs-panel { display: none; }

.card-tabs-input:nth-of-type(1):checked ~ .card-tabs-nav .card-tab:nth-child(1),
.card-tabs-input:nth-of-type(2):checked ~ .card-tabs-nav .card-tab:nth-child(2),
.card-tabs-input:nth-of-type(3):checked ~ .card-tabs-nav .card-tab:nth-child(3),
.card-tabs-input:nth-of-type(4):checked ~ .card-tabs-nav .card-tab:nth-child(4) {
  color: var(--text);
  background: var(--surface);
  border-bottom-color: var(--brand);
  font-weight: var(--fw-medium);
}

.card-tabs-input:nth-of-type(1):checked ~ .card-tabs-panel:nth-of-type(1),
.card-tabs-input:nth-of-type(2):checked ~ .card-tabs-panel:nth-of-type(2),
.card-tabs-input:nth-of-type(3):checked ~ .card-tabs-panel:nth-of-type(3),
.card-tabs-input:nth-of-type(4):checked ~ .card-tabs-panel:nth-of-type(4) {
  display: block;
}

/* Клавиатура (§9.2): кольцо фокуса на подписи активного по Tab радио, само
   радио визуально скрыто выше. */
.card-tabs-input:nth-of-type(1):focus-visible ~ .card-tabs-nav .card-tab:nth-child(1),
.card-tabs-input:nth-of-type(2):focus-visible ~ .card-tabs-nav .card-tab:nth-child(2),
.card-tabs-input:nth-of-type(3):focus-visible ~ .card-tabs-nav .card-tab:nth-child(3),
.card-tabs-input:nth-of-type(4):focus-visible ~ .card-tabs-nav .card-tab:nth-child(4) {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
}

/* ===== T130a: графики и навигация ===== */
/* Компоненты §6.12–§6.18 01-ДИЗАЙН-СИСТЕМА.md: карточка-график, ползунок периода,
   окно графика на весь экран, карточка-слот, вкладки направления, полоска сальдо,
   переключатель периода страницы, спарклайн. Поведение — static/charts.js, данные —
   src/finkontur/app/charts.py. Только токены (tokens.css, раздел «Графики и
   навигация»); все классы раздела начинаются с chart-/ch-/ps-/cm-/slot-/dir-/
   balance-/period-switch-/sparkline — пересечений с разделом T130b нет. */

/* Только для чтения с экрана (подписи полей дат окна графика). */
.ch-sr {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0, 0, 0, 0); white-space: nowrap; border: 0;
}

/* --- Роли рядов §2.4: цвет приходит одной переменной --ch-color, стиль линии —
       отдельно, чтобы ряды различались не только цветом (§9.5). --- */
.ch-s-fact     { --ch-color: var(--series-fact); }
.ch-s-model    { --ch-color: var(--series-model); }
.ch-s-cash     { --ch-color: var(--series-cash); }
.ch-s-accrual  { --ch-color: var(--series-accrual); }
.ch-s-prev     { --ch-color: var(--series-prev); }
.ch-s-neutral  { --ch-color: var(--series-neutral); }
.ch-s-signed,
.ch-s-pos      { --ch-color: var(--series-pos); }
.ch-s-neg      { --ch-color: var(--series-neg); }

.ch-line {
  fill: none; stroke: var(--ch-color); stroke-width: 2;
  stroke-linejoin: round; stroke-linecap: round;
}
.ch-s-model .ch-line   { stroke-dasharray: 6 4; stroke-width: 1.75; }
.ch-s-cash .ch-line    { stroke-width: 1.5; }
.ch-s-accrual .ch-line { stroke-dasharray: 8 3 2 3; stroke-width: 1.75; }
.ch-s-prev .ch-line    { stroke-dasharray: 2 3; stroke-width: 1.5; }
.ch-bar { fill: var(--ch-color); }
.ch-point { fill: var(--ch-color); }
.ch-hatch-bg { fill: var(--ch-color); opacity: .16; }
.ch-hatch-line { stroke: var(--ch-color); stroke-width: 2; }
.ch-bar-partial { stroke: var(--ch-color); stroke-width: 1; }

.ch-grid line { stroke: var(--chart-grid); stroke-width: 1; }
.ch-zero { stroke: var(--chart-zero); stroke-width: 1.5; }
.ch-axis text, .ch-axis-unit {
  fill: var(--chart-axis-text); font-family: var(--font-num);
  font-size: var(--fs-caption); font-variant-numeric: tabular-nums;
}
.ch-axis .ch-axis-sub { fill: var(--text-faint); }
.ch-value-label {
  fill: var(--text); font-family: var(--font-num); font-size: var(--fs-caption);
  font-weight: var(--fw-medium); font-variant-numeric: tabular-nums;
}
.ch-s-signed .ch-value-label, .ch-s-pos .ch-value-label, .ch-s-neg .ch-value-label { fill: var(--ch-color); }
.ch-norm { stroke: var(--series-model); stroke-width: 1.5; stroke-dasharray: 6 4; fill: none; }
.ch-norm-label { fill: var(--series-model); font-size: var(--fs-caption); font-family: var(--font-sans); }
.ch-cursor { stroke: var(--chart-cursor); stroke-width: 1; stroke-dasharray: 3 3; }
.ch-hover-band { fill: var(--surface-2); }
.ch-dot { fill: var(--ch-color); stroke: var(--surface); stroke-width: 2; }
.ch-empty-text { fill: var(--text-muted); font-size: var(--fs-small); font-family: var(--font-sans); }

/* Подсказка перекрестья: дата и значения всех рядов (§6.12). */
.chart-tip {
  position: absolute; z-index: var(--z-sticky); pointer-events: none;
  min-width: 11rem; max-width: min(20rem, 90%);
  padding: var(--space-2) var(--space-3);
  background: var(--chart-tip-bg); color: var(--text);
  border: var(--border-w) solid var(--chart-tip-border); border-radius: var(--radius-md);
  box-shadow: var(--chart-tip-shadow); font-size: var(--fs-caption); line-height: var(--lh-caption);
}
.chart-tip[hidden] { display: none; }
.chart-tip-date { font-weight: var(--fw-semibold); margin-bottom: var(--space-1); }
.chart-tip-row { display: flex; align-items: center; gap: var(--space-2); }
.chart-tip-row .ch-swatch { flex: none; }
.chart-tip-label { flex: 1 1 auto; color: var(--text-muted); }
.chart-tip-value { font-family: var(--font-num); font-variant-numeric: tabular-nums; white-space: nowrap; }
.chart-tip-value.amount-na { color: var(--na); font-family: var(--font-sans); }
.chart-tip-note { color: var(--text-muted); margin-top: var(--space-1); }

/* --- 6.12 Карточка-график ------------------------------------------------ */
.chart-card {
  position: relative; display: flex; flex-direction: column; gap: var(--space-3);
  min-width: 0; background: var(--card-bg); border: var(--border-w) solid var(--card-border);
  border-radius: var(--card-radius); box-shadow: var(--card-shadow); padding: var(--card-padding);
}
.chart-card-error { border-color: var(--neg); }
.chart-card-lg { grid-column: 1 / -1; }
.chart-card-head { display: flex; align-items: flex-start; gap: var(--space-3); flex-wrap: wrap; }
.chart-card-heading { flex: 1 1 12rem; min-width: 0; }
.chart-card-title { margin: 0; font-size: var(--fs-h3); line-height: var(--lh-h3); font-weight: var(--fw-semibold); }
.chart-card-value { margin-top: var(--space-1); }
.chart-card-value .num {
  font-size: var(--fs-kpi); line-height: var(--lh-kpi); font-weight: var(--kpi-value-weight); text-align: left;
}
.chart-card-value .caption, .chart-state .caption { font-size: var(--fs-caption); color: var(--text-muted); }
.chart-card-note { margin-top: var(--space-1); font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--text-muted); }
.chart-lens { color: var(--kpi-lens-color); }
.chart-expand { flex: none; margin-left: auto; }
.chart-expand[disabled] { opacity: .55; cursor: not-allowed; }

.chart-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); }
.chart-toolbar[hidden] { display: none; }
.chart-toolbar-dates { font-size: var(--fs-small); color: var(--text-muted); text-align: left; }

/* Сегменты «быстрый период» и «шаг» — группа кнопок с aria-pressed. */
.ch-seg {
  display: inline-flex; flex-wrap: nowrap; max-width: 100%; overflow-x: auto; scrollbar-width: thin;
  border: var(--border-w) solid var(--border-strong); border-radius: var(--radius-md);
  background: var(--surface);
}
.ch-seg-btn {
  flex: none; min-height: var(--control-h-sm); padding: 0 var(--space-3);
  border: 0; border-right: var(--border-w) solid var(--border); background: transparent;
  color: var(--text-muted); font: inherit; font-size: var(--fs-small); cursor: pointer; white-space: nowrap;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.ch-seg-btn:last-child { border-right: 0; }
.ch-seg-btn:hover { background: var(--surface-2); color: var(--text); }
.ch-seg-btn[aria-pressed="true"] { background: var(--brand-weak); color: var(--brand); font-weight: var(--fw-medium); }
.ch-seg-btn:focus-visible { outline-offset: -2px; }

.chart-plot { position: relative; height: var(--chart-h); min-width: 0; }
.chart-card-lg .chart-plot { height: var(--chart-h-lg); }
.chart-plot > svg { display: block; width: 100%; height: 100%; overflow: visible; }
.chart-plot:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--radius-sm); }

/* Ожидание (§5, §8): скелет появляется, только если отрисовка задержалась на 300 ms. */
.chart-skeleton {
  position: absolute; inset: 0; border-radius: var(--radius-sm);
  background: repeating-linear-gradient(to top, var(--chart-skeleton) 0 var(--space-2), transparent var(--space-2) var(--space-6));
  opacity: 0; animation: ch-skeleton-in var(--dur-base) var(--ease-out) 300ms forwards;
}
@keyframes ch-skeleton-in { to { opacity: 1; } }
.chart-loading-text { margin: 0; }

.chart-plot-state { height: auto; min-height: var(--chart-h); display: flex; align-items: center; justify-content: center; }
.chart-card-lg .chart-plot-state { min-height: var(--chart-h-lg); }
.chart-state {
  display: flex; flex-direction: column; align-items: center; gap: var(--space-2);
  text-align: center; padding: var(--space-4); max-width: var(--measure);
}
.chart-state-title {
  display: inline-flex; align-items: baseline; gap: var(--space-2); flex-wrap: wrap; justify-content: center;
  font-size: var(--fs-body); font-weight: var(--fw-semibold); color: var(--text);
}
.chart-state-title .num { font-size: var(--fs-h2); }
.chart-state-sub { font-size: var(--fs-small); font-weight: var(--fw-regular); color: var(--text-muted); }
.chart-state-error { color: var(--neg); align-items: center; }
.chart-state-text { margin: 0; font-size: var(--fs-small); color: var(--text-muted); }

.chart-legend {
  display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); margin: 0; padding: 0; list-style: none;
  font-size: var(--fs-caption); color: var(--text-muted);
}
.chart-legend-item { display: inline-flex; align-items: center; gap: var(--space-2); }
.ch-swatch { display: inline-block; flex: none; overflow: visible; }
.ch-swatch-bar { fill: var(--ch-color); }

/* --- 6.34 Волна пунктиром ------------------------------------------------- */
.chart-wave-note { margin: var(--space-1) 0 0; font-size: var(--fs-caption); color: var(--text-muted); }

/* --- 6.33 Выбор линий графика ---------------------------------------------- */
.line-picker { position: relative; margin-top: var(--space-2); font-size: var(--fs-caption); }
.line-picker-summary {
  display: inline-flex; align-items: center; gap: var(--space-1); cursor: pointer; list-style: none;
  padding: var(--space-1) var(--space-2); border: var(--border-w) solid var(--border); border-radius: var(--radius-sm);
  color: var(--text-muted);
}
.line-picker-summary::-webkit-details-marker { display: none; }
.line-picker-summary:hover { color: var(--text); border-color: var(--border-strong); }
.line-picker-summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.line-picker-panel {
  position: absolute; z-index: 5; top: calc(100% + var(--space-1)); left: 0; min-width: 16rem; max-width: 20rem;
  background: var(--card-bg); border: var(--border-w) solid var(--card-border); border-radius: var(--card-radius);
  box-shadow: var(--shadow-2); padding: var(--space-3);
}
.line-picker-list { max-height: 16rem; overflow: auto; margin: 0 0 var(--space-2); padding: 0; list-style: none; }
.line-picker-item + .line-picker-item { margin-top: var(--space-1); }
.line-picker-label { display: flex; align-items: center; gap: var(--space-2); cursor: pointer; min-height: 1.75rem; }
.line-picker-label-disabled { color: var(--text-faint); cursor: not-allowed; }
.line-picker-hint { margin: 0 0 var(--space-2); color: var(--warn); }
@media (max-width: 767px) {
  /* Г7: узкий экран — список линий окном на весь экран, не выпадашкой у края
     карточки (некуда прокручивать вместе со страницей, §6.33). */
  .line-picker[open] .line-picker-panel {
    position: fixed; inset: 0; z-index: var(--z-modal, 50); top: 0; left: 0; right: 0; bottom: 0;
    max-width: none; min-width: 0; border-radius: 0; box-shadow: none;
    overflow-y: auto; padding: var(--space-4);
  }
  .line-picker[open] .line-picker-list { max-height: none; }
  .line-picker-label { min-height: 44px; }
}

.chart-table > summary {
  display: inline-flex; cursor: pointer; font-size: var(--fs-small); color: var(--brand); list-style: none;
}
.chart-table > summary::-webkit-details-marker { display: none; }
.chart-table > summary:hover { text-decoration: underline; }
.chart-table-scroll { overflow: auto; max-height: 20rem; margin-top: var(--space-2); }
.chart-data { width: 100%; border-collapse: collapse; font-size: var(--fs-small); }
.chart-data th, .chart-data td {
  padding: var(--table-cell-py) var(--table-cell-px); border-bottom: var(--border-w) solid var(--table-border);
  text-align: left; white-space: nowrap;
}
.chart-data thead th {
  position: sticky; top: 0; background: var(--table-head-bg); font-size: var(--table-head-size);
  font-weight: var(--fw-medium); color: var(--text-muted);
}
.chart-data th[scope="row"] { font-weight: var(--fw-regular); }
.chart-data .num { text-align: right; }

/* --- 6.13 Ползунок периода ----------------------------------------------- */
.period-slider { position: relative; font-size: var(--fs-caption); color: var(--text-muted); user-select: none; }
.ps-track {
  position: relative; height: var(--slider-handle);
  margin: 0 calc(var(--slider-handle) / 2); touch-action: none; cursor: pointer;
}
.ps-track::before {
  content: ""; position: absolute; left: 0; right: 0; top: 50%; height: var(--slider-track-h);
  transform: translateY(-50%); border-radius: var(--radius-full); background: var(--border-strong);
}
.ps-range {
  position: absolute; top: 50%; height: var(--slider-track-h); transform: translateY(-50%);
  left: var(--ps-a); width: calc(var(--ps-b) - var(--ps-a)); min-width: 2px;
  border-radius: var(--radius-full); background: var(--slider-fill); cursor: grab;
}
.ps-handle {
  position: absolute; top: 50%; left: var(--ps-a); z-index: 1;
  width: var(--slider-handle); height: var(--slider-handle); transform: translate(-50%, -50%);
  border-radius: var(--radius-full); background: var(--surface); border: 2px solid var(--slider-fill);
  cursor: grab; touch-action: none;
  transition: border-color var(--dur-fast) var(--ease-out);
}
.ps-handle-to { left: var(--ps-b); }
/* Тап-цель ≥ 44 × 44 (§4.3): прозрачное поле вокруг видимой ручки. */
.ps-handle::after {
  content: ""; position: absolute; left: 50%; top: 50%;
  width: var(--slider-hit); height: var(--slider-hit); transform: translate(-50%, -50%);
}
.ps-handle:hover { border-color: var(--brand-hover); }
.ps-handle:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; border-radius: var(--radius-full); }
.ps-handle.is-dragging, .period-slider.is-dragging .ps-range { cursor: grabbing; }
.ps-handle-label {
  position: absolute; left: 50%; bottom: calc(100% + var(--space-1)); transform: translateX(-50%);
  padding: 0 var(--space-1); border-radius: var(--radius-sm); background: var(--surface-raised);
  color: var(--text); font-family: var(--font-num); font-size: var(--fs-caption); white-space: nowrap;
  opacity: 0; pointer-events: none; transition: opacity var(--dur-fast) var(--ease-out);
}
.ps-handle:focus-visible .ps-handle-label, .ps-handle.is-dragging .ps-handle-label,
.ps-handle:hover .ps-handle-label { opacity: 1; }
.ps-ends { display: flex; justify-content: space-between; margin-top: var(--space-1); color: var(--text-faint); font-family: var(--font-num); }
.ps-custom { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-1) var(--space-2); margin-top: var(--space-1); color: var(--text-muted); }
.ps-custom[hidden] { display: none; }
.ps-reset {
  padding: 0; border: 0; background: none; font: inherit; color: var(--brand); cursor: pointer;
  text-decoration: underline; text-underline-offset: 2px;
}
.ps-reset:hover { color: var(--brand-hover); }
.period-slider.is-disabled .ps-range { opacity: .55; cursor: default; }
.period-slider.is-disabled .ps-track { cursor: default; }

/* Крупный вариант: дорожка — мини-график всей истории, отрезок подсвечен,
   ручки — вертикальные планки по краям отрезка, их даты всегда видны. */
.period-slider-lg { padding-top: calc(var(--lh-caption) + var(--space-2)); }
/* Мини-график лежит НАД подсветкой отрезка (иначе подсветка прячет историю), но
   пропускает мышь к отрезку под собой — его можно тянуть целиком. */
.period-slider-lg .ps-mini {
  position: relative; z-index: 1; pointer-events: none;
  height: var(--slider-mini-h); border-bottom: var(--border-w) solid var(--border-strong);
}
.period-slider-lg .ps-mini > svg { display: block; width: 100%; height: 100%; }
.ps-mini .ch-bar { fill: var(--text-faint); }
.ps-mini .ch-line { stroke: var(--text-faint); stroke-width: 1.5; stroke-dasharray: none; }
.period-slider-lg .ps-track {
  position: absolute; left: 0; right: 0; margin: 0;
  top: calc(var(--lh-caption) + var(--space-2)); height: var(--slider-mini-h);
}
.period-slider-lg .ps-track::before { display: none; }
.period-slider-lg .ps-range {
  top: 0; height: 100%; transform: none; border-radius: 0; background: var(--slider-band);
  border-left: var(--border-w) solid var(--slider-fill); border-right: var(--border-w) solid var(--slider-fill);
}
.period-slider-lg .ps-handle {
  top: 50%; width: var(--space-3); height: 70%; border-radius: var(--radius-sm);
}
.period-slider-lg .ps-handle:focus-visible { border-radius: var(--radius-sm); }
/* Положение дат по горизонтали раскладывает charts.js (PeriodSlider.layoutLabels):
   не за краем ползунка и не друг на друге. */
.period-slider-lg .ps-handle-label { opacity: 1; bottom: auto; top: calc(-1 * (var(--lh-caption) + var(--space-2)) - 15%); }
.ps-months { position: relative; height: var(--lh-caption); margin-top: var(--space-1); color: var(--text-muted); }
.ps-months span { position: absolute; top: 0; white-space: nowrap; transform: translateX(-50%); }
.ps-months span:first-child { transform: none; }
.period-slider-lg.has-months .ps-ends { display: none; }

/* --- 6.14 Окно графика на весь экран ------------------------------------ */
/* <dialog> во весь экран прозрачный: цвет и размытие фона — свой слой внутри
   (custom-свойства в ::backdrop наследуются не во всех браузерах). */
.chart-modal {
  position: fixed; inset: 0; width: 100%; height: 100%; max-width: none; max-height: none;
  margin: 0; padding: 0; border: 0; background: transparent; color: var(--text); overflow: hidden;
}
.chart-modal::backdrop { background: transparent; }
.chart-modal-backdrop {
  position: fixed; inset: 0; background: var(--overlay);
  -webkit-backdrop-filter: blur(var(--overlay-blur)); backdrop-filter: blur(var(--overlay-blur));
}
.chart-modal-window {
  position: fixed; inset: var(--modal-gap); margin: 0 auto; max-width: var(--content-max);
  display: flex; flex-direction: column; gap: var(--space-4); overflow: auto;
  padding: var(--space-5); background: var(--surface); border-radius: var(--modal-radius);
  box-shadow: var(--modal-shadow); border: var(--border-w) solid var(--border);
}
.chart-modal[open] .chart-modal-window { animation: cm-in var(--dur-enter) var(--ease-out); }
.chart-modal[open] .chart-modal-backdrop { animation: cm-fade var(--dur-enter) var(--ease-out); }
@keyframes cm-in { from { opacity: 0; transform: translateY(var(--space-2)) scale(.98); } }
@keyframes cm-fade { from { opacity: 0; } }
/* Шапка окна: название и «свернуть/закрыть» — первой строкой всегда (кнопки в углу,
   как на эскизе 03), панель периодов — под ними; на широком экране — одной строкой. */
.chart-modal-head {
  display: grid; grid-template-columns: minmax(0, 1fr) auto; align-items: start;
  grid-template-areas: "heading actions" "tools tools"; gap: var(--space-3) var(--space-5);
}
.chart-modal-heading { grid-area: heading; min-width: 0; }
.chart-modal-subject { font-size: var(--fs-small); color: var(--text-muted); }
.chart-modal-title { margin: 0; font-size: var(--fs-h2); line-height: var(--lh-h2); font-weight: var(--fw-semibold); }
.chart-modal-value .num { font-size: var(--fs-kpi-lg); line-height: var(--lh-kpi-lg); text-align: left; }
.chart-modal-value .caption { font-size: var(--fs-caption); color: var(--text-muted); }
.chart-modal-note { font-size: var(--fs-small); color: var(--text-muted); }
.chart-modal-tools { grid-area: tools; display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); min-width: 0; }
@media (min-width: 1280px) {
  .chart-modal-head { grid-template-columns: minmax(0, 1fr) auto auto; grid-template-areas: "heading tools actions"; }
  .chart-modal-tools { justify-content: flex-end; }
}
.chart-modal-dates {
  display: inline-flex; align-items: center; gap: var(--space-2); color: var(--text-muted);
  padding: 0 var(--space-3); min-height: var(--control-h-sm);
  border: var(--border-w) solid var(--border-strong); border-radius: var(--radius-md); background: var(--surface);
}
.cm-date {
  border: 0; background: transparent; color: var(--text); font-family: var(--font-num);
  font-size: var(--fs-small); padding: var(--space-1) 0; min-width: 0;
}
.chart-modal-actions { grid-area: actions; display: grid; grid-template-columns: auto auto; align-items: center; gap: var(--space-1) var(--space-2); }
.chart-modal-esc { grid-column: 2; text-align: center; font-size: var(--fs-caption); color: var(--text-faint); }
.chart-modal-legend { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-5); font-size: var(--fs-small); }
.cm-legend-item { display: inline-flex; align-items: center; gap: var(--space-2); cursor: pointer; color: var(--text); }
.cm-legend-item input { margin: 0; accent-color: var(--brand); width: var(--space-4); height: var(--space-4); }
.cm-legend-item input:disabled + .ch-swatch + span { color: var(--text-muted); }
.chart-modal-plotwrap { position: relative; flex: 1 1 auto; min-height: var(--chart-h-modal); }
.chart-plot-modal { position: absolute; inset: 0; height: auto; }
.chart-modal-slider { flex: none; }
.chart-modal-totals {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(9rem, 1fr)); gap: var(--space-3) var(--space-5);
  margin: 0; padding-top: var(--space-4); border-top: var(--border-w) solid var(--border);
}
.chart-modal-totals div { min-width: 0; }
.chart-modal-totals dt { font-size: var(--fs-caption); color: var(--text-muted); }
.chart-modal-totals dd { margin: 0; font-size: var(--fs-h3); line-height: var(--lh-h3); }
.chart-modal-totals dd .num { text-align: left; }
.chart-modal-totals .cm-total-sub { display: block; font-size: var(--fs-caption); color: var(--text-muted); }
.chart-modal-totals .delta-pos { color: var(--pos); }
.chart-modal-totals .delta-neg { color: var(--neg); }

/* --- 6.15 Карточка-слот ------------------------------------------------- */
.slot-card {
  position: relative; display: flex; flex-direction: column; gap: var(--slot-gap); min-width: 0;
  background: var(--card-bg); border: var(--border-w) solid var(--card-border); border-radius: var(--card-radius);
  box-shadow: var(--card-shadow); padding: var(--card-padding);
  transition: border-color var(--dur-fast) var(--ease-out);
}
.slot-card:hover { border-color: var(--brand); }
.slot-card:has(.slot-card-link:focus-visible) { outline: 2px solid var(--focus); outline-offset: 2px; }
.slot-card-head { display: flex; align-items: center; gap: var(--space-2); }
.slot-card-icon { display: inline-flex; color: var(--text); flex: none; }
.slot-card-title { margin: 0; flex: 1 1 auto; min-width: 0; font-size: var(--fs-h3); line-height: var(--lh-h3); font-weight: var(--fw-semibold); }
.slot-card-link { color: inherit; text-decoration: none; }
/* Вся карточка — одна ссылка: слой заголовка растянут на карточку. */
.slot-card-link::after { content: ""; position: absolute; inset: 0; border-radius: inherit; }
.slot-card-link:focus-visible { outline: none; }
.slot-card-arrow { display: inline-flex; color: var(--brand); flex: none; transition: transform var(--dur-fast) var(--ease-out); }
.slot-card:hover .slot-card-arrow { transform: translateX(var(--space-1)); }
.slot-card-body { display: flex; flex-direction: column; gap: var(--space-2); flex: 1 1 auto; }
.slot-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); font-size: var(--fs-small); margin: 0; }
.slot-row-label { color: var(--text-muted); }
.slot-row-value { text-align: right; }
.slot-row-value .caption { display: block; font-size: var(--fs-caption); color: var(--text-muted); }
.slot-row-total { font-weight: var(--fw-semibold); padding-top: var(--space-2); border-top: var(--border-w) solid var(--border-strong); }
.slot-row-total .slot-row-label { color: var(--text); }
.slot-row-lead { justify-content: flex-start; align-items: baseline; gap: var(--space-2); flex-wrap: wrap; }
.slot-row-lead .num { font-size: var(--fs-kpi); line-height: var(--lh-kpi); text-align: left; }
.slot-row-lead .caption { font-size: var(--fs-caption); color: var(--text-muted); }
.slot-lead-label { font-size: var(--fs-body); color: var(--text); }
.slot-row-warn { justify-content: flex-start; align-items: center; gap: var(--space-2); color: var(--warn); }
.slot-row-note { justify-content: flex-start; font-size: var(--fs-caption); color: var(--text-muted); }
.slot-card-action { position: relative; z-index: 1; display: inline-flex; align-items: center; justify-content: center; gap: var(--space-2); width: 100%; margin-top: auto; }

/* --- 6.16 Вкладки направления ------------------------------------------- */
.dir-tabs {
  display: flex; gap: var(--space-1); margin-bottom: var(--space-4);
  border-bottom: var(--border-w) solid var(--border);
  overflow-x: auto; overflow-y: hidden; scrollbar-width: thin;
}
.dir-tab {
  flex: none; display: inline-flex; align-items: center; min-height: var(--nav-item-h);
  padding: 0 var(--space-3); margin-bottom: calc(var(--border-w) * -1);
  border-bottom: 2px solid transparent; border-radius: var(--radius-sm) var(--radius-sm) 0 0;
  color: var(--text-muted); font-size: var(--fs-small); white-space: nowrap; text-decoration: none;
  transition: background var(--dur-fast) var(--ease-out), color var(--dur-fast) var(--ease-out);
}
.dir-tab:hover { color: var(--text); background: var(--surface-2); }
.dir-tab-active { color: var(--text); font-weight: var(--fw-medium); border-bottom-color: var(--brand); }
.dir-tab-off { text-decoration: underline dashed var(--border-strong); text-underline-offset: var(--space-1); }
.dir-tab-active.dir-tab-off { text-decoration: none; }

/* --- 6.17 Полоска сальдо ------------------------------------------------ */
.balance { display: flex; align-items: center; gap: var(--space-3); min-width: 0; }
.balance-track { display: flex; align-items: center; flex: 1 1 var(--space-8); min-width: var(--space-7); }
.balance-half { display: flex; flex: 1 1 0; min-width: 0; }
.balance-half-neg { justify-content: flex-end; }
.balance-axis { flex: none; width: var(--border-w); height: calc(var(--balance-bar-h) * 2.5); background: var(--chart-zero); }
.balance-bar { display: block; height: var(--balance-bar-h); width: var(--bb-w); min-width: var(--space-1); }
.balance-bar-neg { background: var(--balance-neg); border-radius: var(--radius-sm) 0 0 var(--radius-sm); }
.balance-bar-pos { background: var(--balance-pos); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.balance-text { display: flex; flex-direction: column; align-items: flex-end; flex: none; min-width: var(--space-8); text-align: right; }
.balance-amount { font-size: var(--fs-small); color: var(--text); }
.balance-caption { font-size: var(--fs-caption); line-height: var(--lh-caption); color: var(--text-muted); }
.balance-na .num { font-size: var(--fs-small); }

/* --- 6.18 Переключатель периода страницы -------------------------------- */
.period-switch { position: relative; display: inline-block; }
.period-switch > summary { list-style: none; }
.period-switch > summary::-webkit-details-marker { display: none; }
.period-switch-btn { display: inline-flex; align-items: center; gap: var(--space-2); cursor: pointer; }
.period-switch[open] .period-switch-btn svg { transform: rotate(180deg); }
.period-switch-panel {
  position: absolute; right: 0; top: calc(100% + var(--space-1)); z-index: var(--z-sticky);
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3) var(--space-4);
  min-width: min(28rem, calc(100vw - var(--space-6))); padding: var(--space-3);
  background: var(--surface-raised); border: var(--border-w) solid var(--border);
  border-radius: var(--radius-md); box-shadow: var(--shadow-2);
}
.period-switch-title { font-size: var(--fs-caption); font-weight: var(--fw-medium); color: var(--text-muted); margin-bottom: var(--space-1); }
.period-switch-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.period-switch-item {
  display: block; padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm);
  color: var(--text); text-decoration: none; font-size: var(--fs-small);
}
.period-switch-item:hover { background: var(--surface-2); }
.period-switch-item.is-current { background: var(--brand-weak); color: var(--brand); font-weight: var(--fw-medium); }
.period-switch-custom { grid-column: 1 / -1; display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-2); border-top: var(--border-w) solid var(--border); padding-top: var(--space-3); }
.period-switch-custom .period-switch-title { flex: 1 1 100%; margin: 0; }
.period-switch-fields { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.period-switch-field { display: inline-flex; align-items: center; gap: var(--space-1); font-size: var(--fs-small); color: var(--text-muted); }
.period-switch-field input {
  font-family: var(--font-num); font-size: var(--fs-control); color: var(--text); background: var(--field-bg);
  border: var(--border-w) solid var(--field-border); border-radius: var(--field-radius);
  padding: var(--space-1) var(--space-2); min-height: var(--control-h-sm);
}

/* --- 6.18 Спарклайн ----------------------------------------------------- */
.sparkline { display: block; width: 100%; height: var(--sparkline-h); overflow: visible; }
.sparkline-line {
  fill: none; stroke: var(--sparkline-stroke); stroke-width: 1.5;
  stroke-linejoin: round; stroke-linecap: round; vector-effect: non-scaling-stroke;
}
.sparkline-dot { stroke: var(--sparkline-stroke); stroke-width: 5; stroke-linecap: round; vector-effect: non-scaling-stroke; }
.sparkline-empty { font-size: var(--fs-caption); color: var(--na); min-height: var(--sparkline-h); display: flex; align-items: center; }

/* --- Узкий экран (§8 02-САЙТ-И-ЭКРАНЫ.md) -------------------------------- */
@media (max-width: 767px) {
  .chart-modal-window { inset: var(--space-3); padding: var(--space-4); gap: var(--space-3); }
  .chart-modal-totals { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .chart-toolbar { width: 100%; order: 3; }
}
@media (max-width: 479px) {
  /* Под своей кнопкой (шапка на XS переносится в две строки — от высоты шапки
     отсчитывать нельзя), шириной почти во весь экран, прокрутка внутри. */
  .period-switch-panel {
    position: fixed; top: auto; left: var(--space-3); right: var(--space-3);
    min-width: 0; grid-template-columns: 1fr; max-height: 70vh; overflow: auto;
  }
  .balance-text { min-width: var(--space-7); }

  /* T128 (находка 3): на 360 у карточки «Финансовый результат» (во всю ширину)
     сегмент «Быстрый период» — пять кнопок — не помещался в ширину карточки,
     последняя («Всё время») пряталась за прокруткой без явного намёка на неё
     (`scrollbar-width: thin` на тачскрине не видна вовсе). Перенос в две строки
     вместо горизонтальной прокрутки — все периоды видны сразу, прокрутки нет. */
  .ch-seg { flex-wrap: wrap; max-width: none; }
  .ch-seg-btn { flex: 1 1 auto; border-right: var(--border-w) solid var(--border); }
  .ch-seg-btn:last-child { border-right: 0; }
}
@media (pointer: coarse) {
  .period-switch-item { padding: var(--space-2); }
}
/* ===== T130b: таблицы и операции ===== */
/* §6.19-6.27 01-ДИЗАЙН-СИСТЕМА.md — таблица-список без пагинации, прилипающий
   итог, панель фильтров, сортировка в несколько уровней, окно «Поля»,
   строка-группа операции, «Куда ушло», метка источника, подпись исполнителя.
   Поведение — static/datatable.js. Узкий экран этой карточки — < 768 px
   (не 479, как у старого .journal-table/.data-table T94 — компонент новый,
   контракт фазы 13 §5 явно требует превращение в карточки от 768). */

/* --- 6.19 Таблица-список ------------------------------------------------ */
.dt-scroll {
  overflow-x: auto;
}
/* Панель инструментов над таблицей (фильтры/сортировка/поля/счётчик) — общий
   ряд для экранов волны 2, чтобы каждый не собирал свой inline-style (I13). */
.dt-toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  flex-wrap: wrap;
  margin-bottom: var(--space-3);
}
/* Сторно (§6.24/§07 «журнал», описание экрана README.md) — сумма зачёркнута,
   цвет не единственный носитель смысла: статус рядом несёт плашку chip-rev. */
.dt-reversed-sum { text-decoration: line-through; color: var(--text-muted); }
.dt-impact-heading { margin: var(--space-3) 0 0; font-weight: var(--fw-medium); }
table.dt {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-small);
}
table.dt thead th {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  background: var(--table-head-bg);
  font-size: var(--table-head-size);
  font-weight: var(--fw-medium);
  color: var(--text-muted);
  text-align: left;
  padding: var(--table-cell-py) var(--table-cell-px);
  border-bottom: var(--border-w) solid var(--table-border);
  white-space: nowrap;
}
table.dt thead th.num { text-align: right; }
table.dt tbody td {
  padding: var(--table-cell-py) var(--table-cell-px);
  border-bottom: var(--border-w) solid var(--table-border);
}
table.dt tbody tr:hover { background: var(--table-row-hover); }
table.dt tbody tr[hidden] { display: none; }
.dt-sort-badge {
  display: block;
  color: var(--text-faint);
  font-size: var(--fs-caption);
  font-weight: var(--fw-regular);
  text-transform: none;
}

/* Скелет ожидания (§7 02-САЙТ-И-ЭКРАНЫ.md — появляется после 300 ms, решает
   вызывающий экран/HTMX-фрагмент; здесь только вид штрихов). */
.dt-skeleton-row td {
  padding: var(--space-2) var(--table-cell-px);
}
.dt-skeleton-bar {
  display: block;
  height: var(--space-3);
  border-radius: var(--radius-sm);
  background: var(--dt-skeleton-bg);
}

/* --- 6.20 Итог, прилипающий к низу --------------------------------------- */
.dt-total {
  position: sticky;
  bottom: 0;
  background: var(--dt-total-bg);
  z-index: var(--z-sticky);
}
.dt-total td {
  padding: var(--space-3) var(--table-cell-px);
  border-top: 2px solid var(--dt-total-border);
  font-weight: var(--fw-medium);
}
.dt-total[hidden] { display: none; }
.dt-total-sums { font-weight: var(--fw-regular); }
.dt-total-sum .num { font-weight: var(--fw-medium); }

/* --- 6.21 Панель фильтров ------------------------------------------------ */
.dt-filter { position: relative; display: inline-flex; align-items: center; gap: var(--space-3); }
.dt-filter-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--space-4);
  height: var(--space-4);
  padding: 0 5px;
  margin-left: var(--space-1);
  border-radius: var(--radius-full);
  background: var(--brand);
  color: var(--on-brand);
  font-size: var(--fs-caption);
}
.dt-filter-count[hidden] { display: none; }

.dt-filter-chips { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); }
.dt-filter-chips[hidden] { display: none; }
.dt-filter-chip { display: inline-flex; align-items: center; gap: 4px; }
.dt-filter-chip button {
  display: inline-flex;
  background: none;
  border: 0;
  color: inherit;
  cursor: pointer;
  padding: 0;
}
.dt-filter-reset-all {
  background: none;
  border: 0;
  color: var(--brand);
  font-size: var(--fs-small);
  cursor: pointer;
  padding: 0;
}

.dt-filter-panel {
  position: fixed;
  top: var(--header-h);
  right: 0;
  bottom: 0;
  width: min(22rem, 100%);
  display: flex;
  flex-direction: column;
  background: var(--filter-panel-bg);
  border-left: var(--border-w) solid var(--filter-panel-border);
  box-shadow: var(--shadow-2);
  z-index: var(--z-overlay);
  overflow-y: auto;
}
.dt-filter-panel[hidden] { display: none; }
.dt-filter-panel-head {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-4);
  border-bottom: var(--border-w) solid var(--border);
}
.dt-filter-panel-title { font-size: var(--fs-h3); font-weight: var(--fw-semibold); margin: 0; flex: 1; }
.dt-filter-panel-found { color: var(--text-muted); font-size: var(--fs-small); }
.dt-filter-sections { padding: var(--space-4); display: flex; flex-direction: column; gap: var(--filter-section-gap); flex: 1; }
.dt-filter-section-title { font-size: var(--fs-small); font-weight: var(--fw-medium); margin: 0 0 var(--space-2); }
.dt-filter-options { display: flex; flex-direction: column; gap: var(--space-2); max-height: 40vh; overflow-y: auto; }
.dt-filter-check { display: flex; align-items: center; gap: var(--space-2); font-size: var(--fs-small); cursor: pointer; }
.dt-filter-check[hidden] { display: none; }
.dt-filter-check-label { flex: 1; }
.dt-filter-check-count { color: var(--text-faint); font-family: var(--font-num); font-variant-numeric: tabular-nums; }
.dt-filter-search { width: 100%; margin-bottom: var(--space-2); }
.dt-filter-range { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.dt-filter-range-field { display: flex; align-items: center; gap: var(--space-1); font-size: var(--fs-small); color: var(--text-muted); }
.dt-filter-range-field input { width: 6em; }
.dt-filter-range-unit { color: var(--text-faint); font-size: var(--fs-caption); }
.dt-filter-states { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.dt-filter-state-chip {
  padding: var(--chip-padding);
  border-radius: var(--radius-full);
  border: var(--border-w) solid var(--border-strong);
  background: var(--surface);
  color: var(--text-muted);
  font-size: var(--fs-small);
  cursor: pointer;
}
.dt-filter-state-chip[aria-pressed="true"] {
  background: var(--brand-weak);
  border-color: var(--brand);
  color: var(--brand);
}
.dt-filter-panel-actions {
  display: flex;
  gap: var(--space-2);
  padding: var(--space-4);
  border-top: var(--border-w) solid var(--border);
  background: var(--surface);
  position: sticky;
  bottom: 0;
}
.dt-filter-panel-actions .btn { flex: 1; }

@media (max-width: 767px) {
  .dt-filter-panel { top: 0; width: 100%; }
}

/* --- 6.22 Сортировка в несколько уровней --------------------------------- */
.dt-sort-levels { display: flex; align-items: center; gap: var(--space-2); flex-wrap: nowrap; overflow-x: auto; }
.dt-sort-chip {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  background: var(--sort-chip-bg);
  color: var(--sort-chip-color);
  border-radius: var(--chip-radius);
  padding: 2px var(--space-1) 2px var(--space-2);
  font-size: var(--fs-small);
  white-space: nowrap;
}
.dt-sort-chip-label { background: none; border: 0; color: inherit; font: inherit; cursor: pointer; padding: 0; }
.dt-sort-chip-remove { background: none; border: 0; color: inherit; cursor: pointer; display: inline-flex; padding: 2px; }
.dt-sort-chip-add {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  background: none;
  border: var(--border-w) dashed var(--border-strong);
  border-radius: var(--chip-radius);
  color: var(--text-muted);
  font-size: var(--fs-small);
  padding: 2px var(--space-2);
  cursor: pointer;
}
.dt-sort-arrow { color: var(--text-faint); }
.dt-sort-add { display: inline-flex; align-items: center; gap: var(--space-1); }

.dt-sort-menu,
.dt-columns-menu {
  display: flex;
  flex-direction: column;
  background: var(--columns-menu-bg);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-2);
  padding: var(--space-2);
  /* vw, не % — оба меню позиционируются absolute внутри узкой обёртки-кнопки
     (`.dt-columns-wrap`, ширина по содержимому), и `%` посчитал бы долю ОТ ЭТОЙ
     узкой обёртки, а не разумный размер меню (найдено вживую в браузере при
     проверке карточки: меню сжималось до ~80px). */
  min-width: min(16rem, 90vw);
  z-index: var(--z-overlay);
}
.dt-sort-menu.dt-menu-positioned {
  position: absolute;
  top: var(--dt-menu-top, 0);
  left: var(--dt-menu-left, 0);
}
.dt-sort-menu-item {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  padding: var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--fs-small);
  cursor: pointer;
  color: var(--text);
}
.dt-sort-menu-item:hover { background: var(--surface-2); }

/* --- 6.23 Окно «Поля» ----------------------------------------------------- */
.dt-columns-wrap { position: relative; display: inline-block; }
.dt-columns-menu { position: absolute; right: 0; top: calc(100% + var(--space-1)); width: min(18rem, 90vw); }
.dt-columns-menu[hidden] { display: none; }
.dt-columns-item { display: flex; align-items: center; gap: var(--space-2); padding: var(--space-2); font-size: var(--fs-small); cursor: pointer; }
.dt-columns-item:hover { background: var(--surface-2); border-radius: var(--radius-sm); }

/* --- 6.24 Строка-группа операции ------------------------------------------ */
.dt-group-head { background: var(--dt-group-head-bg); }
.dt-group-toggle-cell { width: 2.5em; }
.dt-group-toggle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--control-h-sm);
  height: var(--control-h-sm);
  background: none;
  border: 0;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  cursor: pointer;
}
.dt-group-toggle:hover { background: var(--surface-2); }
.dt-group-toggle svg { transition: transform var(--dur-base) var(--ease-out); }
.dt-group-toggle[aria-expanded="true"] svg { transform: rotate(90deg); }
.dt-group-detail td { padding: var(--space-3) var(--table-cell-px) var(--space-4) var(--dt-group-detail-indent); background: var(--surface); }
.dt-group-detail[hidden] { display: none; }
table.dt-nested { width: 100%; border-collapse: collapse; font-size: var(--fs-small); }
table.dt-nested th, table.dt-nested td { padding: var(--space-1) var(--table-cell-px); text-align: left; }
table.dt-nested th.num, table.dt-nested td.num { text-align: right; }
table.dt-nested thead th { color: var(--text-muted); font-weight: var(--fw-medium); font-size: var(--fs-caption); }

/* --- 6.25 «Куда ушло» ------------------------------------------------------ */
.dt-impact-list { list-style: none; margin: var(--space-3) 0 0; padding: 0; display: flex; gap: var(--space-3); }
.dt-impact-list-column { flex-direction: column; }
.dt-impact-list-row { flex-direction: row; flex-wrap: wrap; overflow-x: auto; }
.dt-impact-item { flex: 1; min-width: 11rem; }
.dt-impact-list-column .dt-impact-item { min-width: 0; }
.dt-impact {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3);
  border-radius: var(--impact-tile-radius);
  background: var(--impact-tile-bg);
  color: inherit;
  text-decoration: none;
}
.dt-impact:hover { background: var(--brand-weak); }
.dt-impact-icon { color: var(--text-muted); flex: none; }
.dt-impact-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.dt-impact-title { font-weight: var(--fw-medium); }
.dt-impact-detail { color: var(--text-muted); font-size: var(--fs-small); }
.dt-impact-arrow { color: var(--text-faint); flex: none; }

/* --- 6.26 Метка источника --------------------------------------------------- */
.dt-source-badge { display: inline-flex; align-items: center; gap: var(--space-1); color: var(--source-badge-color); font-size: var(--fs-small); }
.dt-source-title { white-space: nowrap; }

/* --- 6.27 Подпись исполнителя ------------------------------------------------ */
.dt-signature { display: inline-flex; align-items: center; gap: var(--space-1); color: var(--signature-color); font-size: var(--fs-small); white-space: nowrap; }
.dt-signature-name { color: var(--text); }
.dt-signature-hint { display: block; color: var(--text-faint); font-size: var(--fs-caption); }

/* --- 6.19 Вид карточками на узком экране (< 768 px) ------------------------ */
@media (max-width: 767px) {
  table.dt { display: block; width: 100%; }
  table.dt thead { display: none; }
  table.dt tbody { display: block; }
  table.dt tbody tr[data-row], table.dt tbody tr[data-row-head] {
    display: block;
    border: var(--border-w) solid var(--border);
    border-radius: var(--radius-md);
    padding: var(--space-3);
    margin-bottom: var(--space-3);
    background: var(--surface);
  }
  table.dt tbody tr[data-row-detail] { display: block; border: 0; margin: 0 0 var(--space-3); }
  /* Ячейка раскрытия группы — одна широкая `<td colspan>`, не пара «подпись:
     значение» (§6.24): без этого правило ниже (`table.dt tbody td { display:
     flex; justify-content: space-between }`) кладёт вложенную таблицу позиций
     и блок «Куда ушло» РЯДОМ, а не друг под другом. */
  table.dt tbody tr[data-row-detail] > td { display: block; padding: 0; }
  table.dt tbody td {
    display: flex;
    align-items: baseline;
    justify-content: space-between;
    gap: var(--space-3);
    padding: var(--space-1) 0;
    border-bottom: 0;
    white-space: normal;
    text-align: left;
  }
  table.dt tbody td.num { text-align: right; }
  /* Заголовок карточки — первая КОЛОНКА С ДАННЫМИ, а не колонка раскрытия
     группы (§6.24): у строки-группы `.dt-group-toggle-cell` физически первая,
     но это кнопка-шеврон, не заголовок — заголовком становится ячейка сразу
     после неё. */
  table.dt tbody td:first-child:not(.dt-group-toggle-cell),
  table.dt tbody .dt-group-toggle-cell + td {
    font-weight: var(--fw-semibold);
    font-size: var(--fs-body);
    color: var(--text);
    justify-content: flex-start;
  }
  table.dt tbody td[data-label]::before { content: attr(data-label); color: var(--text-muted); font-weight: var(--fw-regular); flex: none; }
  /* Заголовок карточки не дублирует свою подпись перед собой (§6.19). */
  table.dt tbody td:first-child:not(.dt-group-toggle-cell)::before,
  table.dt tbody .dt-group-toggle-cell + td::before {
    content: none;
  }
  table.dt .dt-group-toggle-cell { justify-content: flex-start; }
  .dt-total { position: sticky; bottom: var(--bottom-nav-h); }

  /* Вложенная таблица позиций внутри раскрытой группы (§6.24) — не участвует
     в фильтре/сортировке внешней таблицы, но так же обязана не ломать
     страницу по горизонтали (§8 02-САЙТ-И-ЭКРАНЫ.md, правило 1): те же
     карточки, попроще (без рамки — она уже внутри карточки группы). */
  table.dt-nested { display: block; }
  table.dt-nested thead { display: none; }
  table.dt-nested tbody { display: block; }
  table.dt-nested tr {
    display: block;
    padding: var(--space-2) 0;
    border-bottom: var(--border-w) solid var(--border);
  }
  table.dt-nested tr:last-child { border-bottom: 0; }
  table.dt-nested td {
    display: flex;
    justify-content: space-between;
    gap: var(--space-3);
    padding: 2px 0;
    white-space: normal;
    text-align: left;
  }
  table.dt-nested td[data-label]::before { content: attr(data-label); color: var(--text-muted); flex: none; }
  table.dt-nested td:first-child { font-weight: var(--fw-medium); }
  table.dt-nested td:first-child::before { content: none; }
}

/* ===== T126: карточка-слот, доп. слот «график» (§6.15 доп., экран 01 «Бизнес») ===== */
.slot-card-chart { margin: var(--space-1) 0; }

/* ===== T126: «Структура реальной ценности» — состав компании по направлениям
   (экран 01, справа). Новая небольшая композиция без отдельного макроса
   (plan/phase13/КОНТРАКТ.md §7 — «мелкое дополнение», не копия компонента):
   заливка сегмента — единственный разрешённый инлайн-стиль, ширина в процентах
   (тот же приём, что §6.9/§6.17 — style="--seg-w: N%"). ===== */
.value-structure-bar {
  display: flex; height: var(--space-3); border-radius: var(--radius-sm); overflow: hidden;
  background: var(--surface-2);
}
.value-structure-seg {
  flex: 0 0 auto; width: var(--seg-w, 0%);
  /* T128, находка от T133: ширина сегмента была, но без фона (`--seg-color`
     оставался неиспользован) — полоса выглядела пустой на всех размерах. */
  background: var(--seg-color, var(--brand));
}
.value-structure-list { display: flex; flex-direction: column; gap: var(--space-2); margin-top: var(--space-3); }
.value-structure-row { display: flex; align-items: center; gap: var(--space-2); font-size: var(--fs-small); }
.value-structure-dot { width: 10px; height: 10px; border-radius: var(--radius-full); flex: none; background: var(--seg-color, var(--brand)); }
.value-structure-name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.value-structure-pct { color: var(--text-muted); width: 4.5em; text-align: right; flex: none; }
.value-structure-amount { text-align: right; flex: none; }

/* ===== T126: раскладка экрана «Бизнес» — GRID/расположение живёт в
   static/screens/business.css (I13: экранный CSS — только раскладка); здесь только
   классы, общие с другими экранами (карточка «Итого», список структуры выше). ===== */
.business-total { display: flex; flex-direction: column; gap: var(--space-4); }
.business-total-row { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-3); }
.business-total-row .num { font-size: var(--fs-kpi); line-height: var(--lh-kpi); }


/* ===== T127: ручной учёт и приём кассы ===== */
/* Дополнения существующих компонентов для экранов 09 и «Приём кассы» (раскладка —
   static/screens/manual.css). Новых визуальных сущностей нет:
   * чип-переключатель §6.21 (`.dt-filter-state-chip`) бывает и ссылкой — фильтр
     экрана задаётся адресом (работает без JS), выбранный чип несёт
     `aria-current="page"` вместо `aria-pressed` и выглядит так же, как нажатый;
   * подсказка подписи §6.27 с `hidden` — ждёт скрипта экрана (прогрессивное
     улучшение `pending_reason`), `display: block` компонента иначе её не прячет;
   * строка ввода ручного учёта в таблице §6.19 выделена фоном выбора (`--brand-weak`,
     §5 «выделение» строки таблицы), на узком экране — карточкой, как строки;
   * «новый» у поля товара/контрагента: набранного нет в справочнике — признак
     подсвечивается `--warn` и жирным (смысл не только цветом, §9);
   * действия строки — `<details>`: у заголовка-кнопки нет треугольника браузера;
   * кнопка §6.1, собранная ссылкой (`button(href=...)`, действие пустого состояния
     §6.3), не подчёркивается — подчёркнутая ссылка внутри кнопки читалась как
     ссылка, а не кнопка (находка проверки 09 в браузере). */
a.btn { text-decoration: none; }
/* Подпись §6.27, вариант `stacked` (параметр макроса): замок и имя, под ними дата и
   время — как на картинке 09; колонка «Подпись» рядом с полями ввода
   иначе растягивала таблицу шире экрана. Цвета и размеры — те же токены компонента. */
.dt-signature-stacked {
  display: inline-grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: var(--space-1);
  align-items: start;
  white-space: normal;
}
.dt-signature-stacked > svg { margin-top: var(--space-1); }
.dt-signature-stacked .dt-signature-at { grid-column: 1 / -1; font-size: var(--fs-caption); white-space: nowrap; }
a.dt-filter-state-chip { text-decoration: none; }
/* Ссылка-переход из строки таблицы приёма кассы («Ручной учёт», «Журнал направления»)
   — цветом бренда, как ссылки в карточках, без подчёркивания до наведения. */
.manual-link { color: var(--brand); text-decoration: none; }
.manual-link:hover { text-decoration: underline; }
/* Флажок «новый» живёт внутри поля §6.2, а старое `.field input:focus { outline: none }`
   (app.css) снимает с него кольцо фокуса §5 — у флажка нет рамки, фокус пропадал
   совсем (проход Tab по экрану 09). Возвращаем единое кольцо системы. */
.manual-new input:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.dt-filter-state-chip[aria-current="page"] {
  background: var(--brand-weak);
  border-color: var(--brand);
  color: var(--brand);
}
.dt-signature-hint[hidden] { display: none; }
table.dt tbody.manual-entry tr { background: var(--brand-weak); }
.manual-entry-title { font-weight: var(--fw-semibold); color: var(--text); }
.manual-new { font-size: var(--fs-caption); color: var(--text-muted); cursor: pointer; }
.manual-new-needed { color: var(--warn); font-weight: var(--fw-semibold); }
.manual-paid label { font-size: var(--fs-small); color: var(--text); cursor: pointer; }
.manual-month-label { font-weight: var(--fw-medium); color: var(--text); }
.manual-action > summary { list-style: none; cursor: pointer; }
.manual-action > summary::-webkit-details-marker { display: none; }
@media (max-width: 767px) {
  table.dt tbody.manual-entry tr {
    background: var(--surface);
    border: var(--border-w) solid var(--brand);
    border-radius: var(--radius-md);
  }
}
/* ===== T131: экраны входа (вход/приглашение/выбор компании) =====
   Одна карточка по центру экрана, 360 px (докстринг §6.2 — та же ширина, что
   у `.stack-form`), знак и имя бренда над формой, подпись-дескриптор бренд-бука
   §2.4. `base.html` рисует обычный каркас (шапка без бокового меню и вкладок —
   `nav_user` пуст до входа), эти классы оформляют только область `content`. */
.auth-shell {
  display: flex;
  justify-content: center;
  padding: var(--space-7) var(--space-4);
}
.auth-card {
  width: 100%;
  max-width: 360px;
  background: var(--card-bg);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
  padding: var(--space-6) var(--space-5);
}
.auth-brand {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  margin-bottom: var(--space-5);
}
.auth-brand-text { display: flex; flex-direction: column; }
.auth-brand-name { font-weight: var(--fw-semibold); font-size: var(--fs-h3); color: var(--text); }
.auth-brand-sub { font-size: var(--fs-caption); color: var(--text-muted); }
.auth-title { font-size: var(--fs-h3); margin: 0 0 var(--space-4); }
.auth-card .stack-form { max-width: none; }
.auth-foot {
  margin: var(--space-5) 0 0;
  font-size: var(--fs-small);
  color: var(--text-muted);
  text-align: center;
}
.auth-foot a { color: var(--brand); }
.auth-meta {
  margin: 0 0 var(--space-4);
  font-size: var(--fs-small);
  color: var(--text-muted);
}
.auth-meta strong { color: var(--text); }

/* ===== T131: сальдо взаиморасчётов — цвет долга (уточнение §11 бренд-бука) =====
   «Нам должны» — зелёный (--pos), «мы должны» — красный (--neg); слово рядом
   несёт тот же смысл, что цвет (§9.5 — цвет не единственный носитель). Полоски
   сальдо (§5 T130a `_balance_bar`) сюда не входят — тот компонент ещё не слит
   (КОНТРАКТ.md §8), эта карточка красит только текст суммы. */
.balance-amount { display: inline-flex; align-items: baseline; gap: var(--space-1); }
.balance-pos { color: var(--pos); }
.balance-pos .num { color: inherit; }
.balance-neg { color: var(--neg); }
.balance-neg .num { color: inherit; }


/* ===== T132: настройки — направления, источники, пользователи (фаза 13) =====
   Мелкое дополнение существующих компонентов (форма §6.2, таблица §6.3): группа
   чекбоксов «Блоки шаблона направления» — обычный <fieldset>, без нового
   компонента дизайн-системы (правка «на этой странице» запрещена I13, поэтому
   стили — не подстройка одного экрана, а обычное оформление fieldset токенами,
   годное для любой формы с группой чекбоксов). */
.settings-tabs + .card fieldset,
.card-wide fieldset {
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin: var(--space-3) 0;
}
.card-wide fieldset legend,
.settings-tabs + .card fieldset legend {
  padding: 0 var(--space-2);
  color: var(--text-muted);
  font-size: var(--fs-caption);
}
/* ===== T124: склад, взаиморасчёты, ОС направления ===== */
/* Мелкие дополнения существующих компонентов (§7 контракта фазы 13, «нужен
   компонент, которого нет» — не копия, а точечная правка своим разделом
   с пояснением в отчёте T124), новых визуальных компонентов не заводилось. */

/* Янтарная плитка «N без эталонной цены» (04) — тот же `.kpi` (§6.4, T95), только
   модификатор цвета рамки/фона: карточка «значение есть — верить нельзя» уровня
   ВСЕЙ плитки (не отдельного числа внутри неё, для этого служит `--value-state`
   `_value.html`), поэтому не то же самое, что `data-value-state="warn"`. */
.kpi-warn {
  background: var(--warn-bg);
  border-color: var(--warn);
}
.kpi-warn .k-label { color: var(--warn); display: flex; align-items: center; gap: var(--space-1); }
.kpi-warn .k-value { color: var(--warn); }

/* Быстрые периоды страницы «Взаиморасчёты» (05) — обычные ссылки-переходы
   (`?from=&to=`), а не JS-переключатель одного графика (`_chart_card.html`
   `data-quick`), поэтому текущий пункт — `aria-current="page"`, не
   `aria-pressed`; сегмент `.ch-seg`/`.ch-seg-btn` (T130a, `components.css`
   строка ~444) уже общий, не только для графиков — только подсветка активного
   пункта под навигационную семантику здесь недостающая. */
.ch-seg-btn[aria-current="page"] {
  background: var(--brand-weak);
  color: var(--brand);
  font-weight: var(--fw-medium);
}

/* Строка поиска в `.dt-toolbar` (04/05) — свободный текст по `[data-dt-search]`
   (аддитивная правка `static/datatable.js`, см. её докстринг у `_wireSearch`);
   вне `.field` (там обязательна видимая подпись, здесь — `aria-label`), поэтому
   нужен минимальный собственный вид полем ввода — токены §6.2, без нового
   компонента. */
.dt-search {
  font: inherit;
  font-size: var(--fs-small);
  color: var(--text);
  background: var(--surface);
  border: var(--border-w) solid var(--border);
  border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3);
  min-width: 16rem;
  flex: 1 1 16rem;
}
/* Кольцо фокуса — общее правило `tokens.css` (`:focus-visible`, снимать нельзя,
   §5); здесь только смена рамки, чтобы поле было заметно активным и без
   фокуса с мыши. */
.dt-search:focus {
  border-color: var(--brand);
}

/* ===== T128: журнал (07) — вкладка вида и чип источника выбираются адресом,
   не переключателем состояния — второй `variant="primary"` рядом с «Новая
   операция» ломал правило «одна первичная кнопка на экране»
   (test_journal_list_screen_has_one_primary_button). Тот же приём, что у
   T127 выше (`.dt-filter-state-chip[aria-current="page"]`): ссылка остаётся
   `btn-secondary`, выбранная — подсвечена цветом бренда через
   `aria-current="page"`, а не сменой варианта кнопки. ===== */
.journal-kind-tabs .btn[aria-current="page"],
.journal-source-chips .btn[aria-current="page"] {
  background: var(--brand-weak);
  border-color: var(--brand);
  color: var(--brand);
  font-weight: var(--fw-medium);
}


/* ===== Матрица доступов §6.28 и панель шаблонов §6.29 (T169, 17.09.2026) =====
   Широкая таблица «сотрудники × разделы»: первая колонка прилипает к левому краю
   при горизонтальной прокрутке (иначе на середине непонятно, чья строка), шапка из
   трёх рядов — вид раздела, раздел, направление. Прокручивается КОНТЕЙНЕР
   (.table-scroll), а не страница, — §8 правило 1 каркаса. ===== */
.access-matrix { border-collapse: separate; border-spacing: 0; }
.access-matrix th,
.access-matrix td { white-space: nowrap; }
.access-matrix thead th {
  vertical-align: bottom;
  border-bottom: var(--border-w) solid var(--border);
  padding: var(--space-1) var(--space-2);
}
.access-matrix thead tr:first-child th { border-left: var(--border-w) solid var(--border); }
.access-matrix-dir { display: block; color: var(--text-muted); font-size: var(--fs-small); }
/* Фон прилипшей колонки обязан быть непрозрачным: под неё уезжают клетки. */
.access-matrix-name {
  position: sticky;
  left: 0;
  z-index: 2;
  background: var(--surface);
  text-align: left;
  border-right: var(--border-w) solid var(--border);
  min-width: 14rem;
}
.access-matrix thead .access-matrix-name { z-index: 3; }
.access-matrix-person { display: block; font-weight: var(--fw-semibold); }
.access-matrix-marks { display: flex; gap: var(--space-3); margin-top: var(--space-1); }
.access-matrix-pick {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  min-height: 44px;
  color: var(--text-muted);
  font-size: var(--fs-small);
}
.access-templates {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: var(--space-3);
  margin-bottom: var(--space-4);
}
.access-templates-preview { flex-basis: 100%; margin: 0; }

/* Узкий экран (§6.28, §8 каркаса правило 6): матрица складывается в КАРТОЧКУ
   СОТРУДНИКА — общий блок `table.ref-table` в app.css уже превращает строку в
   карточку, здесь снимается прилипание (в карточке нечему прилипать) и убирается
   отметка столбца целиком: столбцов на карточках нет. */
@media (max-width: 479px) {
  .access-matrix-name { position: static; min-width: 0; border-right: none; }
  .access-matrix thead .access-matrix-all { display: none; }
  .access-matrix td { white-space: normal; }
  .access-templates { flex-direction: column; align-items: stretch; }
}
