/* =====================================================================
   Дизайн-система финансового портала.
   Перенесена из design/дизайн-система.html без изменения токенов:
   цвета, отступы и размеры — те же, что в прототипе.

   Шрифты подключены ЛОКАЛЬНО. Сервер за VPN, и внешние шрифты с
   fonts.googleapis.com могут не загрузиться — тогда интерфейс поедет
   в самый неподходящий момент. Файлы лежат в static/fonts, лицензии
   рядом: обе гарнитуры под SIL Open Font License 1.1.

   Три ограничения, из которых вырос интерфейс:
     цвет несёт смысл и не украшает;
     числа набраны моноширинным шрифтом с табличными цифрами;
     плотность переключается под задачу — просмотр или разбор.
   ===================================================================== */

/* ============================ ШРИФТЫ ============================ */

/* font-display: swap — текст показывается системным шрифтом сразу,
   а не ждёт загрузки. На медленном канале это разница между
   «страница пустая» и «страница читается». */

/* ============================ ТОКЕНЫ ============================ */

:root {
  --paper:#F1F4F8; --surface:#FFFFFF; --surface-2:#F8FAFC;
  --line:#E1E6ED; --line-2:#C9D2DE;
  --ink:#10151C; --ink-2:#3B4654; --ink-3:#556170; --ink-4:#616D7B;
  --accent:#2F3E8C; --accent-2:#243073; --accent-soft:#EDEFF9;
  --red:#C0392F; --red-soft:#FBEDEC;
  --amber:#A9720B; --amber-soft:#FBF3E4;
  --green:#1F7A4C; --green-soft:#EAF5EF;
  --neutral:#7B8798;
  --radius:6px; --radius-sm:4px;
  --row-y:11px; --fs:14px; --fs-sm:12.5px; --fs-xs:11px;
  --gap:16px;
  --ff:"Golos Text",system-ui,-apple-system,"Segoe UI",Roboto,sans-serif;
  --ff-num:"IBM Plex Mono",ui-monospace,Menlo,Consolas,monospace;
  --side-w:236px;
}

:root[data-theme="dark"] {
  --paper:#0D1117; --surface:#151A22; --surface-2:#1B222C;
  --line:#252D39; --line-2:#36404F;
  --ink:#E7ECF3; --ink-2:#C3CDD9; --ink-3:#A2AEBD; --ink-4:#8894A4;
  --accent:#8098E8; --accent-2:#9FB2F0; --accent-soft:#1A2136;
  --red:#E0685C; --red-soft:#2A1A19;
  --amber:#D3A035; --amber-soft:#2A2317;
  --green:#48B37D; --green-soft:#152A20;
  --neutral:#7F8B9B;
 color-scheme:dark; }
@media (prefers-color-scheme: dark) { :root:not([data-theme="light"]) {
  --paper:#0D1117; --surface:#151A22; --surface-2:#1B222C;
  --line:#252D39; --line-2:#36404F;
  --ink:#E7ECF3; --ink-2:#C3CDD9; --ink-3:#A2AEBD; --ink-4:#8894A4;
  --accent:#8098E8; --accent-2:#9FB2F0; --accent-soft:#1A2136;
  --red:#E0685C; --red-soft:#2A1A19;
  --amber:#D3A035; --amber-soft:#2A2317;
  --green:#48B37D; --green-soft:#152A20;
  --neutral:#7F8B9B;
 color-scheme:dark; } }

[data-density="compact"] { --row-y:6px; --fs:13px; --fs-sm:12px; --gap:12px; }

/* ============================ ОСНОВА ============================ */

* { box-sizing: border-box; }
html, body { margin:0; padding:0; }

body {
  background: var(--paper);
  color: var(--ink);
  font-family: var(--ff);
  font-size: var(--fs);
  line-height: 1.5;
  -webkit-font-smoothing: antialiased;
  transition: background .15s, color .15s;
}

/* Числа: моноширинный шрифт и табличные цифры. Колонка сумм должна
   выравниваться по разряду, иначе глаз не сравнивает значения. */
.num {
  font-family: var(--ff-num);
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum";
}
.num .dim { color: var(--ink-4); }

a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
button { font: inherit; cursor: pointer; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 2px; }

/* Псевдоэлементы перечислены отдельно: `*` их НЕ выбирает, и правило,
   написанное только через звёздочку, тихо пропускало бы то, что на них
   анимировано. Выехало это на выезжающей группе меню — она живёт на
   `::details-content` и продолжала ехать у того, кто просил движение
   выключить. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
  /* Отдельным правилом, а не пятым именем в списке выше: незнакомый
     псевдоэлемент отменяет ВЕСЬ перечень, и браузер постарше выбросил
     бы вместе с ним и звёздочку — просьбу выключить движение перестало
     бы выполнять всё сразу. */
  *::details-content { animation: none !important; transition: none !important; }
}

.wrap { max-width: 1180px; margin: 0 auto; padding: 0 24px; }

h1 { font-size:30px; line-height:1.2; letter-spacing:-.02em; margin:10px 0 12px; font-weight:600; max-width:22ch; }
h2 { font-size:19px; letter-spacing:-.01em; margin:8px 0 6px; font-weight:600; }
h3 { font-size:14px; margin:0 0 10px; font-weight:600; }

.eyebrow {
  font-size: var(--fs-xs); letter-spacing:.14em; text-transform: uppercase;
  color: var(--ink-4); font-weight:600;
}
.lede { color: var(--ink-2); max-width:64ch; margin:0; }
.note { color: var(--ink-3); font-size: var(--fs-sm); max-width:64ch; }

.grid { display:grid; gap:var(--gap); }
.g2 { grid-template-columns:1fr 1fr; }
.g3 { grid-template-columns:repeat(3,1fr); }
.g4 { grid-template-columns:repeat(4,1fr); }
.g5 { grid-template-columns:repeat(5,1fr); }
@media (max-width:900px) { .g2,.g3,.g4 { grid-template-columns:1fr; } }

/* ============================ КАРКАС ============================ */

.top { position:sticky; top:0; z-index:50; background:var(--surface); border-bottom:1px solid var(--line); }
.top-in {
  display:flex; align-items:center; justify-content:space-between; gap:20px;
  padding:12px 24px; flex-wrap:wrap;
}
.brand { font-weight:600; letter-spacing:-.01em; color:var(--ink); }
.brand:hover { text-decoration:none; }
.brand span { color:var(--ink-3); font-weight:400; }

.top-right { display:flex; align-items:center; gap:14px; flex-wrap:wrap; }
.whoami { font-size:var(--fs-sm); color:var(--ink-3); text-align:right; line-height:1.35; }
.whoami b { display:block; color:var(--ink-2); font-weight:500; }

/* Колокольчик доработок. Значок и цифра — в шапке рядом с именем;
   цифра та же по смыслу, что счётчик заявок в меню, и рисуется только
   когда есть что показать. */
.bell {
  position:relative; display:inline-flex; align-items:center; gap:8px;
  color:var(--ink-3); padding:6px; border-radius:var(--radius-sm);
  text-decoration:none; flex:none;
}
.bell:hover { color:var(--accent); background:var(--accent-soft); }
.bell-label { display:none; }
.bell-count {
  min-width:18px; height:17px; padding:0 5px; border-radius:9px;
  display:inline-flex; align-items:center; justify-content:center;
  background:var(--amber); color:var(--paper);
  font-family:var(--ff-num); font-size:var(--fs-xs); font-weight:600;
  font-variant-numeric:tabular-nums;
  position:absolute; top:-1px; left:18px;
}

.switches { display:flex; gap:8px; }
.seg { display:inline-flex; border:1px solid var(--line); border-radius:var(--radius-sm); overflow:hidden; }
.seg button { background:var(--surface); border:0; padding:6px 11px; font-size:var(--fs-sm); color:var(--ink-3); }
.seg button[aria-pressed="true"] { background:var(--accent-soft); color:var(--accent); font-weight:500; }

/* Каркас страницы: боковое меню и содержимое. */
.shell { display:grid; grid-template-columns:var(--side-w) 1fr; min-height:calc(100vh - 57px); align-items:start; }
.side { border-right:1px solid var(--line); background:var(--surface); padding:16px 0 40px; position:sticky; top:57px; }
.main { padding:24px; min-width:0; }

/* Меню-гармошка. Крупные разделы стоят всегда, мелкие показывает один
   раскрытый. Сорок с лишним пунктов подряд человек не читает — он ищет
   нужный глазами по всей колонке; выбор «сначала крупное, потом
   мелкое» короче на порядок.

   Заголовок группы перестал быть подписью и стал кнопкой, поэтому и
   набран как строка меню, а не как надпись над списком: прежние 11px
   капителью цветом `ink-4` для того, по чему щёлкают, слишком тихи. */
.nav-group { border-bottom:1px solid var(--line); }
.nav-group:last-of-type { border-bottom:0; }
.nav-title {
  display:flex; align-items:center; gap:8px;
  padding:10px 16px; margin:0; cursor:pointer; user-select:none;
  font-size:var(--fs-sm); font-weight:600; color:var(--ink-2);
  list-style:none;
}
.nav-title::-webkit-details-marker { display:none; }
.nav-title:hover { background:var(--surface-2); color:var(--accent); }
.nav-group[open] > .nav-title { color:var(--ink); }

/* Галочка справа: закрытая группа показывает вправо, раскрытая вниз.
   Рисуется двумя гранями рамки — ради одного значка не стоит ни файла,
   ни шрифта. */
.nav-chev {
  width:6px; height:6px; flex:none; margin-left:auto;
  border-right:1.5px solid var(--ink-4); border-bottom:1.5px solid var(--ink-4);
  transform:rotate(-45deg); transition:transform .15s ease;
}
.nav-group[open] > .nav-title .nav-chev { transform:rotate(45deg); }

/* Группа не появляется рывком, а выезжает — две десятых секунды.
   Анимация здесь не украшение: она показывает, что список выехал из
   заголовка, по которому щёлкнули, а не подменил собой соседний.

   Высота `auto` сама по себе не анимируется — нужен `interpolate-size`.
   Свойство наследуется, поэтому стоит на группе, а не на `:root`:
   менять поведение высот всему порталу ради меню незачем.
   `content-visibility` в переходе — с `allow-discrete`, иначе при
   закрытии содержимое пропадает в первом же кадре и выезжает пустая
   рамка.

   Браузер, который этого не умеет, раскрывает группу мгновенно — ровно
   как до правки. `prefers-reduced-motion` гасит переход общим правилом
   в начале файла. */
.nav-group { interpolate-size:allow-keywords; }
.nav-group::details-content {
  height:0; overflow:hidden;
  transition:height .2s ease, content-visibility .2s allow-discrete;
}
.nav-group[open]::details-content { height:auto; }

.nav-item {
  display:flex; align-items:center; justify-content:space-between; gap:8px;
  padding:6px 16px 6px 26px; font-size:var(--fs-sm); color:var(--ink-2);
  border-left:2px solid transparent;
}
.nav-group > .nav-item:last-child { margin-bottom:8px; }
.nav-item:hover { background:var(--surface-2); text-decoration:none; }
.nav-item[aria-current="page"] { background:var(--accent-soft); color:var(--accent); font-weight:500; border-left-color:var(--accent); }
.nav-ro { font-size:var(--fs-xs); color:var(--ink-4); font-weight:400; }

/* Счётчик у пункта меню: сколько записей ждёт человека. Рисуется
   только когда число больше нуля — пустой кружок читается как поломка.
   Цвет янтарный, а не красный: заявка на доступ требует внимания,
   но ничего не горит. */
.nav-count {
  min-width:19px; height:18px; padding:0 6px; border-radius:9px;
  display:inline-flex; align-items:center; justify-content:center;
  background:var(--amber); color:var(--paper);
  font-family:var(--ff-num); font-size:var(--fs-xs); font-weight:600;
  font-variant-numeric:tabular-nums; flex:none;
}

/* Кнопка меню. На широком экране её нет: разделы стоят колонкой,
   переключатели — в шапке, прятать нечего. */
/* Специфичность выше, чем у `.btn`: правило `.btn { display:inline-flex }`
   стоит ниже по файлу и одиночный класс переспорил бы. */
.btn.menu-toggle { display:none; }
.burger { position:relative; width:15px; height:11px; flex:none; }
.burger, .burger::before, .burger::after {
  display:block; border-top:2px solid currentColor;
}
.burger::before, .burger::after { content:""; position:absolute; left:0; right:0; }
.burger::before { top:4px; }
.burger::after { top:9px; }

@media (max-width:900px) {
  .shell { grid-template-columns:1fr; }
  .side { position:static; border-right:0; border-bottom:1px solid var(--line); }
  .side[hidden] { display:none; }
  .btn.menu-toggle { display:inline-flex; }

  /* В шапке остаются название портала и кнопка. Всё остальное
     portal.js переносит внутрь меню — разметка одна, копий нет. */
  .top-in { flex-wrap:nowrap; padding:10px 16px; }

  /* Блок настроек и выхода, переехавший в меню: подвал под разделами.
     Разделы идут первыми — за ними открывают меню, а тему меняют
     однажды. */
  .top-right.in-side {
    display:block; margin-top:6px; padding:14px 16px 4px;
    border-top:1px solid var(--line);
  }
  .in-side .switches { flex-direction:column; gap:8px; }
  .in-side .seg { width:100%; }
  .in-side .seg button, .in-side .seg a { flex:1; justify-content:center; }
  /* В меню колокольчик — обычная строка со словом, а не значок в
     углу: значок без подписи в столбце строк не замечают. */
  .in-side .bell { width:100%; padding:8px 0; justify-content:flex-start; }
  .in-side .bell-label { display:inline; font-size:var(--fs-sm); }
  .in-side .bell-count { position:static; margin-left:auto; }
  .in-side .whoami { text-align:left; margin-top:12px; }
  .in-side .logout { margin:10px 0 0; }
  .in-side .logout .btn { width:100%; justify-content:center; }
}

/* ============================ КАРТОЧКИ ========================== */

.card { background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); }
.card-h {
  display:flex; align-items:center; justify-content:space-between; gap:12px;
  padding:11px 14px; border-bottom:1px solid var(--line); background:var(--surface-2);
  border-radius:var(--radius) var(--radius) 0 0;
}
.card-t { font-size:var(--fs-sm); font-weight:600; }
.card-b { padding:14px; }

/* ======================= ШКАЛА ВОЗРАСТА ========================= */
/* Подпись системы. Пороги перестают быть числами в таблице и
   становятся местом на шкале. Шкала нелинейная: каждой зоне отведено
   место по важности, а не по числу дней, иначе первые три месяца
   сжались бы в точку. */

.age { position:relative; height:26px; user-select:none; }
.age-track {
  position:absolute; top:11px; left:0; right:0; height:4px; border-radius:2px;
  background:linear-gradient(90deg,var(--green-soft) 0 30%,var(--amber-soft) 30% 55%,var(--red-soft) 55% 100%);
}
.age-zone { position:absolute; top:11px; height:4px; border-radius:2px; }
.age-tick { position:absolute; top:6px; width:1px; height:14px; background:var(--line-2); }
.age-lab { position:absolute; top:0; font-size:10px; color:var(--ink-4); transform:translateX(-50%); font-family:var(--ff-num); }
.age-mark {
  position:absolute; top:4px; width:3px; height:18px; border-radius:2px; background:var(--ink);
  box-shadow:0 0 0 2px var(--surface); animation:slide .5s cubic-bezier(.2,.8,.2,1);
}
.age-mark[data-s="red"] { background:var(--red); }
.age-mark[data-s="amber"] { background:var(--amber); }
.age-mark[data-s="green"] { background:var(--green); }
@keyframes slide { from { opacity:0; transform:translateX(-14px); } to { opacity:1; transform:none; } }

.age-mini { position:relative; height:8px; width:96px; display:inline-block; vertical-align:middle; }
.age-mini .age-track { top:2px; height:4px; }
.age-mini .age-tick { top:0; height:8px; }
.age-mini .age-mark { top:0; height:8px; width:2px; box-shadow:none; animation:none; }

/* ==================== ПОМЕТКИ СВЁРНУТОГО БЛОКА ================== */
/* «показать» видно, когда блок закрыт; «свернуть» — когда открыт.
   Никогда обе сразу.
                                                                     
   Правило написано для ЛЮБОГО `<details>`, а не для конкретного вида
   блока, и это единственное его место. Дважды оно было написано
   отдельно — для панели фильтров и для свёрнутого блока — и дважды
   новый блок появлялся без него: сначала сводка по сегментам, потом
   «Как работает сценарий». Третьего раза не будет: чтобы правило
   перестало действовать, теперь надо не забыть его добавить, а
   намеренно отменить.
                                                                     
   `.marker.warn` красным здесь же: предупреждение в подписи свёрнутого
   блока — не служебная пометка, а причина его открыть. */
details[open] > summary .marker-closed,
details:not([open]) > summary .marker-open { display:none; }
details > summary .marker.warn { color:var(--red); }

/* ============================ СТАТУСЫ =========================== */

.dot { display:inline-block; width:8px; height:8px; border-radius:50%; flex:none; }
.s-red { background:var(--red); }

/* Текст-предупреждение. Именно ЦВЕТ БУКВ, а не `.s-red`: тот красит фон —
   он сделан для точек светофора, и на тексте даёт красный прямоугольник,
   в котором ничего не прочитать. */
.warn { color:var(--red); }
.s-amber { background:var(--amber); }
.s-green { background:var(--green); }
.s-neutral { background:var(--neutral); }

.badge {
  display:inline-flex; align-items:center; gap:7px; padding:3px 9px; border-radius:100px;
  font-size:var(--fs-sm); font-weight:500; border:1px solid transparent; white-space:nowrap;
}
.b-red { background:var(--red-soft); color:var(--red); border-color:color-mix(in srgb,var(--red) 22%,transparent); }
.b-amber { background:var(--amber-soft); color:var(--amber); border-color:color-mix(in srgb,var(--amber) 22%,transparent); }
.b-green { background:var(--green-soft); color:var(--green); border-color:color-mix(in srgb,var(--green) 22%,transparent); }
.b-gray { background:var(--surface-2); color:var(--ink-3); border-color:var(--line); }

/* ============================ КНОПКИ ============================ */

.btn {
  display:inline-flex; align-items:center; gap:7px; padding:8px 14px; border-radius:var(--radius-sm);
  border:1px solid var(--line-2); background:var(--surface); color:var(--ink); font-size:var(--fs-sm);
  font-weight:500; transition:background .12s,border-color .12s;
}
.btn:hover { background:var(--surface-2); text-decoration:none; }
.btn-primary { background:var(--accent); border-color:var(--accent); color:#fff; }
.btn-primary:hover { background:var(--accent-2); border-color:var(--accent-2); }
.btn-quiet { border-color:transparent; background:transparent; color:var(--ink-2); }
.btn-quiet:hover { background:var(--surface-2); }
.btn-danger { border-color:color-mix(in srgb,var(--red) 40%,transparent); color:var(--red); background:transparent; }
.btn-danger:hover { background:var(--red-soft); }
.btn:disabled { opacity:.45; cursor:not-allowed; }
.btn-wide { width:100%; justify-content:center; }

/* ============================ ПОЛЯ ============================== */

.field { display:block; margin-bottom:14px; }
.label {
  display:block; font-size:var(--fs-xs); letter-spacing:.08em; text-transform:uppercase;
  color:var(--ink-3); font-weight:600; margin-bottom:5px;
}
.label .req { color:var(--red); }
.input {
  width:100%; padding:8px 10px; border:1px solid var(--line-2); border-radius:var(--radius-sm);
  background:var(--surface); color:var(--ink); font-size:var(--fs-sm); font-family:inherit;
}
.input::placeholder { color:var(--ink-4); }
.input:focus { border-color:var(--accent); outline:none; box-shadow:0 0 0 3px var(--accent-soft); }
.input-err { border-color:var(--red); }
textarea.input { min-height:76px; resize:vertical; }
select.input { appearance:auto; }
.hint { font-size:var(--fs-xs); color:var(--ink-3); margin-top:5px; }
.hint-err { color:var(--red); }

.chip {
  display:inline-flex; align-items:center; gap:6px; padding:4px 8px 4px 10px; border-radius:100px;
  background:var(--accent-soft); color:var(--accent); font-size:var(--fs-sm); border:1px solid transparent;
}
.chip button { border:0; background:none; color:inherit; opacity:.6; padding:0 2px; line-height:1; }

/* ===================== ПОЛОСА ВОЗРАСТА ПОРТФЕЛЯ ================= */
/* Не путать со шкалой возраста одного долга (.age): та отвечает на
   вопрос «где стоит вот этот счёт», а эта — «как разложен весь
   портфель». Обе нужны, и они соседствуют на одной странице.

   Доли считаются от суммы, а не от числа счетов: сто мелких долгов и
   один крупный на такой полосе должны выглядеть по-разному. */

.band { display:flex; width:100%; height:34px; border-radius:var(--radius); overflow:hidden;
        border:1px solid var(--line); background:var(--surface-2); }
.band-part {
  display:flex; align-items:center; justify-content:center; min-width:3px;
  font-size:var(--fs-xs); font-weight:600; color:var(--paper);
  text-decoration:none; transition:filter .12s;
}
.band-part:hover { filter:brightness(1.12); text-decoration:none; }
.band-part[data-s="green"] { background:var(--green); }
.band-part[data-s="amber"] { background:var(--amber); }
.band-part[data-s="red"]   { background:var(--red); }
.band-part[data-s="neutral"] { background:var(--neutral); }
.band-part[data-empty="1"] { background:var(--line); }
/* Тонкая щель между зонами: две соседние зоны одного цвета иначе
   сливаются в одну полосу, и границу порога не видно. */
.band-part + .band-part { border-left:1px solid var(--surface); }
/* Выбранная зона: остальные приглушаются, чтобы было видно, что
   таблица отфильтрована именно ею. */
.band[data-picked="1"] .band-part { opacity:.35; }
.band[data-picked="1"] .band-part[aria-pressed="true"] { opacity:1; outline:2px solid var(--ink); outline-offset:-2px; }

.band-legend { display:grid; grid-template-columns:repeat(5, 1fr); gap:8px; margin-top:10px; }
.band-cell {
  display:block; padding:9px 11px; border:1px solid var(--line); border-radius:var(--radius);
  background:var(--surface); color:inherit; text-decoration:none;
}
.band-cell:hover { border-color:var(--line-2); text-decoration:none; }
.band-cell[aria-pressed="true"] { border-color:var(--accent); background:var(--accent-soft); }
.band-cell .band-t { display:flex; align-items:center; gap:6px; font-size:var(--fs-sm); color:var(--ink-3); }
.band-cell .band-v { font-family:var(--ff-num); font-variant-numeric:tabular-nums;
                     font-size:15px; font-weight:600; margin-top:3px; }
.band-cell .band-s { font-size:var(--fs-xs); color:var(--ink-4); }

/* Ряд светофора: те же карточки, что в легенде полосы, но в строку. */
.colors { display:flex; flex-wrap:wrap; gap:10px; align-items:center; margin-bottom:18px; }
.colors-cell { flex:1; min-width:160px; }
.colors > .note { flex-basis:100%; }
.colors > .note:first-child { flex-basis:auto; }

@media (max-width:1000px) { .band-legend { grid-template-columns:repeat(2, 1fr); } }
@media (max-width:1200px) { .g5 { grid-template-columns:repeat(3,1fr); } }

/* ======================== ТЯЖЁЛЫЙ БЛОК ========================== */
/* Свёрнут по умолчанию, содержимое приходит по требованию.
   Свёрнутый блок обязан давать повод развернуть себя: заголовок без
   единой цифры через неделю перестают замечать. Поэтому строка итога
   стоит в самой шапке, рядом с кнопкой. */

/* Шапка блока — это <summary>: разворачивает браузер, без скрипта.
   Родной треугольник убираем, вместо него слово «Развернуть». */
.lazy > summary { cursor:pointer; list-style:none; user-select:none; }
.lazy > summary::-webkit-details-marker { display:none; }
.lazy > summary:hover .lazy-toggle { color:var(--accent); border-color:var(--accent); }
.lazy[open] > summary { border-radius:var(--radius) var(--radius) 0 0; }

.lazy-toggle {
  display:inline-flex; align-items:center; flex:none;
  padding:5px 11px; border:1px solid var(--line-2); border-radius:var(--radius-sm);
  background:var(--surface); color:var(--ink-2);
  font-size:var(--fs-sm); font-weight:500;
}
.lazy .lazy-word-close { display:none; }
.lazy[open] .lazy-word-open { display:none; }
.lazy[open] .lazy-word-close { display:inline; }

.lazy-side { display:flex; align-items:center; gap:12px; flex-wrap:wrap; justify-content:flex-end; }
.lazy-sum { font-size:var(--fs-sm); color:var(--ink-3); }
/* Тон строки итога несёт смысл: рост долга — повод посмотреть,
   снижение — хорошая новость. Янтарный, а не красный: это приглашение
   развернуть блок, а не тревога. */
.lazy-sum-amber { color:var(--amber); font-weight:500; }
.lazy-sum-green { color:var(--green); font-weight:500; }

.lazy-wait { margin:0; }

/* Строка без графика: одна точка — это не график, и рисовать пустую
   сетку ради неё нечестно. */
.chart-none { margin:0 0 4px; }

/* Заголовок внутри загруженного блока: переключатель шага и подпись. */
.hist-head {
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; flex-wrap:wrap; margin-bottom:14px;
}
.hist-move { margin-top:20px; padding-top:16px; border-top:1px solid var(--line); }
.hist-move .block-h { gap:10px; flex-wrap:wrap; }

/* ============================ ГРАФИК ============================ */
/* Единственное место на портале, где линия уместнее полосы: по
   горизонтали здесь время, а не список. Полосы сравнивают величины,
   линия показывает ход — это разные вопросы.

   Две линии, обе в рублях, обе на ОДНОЙ шкале от нуля. Второй оси на
   портале не будет: подобрав два масштаба, на одном поле можно
   показать любую зависимость, включая ту, которой нет.
   Цвета — токены темы, поэтому ночная тема получает свои шаги, а не
   осветлённые дневные. */

.chart { width:100%; }
.chart-svg { display:block; width:100%; height:auto; }

/* Сетка и подписи приглушены: они помогают читать линию, а не спорят
   с ней. Сплошная волосяная линия, без пунктира — пунктир читается
   как «прогноз» или «порог». */
.chart-grid { stroke:var(--line); stroke-width:1; }
.chart-tick {
  fill:var(--ink-4); font-family:var(--ff-num); font-size:11px;
  font-variant-numeric:tabular-nums;
}

.chart-line { fill:none; stroke-width:2; stroke-linejoin:round; stroke-linecap:round; }
.chart-total { stroke:var(--accent); }
.chart-overdue { stroke:var(--red); }
.chart-dot { stroke:var(--surface); stroke-width:2; }
.chart-total-dot { fill:var(--accent); }
.chart-overdue-dot { fill:var(--red); }

/* Полоса наведения во всю высоту: попасть в неё можно и пальцем.
   Точку диаметром восемь пикселей на телефоне не поймать. */
.chart-hit { fill:transparent; }
.chart-hit:hover { fill:color-mix(in srgb, var(--accent) 7%, transparent); }

.chart-legend {
  display:flex; flex-wrap:wrap; align-items:center; gap:8px 20px;
  margin-top:12px; font-size:var(--fs-sm); color:var(--ink-2);
}
.chart-key { display:inline-flex; align-items:center; gap:7px; }
.chart-swatch { width:16px; height:3px; border-radius:2px; flex:none; }
.chart-total-sw { background:var(--accent); }
.chart-overdue-sw { background:var(--red); }

/* Раскрывающийся блок с теми же числами таблицей. В отличие от
   `.panel`, заголовок виден всегда: это не свёрнутая на телефоне
   панель, а второй способ прочитать график — без наведения, без
   цвета, с клавиатуры и на распечатке. */
.foldout { margin-top:14px; border-top:1px solid var(--line); padding-top:10px; }
.foldout > summary {
  cursor:pointer; user-select:none; font-size:var(--fs-sm);
  color:var(--ink-3); font-weight:500;
}
.foldout > summary:hover { color:var(--accent); }
.foldout[open] > summary { margin-bottom:10px; }
.foldout > summary .marker { color:var(--ink-4); font-weight:400; }

/* ======================= ГОРИЗОНТАЛЬНЫЕ ПОЛОСЫ ================== */
/* Круговых диаграмм на портале нет и не будет: доли на них сравнивают
   по углам, а углы человек сравнивает плохо. «Кто должен больше —
   второй или третий» на полосах читается сразу. */

.bars { display:grid; gap:7px; }
.bar-row { display:grid; grid-template-columns:minmax(0,1fr) 96px; gap:10px; align-items:center; }
.bar-label { font-size:var(--fs-sm); color:var(--ink-2); overflow:hidden;
             text-overflow:ellipsis; white-space:nowrap; }
.bar-track { height:7px; border-radius:4px; background:var(--surface-2); margin-top:4px; overflow:hidden; }
.bar-fill { height:100%; background:var(--accent); border-radius:4px; }
.bar-value { font-family:var(--ff-num); font-variant-numeric:tabular-nums;
             font-size:var(--fs-sm); text-align:right; color:var(--ink); }
.bar-sub { font-size:var(--fs-xs); color:var(--ink-4); text-align:right; }
a.bar-link { color:inherit; text-decoration:none; display:block; }
a.bar-link:hover .bar-label { color:var(--accent); }
a.bar-link:hover .bar-fill { filter:brightness(1.1); }

/* Заголовок блока без карточки: подпись и кнопка «i» рядом. */
.block-h { display:flex; align-items:center; gap:4px; margin:0 0 7px; }

/* ========================== БАЗА ЗНАНИЙ ========================= */
/* Тот же текст, что на страницах разделов, собранный подряд. Читают
   его иначе: не «что значит вот эта цифра», а «как здесь всё устроено».
   Поэтому строка длиной в книжную колонку и воздух между блоками. */

.kb-blocks { display:grid; gap:18px; }
.kb-block h3 { margin:0 0 5px; font-size:15px; }
.kb-summary { margin:0 0 8px; color:var(--ink-2); max-width:74ch; }
.kb-body { color:var(--ink-2); max-width:74ch; }
.kb-body p { margin:0 0 9px; }
.kb-body p:last-child { margin-bottom:0; }
.kb-block + .kb-block { border-top:1px solid var(--line); padding-top:16px; }

/* Пояснение под заголовком страницы шире обычного `.lede`: определение
   дебиторки в 64 знака не укладывается и рвётся на пять строк. */
.lede-wide { max-width:76ch; }

/* ========================== НАПРАВЛЕНИЯ ========================= */
/* Верхний переключатель: Коммерция, Сервис и счета без ответственного
   за дебиторку. Третья карточка — не третье направление, а дыра в
   ответственности: долг есть, спросить не с кого. Поэтому она красная
   и стоит рядом с остальными, а не прячется в «Сервисе». */

/* Четыре карточки: «Все», Коммерция, Сервис и счета без ответственного. */
.dirs { display:grid; grid-template-columns:repeat(4,1fr); gap:var(--gap); margin-bottom:14px; }
@media (max-width:1000px) { .dirs { grid-template-columns:repeat(2,1fr); } }
.dir {
  display:block; padding:11px 13px; border:1px solid var(--line); border-radius:var(--radius);
  background:var(--surface); color:inherit; text-decoration:none; border-left:3px solid var(--line);
  transition:border-color .12s, background .12s;
}
.dir:hover { border-color:var(--line-2); text-decoration:none; }
.dir[aria-pressed="true"] { border-color:var(--accent); background:var(--accent-soft); }
.dir-t { display:flex; align-items:center; gap:7px; font-size:var(--fs-sm); color:var(--ink-3); }
.dir-v { font-family:var(--ff-num); font-variant-numeric:tabular-nums;
         font-size:20px; font-weight:600; margin-top:4px; letter-spacing:-.02em; }
.dir-s { font-size:var(--fs-xs); color:var(--ink-4); margin-top:2px; }
/* Незакрытая ответственность видна и без чтения подписи: красная
   грань слева и красное число. Ноль в этой карточке — хорошая новость,
   и тогда она не кричит. */
.dir-problem { border-left-color:var(--red); }
.dir-problem .dir-v { color:var(--red); }

/* ========================== ПОЯСНЕНИЕ «i» ======================= */
/* Текст, который нужен один раз, а место занимает всегда. Кнопка «i»
   у заголовка раскрывает его поверх содержимого. Работает на <details>
   без единой строки скрипта, значит доступна с клавиатуры и не ломается,
   если скрипт не загрузился. */

.hintbox { display:inline-block; position:relative; vertical-align:middle; margin-left:8px; }
/* У крупного заголовка кнопка не должна расти вместе с ним: она
   служебная, а не часть названия раздела. */
h1 .hintbox { vertical-align:middle; margin-left:10px; position:relative; top:-3px; }
.hintbox > summary {
  list-style:none; cursor:pointer; width:18px; height:18px; border-radius:50%;
  display:inline-flex; align-items:center; justify-content:center;
  border:1px solid var(--line-2); background:var(--surface);
  color:var(--ink-3); font-size:var(--fs-xs); font-weight:700; font-style:italic;
  font-family:var(--ff-num); line-height:1; user-select:none;
}
.hintbox > summary::-webkit-details-marker { display:none; }
.hintbox > summary:hover { border-color:var(--accent); color:var(--accent); }
.hintbox[open] > summary { border-color:var(--accent); background:var(--accent-soft); color:var(--accent); }
.hintbox-body {
  position:absolute; z-index:40; top:calc(100% + 6px); left:0; width:min(420px, calc(100vw - 48px));
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius);
  box-shadow:0 14px 34px rgba(10,16,26,.16);
  padding:12px 14px; font-size:var(--fs-sm); font-weight:400; line-height:1.5; color:var(--ink-2);
}
/* Подсказка у последней колонки таблицы уезжала за правый край, и текст
   обрезался. Класс ставит `portal.js`, измерив место: не «последняя
   колонка — всегда влево», а «влево, если иначе не помещается». */
.hintbox-body.hint-left { left:auto; right:0; }

/* ============================ ВКЛАДКИ =========================== */

/* Вкладки переносятся на вторую строку, а не прокручиваются.
   Горизонтальная прокрутка прячет крайние вкладки: юрлиц десять, и
   последние просто не существуют для того, кто не догадался
   потянуть полосу вбок. Перенос показывает все сразу. */
.tabs { display:flex; flex-wrap:wrap; gap:2px 0; border-bottom:1px solid var(--line); }
.tab {
  background:none; border:0; padding:9px 13px; font-size:var(--fs-sm); color:var(--ink-3);
  border-bottom:2px solid transparent; white-space:nowrap;
}
.tab[aria-selected="true"] { color:var(--ink); font-weight:600; border-bottom-color:var(--accent); }
/* Вкладка-ссылка: у переключателя юрлиц адрес должен открываться в
   новой вкладке браузера и попадать в закладки, значит это ссылка,
   а не кнопка. Выглядеть при этом должна так же. */
a.tab { text-decoration:none; display:flex; flex-direction:column; gap:1px; line-height:1.25; }
a.tab:hover { text-decoration:none; color:var(--ink); }
.tab-sum { font-family:var(--ff-num); font-variant-numeric:tabular-nums; font-size:var(--fs-xs); color:var(--ink-4); }
a.tab[aria-selected="true"] .tab-sum { color:var(--ink-3); }

/* Переключатель-ссылка внутри .seg — там же, где кнопки темы. */
.seg a { display:inline-flex; align-items:center; background:var(--surface); border:0;
         padding:6px 11px; font-size:var(--fs-sm); color:var(--ink-3); text-decoration:none; }
.seg a:hover { text-decoration:none; background:var(--surface-2); }
.seg a[aria-pressed="true"] { background:var(--accent-soft); color:var(--accent); font-weight:500; }

/* Строка фильтров над таблицей. */
.filters { display:flex; flex-wrap:wrap; gap:10px; align-items:flex-end; }
.filters .field { margin:0; min-width:170px; }
.filters .field .input { width:100%; }
.filters .field-narrow { min-width:120px; }

/* Сворачиваемая панель. На широком экране заголовок не нужен —
   содержимое просто лежит на странице; на узком превращается в
   кнопку, потому что семь полей фильтров занимают там целый экран
   и отодвигают таблицу за нижний край.
   Свёрнутость на телефоне ставит portal.js: без скрипта панель
   останется раскрытой, и это правильная деградация — данные видны. */
.panel > summary {
  display:none; list-style:none; cursor:pointer; user-select:none;
  align-items:center; gap:8px; padding:2px 0 12px;
  font-size:var(--fs-sm); font-weight:600; color:var(--ink-2);
}
.panel > summary::-webkit-details-marker { display:none; }
.panel > summary .marker { color:var(--ink-4); font-weight:400; }

/* ============================ ТАБЛИЦА =========================== */

.tbl { width:100%; border-collapse:collapse; }
.tbl th {
  text-align:left; font-size:var(--fs-xs); letter-spacing:.06em; text-transform:uppercase;
  color:var(--ink-3); font-weight:600; padding:0 12px 9px 0; white-space:nowrap;
}
.tbl td { padding:var(--row-y) 12px var(--row-y) 0; border-top:1px solid var(--line); vertical-align:middle; }
.tbl tbody tr:hover td { background:var(--surface-2); }
.tbl .r { text-align:right; padding-right:12px; }
.lead-cell { border-left:2px solid transparent; padding-left:10px !important; }
tr[data-s="red"] .lead-cell { border-left-color:var(--red); }
tr[data-s="amber"] .lead-cell { border-left-color:var(--amber); }
tr[data-s="green"] .lead-cell { border-left-color:var(--green); }
/* Серая полоса — «запись выключена». Не цвет статуса, а его отсутствие:
   отключённая учётная запись не требует действия, она просто не в игре. */
tr[data-s="neutral"] .lead-cell { border-left-color:var(--line-2); }
tr[data-s="neutral"] td { color:var(--ink-4); }
.tbl-scroll { overflow-x:auto; }

/* Первая колонка закреплена при прокрутке вбок не только на телефоне
   (там это правило ниже, в мобильном @media, и держится безусловно для
   любой `.tbl-scroll`) — модификатор `.tbl-pin` включает то же самое на
   любой ширине экрана. Отчёты ОПиУ (`mgmt/_report_table.html`) — 14+
   колонок (сравнение ЦФО/городов), таблица переполняет `.tbl-scroll`
   уже на обычном мониторе, и без закрепления прокрутивший вправо теряет
   из виду, к какой строке относится цифра. Точечный модификатор, а не
   правило на весь `.tbl-scroll`, — чтобы не менять поведение остальных,
   более узких таблиц портала на desktop. */
/* `border-collapse:collapse` (правило `.tbl` выше) не даёт `position:sticky`
   рисоваться на table-ячейках в Chromium — геометрия верная, а закреплённая
   ячейка визуально пропадает при прокрутке.
   `separate`+`border-spacing:0` — только для закреплённых таблиц, не для
   всех `.tbl` сайта: `border-top` у каждой строки при этом не задваивается,
   потому что снизу к ячейкам ничего не подмешано. */
.tbl-scroll.tbl-pin { --tbl-bg:var(--paper); }
.card .tbl-scroll.tbl-pin, .card-b .tbl-scroll.tbl-pin { --tbl-bg:var(--surface); }
.tbl-scroll.tbl-pin .tbl { border-collapse:separate; border-spacing:0; }
.tbl-scroll.tbl-pin .tbl th:first-child,
.tbl-scroll.tbl-pin .tbl td:first-child {
  position:sticky; left:0; z-index:2;
  background:var(--tbl-bg); box-shadow:1px 0 0 var(--line);
  min-width:185px; padding-right:10px;
  /* Без своего composite-слоя Chromium иногда красит закреплённую
     ячейку ПОД соседями той же строки, которые уже прокрутились —
     видно хвост чужой колонки сквозь неё. `will-change` поднимает
     ячейку в отдельный слой, и она снова красится поверх. */
  will-change:transform;
}
.tbl-scroll.tbl-pin .tbl thead th:first-child { z-index:3; }
.tbl-scroll.tbl-pin .tbl tbody tr:hover td:first-child { background:var(--surface-2); }

/* Дочерние строки-группы и статьи отчёта ОПиУ (mgmt/_report_line.html).
   Прятать их правилом вида `tr[data-rl-parent]:not(.rl-open)` нельзя —
   без скрипта такое правило запирает дерево навсегда, показывать
   нечем. Поэтому класс `rl-collapsible` навешивает сам `portal.js`
   (`wireReportRows`) уже в рантайме: не выполнился скрипт — класса нет
   ни у одной строки, и дерево отчёта видно целиком. */
tr.rl-collapsible:not(.rl-open) { display:none; }
.rl-toggle {
  width:14px; height:14px; margin:0 6px 0 0; padding:0; border:0; background:transparent;
  cursor:pointer; position:relative; vertical-align:middle; flex:none;
}
.rl-toggle::before {
  content:""; position:absolute; left:2px; top:2px; width:6px; height:6px;
  border-right:1.5px solid var(--ink-4); border-bottom:1.5px solid var(--ink-4);
  transform:rotate(-45deg); transition:transform .15s ease;
}
.rl-toggle[aria-expanded="true"]::before { transform:rotate(45deg); }
/* Отступ по уровню вложенности — не более двух: строка дерева, дочерняя
   группа, статья. `!important` перебивает `.lead-cell` (тоже
   `!important`, ей самой нужно перекрыть более общее правило `.tbl td`). */
.lead-cell.rl-d1 { padding-left:26px !important; }
.lead-cell.rl-d2 { padding-left:42px !important; }
/* Статья — вспомогательная строка, а не равная строкам отчёта: мельче
   и светлее, той же парой токенов, что и `.note`. */
tr.rl-article td { color:var(--ink-3); font-size:var(--fs-sm); }

/* ============================ KPI =============================== */

.kpi { background:var(--surface); border:1px solid var(--line); border-radius:var(--radius); padding:13px 14px; }
.kpi-l { font-size:var(--fs-xs); letter-spacing:.08em; text-transform:uppercase; color:var(--ink-3); font-weight:600; }
.kpi-v {
  font-family:var(--ff-num); font-variant-numeric:tabular-nums; font-size:23px; font-weight:600;
  margin-top:6px; letter-spacing:-.02em;
}
/* Широкой таблице нужна ширина и на большом экране: девять колонок с
   пояснениями браузер иначе ужимает так, что название контрагента
   переносится по слову. Контейнер прокручивается — это честнее, чем
   нечитаемая первая колонка. */
.tbl-wide { min-width:1040px; }
/* Таблица с подписями вместо чисел шире обычной: колонки «Текущий шаг»
   и «Просрочено» несут фразу, а не число. */
.tbl-wider { min-width:1320px; }
.tbl .lead-cell { min-width:190px; }

/* Строка таблицы, окрашенная по смыслу: RFM красит по давности сделки —
   активные зелёным, в зоне риска жёлтым, потерянные красным.

   Заливка мягкая, из тех же токенов, что у статусов: текст на ней
   остаётся читаемым, а строка не превращается в вывеску. Цвет здесь не
   единственный носитель смысла — рядом с кодом стоит точка, а уровень
   назван словом. */
tr[data-tone="green"] > td { background:var(--green-soft); }
tr[data-tone="amber"] > td { background:var(--amber-soft); }
tr[data-tone="red"]   > td { background:var(--red-soft); }

/* Строка, по которой можно щёлкнуть, обязана выглядеть нажимаемой:
   курсор, подсветка под указателем и заметная рамка у выбранной. */
/* Выжимка свёрнутой таблицы сегментов: пять крупнейших строкой.
   Видна, только пока полная таблица закрыта — открытая таблица
   начинается с тех же пяти, и повторять их незачем. */
.seg-preview { display:flex; flex-direction:column; gap:2px; margin:0 0 22px; }
details[open] + .seg-preview { display:none; }
.seg-line {
  display:flex; align-items:center; gap:10px; padding:6px 10px;
  border:1px solid transparent; border-radius:var(--radius-sm);
  color:inherit; text-decoration:none; font-size:var(--fs-sm);
}
.seg-line:hover { border-color:var(--line-2); }
.seg-line.chosen { border-color:var(--accent); font-weight:500; }
.seg-line[data-tone="green"] { background:var(--green-soft); }
.seg-line[data-tone="amber"] { background:var(--amber-soft); }
.seg-line[data-tone="red"]   { background:var(--red-soft); }
.seg-line .seg-name { flex:1; min-width:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap; }

/* Точка перед кодом сегмента. Отступ задан здесь, а не пробелом в
   разметке: `spaceless` убирает пробелы между тегами, и точка
   склеивалась с числом. */
.tbl td .dot { margin-right:6px; }

tr.pickable { cursor:pointer; }
tr.pickable:hover > td { filter:brightness(0.97); }
tr.pickable.chosen > td {
  box-shadow:inset 0 1px 0 var(--accent), inset 0 -1px 0 var(--accent);
  font-weight:500;
}
tr.pickable.chosen > td:first-child { box-shadow:inset 2px 1px 0 var(--accent), inset 0 -1px 0 var(--accent); }
tr.pickable.chosen > td:last-child { box-shadow:inset -2px 1px 0 var(--accent), inset 0 -1px 0 var(--accent); }

/* Число в ячейке таблицы, окрашенное по смыслу: средний срок оплаты
   зелёный до порога и красный за ним. Пороги живут в настройках, а не
   здесь — CSS только знает, как выглядит «хорошо» и «плохо». */
td[data-s="green"] { color:var(--green); }
td[data-s="red"] { color:var(--red); }
td[data-s="amber"] { color:var(--amber); }

/* Показатель, посчитанный по горстке записей. Приглушён намеренно:
   число верное, но опираться на него нельзя, и выглядеть наравне с
   посчитанным по сотне счетов оно не должно. */
td.thin, td.thin[data-s] { color:var(--ink-4); }

/* Кнопка «i» в заголовке колонки. Всплывающий текст открывается вниз,
   поверх строк, и потому не обрезается контейнером с горизонтальной
   прокруткой. У короткой таблицы строк снизу может не хватить —
   тогда контейнеру добавляется место ровно на время, пока подсказка
   открыта. */
.tbl th .hintbox { margin-left:6px; }
.tbl th .hintbox-body { font-weight:400; text-transform:none; letter-spacing:0; }
.tbl-scroll:has(.hintbox[open]) { padding-bottom:170px; }

.kpi-v[data-s="red"] { color:var(--red); }
.kpi-v[data-s="amber"] { color:var(--amber); }
.kpi-v[data-s="green"] { color:var(--green); }
.kpi-s { font-size:var(--fs-sm); color:var(--ink-3); margin-top:3px; }

/* ============================ АЛЕРТЫ ============================ */

.alert {
  display:flex; gap:11px; padding:12px 14px; border-radius:var(--radius); border:1px solid var(--line);
  background:var(--surface); border-left-width:3px;
}
.alert b { display:block; font-size:var(--fs-sm); }
.alert p { margin:3px 0 0; font-size:var(--fs-sm); color:var(--ink-2); }
.a-red { border-left-color:var(--red); background:var(--red-soft); }
.a-amber { border-left-color:var(--amber); background:var(--amber-soft); }
.a-green { border-left-color:var(--green); background:var(--green-soft); }
.a-info { border-left-color:var(--accent); background:var(--accent-soft); }

/* ============================ ПРОЧЕЕ ============================ */

.empty { text-align:center; padding:34px 20px; }
.empty h3 { margin-bottom:6px; }

/* Временный пароль. Показывается ровно один раз — значит должен
   читаться с первого взгляда и без ошибок: крупно, моноширинным,
   с разрядкой, чтобы буквы не слипались, когда его диктуют вслух. */
.secret {
  display:inline-block; margin:6px 0 2px;
  font-family:var(--ff-num); font-size:26px; font-weight:600;
  letter-spacing:.08em; color:var(--ink);
  background:var(--surface); border:1px dashed var(--line-2);
  border-radius:var(--radius); padding:10px 16px; user-select:all;
}

/* Строка действий в ячейке таблицы: кнопки в ряд, перенос разрешён —
   на узком экране они складываются, а не выдавливают таблицу. */
.row-actions { display:flex; flex-wrap:wrap; gap:6px; align-items:center; }
.row-actions form { margin:0; display:flex; gap:6px; align-items:center; }
/* Селект в ячейке не тянется на всю ширину: иначе кнопка рядом
   переносится на вторую строку и таблица теряет ритм. */
.row-actions .input { width:auto; min-width:140px; }

.modal {
  background:var(--surface); border:1px solid var(--line); border-radius:var(--radius);
  box-shadow:0 18px 48px rgba(10,16,26,.18); max-width:420px;
}
.toast {
  display:flex; align-items:center; gap:10px; background:var(--ink); color:var(--paper);
  padding:11px 14px; border-radius:var(--radius); font-size:var(--fs-sm); max-width:400px;
}

.rules { display:grid; gap:10px; }
.rule { display:flex; gap:10px; align-items:flex-start; font-size:var(--fs-sm); color:var(--ink-2); }
.rule i { font-style:normal; font-weight:700; flex:none; width:18px; }
.yes i { color:var(--green); }
.no i { color:var(--red); }

/* ======================= МОБИЛЬНАЯ ВЕРСИЯ ======================= */
/* Портал открывают с телефона — обычно чтобы посмотреть цифру, а не
   разбирать портфель. Поэтому на узком экране:
     показатели идут в одну колонку и читаются пролистыванием;
     полоса возраста остаётся во всю ширину, подписи уходят под неё;
     таблица прокручивается вбок, но контрагент закреплён — иначе
       через две колонки становится непонятно, чей это долг;
     фильтры сворачиваются в панель.
   Ничего не прячется совсем: спрятанное на телефоне поле человек
   ищет потом и на компьютере. */

@media (max-width:1100px) {
  .g5 { grid-template-columns:repeat(2,1fr); }
}

@media (max-width:760px) {
  .wrap { padding:0 16px; }
  .main { padding:16px; }

  h1 { font-size:24px; }

  /* Переключатель переносится по словам. На узком экране четыре
     подписи в одну строку шире экрана, и страница начинает ездить
     вбок целиком — вместе с таблицей, у которой прокрутка своя. */
  .seg { flex-wrap:wrap; }

  /* Показатели, направления и подписи полосы — в одну колонку.
     Две колонки на 360 точках дают числа, которые не помещаются
     в ячейку и переносятся посреди разряда. */
  .g5, .g2, .g3, .g4 { grid-template-columns:1fr; }
  .dirs { grid-template-columns:1fr; gap:8px; }
  .band-legend { grid-template-columns:1fr; gap:6px; }
  .band-cell { display:flex; align-items:baseline; gap:10px; flex-wrap:wrap; }
  .band-cell .band-v { margin-top:0; margin-left:auto; }
  .band-cell .band-s { flex-basis:100%; }

  /* Полоса остаётся во всю ширину, но проценты внутри зон на узком
     экране не читаются — их место под полосой, в подписях. */
  .band { height:26px; }
  .band-part { font-size:10px; }

  .kpi-v { font-size:20px; }
  .dir-v { font-size:18px; }

  /* Заголовок карточки и пояснение справа от него на 390 точках
     не помещаются в одну строку и слипаются. Пусть подпись уходит
     под заголовок целиком. */
  .card-h { flex-wrap:wrap; gap:2px 12px; }
  .card-h .note { flex-basis:100%; }

  /* Строка итога и кнопка — по левому краю, под заголовком: прижатые
     вправо, они на узком экране висят в воздухе. */
  .lazy-side { width:100%; justify-content:flex-start; gap:8px 12px; margin-top:4px; }
  .lazy-sum { flex-basis:100%; }

  .colors-cell { flex:1 1 100%; }

  /* Фильтры: панель со своим заголовком, поля во всю ширину. */
  .panel > summary { display:flex; }
  .filters .field { min-width:0; flex:1 1 100%; }
  /* «Возраст от» и «до» — пара, и на телефоне тоже: два коротких
     числовых поля рядом читаются как диапазон, друг под другом — нет. */
  .filters .field-narrow { flex:1 1 calc(50% - 5px); }

  /* График на экране телефона сжимается вчетверо вместе с подписями,
     и даты под осью перестают читаться совсем. Поэтому он, как и
     таблица, прокручивается вбок: лучше движение пальцем, чем
     нечитаемые цифры. Кому неудобно — под графиком те же числа
     таблицей. */
  .chart { overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .chart-svg { min-width:720px; }
  .chart-tick { font-size:13px; }

  /* Таблица: прокрутка вбок с закреплённой первой колонкой.
     Фон подставляется под то, на чём лежит таблица, иначе строки
     просвечивают сквозь закреплённую ячейку при прокрутке. */
  .tbl-scroll { --tbl-bg:var(--paper); overflow-x:auto; -webkit-overflow-scrolling:touch; }
  .card .tbl-scroll, .card-b .tbl-scroll { --tbl-bg:var(--surface); }
  /* Ширина ставится таблице, а не колонкам: без неё браузер ужимает
     восемь колонок в экран телефона, и контрагент переносится по
     слову — «ООО» на одной строке, «Клиент 11» на четырёх. */
  .tbl-wide { min-width:900px; }
  .tbl-scroll .tbl th:first-child,
  .tbl-scroll .tbl td:first-child {
    position:sticky; left:0; z-index:2;
    background:var(--tbl-bg); box-shadow:1px 0 0 var(--line);
    min-width:185px; padding-right:10px;
  }
  .tbl-scroll .tbl thead th:first-child { z-index:3; }
  .tbl-scroll .tbl tbody tr:hover td:first-child { background:var(--surface-2); }
  /* Пустая строка «ничего не найдено» растянута на все колонки —
     закреплять её нечего и не нужно. */
  .tbl td[colspan] { position:static; max-width:none; box-shadow:none; }
}

/* ============================ ВХОД ============================== */
/* Страница входа живёт без бокового меню: пока человек не вошёл,
   разделов для него не существует. */

.auth { min-height:100vh; display:flex; align-items:center; justify-content:center; padding:24px; }
.auth-box { width:100%; max-width:400px; }
.auth-brand { text-align:center; margin-bottom:20px; }
.auth-brand b { display:block; font-size:19px; font-weight:600; letter-spacing:-.01em; }
.auth-brand span { font-size:var(--fs-sm); color:var(--ink-3); }
.auth-wide { max-width:560px; }
.auth-foot { text-align:center; margin-top:16px; font-size:var(--fs-sm); color:var(--ink-3); }

/* ====================== КАРТОЧКА КОНТРАГЕНТА ==================== */
/* Шапка: реквизиты в ряд, долг справа крупно. На узком экране — в
   колонку: четыре ячейки на 390 точках дают по два слова на строку. */

.cp-head { display:grid; grid-template-columns:repeat(4, 1fr); gap:var(--gap); align-items:start; }
.cp-actions {
  display:flex; align-items:center; justify-content:space-between;
  gap:12px; flex-wrap:wrap; margin-top:16px; padding-top:14px;
  border-top:1px solid var(--line);
}
.cp-actions .foldout { flex:1 1 340px; margin-top:0; border-top:0; padding-top:0; }
.cp-actions .foldout > summary { display:flex; align-items:center; gap:8px; }

@media (max-width:900px) { .cp-head { grid-template-columns:repeat(2, 1fr); } }
@media (max-width:760px) { .cp-head { grid-template-columns:1fr; } }
