/* app-record.css — общие компоненты «список записей».
   Заведён 16.08.2026 по п. 2 заданий 02-documents.md и 03-accounting.md.

   Причина: одна и та же болезнь лечилась постранично уже трижды. Строка
   таблицы разрасталась до 300 px, состояние говорилось пятью способами,
   действия стояли столбиком ссылок. Сначала это чинили в
   `documents_queue.css`, потом то же самое понадобилось в `accounting.css`,
   дальше будут объекты и контрагенты. Поэтому определения переехали сюда,
   в файл, который `base.html` подключает всем страницам.

   Что здесь лежит:

     .rec-tiles / .rec-tile   — плитки показателей (одна геометрия на весь
                                продукт; `.today-tile` — второе имя того же
                                компонента, чтобы не переписывать главную)
     .rec-table               — плотная таблица записей: строка = строка
     .rec-line / .rec-sub     — главная строка ячейки и подпись под ней
     .rec-state               — состояние ОДНИМ каналом: точка + слово
     .rec-chain               — цепочка связей четырьмя метками, а не
                                четырьмя ссылками в столбик
     .rec-menu                — «…» на строке (`.docs-more-menu` — второе имя)
     .status-compact          — переехало из `documents_queue.css`

   Правило, ради которого всё это существует (канон проекта): **у строки
   один цветовой канал состояния** — полоса слева. Всё остальное внутри
   строки нейтрального цвета. */

/* ─────────────────── плитки показателей ─────────────────── */

/* Группа плиток с явной подписью периода. Пять плиток в ряд, где три
   считают месяц, а две — всю историю, читаются как одна шкала и врут
   глазу; подпись группы называет период вслух. */
.rec-tile-group {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  min-width: 0;
}

.rec-tile-group__title {
  margin: 0;
  font-size: var(--font-size-sm);
  font-weight: 700;
  letter-spacing: 0.02em;
  line-height: var(--line-height-tight);
  color: var(--text-secondary);
}

.rec-tile-groups {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  gap: var(--space-4);
  align-items: start;
}

.rec-tiles,
.today-tiles {
  display: grid;
  gap: var(--space-3);
  grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
}

.today-tiles--3,
.today-tiles--4 {
  grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
}

/* ── реестр старения долга ──────────────────────────────────────────── */
/* Нужен и на главной, и в «Финансах» (решение Tim 17.08.2026), поэтому
   объявлен здесь и сразу под двумя именами — как .rec-tile / .today-tile.
   Строка читается слева направо: срок → доля полосой → сумма → сколько
   ожиданий. Полоса нужна, чтобы перекос было видно, не сравнивая цифры. */
.rec-aging,
.today-aging {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  background: var(--surface-primary);
  overflow: clip;
}

.rec-aging__row,
.today-aging__row {
  display: grid;
  /* 09.09.2026: добавлена колонка доли. Полоса сравнивает корзины между
     собой, а процент — доля от всей просрочки; без него полоса отвечает на
     один вопрос, а число рядом на другой. */
  grid-template-columns:
    minmax(120px, auto) minmax(80px, 1fr) minmax(120px, auto)
    44px 44px;
  align-items: center;
  gap: var(--space-3);
  padding: 10px var(--space-4);
  min-height: 44px;
  color: inherit;
  text-decoration: none;
  border-top: 1px solid var(--border-color);
}

.rec-aging__row:first-child,
.today-aging__row:first-child {
  border-top: 0;
}

.rec-aging__row:hover,
.today-aging__row:hover {
  background: var(--surface-secondary);
}

/* Пустая корзина не должна выглядеть как проблема: гасим её целиком,
   но не убираем — отсутствие долга в интервале это тоже сведение. */
.rec-aging__row.is-empty,
.today-aging__row.is-empty {
  color: var(--text-secondary);
}

.rec-aging__label,
.today-aging__label {
  font-size: var(--font-size-sm);
}

.rec-aging__bar,
.today-aging__bar {
  display: block;
  height: 6px;
  border-radius: 999px;
  background: var(--surface-tertiary);
  overflow: clip;
}

.rec-aging__fill,
.today-aging__fill {
  display: block;
  height: 100%;
  border-radius: 999px;
  background: var(--accent-interactive);
}

/* Долг старше 90 дней — не сегодняшняя работа, и цветом он не кричит:
   отдельный оттенок, а не тревожный красный. Красным на этом экране
   помечено то, что требует действия сейчас. */
.rec-aging__row.is-stale .rec-aging__fill,
.today-aging__row.is-stale .today-aging__fill {
  background: var(--text-secondary);
}

/* Непустая корзина видна даже при одном проценте: «мало» не должно
   выглядеть как «ничего». 09.09.2026 */
.rec-aging__row:not(.is-empty) .rec-aging__fill,
.today-aging__row:not(.is-empty) .today-aging__fill {
  min-width: 6px;
}

.rec-aging__amount,
.today-aging__amount {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  font-size: var(--font-size-sm);
}

.rec-aging__count,
.today-aging__count {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
}

/* Доля корзины во всей просрочке. Полоса показывает соотношение корзин
   между собой, а это число — сколько от общего долга. 09.09.2026 */
.rec-aging__share,
.today-aging__share {
  text-align: right;
  font-variant-numeric: tabular-nums;
  font-size: var(--font-size-xs);
}

/* Подпись справа от заголовка раздела: итог, чтобы разложение не
   заставляло складывать четыре числа в уме. */
.today-section__aside {
  margin-left: var(--space-2);
  font-weight: 500;
  color: var(--text-secondary);
}

/* Оговорка под «Долгом по срокам»: пока выписки не заведены, это не долг
   арендаторов, а все начисления с прошедшим сроком. Без неё самое крупное
   число на экране читается неправильно. 08.09.2026, отчёт 189. */
.today-aging__caveat {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-xs);
  line-height: 1.4;
  color: var(--text-secondary);
  border-left: 3px solid var(--warning-500);
  padding-left: var(--space-2);
}

.today-section__link {
  margin-left: auto;
  font-size: var(--font-size-xs);
  font-weight: 600;
  color: var(--link-color);
  text-decoration: none;
}

.today-section__link:hover {
  text-decoration: underline;
}

@media (max-width: 640px) {
  .rec-aging__row,
  .today-aging__row {
    grid-template-columns: 1fr auto;
    row-gap: 4px;
  }

  .rec-aging__bar,
  .today-aging__bar {
    grid-column: 1 / -1;
    order: 3;
  }

  .rec-aging__count,
  .today-aging__count {
    display: none;
  }

  /* На узком экране доля важнее счётчика: она объясняет длину полосы. */
  .rec-aging__share,
  .today-aging__share {
    order: 2;
  }
}

.rec-tile,
.today-tile {
  display: block;
  padding: var(--card-padding-sm, 16px);
  border: 1px solid var(--card-border);
  border-radius: var(--radius-lg);
  background: var(--card-bg);
  color: var(--text-primary);
  text-decoration: none;
  transition: background-color 0.16s ease;
}

a.rec-tile:hover,
a.today-tile:hover,
button.rec-tile:hover {
  background: var(--surface-hover);
  color: var(--text-primary);
}

.rec-tile__label,
.today-tile__label {
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
  line-height: var(--line-height-tight);
}

.rec-tile__value,
.today-tile__value {
  margin-top: var(--space-2);
  font-size: var(--font-size-2xl);
  font-weight: 700;
  line-height: var(--line-height-tight);
  letter-spacing: -0.01em;
  color: var(--text-primary);
  /* Сумма не должна рваться переносом посреди разрядов.
   *
   * Здесь стояло `overflow-wrap: anywhere`, которое делает ровно
   * обратное — разрешает разрыв в любом месте. На телефоне «518 458 ₽»
   * разрывалось, и знак рубля уезжал на вторую строку. Разряды и знак
   * валюты Intl и так соединяет неразрывным пробелом; нам остаётся не
   * ломать это правилом переноса. Чтобы длинная сумма при этом не
   * вылезала за плитку, на узком экране уменьшается кегль — ниже.
   * 18.08.2026 */
  overflow-wrap: normal;
}

.rec-tile__note,
.today-tile__note {
  margin-top: var(--space-1);
  font-size: var(--font-size-xs);
  color: var(--text-muted);
  line-height: var(--line-height-tight);
}

.rec-tile--danger .rec-tile__value,
.today-tile--danger .today-tile__value {
  color: var(--status-error-text);
}

/* ─────────────────── строка записи ─────────────────── */

/* Целевая высота строки — 56–72 px. Достигается тремя вещами сразу:
   паддинг 8/12, вертикальное выравнивание по середине и запрет на
   вторую строку текста в ячейке (`.rec-line`). Ни одна из трёх не
   работает без остальных: с `vertical-align: top` строка растёт от
   самой высокой ячейки, а без `.rec-line` растёт от самого длинного
   названия объекта. */
.rec-table {
  width: 100%;
  border-collapse: collapse;
  table-layout: fixed;
}

.rec-table th,
.rec-table td {
  padding: 8px 12px;
  vertical-align: middle;
  border-bottom: 1px solid var(--border-color);
  font-size: var(--font-size-sm);
}

/* Слово длиннее колонки переносится, а не выпирает в соседнюю ячейку
   («АВИАКОНСТРУКТОРОВ», «Водоотведение(соглашение…)» — замер 03.10.2026,
   ЛК Водоканала до 1366 px). `break-word` рвёт только то, что иначе не
   помещается: суммы с неразрывными пробелами в своей колонке целы.
   Обрезка многоточием (`.rec-line`, nowrap) этим не затрагивается. */
.rec-table td {
  overflow-wrap: break-word;
}

.rec-table thead th {
  /* Было --surface-secondary: 1,05 к карточке, шапка сливалась с телом
     таблицы. Токен --table-header-bg существовал с 12.08 и не был
     подключён нигде — подключён. 23.08.2026 */
  background: var(--table-header-bg);
  color: var(--text-secondary);
  font-size: var(--font-size-xs);
  font-weight: 600;
  text-align: left;
  /* Было `nowrap`: при `table-layout: fixed` колонка не растёт под
     заголовок, и «Долг по коммуналке», «Следующая поверка» наезжали на
     соседний заголовок (замер 03.10.2026: «Остатки», ЛК Водоканала
     860–1180, «Финансы» 860). Заголовок переносится по словам. */
  white-space: normal;
  overflow-wrap: break-word;
  vertical-align: bottom;
  letter-spacing: 0.02em;
}

.rec-table thead th[data-sort] {
  cursor: pointer;
  user-select: none;
}

.rec-table tbody tr {
  /* Полоса состояния слева — единственный цветной канал строки.
     Прозрачная по умолчанию, чтобы текст не ездил на 3 px, когда
     состояние меняется. */
  border-left: 3px solid transparent;
}

.rec-table tbody tr:hover {
  background: var(--surface-hover);
}

/* Специфичность, а не флаг: базовое правило выше — `.rec-table tbody tr`
   (0,1,2), и одиночный класс его не перебивал. Селектор с тем же
   контекстом даёт (0,2,2) и выигрывает честно. 17.08.2026 */
.rec-table tbody tr.rec-row--warning {
  border-left-color: var(--warning-500);
}

.rec-table tbody tr.rec-row--danger {
  border-left-color: var(--danger-500);
}

.rec-row--muted td {
  opacity: 0.55;
}

.rec-line {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-primary);
  line-height: var(--line-height-tight);
}

.rec-sub {
  display: block;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  margin-top: 2px;
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
  line-height: var(--line-height-tight);
}

.rec-amount {
  display: block;
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  color: var(--text-primary);
}

/* ─────────────────── состояние одним каналом ─────────────────── */

.rec-state {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  min-width: 0;
  max-width: 100%;
}

.rec-state__dot {
  flex: 0 0 auto;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--text-muted);
}

.rec-state--ok .rec-state__dot {
  background: var(--success-500);
}

.rec-state--warning .rec-state__dot {
  background: var(--warning-500);
}

.rec-state--danger .rec-state__dot {
  background: var(--danger-500);
}

.rec-state__text {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--text-primary);
}

/* ─────────────────── цепочка связей ─────────────────── */

/* Было: четыре ссылки-чипа со стрелками между ними — в узкой колонке
   они переносились и добавляли строке до 90 px. Стало: четыре метки по
   одной букве. Что связано — заполнено, чего нет — обведено пунктиром.
   Расшифровка в подсказке к ячейке. */
.rec-chain {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  cursor: help;
}

.rec-chain__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: var(--radius-sm);
  border: 1px dashed var(--border-color-strong);
  background: transparent;
  color: var(--text-muted);
  font-size: 10px;
  font-weight: 700;
  line-height: 1;
  text-decoration: none;
}

/* Заливка `--surface-tertiary` в тёмной теме почти совпадает с фоном
   карточки (#1f2a36 против #1e293b) — замер 16.08.2026: связанная и
   несвязанная метки выглядели одинаково. Различаем по обводке: сплошная
   и яркая против пунктирной и приглушённой. */
.rec-chain__link.is-on {
  border-style: solid;
  border-color: currentColor;
  background: transparent;
  color: var(--text-primary);
}

/* Прозрачность у «пустой» метки не ставим: `--text-muted` даёт 5,7:1 к
   фону карточки, а 60 % прозрачности роняли контраст до ~2,9:1 — ниже
   порога 4,5:1. Разница читается обводкой: сплошная против пунктирной. */

a.rec-chain__link.is-on:hover {
  background: var(--surface-hover);
  color: var(--text-primary);
}

/* ─────────────────── меню «…» ─────────────────── */

/* Ячейка, в которой только меню «…»: колонка у страниц 44–48 px, отступы
   ячейки 12+12 — кнопке 32 px оставалось 20, и она вылезала к краю строки
   (замер 03.10.2026: «Финансы», «Договоры» на всех ширинах). */
.rec-table td:has(> .rec-menu:only-child),
.rec-table td:has(> .docs-more-menu:only-child) {
  padding-left: 4px;
  padding-right: 4px;
  text-align: center;
}

.rec-menu,
.docs-more-menu {
  position: relative;
}

.rec-menu__trigger,
.docs-more-menu__trigger {
  list-style: none;
  cursor: pointer;
}

/* Треугольник-маркер `<summary>` рисуют по-разному: в WebKit это
   ::-webkit-details-marker, в остальных — ::marker. Гасим оба. */
.rec-menu__trigger::-webkit-details-marker,
.rec-menu__trigger::marker,
.docs-more-menu__trigger::-webkit-details-marker,
.docs-more-menu__trigger::marker {
  display: none;
  content: "";
}

.rec-menu__list,
.docs-more-menu__list {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 40;
  min-width: 220px;
  display: flex;
  flex-direction: column;
  padding: var(--space-1);
  border: 1px solid var(--card-border);
  border-radius: var(--radius-md);
  background: var(--card-bg);
  box-shadow: var(--shadow-lg);
}

.rec-menu__item,
.docs-more-menu__item {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  width: 100%;
  padding: var(--space-2);
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text-primary);
  font-size: var(--font-size-sm);
  text-align: left;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}

.rec-menu__item:hover,
.docs-more-menu__item:hover {
  background: var(--surface-hover);
  color: var(--text-primary);
}

.rec-menu__item i,
.docs-more-menu__item i {
  width: 16px;
  color: var(--text-secondary);
}

.rec-menu__item--danger,
.rec-menu__item--danger i {
  color: var(--status-error-text);
}

/* ─────────────────── подпись состояния под названием ─────────────────── */

/* Переехало из `documents_queue.css`: тем же компонентом теперь
   пользуется и «Финансы». Постраничные поправки остались на месте. */
.status-compact {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 8px;
  flex-wrap: wrap;
}

.status-compact .status-badge {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.status-compact-note {
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
  line-height: var(--line-height-tight);
}

/* ─────────────────── строка фильтров ─────────────────── */

/* Одна строка вместо трёх мест. Геометрия та же, что на `/documents/`:
   поиск тянется, остальные поля фиксированной доли, кнопки справа. */
.rec-filters {
  display: grid;
  grid-template-columns: minmax(200px, 1.7fr) repeat(4, minmax(120px, 1fr)) auto;
  gap: var(--space-2);
  align-items: center;
}

@media (max-width: 1180px) {
  .rec-filters {
    grid-template-columns: minmax(180px, 1.6fr) repeat(2, minmax(120px, 1fr)) auto;
  }
}

/* На телефоне поля идут по два в ряд: в один столбец семь контролов
   давали 428 px только на фильтры (замер 16.08 при 390 px). Поиск
   занимает всю ширину — он длиннее остальных. */
@media (max-width: 760px) {
  .rec-filters {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
  .rec-filters > *:first-child {
    grid-column: 1 / -1;
  }
}

/* Плитки показателей на узком экране — тоже по две: пять плиток в
   столбик занимали 628 px, то есть полтора экрана до первой строки. */
@media (max-width: 520px) {
  .rec-tiles,
  .today-tiles,
  .today-tiles--4 {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Две колонки на 390 px — это 140 px под плитку, и 24 px кегля сумма
     уже не помещается. Уменьшаем кегль по ширине окна, а не рвём число. */
  .rec-tile__value,
  .today-tile__value {
    font-size: clamp(15px, 4.4vw, var(--font-size-2xl));
  }

  /* Подпись в 125–140 px: «Собственникам к перечислению», «Заполнено»
     длиннее строки и вылезали за плитку (замер 03.10.2026, 320–360 px). */
  .rec-tile__label,
  .today-tile__label,
  .rec-tile__note,
  .today-tile__note {
    overflow-wrap: break-word;
    hyphens: auto;
  }
}

/* 320–400 px: плитка 125 px, отступ 16+16 оставлял сумме 93 px — «604 999,17 ₽»
   в 15 px не помещалась. */
@media (max-width: 400px) {
  .rec-tile,
  .today-tile {
    padding: var(--space-3);
  }

  .rec-tile__value,
  .today-tile__value {
    font-size: clamp(14px, 4.2vw, var(--font-size-2xl));
  }
}

.rec-filters > * {
  min-width: 0;
}

.rec-filters .filter-control {
  width: 100%;
  /* Было 36 px — ступень «между» двумя, ничего не выражавшая. Панель
     фильтров над списком — обычная, не вспомогательная. 17.08.2026 */
  height: var(--control-h);
  padding: 0 var(--space-3);
  font-size: var(--font-size-sm);
}

.rec-filters__actions {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
  min-width: 0;
}

/* Чипы быстрых фильтров: одна переносящаяся полоса, а не панель с
   заголовком и рамкой (панель занимала 250 px и повторяла то, что уже
   стоит в выпадающих списках). */
.rec-chips {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-2);
}

/* Строка-пояснение рядом с чипами: то, что чипом быть перестало.
   09.09.2026 — «У всех 30 нет: счёта · есть у всех: документ, договор,
   платёж». Занимает одну строку и не притворяется кнопкой. */
.rec-chips__note {
  flex-basis: 100%;
  margin-top: 2px;
  font-size: 0.8125rem;
  line-height: 1.35;
}

.rec-chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border: 1px solid var(--card-border);
  border-radius: var(--radius-base);
  background: var(--card-bg);
  color: var(--text-secondary);
  font-size: var(--font-size-xs);
  line-height: 1.4;
  cursor: pointer;
}

.rec-chip strong {
  color: var(--text-primary);
  font-variant-numeric: tabular-nums;
}

.rec-chip:hover {
  background: var(--surface-hover);
}

.rec-chip.is-active {
  border-color: var(--accent-interactive);
  color: var(--text-primary);
}

/* `--accent-interactive` — цвет ЗАЛИВКИ кнопки (#9333ea): как текст на
   тёмной карточке он даёт 2,7:1. Для текста в проекте есть парный
   `--accent-text` (#c084fc в тёмной теме). Замер 17.08.2026. */
.rec-chip.is-active strong {
  color: var(--accent-text);
}

/* `.hidden` объявлен в unified-bundle.css, то есть РАНЬШЕ этого файла, и
   при равной специфичности проигрывает `.rec-chips`/`.rec-menu`. Скрипт
   гасит полосу чипов именно классом `hidden` — возвращаем ему силу. */
.rec-chips.hidden,
.rec-tiles.hidden,
.rec-menu.hidden {
  display: none;
}

/* ─────────────────── заголовок группы внутри таблицы ───────────────────

   Две таблицы сводятся в одну, группы разделяются строкой-заголовком, а
   не второй карточкой. Заведено на `/documents/` 16.08.2026 («В работе»
   и «В реестре»), в тот же день понадобилось «Финансам» («Ожидания» и
   «Проводки») — определения переехали сюда. `.docs-group-*` — второе имя
   того же компонента. */

/* 17.08.2026: «Объекты» выводят заголовок группы через <td colspan>, а не
   <th> — в теле таблицы <th> ломает разметку колонок. Компонент общий,
   поэтому оба варианта здесь. */
.rec-group-head th,
.rec-group-head td,
.docs-group-head th,
.docs-group-head td {
  padding: var(--space-4) var(--space-3) var(--space-2);
  border-bottom: 1px solid var(--border-color);
  background: var(--surface-secondary);
  text-align: left;
  font-weight: 400;
  /* Прописные у шапки таблицы сняты ещё 13.08: для кириллицы они
     читаются хуже строчных. Здесь тем более — это подпись, не ярлык. */
  text-transform: none;
  letter-spacing: 0;
}

.rec-group-title,
.docs-group-title {
  font-size: var(--font-size-sm);
  font-weight: 700;
  color: var(--text-primary);
}

.rec-group-count,
.docs-group-count {
  display: inline-block;
  margin-left: var(--space-2);
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--surface-tertiary);
  color: var(--text-secondary);
  font-size: var(--font-size-xs);
  font-weight: 700;
}

.rec-group-count:empty,
.docs-group-count:empty {
  display: none;
}

.rec-group-note,
.docs-group-note {
  margin-left: var(--space-2);
  font-size: var(--font-size-xs);
  font-weight: 400;
  color: var(--text-muted);
}

.rec-group-help,
.docs-group-help {
  width: 22px;
  height: 22px;
  min-width: 22px;
  min-height: 22px;
  margin-left: var(--space-2);
  padding: 0;
  border: 1px solid var(--border-color);
  border-radius: 999px;
  background: transparent;
  color: var(--text-secondary);
  font-size: 10px;
  cursor: pointer;
  vertical-align: middle;
}

.rec-group-help:hover,
.docs-group-help:hover {
  border-color: var(--border-color-strong);
  color: var(--text-primary);
}

/* Правый край строки-заголовка группы: там живут её собственные
   переключатели (у «Финансов» — состояние ожидания и «обновить»). */
.rec-group-head th {
  position: relative;
}

.rec-group-tools {
  float: right;
  display: inline-flex;
  align-items: center;
  gap: var(--space-2);
}

/* Период в подписи плитки — отдельным словом после точки-разделителя.
   Ставить его в название нельзя: «Ожидания открытые за все периоды»
   переносится на две строки и плитки становятся разной высоты. */
.rec-tile__period {
  color: var(--text-muted);
}

.rec-tile__note > .rec-tile__period::before {
  content: " · ";
}

/* ───────── панель раздела, 16.08.2026 ─────────

   Одна строка: поиск тянется, остальное фиксировано, редкое — под «…».
   Заменяет `.action-row`, в которой у «Истории платежей» стояло 13
   кнопок и 5 полей подряд. */

.portal-toolbar {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  /* Не переносим: поле поиска сжимается, кнопки — нет. С переносом
     «…» уезжала на вторую строку и панель раздела занимала 120 px. */
  flex-wrap: nowrap;
  min-width: 0;
}

@media (max-width: 760px) {
  .portal-toolbar {
    flex-wrap: wrap;
    width: 100%;
  }
}

.portal-toolbar__search {
  flex: 1 1 220px;
  min-width: 0;
  max-width: 340px;
}

.portal-toolbar .filter-control {
  /* Плотная ступень: панель кабинета вспомогательная. */
  height: var(--control-h-sm);
  padding: 0 var(--space-2);
  font-size: var(--font-size-sm);
}

.portal-toolbar__select {
  flex: 0 1 180px;
  min-width: 0;
}

.portal-toolbar__period {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  color: var(--text-muted);
}

.portal-toolbar__period .filter-control {
  width: 140px;
}

/* Поля внутри меню «…»: подпись слева, элемент справа. */
.rec-menu__field {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-3);
  padding: var(--space-2);
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
}

.rec-menu__field .filter-control {
  flex: 0 0 auto;
  width: 190px;
  /* Было 30 px. Внутри меню — плотная ступень. */
  height: var(--control-h-sm);
  padding: 0 var(--space-2);
  font-size: var(--font-size-sm);
}

.rec-menu__group {
  padding: var(--space-2) var(--space-2) 4px;
  font-size: var(--font-size-xs);
  font-weight: 700;
  color: var(--text-muted);
}

.rec-menu__group:not(:first-child) {
  margin-top: 4px;
  border-top: 1px solid var(--border-color);
}

/* Кнопка загрузки прячет системное поле выбора файла: раньше оно стояло
   в строке само по себе — чужой шрифт и надпись «Файл не выбран». */
.portal-upload {
  position: relative;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  overflow: hidden;
  cursor: pointer;
}

.portal-upload__input {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
}

/* Фокус с клавиатуры попадает на скрытое поле (`opacity: 0`), и кольцо
   рисуется на невидимом элементе: замер 17.08.2026 дал 1,41 — кольца не
   видно. Показываем его на самой кнопке. `overflow: hidden` выше обрезал
   бы обводку, поэтому на время фокуса возвращаем видимое переполнение. */
.portal-upload:focus-within {
  overflow: visible;
  outline: 3px solid var(--focus-ring-color);
  outline-offset: 2px;
}

/* ───────── полоса «смотрю от лица», 16.08.2026 ─────────
   Была полноразмерная секция с заголовком, подзаголовком и подписью
   поля — три пересказа одного и того же на 210 px над содержимым
   кабинета, и это при том, что арендатор её вообще не видит: секция
   только для администратора. */

.portal-impersonate {
  margin-bottom: var(--space-4);
}

.portal-impersonate.is-hidden {
  display: none;
}

.portal-impersonate__row {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  flex-wrap: wrap;
  padding: var(--space-2) var(--space-3);
  border: 1px dashed var(--border-color-strong);
  border-radius: var(--radius-md);
  background: var(--surface-secondary);
}

.portal-impersonate__row.is-hidden {
  display: none;
}

.portal-impersonate__label {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
  white-space: nowrap;
}

.portal-impersonate__select {
  flex: 1 1 260px;
  min-width: 0;
  height: 32px;
  padding: 0 var(--space-2);
  font-size: var(--font-size-sm);
}

.portal-impersonate__search {
  flex: 0 1 200px;
  min-width: 0;
  height: 32px;
  padding: 0 var(--space-2);
  font-size: var(--font-size-sm);
}

/* Контакты поддержки в кабинетах. 17.08.2026 */
.support-contacts {
  display: grid;
  gap: var(--space-2);
}

.support-line {
  display: grid;
  grid-template-columns: minmax(140px, 200px) minmax(0, 1fr);
  gap: var(--space-3);
  align-items: baseline;
}

.support-line__key {
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
}

.support-line__value {
  color: var(--text-primary);
}

@media (max-width: 600px) {
  .support-line {
    grid-template-columns: minmax(0, 1fr);
    gap: 0;
  }
}

/* ── отсеянный долг по заменённым договорам ─────────────────────────── */
/* Решение Tim 17.08.2026. Прятать молча нельзя: если статус договора
   где-то проставлен ошибочно, отсев спрячет настоящий долг. Строка
   свёрнута, но на виду, и раскрывается в разбивку по тем же срокам. */

.rec-aging__hidden {
  border-top: 1px solid var(--border-color);
}

.rec-aging__hidden-head,
.rec-aging__hidden > summary {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 10px var(--space-4);
  min-height: 44px;
  cursor: pointer;
  font-size: var(--font-size-sm);
  color: var(--text-secondary);
  list-style: none;
}

.rec-aging__hidden > summary::-webkit-details-marker {
  display: none;
}

/* Треугольник рисуем сами: у details он выглядит по-разному в разных
   браузерах, а тут это часть строки таблицы. */
.rec-aging__hidden > summary::before {
  content: "▸";
  display: inline-block;
  width: 12px;
  transition: transform 0.15s ease;
}

.rec-aging__hidden[open] > summary::before {
  transform: rotate(90deg);
}

.rec-aging__hidden > summary:hover {
  background: var(--surface-secondary);
  color: var(--text-primary);
}

.rec-aging__hidden-amount {
  margin-left: auto;
  font-variant-numeric: tabular-nums;
}

.rec-aging__hidden-body {
  padding: 0 var(--space-4) var(--space-3)
    calc(var(--space-4) + 12px + var(--space-3));
  background: var(--surface-secondary);
}

.rec-aging__hidden-note {
  margin: 0 0 var(--space-2);
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
}

.rec-aging__hidden-row {
  display: grid;
  grid-template-columns: minmax(120px, 1fr) minmax(100px, auto) 44px;
  gap: var(--space-3);
  padding: 4px 0;
  font-size: var(--font-size-xs);
  color: var(--text-secondary);
}

.rec-aging__hidden-row > :nth-child(2),
.rec-aging__hidden-row > :nth-child(3) {
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* ── списки на узком экране: таблица → карточки ─────────────────────── */
/*
  Заведено 17.08.2026.

  Замер на 390 px: «Контрагенты», «Объекты», «Документы» и «Приборы»
  выводили десктопную таблицу как есть — из 161 нажимаемой цели 137
  меньше 24 px (ссылки строк 19 px, флажки 18×18). Пальцем не попасть.

  Подписи ячейкам проставляет `responsive-table.js` из шапки таблицы,
  поэтому рендереры страниц не меняются, а новые списки получают
  мобильный вид сами собой. Таблице, которой это не подходит, ставят
  класс `no-mobile-cards`.
*/
/* Списки на узком экране: строка таблицы → карточка «подпись → значение».
   ------------------------------------------------------------------
   Класс `has-mobile-cards` ставит `js/responsive-table.js` тем таблицам,
   которые об этом попросили атрибутом `data-mobile-cards`. По умолчанию
   слой не применяется ни к чему: в продукте уже есть постраничные
   мобильные вёрстки, и поверх них он ломается (разбор — в шапке
   помощника). 17.08.2026 */
/* Порог «список → карточки» — 860 px.
   ---------------------------------------------------------------------
   Замер 17.08.2026: одно и то же решение принималось на ПЯТИ разных
   ширинах — «Контрагенты» 860, «Объекты» 767, «Документы» 767,
   «Финансы» 768, общий слой 720. Причём 767 и 768 стоят рядом: между
   ними полпикселя, на котором не срабатывает ни то, ни другое.

   На практике это значило, что при сужении окна списки превращались в
   карточки по очереди, а не вместе.

   860 выбрано не на глаз: таблицам этих страниц нужно 900–1101 px
   (замер ширины содержимого), ниже они всё равно уезжают вбок. Значит
   переключаться надо раньше, чем начнётся теснота, а не когда станет
   совсем узко.

   Медиа-запрос не умеет читать переменные, поэтому число повторяется в
   файлах страниц — но всегда с ссылкой на эту запись. */
/* Карточки — по классу `rec-cards` (ставит js/responsive-table.js): на окне
   ≤860 px И всякий раз, когда таблица не влезает в свой блок. Боковое меню
   отнимает ~300 px: при окне 1100 таблице «Договоров» оставалось 716 px при
   нужных 1040, порог окна не срабатывал — страница уезжала вбок. 03.10.2026,
   Tim: «должно нормально показывать на любых размерах экрана». */
table.has-mobile-cards.rec-cards,
table.has-mobile-cards.rec-cards tbody,
table.has-mobile-cards.rec-cards tfoot,
table.has-mobile-cards.rec-cards tr,
table.has-mobile-cards.rec-cards td {
  display: block;
  width: auto;
}

/* Карточка в широком блоке (≥640 px, класс ставит responsive-table.js):
   поля плиткой в несколько колонок, подпись над значением. Столбик
   «подпись — значение» на 1000 px давал карточку в ~300 px высоты при
   трети заполненной ширины («Договоры» при окне 1340, 03.10.2026). */
table.has-mobile-cards.rec-cards.rec-cards--wide tbody tr:not(.rec-group-head):not(.docs-group-head),
table.has-mobile-cards.rec-cards.rec-cards--wide tfoot tr {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(min(200px, 100%), 1fr));
  column-gap: var(--space-4);
  row-gap: var(--space-2);
  align-items: start;
}
table.has-mobile-cards.rec-cards.rec-cards--wide td {
  grid-template-columns: minmax(0, 1fr);
  gap: 2px;
  align-content: start;
  min-height: 0;
}
/* Страницы ставят части значения во вторую колонку подписи (`grid-column: 2`)
   — в плитке колонка одна, всё под подписью. */
table.has-mobile-cards.rec-cards.rec-cards--wide td > * {
  grid-column: 1 / -1 !important;
}

/* ≤400 px: подпись над значением. Сеткой «подпись | значение» колонке
   значения оставалось 82 px на 320 — длинная фамилия или название в нём
   не помещались (замер 03.10.2026, кабинет собственника). */
@media (max-width: 400px) {
  table.has-mobile-cards.rec-cards td {
    grid-template-columns: minmax(0, 1fr);
    gap: 2px;
  }
  table.has-mobile-cards.rec-cards td > * {
    grid-column: 1 / -1 !important;
  }
}

/* Строка «Итого» (отчёты) — последней карточкой, полужирно. Подписи ей
   ставит responsive-table.js теми же заголовками; пустые ячейки не видны. */
table.has-mobile-cards.rec-cards tfoot tr {
  margin-bottom: var(--space-3);
  padding: var(--space-3);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  background: var(--surface-secondary);
  font-weight: 600;
}
table.has-mobile-cards.rec-cards tfoot td:empty {
  display: none;
}

/* Сброс десктопных ширин.
   ----------------------------------------------------------------
   Одного `width: auto` мало. В `unified-bundle.css` на узком экране
   стоит `.table { min-width: 640px }` — правило родом из времён, когда
   единственным ответом на телефон была горизонтальная прокрутка. Плюс
   колонки просят своё: `.meters-table .col-object { min-width: 170px }`
   и подобные.

   Замер 17.08.2026: карточки на «Приборах» получились шириной 640 px
   внутри экрана в 390 — значения обрезались по правому краю
   («18013448», «30.11.201…»).

   `!important` здесь по делу, и это проверено дважды. 17.08.2026 я
   попробовал снять флаги, решив, что после уборки страничных файлов
   надобность отпала, — и замер на «Приборах» в 390 px показал возврат
   дефекта: `td.col-object` получал `min-width: 170px`, `td.col-actions`
   сжимался с 283 до 48 px. Колоночные правила задаются через
   `colgroup`/`col` и по специфичности слою не уступают. Флаг остаётся:
   слой обязан пересилить ширины, назначенные страницей под свои
   колонки, а перечислять их поимённо — это ровно то размножение
   правил, от которого слой и заводился. */
table.has-mobile-cards.rec-cards {
  min-width: 0 !important;
}

table.has-mobile-cards.rec-cards td {
  min-width: 0 !important;
  max-width: none !important;
  width: auto !important;
}

/* Шапка не нужна: подписи переехали в сами ячейки. */
table.has-mobile-cards.rec-cards thead {
  display: none;
}

table.has-mobile-cards.rec-cards tr {
  margin-bottom: var(--space-3);
  padding: var(--space-3) var(--space-4);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  background: var(--surface-primary);
}

/* Заголовок группы («Срок истёк 22») остаётся полосой, а не карточкой:
   он и так одна ячейка во всю ширину. */
table.has-mobile-cards.rec-cards tr.rec-group-head,
table.has-mobile-cards.rec-cards tr.docs-group-head {
  margin-bottom: 0;
  padding: 0;
  border: 0;
  background: transparent;
}

table.has-mobile-cards.rec-cards td {
  display: grid;
  /* `minmax(0, 1fr)`, не `1fr`: у `1fr` нижняя граница — ширина содержимого,
     и плашка с nowrap («Окончание договора аренды», роль, бейдж) растягивала
     колонку за край карточки (замер 03.10.2026, 320–390 px). */
  grid-template-columns: minmax(90px, 38%) minmax(0, 1fr);
  gap: var(--space-3);
  align-items: baseline;
  padding: 6px 0;
  border: 0;
  /* Строка карточки — цель для пальца, не только для глаза. */
  min-height: 32px;
}

/* Значение не шире своей колонки: плашка и бейдж переносятся, а не
   вылезают за карточку. Перенос — по словам (`break-word`), сумма с
   неразрывными пробелами не рвётся, пока помещается. */
table.has-mobile-cards.rec-cards td > * {
  min-width: 0;
  max-width: 100%;
}
table.has-mobile-cards.rec-cards td > span,
table.has-mobile-cards.rec-cards td > .badge,
table.has-mobile-cards.rec-cards td > a {
  white-space: normal;
  overflow-wrap: break-word;
}
/* Ячейка-текст без обёртки: в карточке колонка значения узкая (170 px на
   320), запрет переноса страниц (числа, назначение платежа) здесь снимаем. */
table.has-mobile-cards.rec-cards td {
  white-space: normal;
  /* `anywhere`, а не `break-word`: текст прямо в ячейке-сетке не сжимается
     ниже самого длинного «слова» — номер счёта из 20 цифр выпирал на 22 px
     (отчёт «Движение денег», 360 px). */
  overflow-wrap: anywhere;
}

table.has-mobile-cards.rec-cards td::before {
  content: attr(data-label);
  color: var(--text-secondary);
  font-size: var(--font-size-xs);
  /* Подпись переносится, даже если ячейка запрещает перенос.
     Страницы ставят `white-space: nowrap` на колонки дат и номеров
     осознанно — «30.11.202 2» читается как другое число. Но подпись
     это ограничение наследовала: замер 17.08.2026 на «Приборах» —
     «Следующая поверка» не уместилась в свой столбец и наехала на
     дату. Запрет переноса нужен значению, не подписи. */
  white-space: normal;
  overflow-wrap: anywhere;
}

/* Ячейка без подписи (флажок, меню «…») занимает всю ширину и стоит
   первой строкой карточки — как ручка, за которую её берут. */
table.has-mobile-cards.rec-cards td:not([data-label]) {
  grid-template-columns: 1fr;
}

table.has-mobile-cards.rec-cards td:not([data-label])::before {
  content: none;
}

/* Обрезанное значение раскрывается по нажатию.
   ----------------------------------------------------------------
   Решение Tim 18.08.2026: «Раскрывай». На телефоне подсказка `title`
   не всплывает, и из «Максимов Владими…» нельзя узнать целое имя.
   Ячейки, чьё содержимое не помещается, помечает
   `js/responsive-table.js`; здесь только вид. */
table.has-mobile-cards.rec-cards td[data-truncated] {
  cursor: pointer;
}

/* Ссылку раскрывать нажатием нельзя — нажатие по ней ведёт по ссылке.
   Поэтому название, которое и есть ссылка (объект, документ), в
   карточке просто переносится: это главное поле строки, и обрезать
   его без возможности раскрыть — хуже, чем отдать ему вторую строку.
   18.08.2026 */
table.has-mobile-cards.rec-cards td > a.rec-line,
table.has-mobile-cards.rec-cards td > a.rec-line:only-child {
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  overflow-wrap: anywhere;
}

/* Знак того, что есть что раскрыть: значение подчёркнуто пунктиром —
   тем же приёмом, что подсказки в остальном интерфейсе. Отдельной
   кнопки нет: она заняла бы строку в карточке из четырёх. */
table.has-mobile-cards.rec-cards td[data-truncated] > .rec-line,
table.has-mobile-cards.rec-cards td[data-truncated] > .rec-state .rec-state__text {
  text-decoration: underline dotted var(--border-color);
  text-underline-offset: 3px;
}

table.has-mobile-cards.rec-cards td[data-expanded] {
  align-items: start;
}

table.has-mobile-cards.rec-cards td[data-expanded],
table.has-mobile-cards.rec-cards td[data-expanded] .rec-line,
table.has-mobile-cards.rec-cards td[data-expanded] .rec-state,
table.has-mobile-cards.rec-cards td[data-expanded] .rec-state__text {
  overflow: visible;
  text-overflow: clip;
  white-space: normal;
  overflow-wrap: anywhere;
}

table.has-mobile-cards.rec-cards td[data-expanded] > .rec-line,
table.has-mobile-cards.rec-cards td[data-expanded] > .rec-state .rec-state__text {
  text-decoration: none;
}

table.has-mobile-cards.rec-cards td[data-truncated]:focus-visible {
  outline: 2px solid var(--accent-interactive);
  outline-offset: 2px;
  border-radius: var(--radius-sm);
}

/* Колонка, скрытая на десктопе (свёрнутый «Менеджер»), в карточке
   тоже не нужна: пустая строка «Менеджер —» не сообщает ничего. */
table.has-mobile-cards.rec-cards td[data-mobile-hidden],
table.has-mobile-cards.rec-cards td[hidden] {
  display: none;
}

/* Цели под палец. 24 px — нижняя граница по WCAG 2.5.8, 44 — размер,
   при котором не приходится целиться. */
table.has-mobile-cards.rec-cards a,
table.has-mobile-cards.rec-cards button,
table.has-mobile-cards.rec-cards summary,
table.has-mobile-cards.rec-cards [role="button"] {
  min-height: 44px;
  display: inline-flex;
  align-items: center;
}

table.has-mobile-cards.rec-cards input[type="checkbox"],
table.has-mobile-cards.rec-cards input[type="radio"] {
  width: 22px;
  height: 22px;
  /* Сам флажок оставляем узнаваемым, а зону нажатия расширяем полем. */
  margin: 11px;
}

/* Ссылка-подложка строки («открыть карточку по клику в любом месте»)
   на телефоне растягивается на всю карточку, а не на ячейку. */
table.has-mobile-cards.rec-cards td .property-row-open,
table.has-mobile-cards.rec-cards td .contractor-row-link {
  min-height: 44px;
}

/* Горизонтальная прокрутка контейнера теперь ни к чему: ширины нет. */
.table-container:has(table.has-mobile-cards.rec-cards),
.table-wrapper:has(table.has-mobile-cards.rec-cards) {
  overflow-x: visible;
}


/* Цели под палец в списках — общее правило, не привязанное к карточному
   слою.
   ------------------------------------------------------------------
   Замер 17.08.2026 на ширине 390 px, уже ПОСЛЕ того как у страниц
   появилась своя мобильная вёрстка:

     «Контрагенты»  136 целей из 136 меньше 24 px
     «Объекты»       42 из 84
     «Документы»    114 из 146

   Разбор «Контрагентов»: 68 флажков 18×18 и 68 ссылок строки высотой
   19 px. Вёрстка карточек тут ни при чём — карточки как раз есть; мелкие
   именно нажимаемые места. Поэтому правило живёт отдельно от
   `.has-mobile-cards` и работает на любой таблице.

   Нижняя граница WCAG 2.5.8 (AA) — 24×24. Её и берём за минимум для
   ссылок: тянуть текстовую строку до 44 px значит раздуть карточку на
   четверть без пользы.

   `min-height` намеренно без смены `display`: у строчной ссылки внутри
   текста он не действует и ничего не ломает, а у блочной (`.contractor-row-link`
   и подобных, которые и есть вся строка) поднимает высоту до нормы. */
@media (max-width: 860px) {
  table td a,
  table td button,
  table td summary,
  table td [role="button"] {
    min-height: 24px;
    /* Квадратная кнопка-значок («?» у заголовка группы) была 22×22:
       высоту поднимает правило выше, ширину — это. У строчной ссылки
       `min-width` не действует, длинный текст не растягивает. */
    min-width: 24px;
  }
}

/* ── зона нажатия у флажка ──────────────────────────────────────────────
   Флажок остаётся 16×16 на вид — размер задан вёрсткой страницы, и менять
   его значит спорить с её сеткой. Расширяем не сам флажок, а зону нажатия:
   прозрачная накладка вокруг доводит цель до 44 px (16 + 14×2). Видимое не
   меняется, промахнуться становится нечем.

   22.09.2026, две правки по замеру:

   1. Условие было `max-width: 860px` — ШИРИНА, а не касание. На планшете
      с вьюпортом шире 860 накладки не было вовсе, хотя палец там ровно тот
      же; а на узком окне десктопа она висела зря. Условие переведено на
      `(hover: none) and (pointer: coarse)` — то же, что у этажа целей
      нажатия в `ds-components.css`.
   2. Селектор перечислял только `table td` — накладки не получали ни
      «Выбрать все» в шапке таблицы (`th`), ни флажки в формах и модальных
      окнах. Замер на карточке контрагента, 412 px: «Тестовая запись» имела
      зону 13 px против 42 у соседей по странице. Теперь правило общее для
      всех флажков и переключателей.

   Проверено, что накладка не ворует чужие нажатия: на карточке контрагента
   у четырнадцати соседних интерактивных элементов центр по-прежнему
   принадлежит им, а не флажку.

   22.09.2026, дважды. Сначала `-14px` -> `-15px`: флажок списка
   контрагентов оказался ровно 15x15 px (не 16 и не 18, как я считал), и
   накладка давала 43x43 — на пиксель ниже порога. Сто флажков списка не
   дотягивали.

   Потом выяснилось, что гнаться за числом бессмысленно: флажки в
   приложении разного размера — 13 px в модальных окнах, 14 на «Объектах»
   и в очереди документов, 15 в списке контрагентов. Отступ, взятый от
   края, даёт три разных итога, и 13 + 15 + 15 = 43 снова мимо. Поэтому
   накладка больше не отступ, а размер: ровно 44x44 от центра флажка,
   с `min-*: 100%` на случай флажка крупнее порога. Замер на карточке
   контрагента при 884 px: 102 флажка, коробки 13 и 15 px, зона нажатия
   у всех одна — 44x44. */
@media (hover: none) and (pointer: coarse) {
  input[type="checkbox"],
  input[type="radio"] {
    position: relative;
  }

  input[type="checkbox"]::after,
  input[type="radio"]::after {
    content: "";
    position: absolute;
    top: 50%;
    left: 50%;
    width: 44px;
    height: 44px;
    min-width: 100%;
    min-height: 100%;
    transform: translate(-50%, -50%);
  }
}

/* Каркас карточки списка — одно определение на все списки.
   ---------------------------------------------------------------------
   Замер 17.08.2026 на 390 px. Одна и та же вещь — строка списка,
   ставшая карточкой, — была нарисована ЧЕТЫРЕ раза, и каждый раз своими
   числами:

     «Контрагенты»  радиус 20, отступ 14, тень 0 16px 34px
     «Объекты»      радиус 16, отступ 12, тень 0 10px 24px
     «Документы»    радиус 12 (токен), отступ 8, тени нет
     общий слой     радиус 16 (токен), отступ 12, тени нет

   Из четырёх радиусов два (20 и 12) вне шкалы для этого размера, тени
   расходятся втрое, отступы — вдвое. Ни одно из различий ничего не
   выражает: это один и тот же объект, просто нарисованный разными
   руками в разное время.

   Здесь он один. Странице остаётся только своё:
   `--list-card-gutter` — место слева под флажок, если он вынесен, и
   `--list-card-gutter-end` — место справа под меню строки.

   Список селекторов вместо класса — чтобы не трогать разметку четырёх
   страниц. Новый список подключается общим слоем (`data-mobile-cards`)
   и попадает сюда сам. */
@media (max-width: 860px) {
  .contractors-page #contractors-table tbody tr[data-contractor-row],
  .properties-page #properties-table tbody tr[data-property-row],
  .documents-queue-table tbody tr {
    position: relative;
    margin-bottom: var(--space-3);
    padding: var(--space-3);
    padding-left: var(--list-card-gutter, var(--space-3));
    padding-right: var(--list-card-gutter-end, var(--space-3));
    border: 1px solid var(--border-color);
    border-radius: var(--radius-lg);
    background: var(--surface-primary);
    box-shadow: var(--shadow-md);
  }

  /* Заголовок группы карточкой не становится — он и так полоса. */
  .documents-queue-table tbody tr.docs-group-head {
    margin-bottom: 0;
    padding: 0;
    border: 0;
    border-radius: 0;
    background: transparent;
    box-shadow: none;
  }
}

/* Строка-карточка по классу `rec-cards` — см. выше. */
table.has-mobile-cards.rec-cards tbody tr {
  position: relative;
  margin-bottom: var(--space-3);
  padding: var(--space-3);
  padding-left: var(--list-card-gutter, var(--space-3));
  padding-right: var(--list-card-gutter-end, var(--space-3));
  border: 1px solid var(--border-color);
  border-radius: var(--radius-lg);
  background: var(--surface-primary);
  box-shadow: var(--shadow-md);
}

/* Заголовок группы карточкой не становится — он и так полоса. */
table.has-mobile-cards.rec-cards tbody tr.rec-group-head,
table.has-mobile-cards.rec-cards tbody tr.docs-group-head {
  margin-bottom: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
}

/* И его единственная ячейка — тоже полоса во всю ширину, иначе она
   остаётся шириной первого столбца и режет заголовок («В р…»).
   19.08.2026 */
table.has-mobile-cards.rec-cards tbody tr.rec-group-head > *,
table.has-mobile-cards.rec-cards tbody tr.docs-group-head > * {
  display: block;
  width: 100%;
  overflow: visible;
  white-space: normal;
}


/* Расшифровка меток связей в заголовке столбца.
   Была под «?» — её видел только тот, кто уже догадался навести мышь.
   Решение Tim 18.08.2026: подписать. */
.accounting-chain-legend {
  margin-top: 2px;
  font-size: var(--font-size-xs);
  font-weight: 400;
  line-height: 1.25;
  color: var(--text-muted);
  text-transform: none;
  letter-spacing: 0;
  /* Переносится внутри столбца: в одну строку расшифровка вылезала на
     соседний столбец и обрезалась по краю таблицы. */
  white-space: normal;
  max-width: 220px;
}

/* Строка «показать ещё» под группой таблицы. */
.accounting-more-cell {
  padding: 10px 12px;
  text-align: center;
  background: var(--surface-secondary);
}

/* Период в панели кабинета («с … по …», два поля по 140 px) на 320–390
   вылезал на 96 px (замер 03.10.2026) — переносится, поля сжимаются. */
@media (max-width: 480px) {
  .portal-toolbar__period {
    flex-wrap: wrap;
    max-width: 100%;
  }
  .portal-toolbar__period .filter-control {
    width: auto;
    flex: 1 1 120px;
    min-width: 0;
  }
}

/* Ссылка-сноска под значением в ячейке (ЛК ПСК: адрес объекта) на 320
   длиннее строки (03.10.2026). */
.rec-sub {
  overflow-wrap: anywhere;
}

/* Заголовок группы («Сдано · 34») на 320 обрезался вместе со счётчиком
   (замер 03.10.2026, «Объекты») — переносится. */
.rec-group-head th,
.rec-group-head td,
.docs-group-head th,
.docs-group-head td {
  white-space: normal;
  overflow-wrap: break-word;
}
