/* Экран дома и окно квартиры: поиск, фильтры, три блока месяца (UNI-2).
   Часть CRM аренды. ПОРЯДОК ПОДКЛЮЧЕНИЯ ВАЖЕН: файл последний, правила ниже
   перекрывают правила выше. Новых hex-значений здесь нет — только var()
   из 01-tokens.css.

   Карточки квартир (.house-cards/.house-card, раздел 1b) — своя сетка под
   CARD-2 (REQUIREMENTS.md п. 77, отменяет п. 55/UI-8e): не меньше десяти в
   ряд на 1440. Сетка окон витрины и атласа «Обзора» (.sc-windows/.sc-window,
   205 px) по-прежнему описана в 11-showcase.css и здесь не переопределяется —
   у двух экранов теперь разные компоненты для одной и той же мысли
   (карточка квартиры), см. заметку в 23-house.js, раздел 2b. */

/* ============================================================
   0. Заголовок экрана: месяц и деньги
   ============================================================ */

/* На мониторе деньги — продолжение заголовка: тот же кегль, вес и цвет, от
   прежней сплошной строки не отличить. Тире — настоящий текст (см.
   houseMoneyTail в 23-house.js), поэтому здесь для него правил нет. */

/* На телефоне вся фраза заголовочным кеглем занимала три строки и съедала
   первый экран (VIS-1b, решение руководителя). Деньги уходят под заголовок
   строкой основного текста: читать их надо, но кричать о них не надо.
   Тире выключается вместе со своим узлом — строка начинается со слова. */
@media (max-width: 780px) {
  .house-dash {
    display: none;
  }
  .house-money {
    display: block;
    margin-top: 6px;
    font-size: var(--text-body);
    font-weight: 400;
    letter-spacing: normal;
    line-height: 1.4;
    color: var(--soft);
  }
}

/* ============================================================
   1. Панель управления сеткой: поиск, фильтры, две кнопки
   ============================================================ */

.house-tools {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 14px 18px;
  align-items: end;
  margin-bottom: 16px;
}

.house-search {
  max-width: 340px;
}

/* Крестик очистки в поле поиска Chrome красится системно и на тёмном фоне
   почти не виден: убираем его, очистка — Escape и стирание. */
.house-search input::-webkit-search-cancel-button {
  display: none;
}

.house-actions {
  display: flex;
  flex-wrap: wrap;
  /* center, а не растяжка по высоте (POL-3): в строке стоят переключатель вида
     и две кнопки, и растяжка тянула кнопки до высоты самого высокого соседа —
     34px превращались в 44. */
  align-items: center;
  gap: 10px;
}

/* Кнопки панели управления — 34px (POL-3, REQUIREMENTS.md п. 78: «кнопки и
   шрифт меньше»). Раньше они были 54px: `min-height: var(--tap)` плюс
   собственные отступы `.secondary`. Тот же приём, что у строк инвестора на
   столе (21-desk.css): мышью цель и так точная, пальцем её добирает правило
   `pointer: coarse` ниже. */
.house-actions button {
  min-height: 34px;
  padding: 6px 14px;
  font-size: var(--text-small);
}

/* Переключатель «Карточки / Таблицей, как в книге» и переключатель порядка
   «По дате оплаты / По номеру» (SORT-1) — оба переключатели, а не кнопки
   действия: 32px, как чипы фильтров под ними (POL-3). Базовое правило в
   11-showcase.css (`.sc-range button`) остаётся для витрины инвестора. */
.house-view .sc-range button,
.house-sort .sc-range button {
  min-height: 32px;
  padding: 5px 13px;
  font-size: var(--text-small);
}

@media (pointer: coarse) {
  .house-actions button,
  .house-view .sc-range button,
  .house-sort .sc-range button {
    min-height: var(--tap);
  }
}

/* Фильтры-чипы: переключатели с состоянием, не ссылки. Форма выбранного
   отличается заливкой и весом, а не только цветом. */
.house-filters {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 14px;
}

.house-filters button {
  /* 32px (POL-3): шесть чипов в ряд полной высоты отодвигали сетку квартир
     вниз на треть экрана. Пальцем цель добирается правилом ниже. */
  min-height: 32px;
  padding: 5px 13px;
  border: 1px solid var(--border-field);
  border-radius: var(--radius-pill);
  background: var(--sunken);
  color: var(--soft);
  font-size: var(--text-small);
  transition:
    background 160ms ease,
    color 160ms ease,
    border-color 160ms ease;
}

.house-filters button:hover {
  border-color: var(--violet-edge);
  color: var(--pearl);
}

.house-filters button[aria-pressed='true'] {
  background: var(--state-active);
  border-color: var(--violet);
  color: var(--pearl);
  font-weight: 700;
}

@media (pointer: coarse) {
  .house-filters button {
    min-height: var(--tap);
  }
}

/* Сколько окон осталось после фильтра. Читается вслух: role="status". */
.house-count {
  margin-bottom: 14px;
  font-size: var(--text-small);
  color: var(--mist);
}

.house-count:empty {
  display: none;
}

/* «Никого не нашли» (SEARCH-1) — под сеткой, переиспользует .empty
   (04-components.css: заливка, пунктирная рамка, кнопка внутри — 34px, на
   пальце `var(--tap)` тем же общим правилом ниже, раздел 1). Свой класс
   только ради отступа сверху: сетка над блоком не пропадает из разметки
   (скрытые карточки остаются в DOM), а стоит пустой высотой 0. */
.house-empty-search {
  margin-top: 16px;
}

/* Фильтрация прячет окна классом, сетка при этом не перерисовывается:
   на 150 окнах пересборка разметки стоила бы кадр целиком. .sc-window —
   короткий атлас «Обзора» (06-units.js, unitAtlas()), там фильтра нет, но
   класс общий с .hidden у других списков; .house-card — сетка этого экрана
   (CARD-2). */
.sc-window.hidden,
.house-card.hidden,
.window-grid-group.hidden {
  display: none;
}

/* CLR-4: .sc-meterless и .sc-key .sc-meterless удалены — тот же значковый
   уголок «счётчики не введены», что легенду .sc-key/.sc-mark в 11-showcase.css
   убрала FIX-N2 №4: состояние квартиры называется чипом-словом
   (.sc-window-chip), значков больше нет ни на «Объектах», ни на «Квартирах»
   (п. 43–44). Класс .sc-key в этом файле не существует, .sc-meterless нигде
   не ставится 23-house.js — правило было мёртвым кодом, найденным «side-tab»
   детектором как боковая рамка (border-left: 2px dashed). */

/* Подпись над чипами фильтра стоит одна, без поля ввода под ней. POL-3: на
   «Квартирах» её больше нет (слова остались в aria-label группы), правило
   держится для тех же чипов на других экранах. */
.house-filter-label {
  margin-bottom: 8px;
}

/* Пустая панель: одна строка словами и одна кнопка (POL-3). Рабочий стол и
   витрина исключены явно — их пустые состояния приняты владельцем как есть,
   и эта волна их не трогает. */
.page:not(.desk):not(.showcase) .empty > .secondary,
.page:not(.desk):not(.showcase) .empty > .primary {
  margin-top: 10px;
  min-height: 34px;
  padding: 5px 12px;
  font-size: var(--text-small);
}

@media (pointer: coarse) {
  .page:not(.desk):not(.showcase) .empty > .secondary,
  .page:not(.desk):not(.showcase) .empty > .primary {
    min-height: var(--tap);
  }
}

/* ============================================================
   1a. Добавить квартиру (UNIT-ADD-1, REQUIREMENTS.md п. 120)
   ============================================================ */

/* Пустая панель дома получает вторую кнопку (housePanel(), 23-house.js):
   у Завода 2 нет книги Excel, и здесь единственный способ завести квартиру.
   Модификатор ставит обе кнопки в столбец на любой ширине — этот экран видят
   редко, а колонка сразу разводит их зазором: без неё два соседних
   inline-block <button> без текстового узла между ними просто слипаются. */
.empty.unit-add-empty {
  display: flex;
  flex-direction: column;
  align-items: center;
}

.empty.unit-add-empty > .primary,
.empty.unit-add-empty > .secondary {
  width: 100%;
  max-width: 320px;
}

/* Форма на месте, без модального окна (ТЗ, раздел «Интерфейс»): скрыта
   атрибутом hidden, лежит сиблингом своей кнопки — под панелью управления
   houseTools() или под пустой панелью housePanel(). На телефоне (≤780px)
   остаётся общая одноколоночная .detail-form (09-responsive.css) — поля
   идут столбиком. С 781px собственная сетка ниже разводит поля и обе кнопки
   в один ряд («форма в одну строку», ТЗ, критерий 1). */
.unit-add-form {
  margin-top: 14px;
}

/* `.detail-form` задаёт display: grid своим классом — без этого правила
   родовое `[hidden] { display: none }` браузера проигрывает ему по
   специфичности, и форма осталась бы видна закрытой (тот же приём, что у
   `.vacate-rest[hidden]` ниже и `.rent-operation-fields[hidden]`,
   08-screens.css: style= запрещён CSP, скрывает и показывает только hidden). */
.unit-add-form[hidden] {
  display: none;
}

@media (min-width: 781px) {
  .unit-add-form {
    grid-template-columns: minmax(90px, 120px) minmax(90px, 120px) minmax(260px, 1fr) auto;
    align-items: end;
  }
}

/* Переключатель «Сейчас в квартире» — тот же .sc-range, что и у выбора
   судьбы остатка депозита (vacateRestBlock, 08-departures.js) и у вида
   «Карточки / Таблицей» (houseViewSwitch выше), но без предвыбора: обе
   кнопки начинают без aria-pressed="true" — человек обязан ответить сам
   (ТЗ). На мониторе — в ряд, во всю ширину своей дорожки грид-формы. */
.unit-add-occupied .sc-range {
  width: 100%;
}

/* ≤780px: длинная подпись второй кнопки («Живёт жилец — внесу данные
   позже») в ряду с короткой «Свободна» тянула вторую строку внутрь пилюли
   и растягивала обе кнопки по высоте общей чертой flex (align-items:
   stretch по умолчанию) — рослая, неровная пара. Столбиком обе кнопки
   становятся во всю ширину и в одну строку текста каждая — то же поле
   читается спокойнее, без прокрутки вбок. */
@media (max-width: 780px) {
  .unit-add-occupied .sc-range {
    flex-direction: column;
  }
}

/* Кнопки «Добавить» и «Отмена» — в ряд всегда (ТЗ), даже когда поля над ними
   стоят столбиком на телефоне: это одно решение формы, а не два разных дела,
   которые стоило бы развести по высоте. */
.unit-add-buttons {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin-top: 4px;
}

/* Тихая строка про тариф дома (ТЗ, bindUnitAddForm() в 23-house.js) — тот же
   приглушённый кегль, что у «Бот не подключён» (unitRemindersPanel,
   06-units.js): читается, но не спорит с плитками и заголовком панели. */
.house-add-notice {
  margin: 0 0 14px;
}

/* Чипы состояния на карточке квартиры — CARD-3 (REQUIREMENTS.md п. 85,
   уточнение владельца 10:15) разрешает им 11–12 px: плотность сведений
   важнее прежнего запрета «мельче 13 px в системе нет» (POL-3), который был
   исключением из CONVENTIONS §8 именно для этих чипов. Своего правила здесь
   больше нет — держится базовый кегль `.chip.chip--compact` (05-status.css,
   12px), он уже в требуемой вилке. */

/* ============================================================
   1b. Карточки квартир (CARD-3, REQUIREMENTS.md п. 85)
   ============================================================ */

/* Своя разметка (.house-cards/.house-card, 23-house.js), не .sc-windows/
   .sc-window из 11-showcase.css: тем же компонентом рисуются окна витрины
   инвестора и атлас «Обзора» (06-units.js), у них другие пропорции и
   трогать их здесь не просят. Владелец прислал снимок другой своей системы
   и попросил ту же плотность сведений на карточке (номер и этаж, чип
   оплаты в углу, жилец и телефон, сумма крупно, полоса «оплачено из
   ожидаемого», счётчики, день оплаты, чип выезда) — плотность самих
   карточек при этом уступает: «до пяти-шести в ряд» на 1440, а не десять
   (CARD-2 отменена).

   Ширина карточки на 1440: панель ≈ 1080 px внутри страницы (тот же расчёт,
   что был у CARD-2). minmax(190px, 1fr) с зазором 10 px даёт пять колонок
   по ~208 px (1080 = 5×190 + 4×10) — в вилке 200–235 px, которую разрешил
   владелец; на панели шире (все дома, широкий монитор) колонок станет
   больше сама собой, вплоть до шести. 768/390 — точные числа владельца
   фиксированным repeat(), тем же приёмом, что был у CARD-2 (1024 с
   HOUSE-CARD-1 больше не входит в их число — см. правку ниже, раздел 1b). */
.house-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(190px, 1fr));
  align-items: stretch;
  gap: 10px;
  margin-bottom: 18px;
}

/* Рамка фокуса внутрь, как у .sc-windows (02-base.css): на узком зазоре
   внешний сдвиг рамки резал бы соседнюю карточку. Действует на любой
   фокусируемый потомок — открывающую кнопку и ссылку телефона разом. */
.house-cards :focus-visible {
  outline-offset: -1px;
}

/* Высота — по содержимому, не квадрат. align-items: stretch на сетке выше
   уравнивает карточки одного ряда — короткая карточка (свободная квартира)
   не проседает ниже соседней. position: relative держит открывающую кнопку
   (ниже) внутри границ карточки. */
.house-card {
  position: relative;
  min-height: var(--tap);
  padding: 10px 12px;
  border-radius: var(--radius-sm);
  background: var(--sunken);
  border: 1px solid var(--border-strong);
  color: var(--pearl);
  font-variant-numeric: tabular-nums;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  text-align: left;
  transition: border-color 160ms ease;
}

/* Открывающая кнопка — прозрачный слой на всю карточку (CARD-3: карточка
   стала <article>, а не <button>, чтобы вместить второй орган управления —
   ссылку tel:, которую HTML не разрешает класть внутрь кнопки). Явный
   z-index обязателен: у абсолютно спозиционированного элемента иначе нет
   гарантии, что он ляжет НАД текстом в потоке — а лечь под ссылку телефона
   (z-index ниже, см. .house-card-phone) он обязан. */
.house-card-open {
  position: absolute;
  inset: 0;
  z-index: 1;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  cursor: pointer;
}

.house-card:active {
  transform: scale(0.97);
}

/* --- Наведение (HOUSE-2, REQUIREMENTS.md п. 86): увеличение 1,02–1,03,
   рамка золотом (`--window`, та же амбра, что и «деньги» — DESIGN.md, не
   новый цвет), лёгкая тень, за 150–200 мс. Только мышь: `hover: hover` и
   `pointer: fine` исключают телефон и планшет — палец не наводится, у него
   есть :active (0.97, выше) и открытие окна нажатием (23-house.js: карточка
   всегда остаётся <article>, обработчик стоит на вложенной кнопке).

   Border-color и box-shadow не в `prefers-reduced-motion`-развилке: это
   изменение цвета/тени, не движение — «никогда не прятать видимое» и
   правило проекта требуют убрать только transform (см. блок ниже). z-index
   поднимает наведённую карточку и её раскрывающийся блок (.house-card-more)
   над соседями следующего ряда сетки: без этого текст «Скоро освободятся» —
   то есть просто следующая строка карточек — перекрывал бы всплывающие
   строки снизу.

   Класс написан дважды (`.house-card.house-card:hover`), тот же приём, что
   и `.chip.chip--compact` в 05-status.css: цвет карточки по вниманию —
   `.house-card[data-scheme='…']` (раздел 1b ниже по файлу) — атрибутный
   селектор равной специфичности с одним классом; при одиночном `:hover` он
   стоит позже в каскаде и молча перекрашивал бы рамку обратно в зелёный или
   тлеющий цвет своей схемы вместо золота наведения. */
@media (hover: hover) and (pointer: fine) {
  .house-card.house-card:hover {
    z-index: 2;
    border-color: var(--window);
    box-shadow: var(--shadow-1);
  }
}

/* Сам transform — движение, поэтому только при отсутствии запроса на его
   отключение (CONVENTIONS/REQUIREMENTS: `prefers-reduced-motion` уважается
   всегда). Без этого блока карточка при наведении меняет только цвет рамки
   и тень — ровно то, что просит «без transform». Transition здесь же, а не
   на базовом `.house-card`: под reduced-motion её не должно быть вовсе, а
   не просто нечему её запускать. */
@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .house-card {
    transition:
      transform 180ms ease,
      border-color 180ms ease,
      box-shadow 180ms ease;
  }

  .house-card:hover {
    transform: scale(1.025);
  }
}

/* Раскрытие 2–3 тихих строк (23-house.js: houseCardMoreLines()) — абсолютным
   блоком под карточкой, а не изменением её высоты: сетка на 150 окнах не
   должна сдвигать соседей вниз при наведении на одну карточку
   (REQUIREMENTS.md п. 86: «блок не должен менять высоту сетки для
   соседей»). aria-hidden в разметке — то же самое (долг, статус) уже
   произносит открывающая кнопка карточки (houseCardLabel(), 23-house.js). */
.house-card-more {
  position: absolute;
  left: -1px;
  right: -1px;
  top: 100%;
  z-index: 1;
  margin-top: 6px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--window-edge);
  background: var(--raised);
  box-shadow: var(--shadow-1);
  opacity: 0;
  pointer-events: none;
}

/* Кегль — тот же --text-13, что у тихой строки-пояснения (.footnote,
   02-base.css): 12 px в системе разрешены только чипам и телефону
   (REQUIREMENTS.md п. 85), обычному тексту — не ниже 13 (CONVENTIONS §8). */
.house-card-more p {
  margin: 0;
  font-size: var(--text-13);
  line-height: 1.4;
  color: var(--soft);
}

.house-card-more p + p {
  margin-top: 2px;
}

@media (hover: hover) and (pointer: fine) and (prefers-reduced-motion: no-preference) {
  .house-card-more {
    transition: opacity 180ms ease;
  }
}

/* На касании блок не показывается вовсе (REQUIREMENTS.md п. 86) — правило
   живёт в самом селекторе выше: `:hover` внутри `hover: hover` не срабатывает
   от касания, второго исключения не нужно. */
@media (hover: hover) and (pointer: fine) {
  .house-card:hover .house-card-more {
    opacity: 1;
  }
}

/* Шапка карточки: номер сверху, дальше — статус оплаты и пометки, каждая
   своей строкой по левому краю (HOUSE-CARD-1, REQUIREMENTS.md п. 142;
   отменяет прежний «чип в правом углу» CARD-3 — на снимке владельца
   «просрочено на 21 день» справа переносилось на две строки, а «депозит
   неполный» съезжала вправо непредсказуемо). Колонка вместо ряда: номер,
   чип оплаты, «прежний жилец», «депозит неполный», пометка договора —
   .house-card-head держит их вертикалью через flex-direction: column,
   align-items: flex-start; gap задаёт одинаковый отступ между строками сразу
   для всех — переносить margin-top на каждую пометку не нужно (было в
   разделе 9 файла, POL-6/DEP-5/LEASE-1 — правки там же, см. ниже). */
.house-card-head {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
}

.house-card-number {
  font-size: 16px;
  font-weight: 700;
  line-height: 1.2;
}

/* Оплачено — номер обычным весом, не жирным: карточка уже зелёная, кричать
   номером незачем (тот же приём, что был у .sc-window[data-scheme='paid']). */
.house-card[data-scheme='paid'] .house-card-number {
  font-weight: 600;
}

/* Этаж — рядом с номером, тем же узлом (23-house.js: пустая строка, если
   поля unit.floor в данных ещё нет — до миграции сервера ничего не рисуется,
   номер остаётся один). Разделитель « · » — часть текста узла, не margin: два
   числа подряд без него читались бы как одно («1» и «3 эт.» — «13 эт.»). */
/* POL-6 21.3 (units-11, shell-21, lists-29): было 11px цветом --mist —
   единственные 11px в системе и единственный текст ниже нормы контраста
   (4,27 на подложке --ember-tint при норме 4,5). 12px — пол шкалы раздела 1
   ТЗ, --soft (#b8b9d0) держит 4,5 на всех шести подложках карточки. */
.house-card-floor {
  font-size: 12px;
  font-weight: 400;
  color: var(--soft);
}

/* HOUSE-CARD-1: компактный чип внутри карточки квартиры — на ступень
   плотнее общего .chip.chip--compact (12px/значок 11px, 05-status.css) —
   11px и значок 10px, летом letter-spacing чуть плотнее (-0.25px вместо
   -0.1px общего правила). Тот файл не трогаем: специфичность (три класса
   вместо двух — «.house-card» добавляет вес) побеждает без правки
   05-status.css. Тот же уменьшенный размер достаётся чипу выезда
   (.house-card-leaving) и чипу счётчиков (.house-card-meterchip, раздел 9
   файла) — один общий приём на все компактные чипы карточки, а не три
   похожих правила порознь. Мера — «просрочено на 21 день» (21 символ,
   самое длинное слово chipa, REQUIREMENTS.md п. 142) на самой узкой
   карточке (161 px, 390 телефон, 137 px внутри рамки): при 11px/-0.25px
   натуральная ширина чипа (значок 10 + зазор 2 + текст) — около 132 px,
   помещается с запасом 2–5 px на всех проверенных ширинах. */
.house-card .chip.chip--compact {
  font-size: 11px;
  letter-spacing: -0.25px;
  gap: 2px;
}

.house-card .chip.chip--compact:before {
  width: 10px;
  height: 10px;
  -webkit-mask-size: 10px 10px;
  mask-size: 10px 10px;
}

/* Сам чип оплаты — своя строка под номером (.house-card-head теперь
   колонка, раздел 1b выше), слева, без переноса. Три класса в селекторе —
   тот же приём, что и выше: специфичность обязана перебить мобильное
   `.chip[class] { white-space: normal }` (05-status.css, ≤780px, два
   класса) — без этого «просрочено на 21 день» на телефоне снова переносилось
   бы по словам, ровно то, что просит исправить владелец. max-width: 100% —
   на всю ширину головы карточки, а не 60% правого угла, как было у CARD-3. */
.chip.chip--compact.house-card-pay {
  flex: 0 0 auto;
  max-width: 100%;
  text-align: left;
  white-space: nowrap;
}

/* Чип выезда — тлеющий цвет, стоит прямо над суммой, после жильца и
   телефона (REQUIREMENTS.md п. 85: «у съезжающих — чип над суммой»; порядок
   узлов — houseCard(), 23-house.js). Своей строкой, не в шапке: дата
   длиннее, чем помещается рядом с номером и чипом оплаты одновременно.
   HOUSE-CARD-1: явный nowrap той же специфичностью, что у чипа оплаты выше
   («съезжает 08.10.26» короче «просрочено на 21 день» и без правки уже
   помещалось бы, но мобильное `.chip[class] { white-space: normal }» —
   05-status.css) иначе отменило бы это молча на ≤780px). */
.chip.chip--compact.house-card-leaving {
  align-self: flex-start;
  color: var(--ember);
  white-space: nowrap;
}

/* Имя жильца — только при tenants.read (houseCardTenant(), 23-house.js:
   строка не рисуется вовсе без права или без жильца). */
.house-card-tenant {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
  color: var(--pearl);
  overflow-wrap: break-word;
}

/* Телефон — настоящая ссылка tel:, тем же приёмом и цветом, что у телефона
   жильца в окне квартиры (.uw-phone, 15-unit-hub) и в карточке жильца
   (.contact-link, 07-tenants.js): лавандовый — цвет ссылки в системе, здесь
   же и физически приглушённее «pearl», которым набрано имя. position:
   relative + z-index выше открывающей кнопки — обязательно: иначе нажатие
   на номер открывало бы окно квартиры вместо звонка. */
.house-card-phone {
  position: relative;
  z-index: 2;
  display: inline-block;
  font-size: 12px;
  font-weight: 400;
  color: var(--lavender);
  text-decoration: none;
}

@media (hover: hover) and (pointer: fine) {
  .house-card-phone:hover {
    color: var(--pearl);
    text-decoration: underline;
  }
}

/* Сумма аренды — главная цифра карточки, крупно и табличными цифрами
   (`font-variant-numeric: tabular-nums` уже стоит на .house-card целиком,
   REQUIREMENTS.md п. 85: «19 585,50 ₽»). */
.house-card-amount {
  font-size: 17px;
  font-weight: 700;
  line-height: 1.25;
}

/* POL-6 21.16: «нет цены» — не сумма, а отсутствие данных, и на 11 из 13
   карточек оно кричало громче номера квартиры тем же кеглем и весом, что и
   настоящая сумма рядом. Тихая заливка и обычный вес — тем же приёмом, что
   у остальных «неизвестно» карточки (`.house-card-utilities--unknown` выше).
   Мобильный блок — правки POL-6 меняют только телефон (общее правило 1
   документа), 1440 остаётся прежним. */
@media (max-width: 780px) {
  .house-card-amount--empty {
    font-weight: 400;
    color: var(--soft);
  }
}

/* Строка «за счётчики» — CARD-4 (REQUIREMENTS.md п. 92, уточнение владельца
   13:15): не зависит от чипа оплаты аренды в углу карточки (жилец мог
   оплатить аренду, сдать показания и не оплатить сами счётчики). Цвет —
   те же токены внимания, что и у остальной карточки: тлеющий («не
   оплачено»), амбра («частично»), --leaf тихо, без жирности («оплачено») —
   деньги уже получены, кричать о них незачем; приглушённый мист —
   «неизвестно» (ставка ещё не подтверждена, суммы нет). */
.house-card-utilities {
  font-size: 12px;
  font-weight: 600;
  line-height: 1.3;
}

.house-card-utilities--unpaid {
  color: var(--ember);
}

.house-card-utilities--partial {
  color: var(--window);
}

.house-card-utilities--paid {
  color: var(--leaf);
  font-weight: 400;
}

.house-card-utilities--unknown {
  color: var(--mist);
  font-weight: 400;
}

/* Полоса «оплачено из ожидаемого» — тонкая, без анимации при появлении
   (REQUIREMENTS.md п. 85; houseCardBar(), 23-house.js: ширина заливки
   считается один раз при отрисовке, не растёт на глазах — это рабочий
   экран управляющего, суммы и доли на нём не анимируются). */
.house-card-bar {
  display: block;
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--border-subtle);
  overflow: hidden;
}

/* Ширина заливки — переменная --w через data-vars (SEC-4, 18-data-table.js:
   applyStyleVars()), не атрибут style: боевой сервер шлёт CSP без
   unsafe-inline в style-src, и строка style="width:…" молча пропадала бы. */
.house-card-bar-fill {
  display: block;
  width: var(--w, 0%);
  height: 100%;
  border-radius: var(--radius-pill);
}

.house-card-bar-fill--paid {
  background: var(--leaf);
}

.house-card-bar-fill--partial {
  background: var(--window);
}

.house-card-bar-fill--overdue {
  background: var(--ember);
}

.house-card-bar-fill--waiting {
  background: var(--mist);
}

/* Низ карточки: счётчики слева, день оплаты справа (REQUIREMENTS.md п. 85).
   margin-top: auto прижимает строку к низу карточки, когда у соседней в
   ряду карточки контента больше (align-items: stretch выше уравнивает
   высоту, а не содержимое). HOUSE-CARD-1 (REQUIREMENTS.md п. 142):
   flex-wrap: nowrap — «ждём счётчики · платит N-го» одной строкой на всех
   ширинах ≥768 (критерий готовности требует нуля переносов на 1440/1280/
   1024, 768-колонка и так шире необходимого, см. таблицу в отчёте); на
   самом узком телефоне (390, 2 карточки в ряд) паре текстов физически не
   хватает места — там перенос возвращается точечно, `.house-card-foot`
   ниже по файлу, раздел 1c. */
.house-card-foot {
  display: flex;
  flex-wrap: nowrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 2px 8px;
  margin-top: auto;
  padding-top: 2px;
}

/* Кегль — 11px, тот же, что у пометок шапки (HOUSE-CARD-1, «одинаковые
   кегли у одинаковых подписей», REQUIREMENTS.md п. 142). */
.house-card-quiet {
  font-size: 11px;
  color: var(--soft);
}

.house-card-day {
  font-size: 11px;
  color: var(--soft);
  white-space: nowrap;
}

/* HOUSE-CARD-1: явный nowrap той же специфичностью, что у чипа оплаты и
   чипа выезда выше — «ждём счётчики» короче их обоих и уже помещается, но
   без этого мобильное `.chip[class] { white-space: normal }`
   (05-status.css, ≤780px) молча включило бы перенос по словам. */
.chip.chip--compact.house-card-meterchip {
  flex-shrink: 0;
  white-space: nowrap;
}

/* Свободная квартира — короткий вид, без жильца и денег (REQUIREMENTS.md
   п. 85: «свободна и без жильца»). */
.house-card-vacant {
  font-size: 13px;
  color: var(--mist);
}

/* --- Цвет карточки = уровень внимания к оплате месяца — те же шесть
   состояний и токены, что у .sc-window[data-scheme] (11-showcase.css,
   UI-8d), своя копия под другую разметку. --- */
.house-card[data-scheme='overdue'] {
  background: var(--ember-tint);
  border-color: var(--ember-edge);
}

.house-card[data-scheme='attention'] {
  background: var(--window-tint);
  border-color: var(--window-edge);
}

.house-card[data-scheme='paid'] {
  background: var(--leaf-tint);
  border-color: var(--leaf-edge);
}

.house-card[data-scheme='waiting'] {
  background: var(--raised);
  border-color: var(--border-subtle);
}

.house-card[data-scheme='vacant'] {
  background: var(--sunken);
  border-color: var(--border-strong);
  color: var(--mist);
}

.house-card[data-scheme='unknown'] {
  border-style: dashed;
  background: none;
  color: var(--mist);
}

/* HOUSE-CARD-1 (REQUIREMENTS.md п. 142): фиксированные «четыре в ряд» на
   1024 px (уточнение владельца 10:15) сняты. Панель на 1024 даёt 704 px —
   4 колонки оставляли карточке 168,5 px (144,5 px внутри рамки), а подвалу
   («ждём счётчики» + «платит 5‑го», оба nowrap, п. 5 ниже) нужно 153–157 px:
   не влезало без переноса, а критерий готовности требует нуля переносов
   именно на 1024. Тот же приём, что просит ТЗ для 1440 («шире колонку, не
   переносить») — просто общее правило auto-fill(190px) снизу доходит до
   1024 само, без своего медиазапроса: на этой ширине оно даёт три колонки
   по 228 px (704 = 3×190 + 2×10 умещается, 4×190 + 3×10 = 790 — нет), с
   большим запасом под подвал и чип оплаты. 768 и 390 не трогаем — там
   фиксированные числа владельца, и на них подвал и так помещается (768) или
   переносится сознательно (390, см. .house-card-foot ниже). */

/* 768 px — три карточки в ряд (уточнение владельца 10:15, отменяет «шесть»
   из CARD-2). */
@media (max-width: 780px) {
  .house-cards {
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }

  /* POL-6 21.16, находка проверяющего: сумма карточки 17 → 16 px — на одну
     ступень шкалы (§1 документа), 1440 не меняется. */
  .house-card-amount {
    font-size: 16px;
  }

  /* POL-6 21.4: второй заголовок «Квартиры дома» дублирует h1 экрана
     («Квартиры · сентябрь 2026») и на телефоне только съедал первый экран —
     класс стоит в 23-house.js:housePanel(). */
  .house-cards-head {
    display: none;
  }
}

/* 390 px — две карточки в ряд, если имя и телефон умещаются (уточнение
   владельца 10:15); имя и телефон переносятся по словам
   (overflow-wrap: break-word выше), а не обрезаются — правило «не прятать
   видимое». */
@media (max-width: 480px) {
  .house-cards {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* HOUSE-CARD-1 (REQUIREMENTS.md п. 142): подвал держит одну строку на
     всех ширинах ≥768 (правило в разделе 1b выше). На двух карточках в ряд
     (161 px, 137 px внутри рамки) «ждём счётчики» + «платит 5-го» вместе
     просят около 155–160 px — не влезают ни при каком разумном кегле, а
     критерий готовности требует нуля переносов только на 1440/1280/1024.
     Здесь — сознательный перенос вместо обрезанного или наползающего
     текста («не прятать видимое»): day уходит под meterchip, оба остаются
     по своим краям. */
  .house-card-foot {
    flex-wrap: wrap;
  }
}

/* ============================================================
   1c. Плитки и «Скоро освободятся» (HOUSE-2, REQUIREMENTS.md п. 86)
   ============================================================ */

/* Четыре плитки — сводка месяца над сеткой карточек, не часть панели
   управления (23-house.js: houseTiles()). align-items: stretch плюс общая
   внутренняя структура (подпись сверху, число снизу) держат одинаковую
   высоту без фиксированного px — подпись длиннее соседней переносится по
   словам той же вёрсткой, что и везде в системе. */
.house-tiles {
  display: grid;
  /* 160, не 180 (находка проверяющего, COLLECTED-1, блокирует): при шести
     плитках (finance.read + meters.read, houseTiles(), 23-house.js) панель
     на 1440 даёт ровно 1126px — при 180px auto-fit укладывал только пять
     колонок (6×180+5×10=1130 > 1126) и шестая плитка уходила отдельным
     рядом с пустотой рядом. 160px даёт запас (6×160+5×10=1010 < 1126) без
     смены самой раскладки: 1fr всё равно растягивает колонки до фактической
     ширины — при пяти и менее плитках ряд выглядит как прежде. */
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  /* Один ряд на мониторе уравнивает stretch; на телефоне плитки в два ряда,
     и без grid-auto-rows: 1fr ряд с переносом подписи («Свободных
     квартир») был на 20 px выше соседнего — плитки должны быть одной
     высоты везде (REQUIREMENTS.md п. 86). */
  grid-auto-rows: 1fr;
  align-items: stretch;
  gap: 10px;
  margin-bottom: 18px;
}

.house-tile {
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
  min-height: 76px;
  padding: 14px 16px;
  border-radius: var(--radius-lg);
  background: var(--surface);
  border: 1px solid var(--border-subtle);
  box-shadow: var(--shadow-1);
}

/* margin: 0 у обоих абзацев: базовое `p { margin: 8px 0 }` (02-base.css)
   складывалось с gap плитки в 22 px между подписью и числом и добавляло по
   8 px сверху и снизу — плитка выглядела пустее соседних панелей. */
.house-tile-label {
  margin: 0;
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--mist);
}

/* 20–24 px, вес 700, табличные цифры (REQUIREMENTS.md п. 86) — крупнее
   подписи, заметно скромнее витрины инвестора (--text-display остаётся ей
   одной). */
.house-tile-value {
  margin: 0;
  font-size: 22px;
  font-weight: 700;
  line-height: 1.2;
  letter-spacing: -0.01em;
  font-variant-numeric: tabular-nums;
  color: var(--pearl);
}

/* Тлеющий — только у плиток, где число больше нуля значит проблему («Не
   оплачено», «Свободных квартир»): решение владельца п. 86, тот же цвет,
   что у просрочки на карточке ниже по файлу. */
.house-tile--attention {
  border-color: var(--ember-edge);
  background: var(--ember-tint);
}

.house-tile--attention .house-tile-value {
  color: var(--ember);
}

/* COLLECTED-1 (REQUIREMENTS.md п. 139): плитка «Собрано», когда за месяц
   собрано всё до копейки (paid ≥ expected > 0, 23-house.js:
   houseCollectedTile()) — тот же тихий зелёный акцент, что у слова
   «оплачено» на карточке квартиры и в чипах (`--leaf`, `.chip--paid`,
   `.house-card-utilities--paid`). Только число меняет цвет — рамка и
   заливка плитки остаются обычными (`.house-tile--attention` сюда не
   подмешивается: это не предупреждение). */
.house-tile-value--paid {
  color: var(--leaf);
}

/* Плитка-кнопка «Освобождаются в этом месяце» (LEAVE-1, REQUIREMENTS.md
   п. 137) — тот же вид, что у остальных плиток («не кричащая», решение
   владельца), только настоящий `<button>` внутри `.house-tiles`: сброс
   центрирования и рамки браузера по умолчанию (`.tariff-house-tile`,
   в этом же файле, — тот же приём для «плитки-кнопки»); цвет, тень и рамка
   берутся у `.house-tile` соседством классов. Курсор и видимый фокус —
   общие правила `button` (02-base.css), здесь не повторяются. */
.house-tile--link {
  width: 100%;
  text-align: left;
  appearance: none;
}

@media (hover: hover) and (pointer: fine) {
  .house-tile--link:hover {
    border-color: var(--violet-edge);
  }
}

/* Подпись под числом плитки — «ещё K позже» / «выездов не намечено»:
   тише подписи сверху, обычный текстовый вес. */
.house-tile-caption {
  margin: 0;
  font-size: var(--text-small);
  font-weight: 400;
  color: var(--mist);
}

/* Телефон — 2×2, а не один столбик: четыре плитки в ряд заняли бы весь
   первый экран (REQUIREMENTS.md п. 86: «мобильная раскладка плиток 2×2»). */
@media (max-width: 780px) {
  .house-tiles {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* POL-6, находка проверяющего: значение плитки-сводки 20 → 18 px — на
     одну ступень шкалы (§1 документа), 1440 не меняется. */
  .house-tile-value {
    font-size: 18px;
  }

  /* Плитка-кнопка (LEAVE-1) не делит пару с соседкой — своей строкой во
     всю ширину, а не одна в паре с пустой ячейкой рядом. */
  .house-tile--link {
    grid-column: 1 / -1;
  }

  /* Находка проверяющего (желательно, COLLECTED-1): она же — «дыра» одним
     рядом выше, когда обычных плиток (без плитки-кнопки) нечётное число.
     houseTiles() (23-house.js) даёт 1, 2, 4 или 5 обычных плиток по правам
     (finance.read/meters.read) плюс плитка-кнопка всегда последней — итого
     2, 3, 5 или 6 в ряду. При 2 и при 5 (последняя обычная плитка — 1-я и,
     соответственно, 5-я, а всего в ряду 2 и 6) она остаётся одна в паре, а
     вторая ячейка пустует. Тот же приём, что у `.uw-bar` ниже по файлу
     (позиция от начала И от конца вместе называют ровно нужную плитку —
     остальные права счёт не трогает): без плитки-кнопки, `:nth-last-child`
     всегда даёт 2 (сама плитка-кнопка стоит здесь последней). */
  .house-tiles > *:nth-child(1):nth-last-child(2),
  .house-tiles > *:nth-child(5):nth-last-child(2) {
    grid-column: 1 / -1;
  }
}

/* ============================================================
   2. Окно квартиры: шапка месяца и полоса действий (UX-1b)
   ============================================================ */

/* Ширина окна квартиры (UNI-7, решение владельца п. 94: «ширина окна на
   мониторе до 720–760 px»). Общий `.detail-dialog` (06-dialogs.css) остаётся
   790 px — там живут и другие листы (`sheetFrame()` зовут ещё пять экранов), и
   диалоги с таблицами. Сужается только окно квартиры, и узнаётся оно по
   собственной шапке: `.uw-head` есть только в нём, `.uw-loading` — его же
   заставка, чтобы ширина не прыгала, пока идёт запрос. Браузер без `:has()`
   оставит прежние 790 px — это не поломка, а прежний вид.
   Ниже 780 px правила 17-mobile-input.css всё равно делают из окна лист во
   всю ширину, поэтому ограничение здесь только для монитора.
   POL-6 21.1 (units-1): медиазапроса у правила не было, а `:has()` даёт ему
   больше веса, чем `.detail-dialog.as-sheet { width: 100% }` из
   17-mobile-input.css (тот файл подключается раньше) — на телефоне побеждало
   оно, и лист выходил 358 px при экране 390, прижатый к левому краю. Оба
   правила заперты порогом монитора: телефону они не адресованы вовсе. */
@media (min-width: 781px) {
  .detail-dialog.as-sheet:has(.uw-head),
  .detail-dialog.as-sheet:has(.uw-loading) {
    width: min(760px, calc(100vw - 32px));
  }
}

/* Запасной путь для браузера без `:has()` (UNI-7b): там правило выше не
   применяется вовсе, и окно осталось бы прежними 790 px. Класс
   `as-unit-window` ставит на лист само окно квартиры (22-unit-window.js) и
   снимает его при закрытии, поэтому чужие листы ширину не наследуют. В
   браузере с `:has()` это правило не читается — верх остаётся один. */
@supports not selector(:has(*)) {
  @media (min-width: 781px) {
    .detail-dialog.as-sheet.as-unit-window {
      width: min(760px, calc(100vw - 32px));
    }
  }
}

/* Блок «Жилец» — первый в окне (UNI-4, `REQUIREMENTS.md` п. 69). Владелец:
   «жилец написан просто „Жилец квартиры №13“ — не видно, что фамилия и имя
   не введены, телефон не введён, есть ли Телеграм». Поэтому слева имя,
   контакты и слова о том, чего не хватает, справа — кнопка, которая это
   исправляет, и форма раскрывается здесь же, под ними.

   Панель того же веса, что форма действия (`.uw-form`): это не подпись под
   заголовком, а рабочее место, с которого начинается любое дело. */
.uw-tenant {
  padding: 12px 16px;
  margin-bottom: 10px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
}

/* Текст и кнопки в один ряд: на мониторе блок занимает одну полосу высотой в
   три строки, а не пять. Ниже 780px `flex-wrap` сам ставит кнопки под текст. */
.uw-tenant-row {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: 10px 18px;
}

/* NQA-GAP0-1 (ночной аудит NIGHT-QA-1, REQUIREMENTS.md п. 140): базис был
   320px — при широких кнопках справа (`.uw-tenant-acts`, «Внести данные
   жильца» + «Выселить» одновременно, ≈290px) текст оставался единственным,
   кто уступает место: `flex-grow` отдавал колонке фактов только остаток
   строки (≈345px из ≈657), и абзац с четырьмя фактами и тремя «Изменить»
   переносился в 6+ строк, а под короткой парой кнопок оставалось пустое
   поле высотой в их же рост. 420px — тот же приём, что у соседних
   `minmax(...)` дорожек форм окна ниже: при широких кнопках колонки уже не
   помещаются рядом, и `flex-wrap` кладёт кнопки на отдельную строку под
   текст во всю ширину — то же самое расположение, что и на телефоне
   (779px и ниже), без ужатого текста и без пустоты. */
.uw-tenant-main {
  flex: 1 1 420px;
  min-width: 0;
}

.uw-tenant-name {
  margin: 0 0 2px;
  font-size: var(--text-h2);
  font-weight: 700;
  line-height: 1.25;
  color: var(--pearl);
}

/* «Данные жильца не внесены» — такая же крупная строка, как имя: это ответ на
   вопрос «кто здесь живёт», а не сноска. Цвет — обычный текстовый: тлеющим в
   системе красится только тревога (DESIGN.md, One Meaning), а незаполненная
   карточка — это работа, а не авария. */
.uw-tenant-name.is-empty {
  color: var(--pearl);
}

/* Подпись роли без права на жильцов («Кто здесь живёт, вам не показывается»):
   это не имя, и крупным весом его набирать незачем. */
.uw-tenant-name.is-quiet {
  font-size: var(--text-body);
  font-weight: 400;
  color: var(--soft);
}

.uw-tenant-contacts {
  margin: 0;
  font-size: var(--text-body);
  line-height: 1.4;
  color: var(--soft);
}

/* TENANT-FIELDS-1 (REQUIREMENTS.md п. 133(10)): «Представитель» — ещё одна
   тихая строка под контактами жильца, тем же цветом и кеглем, что
   `.uw-tenant-contacts` выше — это тоже способ связаться с тем же жильцом,
   не факт о деньгах и не тревога. */
.uw-tenant-representative {
  margin: 3px 0 0;
  font-size: var(--text-body);
  line-height: 1.4;
  color: var(--soft);
}

.uw-tenant-dot {
  color: var(--mist);
}

/* Чего не хватает — словами и в общем ряду с контактами: список пробелов
   стоит там же, где сами контакты, и читается как продолжение строки. */
.uw-tenant-gap {
  color: var(--mist);
}

.uw-tenant-gap.is-gap {
  color: var(--pearl);
  font-weight: 700;
}

.uw-tenant-note {
  margin: 3px 0 0;
  font-size: var(--text-small);
  line-height: 1.35;
  color: var(--mist);
}

/* Тихая строка фактов под именем (UNI-5, п. 72): «Заехал 10 июля 2026 · живёт
   2 месяца · депозит 27 000 ₽ на хранении». Владелец: «небольшие строчки, не
   бросаются в глаза, но видны» — поэтому 14px и `--soft` (9,05:1), а не
   `--mist`: это факты, которые читают, а не сноска. */
.uw-tenant-facts {
  margin: 3px 0 0;
  font-size: var(--text-small);
  line-height: 1.4;
  color: var(--soft);
}

/* DEP-5: тон предупреждения на недостающий депозит (`partial`/`none`) — тот
   же `--ember`, что у долга по аренде (`.uw-former.is-warn`). Красится
   только сама фраза сервера про депозит, а не вся строка фактов («Заехал …
   · живёт …» остаются вспомогательным цветом): один факт — один цвет. */
.uw-fact-warn {
  color: var(--ember);
}

/* PAY-WAY-1 (REQUIREMENTS.md п. 126): «Способ оплаты не указан» — тот же
   приглушённый цвет, что у пустого `.uw-tenant-gap` (`--mist`, 5,76:1 на
   поверхности / 4,86:1 на утопленном фоне — выше порога 3:1 для
   вспомогательного текста). Это отсутствие сведений, а не тревога: указанный
   способ остаётся обычным цветом строки фактов. */
.uw-payment-quiet {
  color: var(--mist);
}

/* «Довнести» — тихое действие рядом с фразой депозита, тот же приём, что и
   «оплаты» у итога счётчиков (`.uw-util-link`): маленькая ссылка-кнопка без
   заливки, цель касания 44px только там, где тычут пальцем. */
.uw-deposit-topup {
  min-height: 24px;
  padding: 0;
  font-size: var(--text-small);
}

/* «Изменить» у строки способа оплаты — тот же тихий приём, что «Довнести»
   выше: тонкая ссылка-кнопка внутри строки фактов, не отдельная кнопка
   жильца (`.uw-tenant-btn`). */
.uw-payment-way-edit {
  min-height: 24px;
  padding: 0;
  font-size: var(--text-small);
}

/* LEASE-1 (REQUIREMENTS.md п. 129): «Изменить» у строки договора — тот же
   приём, что у соседней строки способа оплаты выше. */
.uw-contract-edit {
  min-height: 24px;
  padding: 0;
  font-size: var(--text-small);
}

/* MOVEIN-DATE-1 (REQUIREMENTS.md п. 133 (8)): «Изменить» у строки «Заехал
   …» — тот же приём, что у способа оплаты и договора выше. */
.uw-move-in-edit {
  min-height: 24px;
  padding: 0;
  font-size: var(--text-small);
}

/* DEP-FIX-1 (REQUIREMENTS.md п. 134): «Исправить сумму» у строки депозита —
   тот же тихий приём, что «Довнести» рядом. */
.uw-deposit-fix {
  min-height: 24px;
  padding: 0;
  font-size: var(--text-small);
}

@media (pointer: coarse) {
  .uw-deposit-topup,
  .uw-payment-way-edit,
  .uw-contract-edit,
  .uw-move-in-edit,
  .uw-deposit-fix {
    min-height: var(--tap);
  }
}

.uw-tenant-acts {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

/* Кнопки жильца — того же размера, что полоса действий (36px, кегль 14/700):
   владелец просил кнопки меньше и слов меньше (UNI-5). Цель касания пальцем
   возвращается к 44px правилом `pointer: coarse` и на телефоне. */
.uw-tenant-btn {
  min-height: 36px;
  padding: 0 13px;
  border: 1px solid var(--border-field);
  border-radius: var(--radius-md);
  background: var(--raised);
  color: var(--pearl);
  font-size: var(--text-small);
  font-weight: 700;
  transition:
    background 140ms ease,
    border-color 140ms ease;
}

/* Заметная кнопка — пока данных нет: заливка акцентом, как у главной кнопки
   формы. Заполненный жилец получает тихую «Изменить данные». */
.uw-tenant-btn.is-primary {
  background: var(--violet);
  border-color: var(--violet);
  color: var(--on-violet);
}

@media (hover: hover) and (pointer: fine) {
  .uw-tenant-btn:hover {
    border-color: var(--violet-edge);
    background: var(--state-hover);
  }
  .uw-tenant-btn.is-primary:hover {
    background: var(--lavender);
    border-color: var(--lavender);
  }
}

/* Раскрытая кнопка — та же светящаяся полоса снизу, что у полосы действий:
   форма раскрывается прямо под ней, и связь «кнопка → поля» видна. */
.uw-tenant-btn[aria-expanded='true'] {
  box-shadow: inset 0 -3px 0 0 var(--violet);
}

.uw-tenant-btn.is-primary[aria-expanded='true'] {
  box-shadow: inset 0 -3px 0 0 var(--on-violet);
}

/* Форма жильца раскрывается внутри блока: не вторая карточка в карточке, а
   продолжение той же — отделена чертой, фона не меняет. */
.uw-tenant-form:empty {
  display: none;
}

.uw-tenant-form {
  margin-top: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--border-subtle);
}

.uw-tenant-form .detail-form > .primary {
  grid-column: 1/-1;
}

/* HOLDER-1 (REQUIREMENTS.md п. 133 (5)): «Название нового хранителя» скрыта
   до выбора «+ новый хранитель…» в форме заселения (`uwWireDepositHolderNew`,
   22-unit-window.js) — тот же приём, что у `.unit-add-form[hidden]` выше:
   `.field` задаёт `display: flex` своим классом, и родовое `[hidden] {
   display: none }` браузера проигрывает ему по специфичности. */
.uw-holder-new[hidden] {
  display: none;
}

/* HOLDER-1: на телефоне `.hub-row > div` сводит заголовок и первую строку значения в
   одну строку через flex-wrap (08-screens.css §9.2, чужая зона) — верно для «Кто хранит
   — …» под своим h3, но список хранителей объекта встал бы следом за «Историей
   хранителей» прямо перед собой в один ряд: два разных заголовка подряд без связи
   (`tariffHolderRegistry`, 24-tariffs-page.js). `flex-basis: 100%` заставляет весь блок
   начаться с новой строки, что бы перед ним ни стояло. */
@media (max-width: 780px) {
  .tariff-holder-block {
    flex-basis: 100%;
  }
}

/* Ошибка поля — под самим полем, словами (CONVENTIONS §8). Общий обработчик
   `invalid` (02-dialogs.js) отвечает за пустые обязательные поля; здесь
   данные необязательные, и проверяется вид записи — телефон, ник, паспорт. */
.uw-field-note {
  display: block;
  margin-top: 4px;
  font-size: var(--text-small);
  line-height: 1.35;
  color: var(--ember);
}

/* `textarea` — ради «Соцсети и ссылки» (SOCIAL-1): единственное многострочное
   поле формы жильца, ошибку сервера («Не больше десяти ссылок») подсвечиваем
   тем же цветом рамки, что и остальные поля. */
.uw-tenant-form .field.is-error input,
.uw-tenant-form .field.is-error textarea {
  border-color: var(--ember);
}

/* Первый `<textarea>` в системе (`.field textarea` уже одета в 04-components.css:
   рамка, фон, отступ). Браузер по умолчанию разрешает тянуть его и вширь —
   поле растягивало бы форму за её ширину на телефоне. Высоту оставляем
   растяжимой: три строки — расчётная, но записей может быть до десяти. */
.field textarea {
  resize: vertical;
}

.uw-phone {
  font-weight: 400;
  color: var(--lavender);
  white-space: nowrap;
}

.uw-phone:focus-visible {
  color: var(--pearl);
}

@media (hover: hover) and (pointer: fine) {
  .uw-phone:hover {
    color: var(--pearl);
  }
}

/* SOCIAL-1 (REQUIREMENTS.md п. 132): ссылка на соцсеть — тот же цвет и
   поведение, что у телефона и Телеграма (.uw-phone), но текст свободный и
   бывает длиннее ника — там, где .uw-phone держит номер и ник одной
   строкой (nowrap), здесь строка обязана переноситься, иначе длинная
   ссылка вылезла бы за край экрана на 390. Телефон и Телеграм это правило
   не трогает — модификатор добавлен только к ссылкам соцсетей. */
.uw-social-link {
  white-space: normal;
  overflow-wrap: anywhere;
}

/* Приёмка TZ-SOCIAL-1 (находка 1, проверяющий, 2026-09-22): цель касания
   ссылки на соцсеть должна быть ≥ 44px (CONVENTIONS.md §8). `.uw-phone`
   (телефон, Телеграм) такой цели не имел и до этой задачи — трогать его
   здесь нельзя, это не регрессия SOCIAL-1, а отдельный вопрос вне зоны
   файлов задачи. Тот же приём, что у «Довнести» / «Изменить» выше в этом
   файле: на мышь строка остаётся тихой строкой фактов без отступов, палец
   получает высоту `--tap` через `pointer: coarse`, раскладка на мониторе не
   меняется. `inline-flex` не ломает перенос длинной ссылки — `overflow-wrap:
   anywhere` уже выше даёт flex-элементу сжиматься ниже своего текста
   (стандартный приём против `min-width: auto` в застревающих flex-текстах),
   перенос проверен на стенде на 390 с эмуляцией пальца. */
@media (pointer: coarse) {
  .uw-social-link {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap);
  }
}

/* Текст без ссылки (`social_links_list` без url) — обычный `.chip`
   (05-status.css), у которого `white-space: nowrap` держит короткие подписи
   состояния в одну строку. Здесь текст свободный и может быть длиннее —
   разрешаем перенос только в этих двух местах, не трогая `.chip` в
   остальной системе (CODEX-NOTES §7: чужой каскад не менять). */
.contact-row .chip,
.uw-tenant-contacts .chip {
  white-space: normal;
  overflow-wrap: anywhere;
  text-align: left;
}

/* TENANT-FIELDS-1 (REQUIREMENTS.md п. 133(10)): «Представитель» в профиле
   жильца — строка под рядом контактов, тем же основным цветом текста
   панели (`.panel` его не переопределяет — читается как обычный абзац),
   только с отступом снизу, симметричным `.contact-row` над ней (14px). */
.contact-representative {
  margin: 0 0 14px;
}

/* Шапка: шесть цифр месяца двумя строками и месяц справа. Прежние вкладки
   «Месяц / Квартира» и три плашки по 90 px в каждом из двух блоков убраны —
   те же цифры читаются здесь одним взглядом. */
.uw-head {
  padding: 12px 16px;
  margin-bottom: 10px;
  background: var(--sunken);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}

.uw-head-top {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 14px;
  margin-bottom: 8px;
}

/* Месяц маленьким списком в одну строку с подписью: он редко меняется, но
   всегда виден, и второй строки под себя не просит. `flex: 0 1 auto` —
   рядом с ним теперь стоит чип состояния (UNI-4), и список не должен
   растягиваться на всю строку, оттесняя чип на вторую. */
.uw-month {
  flex: 0 1 auto;
  flex-direction: row;
  align-items: center;
  gap: 4px 10px;
  margin: 0;
}

.uw-month select {
  min-height: var(--tap);
  max-width: 260px;
}

.uw-line {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 14px;
  margin: 0 0 4px;
  font-size: var(--text-body);
  color: var(--soft);
  line-height: 1.4;
}

/* SEC-6: строка вместо шести сумм, которых этой роли не показывают. Тот же
   кегль, что у строки аренды, которую она заменяет, — это ответ на месте
   ответа, а не сноска внизу окна. */
.uw-no-money {
  margin: 0 0 4px;
  font-size: var(--text-body);
  color: var(--soft);
  line-height: 1.4;
}

.uw-line-name {
  min-width: 84px;
  font-weight: 700;
  color: var(--pearl);
}

.uw-line strong {
  color: var(--pearl);
  font-variant-numeric: tabular-nums;
}

/* Остаток — то, ради чего экран открыли: он один набран амброй денег. */
.uw-line-left strong {
  color: var(--window);
}

/* Чип состояния стоит в одной строке с месяцем (UNI-4): «за сентябрь» и
   «оплачено» — один ответ, и незачем разносить его на две строки. Пояснения
   («просрочено на 3 дн.», «условия менялись») идут тут же inline и переносятся
   сами, забирая пустое место справа от списка месяцев. */
/* UNI-7: `flex: 0 1 auto` вместо `1 1 220px` — чип занимает столько, сколько
   в нём слов, и не отжимает счётчики со сроком оплаты на вторую строку. Длинные
   пояснения внутри чипа переносятся сами: `min-width: 0` им это позволяет. */
.uw-status {
  flex: 0 1 auto;
  min-width: 0;
  margin: 0;
}

.uw-status .cell-note {
  display: inline;
  margin-left: 8px;
}

/* UNI-7: срок оплаты уехал в ту же первую строку шапки — прежде это была
   отдельная строка (сноской под цифрами). `margin-left: auto` прижимает его
   вправо, к краю шапки: слева месяц и состояние, справа — срок.
   Счётчики месяца стояли в этой же строке рядом со сроком (`.uw-utility`) —
   убраны находкой проверяющего UTIL-1B: сумма дословно повторяла итог блока
   «За счётчики» ниже. */
.uw-due {
  margin: 0 0 0 auto;
  font-size: var(--text-small);
  color: var(--soft);
  white-space: nowrap;
}

/* «Сумма изменена управляющим» (`rentAdjustedNote`, 12-rent.js) — строка-
   раскрытие, а не панель: общее правило `.detail-body details`
   (06-dialogs.css) даёт ей фон, рамку и 15px полей, из-за чего шапка месяца
   на квартире с правкой вырастала на 90px. Содержимое то же. */
.uw-status .rent-notice {
  margin: 4px 0 0;
  padding: 0;
  max-width: none;
  background: none;
  border: 0;
}

.uw-status .rent-notice > summary {
  min-height: 0;
  font-size: var(--text-small);
}

.uw-status .rent-notice[open] > summary {
  margin-bottom: 4px;
}

/* Счётчики по видам — одной строкой под чипом состояния (UNI-3): слова целиком
   готовит сервер (`entered_words`), здесь только раскладка чипов/подписей в
   ряд. Невнесённый счётчик — кнопка `.chip--pending` (тот же пустой кружок,
   что у «ждём оплату»): заметнее плоской подписи и ведёт прямо к «Внести
   счётчики» (`data-uw-kind-open`, 22-unit-window.js). */
.uw-kinds {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 10px;
  margin: 6px 0 0;
}

/* UNI-7: слово «Счётчики» слева — той же ширины, что название денежной строки
   над ним, чтобы обе строки шапки начинались с одной вертикали (владелец
   п. 94: «выровнять положение текста»). */
.uw-kinds-name {
  min-width: 84px;
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--pearl);
}

.uw-kind {
  font-size: var(--text-small);
  color: var(--soft);
}

/* Чип-кнопка получает нормальную цель касания: базовый `.chip` из
   05-status.css рассчитан на подпись, а не на орган управления (28px). На
   мониторе с мышью хватает 36px — это те же 27px текста плюс поля, и шапка
   месяца не отнимает у формы лишнюю строку; пальцу 44px возвращает правило
   `@media (pointer: coarse)` в §8. */
.uw-kinds button.chip {
  min-height: 36px;
  border: 1px solid var(--border-field);
  font: inherit;
  font-size: var(--text-small);
  font-weight: 700;
  cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
  .uw-kinds button.chip:hover {
    border-color: var(--violet-edge);
  }
}

.uw-head .footnote {
  margin: 4px 0 0;
}

/* Полоса действий: пять кнопок в один ряд на мониторе, кегль 14/700, высота
   36 (владелец п. 69: «кнопки можно меньше, текста меньше»). Порядок — по
   частоте за день (оплата → счётчики → расход → цена → пересчёт), поэтому на
   телефоне первым под большим пальцем оказывается то, что управляющий делает
   каждый день. Заселение, выселение и депозит ушли в блок «Жилец» — там же,
   где имя и строка «депозит … на хранении».
   Основа дорожки 132px, а не 150: пятая кнопка (EXP-1 «Расход») в прежнюю
   сетку на 1440 входила только вторым рядом.
   На сенсорном экране цель касания возвращается к 44px (правило ниже). */
/* UNI-7 (решение владельца п. 94: «кнопки, которые можно, — в один ряд»):
   основа дорожки 112px, а не 132. Окно сузилось до 760px, и при 132px пятая
   кнопка («Пересчёт») уходила вторым рядом — ровно то, из-за чего полоса
   переставала читаться как один ряд равных кнопок. Самое длинное слово
   («Пересчёт», 14/700) занимает 70px, поля дают ещё 24 — 112px хватает с
   запасом, а `1fr` всё равно растягивает дорожки до равной ширины. */
.uw-bar {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(112px, 1fr));
  gap: 8px;
  margin-bottom: 12px;
}

.uw-action {
  min-height: 36px;
  padding: 6px 12px;
  border: 1px solid var(--border-field);
  border-radius: var(--radius-md);
  background: var(--raised);
  color: var(--pearl);
  font-size: var(--text-small);
  font-weight: 700;
  text-align: center;
  transition:
    background 140ms ease,
    border-color 140ms ease,
    color 140ms ease;
}

/* Сенсорный экран любой ширины: пальцем в 40px попадают хуже, чем мышью
   (CONVENTIONS §8 — цель касания не меньше 44px). На мониторе с мышью
   кнопка остаётся низкой, как просил владелец. */
@media (pointer: coarse) {
  .uw-notes-history > summary,
  .uw-expense-history > summary,
  .uw-meter input {
    min-height: var(--tap);
  }
  .uw-action,
  .uw-tenant-btn,
  .uw-kinds button.chip,
  .uw-form .primary,
  .uw-form .secondary,
  .uw-tenant-form .primary,
  .uw-tenant-form .secondary,
  .uw-notes .detail-form .primary {
    min-height: var(--tap);
  }
}

@media (hover: hover) and (pointer: fine) {
  .uw-action:hover {
    border-color: var(--violet-edge);
    background: var(--state-hover);
  }
}

/* Раскрытое действие: заливка акцентом, кромка и светящаяся полоса снизу —
   тот же приём, что у активного пункта меню (03-shell.css). Различие не
   только в цвете: полоса — форма, её видно и в оттенках серого. */
.uw-action[aria-expanded='true'] {
  background: var(--state-active);
  border-color: var(--violet);
  color: var(--pearl);
  box-shadow: inset 0 -3px 0 0 var(--violet);
}

/* Форма нажатого действия — под полосой, на месте, без нового диалога. */
.uw-form:empty {
  display: none;
}

.uw-form {
  padding: 12px 14px;
  margin-bottom: 12px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
}

/* «За что заплатили?» — подпись и два ответа в одну строку и без рамки:
   вопрос с двумя ответами не стоит отдельной рамки в 15px полей, из-за
   которой главная кнопка формы уезжала под нижний край окна. */
.uw-form .uw-pay-kind {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  padding: 0;
  border: 0;
}

/* Строки формы в окне стоят чуть плотнее, чем в обычном диалоге: поля те же,
   но форма должна помещаться в окно целиком вместе с главной кнопкой. */
.uw-form .detail-form,
.uw-tenant-form .detail-form {
  gap: 12px 14px;
}

/* «Ещё» внутри окна (заметка к оплате, паспорт жильца) — компактнее общего
   правила `.detail-body details`: в окне квартиры это строка под формой, а не
   отдельная панель. */
.uw-form .passport-fields,
.uw-tenant-form .passport-fields {
  margin-top: 8px;
  padding: 8px 12px;
}

/* Кнопки форм окна — по содержимому и ниже обычных (UNI-5, владелец п. 72:
   «„Записать оплату“ во всю ширину не нужна — маленькая»). Полосу во всю
   ширину они занимали с UX-1b; теперь кнопка стоит рядом с полями, к которым
   относится, и ровно такой ширины, сколько в ней слов. */
.uw-form .primary,
.uw-form .secondary,
.uw-tenant-form .primary,
.uw-tenant-form .secondary,
.uw-notes .detail-form .primary {
  min-height: 38px;
  padding: 8px 16px;
  font-size: var(--text-small);
  justify-self: start;
  width: auto;
}

/* Формы в одну строку: поля и кнопка в общем ряду, кнопка — по содержимому и
   выровнена по нижнему краю поля (подпись стоит над полем, а не слева).
   `auto` в последней дорожке и есть «по содержимому». */
.uw-row-form {
  grid-template-columns: minmax(130px, 200px) minmax(130px, 1fr) auto;
  align-items: end;
}

.uw-row-form > .primary {
  grid-column: auto;
}

/* Дата обхода счётчиков — одна, поэтому дорожек две: поле и кнопка. */
.uw-meters-foot {
  grid-template-columns: minmax(150px, 220px) auto;
}

/* Этаж (FLOOR-1) — то же устройство, что у даты обхода счётчиков выше:
   одно короткое поле и кнопка рядом, без второй дорожки под подпись. */
.uw-floor-row {
  grid-template-columns: minmax(90px, 140px) auto;
}

/* UNI-7: кнопка «Сохранить» у этажа стоит вне `.uw-form`, и общее правило
   «кнопки форм окна — по содержимому» её не достаёт: дорожка `auto`
   разливала её на всю оставшуюся ширину раскрытых «Истории и настроек».
   Те же размеры, что у кнопок форм выше. */
.uw-floor-row > button {
  justify-self: start;
  width: auto;
  min-height: 38px;
  padding: 8px 16px;
  font-size: var(--text-small);
}

@media (pointer: coarse) {
  .uw-floor-row > button {
    min-height: var(--tap);
  }
}

/* MOVEIN-DATE-1 (REQUIREMENTS.md п. 133 (8)) — «Изменить» у строки «Заехал
   …»: одно поле даты и пара тихих кнопок (`.uw-inline-acts`), та же ширина
   поля, что у даты обхода счётчиков (`.uw-meters-foot`) — дата, а не
   короткое число, как у этажа. */
.uw-move-in-row {
  grid-template-columns: minmax(150px, 220px) auto;
}

/* HOLDER-1 (REQUIREMENTS.md п. 133 (5)): «У кого хранится» в «Изменить
   депозит» — то же устройство, что у этажа и даты заезда выше: одно поле
   (список хранителей) и кнопка рядом, без второй дорожки под подпись. Шире,
   чем у этажа: имя хранителя длиннее двух цифр («ООО ВСС», а не «3»). */
.uw-holder-row {
  grid-template-columns: minmax(160px, 260px) auto;
}

/* Заметка: дата, текст и кнопка. Текст забирает всё свободное место — в нём
   пишут фразу, а не число. */
.uw-note-row {
  grid-template-columns: minmax(130px, 170px) minmax(160px, 1fr) auto;
}

/* Цена, день оплаты и дата действия — одна строка (UNI-6, REQUIREMENTS.md
   п. 89): день оплаты переехал сюда из «Истории и настроек», к цене, а не
   под сгиб. Причина и предпросмотр остаются на всю ширину ниже своими
   классами (`.field.full-field`, `.uw-preview`) — эта дорожка задаёт только
   первую строку формы, кнопка в неё не входит. */
.uw-price-row {
  grid-template-columns: minmax(140px, 1fr) minmax(110px, 130px) minmax(140px, 170px);
}

/* Кнопка формы данных жильца стоит в своей строке (полей пять, в ряд они не
   встанут), но ширину держит по содержимому. */
.uw-tenant-form .detail-form > .primary {
  grid-column: 1/-1;
}

.uw-form-title {
  font-size: var(--text-h3);
  color: var(--pearl);
  margin: 0 0 4px;
}

.uw-form-sub {
  font-size: var(--text-small);
  color: var(--soft);
  line-height: 1.45;
  margin: 0 0 10px;
}

/* Предпросмотр «Что изменится» в форме цены: не украшение, а ответ на
   вопрос «поменялось или нет», из-за которого владелец ходил по формам. */
.uw-preview {
  /* Форма диалога — сетка в две колонки (06-dialogs.css): предпросмотр в
     половину ширины рвал бы строки «сентябрь 2026 — ждём 30 000 ₽» пополам. */
  grid-column: 1/-1;
  padding: 12px 14px;
  margin: 4px 0 14px;
  background: var(--sunken);
  /* Тонкая амбровая рамка по контуру, без толстой полосы слева: блок и так
     выделен фоном и заголовком «Что изменится». */
  border: 1px solid var(--window-edge);
  border-radius: var(--radius-md);
  font-size: var(--text-body);
  color: var(--soft);
  line-height: 1.5;
}

.uw-preview-word {
  display: block;
  font-size: var(--text-small);
  font-weight: 700;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--mist);
  margin-bottom: 6px;
}

.uw-preview p {
  margin: 0;
}

.uw-preview ul {
  margin: 0;
  padding-left: 18px;
}

.uw-preview li {
  font-variant-numeric: tabular-nums;
  color: var(--pearl);
  margin-bottom: 2px;
}

.uw-preview .footnote {
  margin-top: 6px;
}

/* ---------- Форма «Жилец выехал» (DEP-4, REQUIREMENTS.md п. 98) ---------- */

/* Тихая строка депозита над полем возврата: «внесено · удержано · на хранении ·
   хранит». Не поле и не заголовок — факт, который читают перед тем, как
   вписать сумму, поэтому цвет второстепенного текста, а не основного. */
.vacate-dep {
  grid-column: 1/-1;
  margin: 0;
  font-size: var(--text-small);
  line-height: 1.45;
  color: var(--soft);
}

/* Строка про право на деньги стоит там же, где стояло бы поле: она отвечает на
   вопрос «а где ввести сумму», а не рассказывает о системе вообще. */
.vacate-dep--right {
  color: var(--mist);
}

/* Блок остатка появляется прямо под полем возврата и во всю ширину формы:
   переключатель «Удержано / Оставить на хранении» в половину дорожки ломался бы
   на две строки. Показ и скрытие — атрибутом `hidden`: `style=` запрещён (CSP). */
.vacate-rest {
  grid-column: 1/-1;
}

.vacate-rest[hidden],
.vacate-reason[hidden],
.vacate-note[hidden] {
  display: none;
}

/* Полстроки под кнопкой вместо прежнего абзаца в три предложения (п. 94):
   что закроется и где записывают счётчики — в подсказке на этих же словах. */
.vacate-hint {
  grid-column: 1/-1;
  margin: 0;
  font-size: var(--text-small);
  line-height: 1.4;
  color: var(--mist);
}

/* Редкий случай внутри действия («Он только предупредил»): ссылка-раскрытие,
   а не вторая равноправная форма. */
.uw-rare {
  margin-top: 14px;
  border-top: 1px solid var(--border-subtle);
  padding-top: 10px;
}

.uw-rare > summary {
  min-height: var(--tap);
  display: flex;
  align-items: center;
  cursor: pointer;
  color: var(--lavender);
  font-size: var(--text-body);
}

/* История и настройки: свёрнуто внизу окна, грузится только при открытии. */
.uw-more {
  margin-top: 14px;
  border-top: 1px solid var(--border-subtle);
  padding-top: 12px;
}

.uw-more > summary {
  min-height: var(--tap);
  display: flex;
  align-items: center;
  cursor: pointer;
  color: var(--lavender);
  font-size: var(--text-body);
  font-weight: 700;
}

/* MOVEIN-DATE-1 (REQUIREMENTS.md п. 133 (9)): «День оплаты: 27-го числа» —
   первая строка внутри раскрытых «Истории и настроек» (п. 93: «цена и день
   оплаты, этаж…»), тем же отступом сверху, что раньше был у этажа. */
.uw-payment-day {
  margin-top: 14px;
}

.uw-payment-day-words {
  margin: 0;
  font-size: var(--text-small);
  color: var(--soft);
}

.uw-payment-day-edit {
  min-height: 24px;
  padding: 0;
  font-size: var(--text-small);
}

@media (pointer: coarse) {
  .uw-payment-day-edit {
    min-height: var(--tap);
  }
}

/* Этаж (FLOOR-1) — тем же отступом, что у строки дня оплаты выше, чтобы шов
   между статичным блоком этого файла и догруженным содержимым
   (`unitConditions()`, 06-units.js) не был заметен. */
.uw-floor {
  margin-top: 14px;
}

.uw-floor-title {
  font-size: var(--text-h3);
  color: var(--pearl);
  margin: 0 0 8px;
}

/* Депозит внутри «Истории и настроек» (UNI-7, решение владельца п. 94): те же
   отступы, что у этажа выше, — раскрытый блок читается как один список
   настроек, а не как набор разнородных панелей. */
.uw-deposit-block {
  margin-top: 16px;
}

.uw-deposit-words {
  margin: 0 0 8px;
  font-size: var(--text-small);
  color: var(--soft);
}

/* «Удалить квартиру» (UNIT-DEL-1, REQUIREMENTS.md п. 127) — последняя строка
   окна, ниже депозита, теми же отступами, чтобы шов между разделами не был
   заметен. Кнопка открытия — обычный `.secondary`, тон опасного действия
   появляется только у раскрытого подтверждения (`.uw-inline--void`,
   `.secondary.danger` — правила уже есть в файле ниже, §2б). */
.uw-delete-zone {
  margin-top: 16px;
}

/* Подтверждение действия на самой кнопке вместо системного окна браузера. */
.is-armed {
  border-color: var(--ember);
  color: var(--ember);
}

.confirm-note {
  display: block;
  margin-top: 6px;
  color: var(--soft);
}

/* ============================================================
   2б. Расход по квартире, депозит и правка строк (EXP-1, DEP-2)
   ============================================================ */

/* Разметку собирает web/js/22-unit-window.js. Правило одно на весь раздел:
   правка идёт СТРОКОЙ НА МЕСТЕ, а не новым окном — общий <dialog> у системы
   один, и диалог поверх окна квартиры закрыл бы само окно. Поэтому у списков
   тут два состояния: строка и та же строка, ставшая формой. */

/* Форма расхода (EXP-3): статья ушла за «Ещё» (`.detail-form > .passport-fields`
   в 08-screens.css растягивает её на всю ширину сама) — на виду остались три
   дорожки, те же, что задаёт базовый `.uw-row-form`: сумма, «за что» и кнопка
   (или, в строке правки, сумма, «за что» и пара тихих кнопок). Своего
   переопределения здесь больше не нужно. */

/* Удержание: сумма, причина, пояснение и кнопка. Пояснение забирает свободное
   место — в нём пишут фразу, а не число. */
.uw-withhold-row {
  grid-template-columns: minmax(110px, 140px) minmax(150px, 200px) minmax(160px, 1fr) auto;
}

/* Заголовок списка под формой: «Расходы за сентябрь: 5 000 ₽». */
.uw-list-title {
  margin: 14px 0 6px;
  font-size: var(--text-small);
  color: var(--soft);
}

.uw-list-title b {
  color: var(--pearl);
  font-variant-numeric: tabular-nums;
}

.uw-money-list {
  display: grid;
  gap: 0;
}

/* Строка списка: текст слева, сумма и две тихие кнопки справа. Три дорожки, а
   не флекс: суммы всех строк стоят на одной вертикали, как в книге. */
.uw-money-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto auto;
  align-items: baseline;
  gap: 4px 12px;
  padding: 8px 0;
  border-bottom: 1px solid var(--border-subtle);
  font-size: var(--text-small);
  color: var(--soft);
}

.uw-money-row:last-child {
  border-bottom: 0;
}

.uw-money-text {
  min-width: 0;
  line-height: 1.4;
}

.uw-money-row .money {
  color: var(--pearl);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Удалённая запись приходит только владельцу (`REQUIREMENTS.md` п. 76): у
   управляющего и инвестора этих строк нет вовсе. Зачёркнута сумма — именно она
   ушла из учёта; слова «Удалена — причина» стоят отдельной строкой и не
   зачёркиваются (`text-decoration` у потомка снять нельзя). */
.uw-money-row.is-void {
  color: var(--mist);
}

.uw-money-row.is-void .money {
  text-decoration: line-through;
  text-decoration-color: var(--border-field);
}

.uw-money-gone,
.uw-money-mark {
  display: block;
  margin-top: 2px;
  font-size: var(--text-small);
  color: var(--mist);
}

.uw-row-acts {
  display: flex;
  gap: 10px;
  justify-content: flex-end;
}

.uw-row-acts .subtle-btn {
  min-height: 30px;
  padding: 2px 0;
  font-size: var(--text-small);
}

@media (pointer: coarse) {
  .uw-row-acts .subtle-btn {
    min-height: var(--tap);
  }
}

/* Строка, ставшая формой: подложка и рамка акцентом — видно, что правится
   именно она. Конечное состояние без анимации: экран ввода статичен. */
.uw-inline {
  margin: 6px 0;
  padding: 10px 12px;
  border: 1px solid var(--violet-edge);
  border-radius: var(--radius-md);
  background: var(--sunken);
}

.uw-inline-title {
  margin: 0 0 8px;
  font-size: var(--text-small);
  color: var(--soft);
  line-height: 1.4;
}

/* Три готовые причины удаления: щелчок по любой и есть удаление. Кнопки
   пониже обычных, потому что их три в ряд, но цель касания пальцем полная. */
.uw-inline-reasons {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
}

.uw-inline-reasons .secondary {
  min-height: 36px;
  padding: 6px 12px;
  font-size: var(--text-small);
}

@media (pointer: coarse) {
  .uw-inline-reasons .secondary {
    min-height: var(--tap);
  }
}

.uw-inline-own {
  grid-template-columns: minmax(160px, 1fr) auto;
  align-items: end;
}

.uw-inline-acts {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  align-items: stretch;
  gap: 10px;
  width: max-content;
  max-width: 100%;
}

/* Кнопки внутри строки-формы — по содержимому и того же размера, что у
   остальных форм окна (правило `.uw-form .primary` выше по файлу их не
   достаёт: форма стоит в списке, а не в теле действия). */
.uw-inline .primary,
.uw-inline .secondary,
.uw-inline-own .secondary {
  min-height: 36px;
  padding: 7px 14px;
  font-size: var(--text-small);
  width: auto;
}

/* Сохранение и отмена — равная пара на любой ширине. Растяжение ячеек
   перекрывает align-self: end главной кнопки из .detail-form; заливка и
   насыщенность по-прежнему различают основное и вторичное действие. */
.uw-inline-acts > .primary,
.uw-inline-acts > .secondary,
.uw-inline-acts > .subtle-btn {
  align-self: stretch;
  min-height: 38px;
  padding: 7px 14px;
  font-size: var(--text-small);
  width: auto;
  text-align: center;
}

@media (pointer: coarse) {
  .uw-inline .primary,
  .uw-inline .secondary,
  .uw-inline-own .secondary {
    min-height: var(--tap);
  }
}

/* MET-2: «Изменить» и «Удалить» у показания, уже внесённого за месяц. Стоят
   своей строкой под всей парой «подпись — поле»: `.uw-meter` — сетка в две
   колонки, и в левой (вместе с «Было 5200 кВт·ч…») кнопки ужимались до двух
   слов в столбик. Подтверждение `confirmTwice` кладёт свою приписку сразу за
   кнопкой, поэтому она получает всю строку. */
.uw-meter-acts {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 4px 14px;
  margin-top: 4px;
}

.uw-meter-acts .confirm-note {
  flex: 1 1 100%;
  margin: 0;
  line-height: 1.4;
}

.uw-meter-acts .subtle-btn {
  min-height: 30px;
  padding: 2px 0;
  font-size: var(--text-small);
}

.uw-meter-acts .cell-note {
  margin: 0;
}

@media (pointer: coarse) {
  .uw-meter-acts .subtle-btn {
    min-height: var(--tap);
  }
}

/* «Получено ещё / Возвращена часть жильцу» — тот же переключатель, что
   «Аренда / Счётчики» у оплаты: вопрос и два ответа в одну строку, без рамки. */
.uw-deposit-kind {
  flex-direction: row;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 12px;
  padding: 0;
  border: 0;
  margin-bottom: 10px;
}

/* Предупреждение «больше остатка»: это не ошибка — запись пройдёт, — поэтому
   амбра «внимание», а не тлеющий «беда». Галочка стоит под текстом. */
.uw-deposit-warn {
  grid-column: 1/-1;
  margin-top: 4px;
  padding: 10px 12px;
  border: 1px solid var(--window-edge);
  border-radius: var(--radius-md);
  background: var(--sunken);
  font-size: var(--text-small);
  color: var(--soft);
}

.uw-deposit-warn p {
  margin: 0 0 8px;
  line-height: 1.4;
}

/* История расходов за весь период (EXP-HIST-1, REQUIREMENTS.md п. 125) —
   раскрытие оформлено как `.uw-notes-history` (селектор общий, см. выше);
   здесь только то, чего у заметок не было: панель периода и разбивка по
   статьям. Сами группы месяцев и строки — `.uw-notes-group`/
   `.uw-notes-group-title` и `.uw-money-list`/`.uw-money-row` без изменений,
   тот же вид, что у истории заметок и у списка месяца, второй раз не заводим.

   На мониторе поля «С»/«По» и три чипа — в одну строку (владелец, ТЗ): гибкая
   строка, а не сетка формы на всю ширину панели, иначе два узких месяца
   растягивались бы на половину окна каждый (базовое `.detail-form` даёт
   `1fr 1fr`).

   Диалог квартиры не растёт за `min(790px, 100vw − 32px)` (06-dialogs.css) —
   на любом мониторе ≥822px, включая 1440×900, панели внутри раскрытия
   `<details>` (padding 15px) достаётся ровно 661px, не больше, сколько бы ни
   было места у самого окна браузера. Приёмка QA (EXP-HIST-1, повторно) на
   1440×900 замерила через `getBoundingClientRect()`: поля 354px + чипы 362px
   + зазор 20px = 736px — на 75px шире 661px, чипы переносились второй
   строкой.

   Первая правка сузила поля до 140px по колонке — этого хватает для пустого
   `----.--`, но не для настоящего значения: `<input type="month">` рисует
   локализованное «Сентябрь 2026» самим браузером (теневой контрол, не наш
   текст), и при 140px браузер обрезает «2026» под значком календаря —
   проверено вручную вводом значения на стенде. 130px снизу — тот же минимум,
   что держит «2026» на телефоне (см. `@media (max-width: 780px)` ниже);
   верхний край поднят ровно настолько, насколько самое длинное русское имя
   месяца («Сентябрь 2026») помещается без наложения на значок — 165px,
   проверено тем же способом (160px ещё обрезает последнюю цифру года).

   Оставшееся место отдано чипам: зазор между полями и внутри пары полей
   10px (было 14/20 — чипам эти 10px были нужнее, чем полям лишний воздух),
   горизонтальный отступ кнопки чипа 16px→5px — только на мониторе, через
   `min-width: 781px` ниже, чтобы не задеть уже подобранный мобильный отступ
   `.sc-range button` (10px 6px, @media max-width:780px, 11-showcase.css) —
   тот же селектор с той же специфичностью иначе перебил бы его и на
   телефоне тоже. Высота цели касания не трогалась — `min-height:
   var(--tap)` у `.sc-range button` (04/11), не отсюда.

   Итог на 1440×900 (тот же способ: `getBoundingClientRect()`, поля с
   настоящими значениями «Январь 2025»/«Сентябрь 2026», не с пустым
   плейсхолдером — на нём тесная колонка чуть шире): поля 344px + чипы 296px
   + зазор 10px = 650px — укладывается в 661px с запасом ~11px, не впритык.
   */
.uw-expense-history-panel {
  display: flex;
  flex-wrap: wrap;
  align-items: end;
  gap: 10px;
  margin: 4px 0 14px;
}

.uw-expense-history-fields {
  grid-template-columns: minmax(130px, 165px) minmax(130px, 165px);
  gap: 10px;
  flex: 0 0 auto;
}

.uw-expense-history-chips {
  flex: 0 0 auto;
}

@media (min-width: 781px) {
  .uw-expense-history-chips button {
    padding: 8px 5px;
  }
}

/* Разбивка по статьям — тихая строка сразу под итогом периода, тем же
   кеглем и цветом, что у заголовка «За период: …» (`.uw-list-title`), но без
   готового класса: здесь несколько сумм в одной строке через «·», а не
   заголовок с одной суммой жирным. */
.uw-expense-history-categories {
  margin: 0 0 14px;
  font-size: var(--text-small);
  color: var(--soft);
}

/* Тихая строка внизу истории — «Править и удалять…». Не `.cell-note`: тот
   класс на ≤780px обрезает текст до одной строки с многоточием (правило для
   примечания под строкой таблицы витрины, §7.8 выше) — здесь целое
   предложение, прятать часть которого нельзя (владелец: экран не должен
   скрывать то, что на нём написано). Свой класс несёт то же самое, чем
   отличается `.cell-note`, без чужого правила усечения. */
.uw-expense-history-note {
  margin-top: 12px;
  font-size: var(--text-small);
  color: var(--mist);
  line-height: 1.4;
}

@media (max-width: 780px) {
  /* 390×844 (ТЗ): поля периода столбиком — на ширине телефона два `minmax`
     из правила выше делят панель пополам и превращают «2026» в «20…26».
     Чипы переносятся сами: `.sc-range` уже во всю ширину на этом переломе
     (11-showcase.css) — второе правило здесь не нужно. */
  .uw-expense-history-panel {
    flex-direction: column;
    align-items: stretch;
  }
  .uw-expense-history-fields {
    grid-template-columns: minmax(0, 1fr);
  }
  /* DEP-FIX-1 (REQUIREMENTS.md п. 134): третья кнопка «Исправить сумму» в
     том же кольце «Получено ещё / Возвращена часть жильцу» — на 390 три
     подписи в одну строку не умещаются без переноса самого текста (проверено:
     «Возвращена часть жильцу» сжималась на три строки). Переносим ряд на
     две строки (2 + 1), а не подписи внутри кнопок: так самая длинная
     подпись остаётся на двух строках — тех же, что были у неё при двух
     кнопках. */
  .uw-deposit-kind .sc-range {
    flex-wrap: wrap;
  }
  .uw-deposit-kind .sc-range button {
    flex: 1 1 calc(50% - 4px);
  }
}

/* История депозита — свёрнутая по умолчанию строка под фактами жильца. Тот же
   вид, что у «Показать историю и настройки» внизу окна. */
/* Тихая строка, а не карточка: общий вид `<details>` в диалоге (06-dialogs.css)
   даёт рамку по периметру и подложку, из-за которых история выглядела вторым
   блоком внутри блока «Жилец». Здесь остаётся только черта сверху. */
/* Два класса в селекторе — ради специфичности: общий вид `<details>` в диалоге
   задан как `.detail-body details` (06-dialogs.css), и одного класса ему не
   перебить. Без этого история выглядела вторым блоком внутри блока «Жилец» —
   с рамкой по периметру и своей подложкой. */
.uw-tenant .uw-deposit-history {
  margin-top: 10px;
  padding: 8px 0 0;
  background: none;
  border: 0;
  border-top: 1px solid var(--border-subtle);
  border-radius: 0;
}

.uw-tenant .uw-deposit-history > summary {
  min-height: 36px;
  display: flex;
  align-items: center;
  font-size: var(--text-small);
  color: var(--lavender);
  cursor: pointer;
}

@media (hover: hover) and (pointer: fine) {
  .uw-tenant .uw-deposit-history > summary:hover {
    color: var(--pearl);
  }
}

@media (pointer: coarse) {
  .uw-tenant .uw-deposit-history > summary {
    min-height: var(--tap);
  }
}

@media (max-width: 780px) {
  /* Формы в одну строку на телефоне становятся столбиком: 390px на четыре
     поля не делится (это общее правило форм окна ниже по файлу — здесь только
     новые сетки). */
  .uw-expense-row,
  .uw-withhold-row,
  .uw-payment-row,
  .uw-inline-own {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Строка списка: текст, под ним сумма и кнопки в один ряд. */
  .uw-money-row {
    grid-template-columns: minmax(0, 1fr) auto;
    font-size: var(--text-body);
  }

  .uw-money-text {
    grid-column: 1/-1;
  }

  .uw-row-acts {
    justify-content: flex-start;
    gap: 18px;
  }

  /* На экране телефона цель касания 44px обязательна независимо от того,
     чем по нему тычут (`CONVENTIONS.md` §8): правило `pointer: coarse` выше
     не срабатывает, когда телефонную ширину смотрят мышью. */
  .uw-row-acts .subtle-btn,
  .uw-meter-acts .subtle-btn {
    min-height: var(--tap);
    font-size: var(--text-body);
  }

  .uw-inline .primary,
  .uw-inline .secondary,
  .uw-inline-own .secondary,
  .uw-inline-reasons .secondary {
    min-height: var(--tap);
  }

  /* Пара действий остаётся в одном ряду и не растягивается на всю форму. */
  .uw-inline-acts {
    gap: 10px 14px;
  }
}

/* ============================================================
   3. Заметки по жильцу (UNI-3, REQUIREMENTS.md п. 64)
   ============================================================ */

/* Заметки видны без раскрытия. Спокойная рамка и вторичная кнопка оставляют
   главный акцент у формы текущего действия, не скрывая записи или ввод. */
.uw-notes {
  padding: 12px 14px;
  margin-bottom: 12px;
  background: var(--surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
}

.uw-notes-title {
  font-size: var(--text-h3);
  color: var(--pearl);
  margin: 0 0 10px;
}

.uw-notes .detail-form {
  margin-bottom: 12px;
}

.uw-notes .detail-form > .primary {
  background: var(--raised);
  border-color: var(--border-field);
  color: var(--pearl);
}

.uw-notes .detail-form > .primary:hover {
  background: var(--state-active);
  border-color: var(--violet-edge);
}

.uw-note-list {
  display: grid;
  gap: 10px;
}

.uw-note {
  padding: 10px 12px;
  background: var(--raised);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}

.uw-note-meta {
  margin: 0 0 4px;
  font-size: var(--text-small);
  color: var(--mist);
}

.uw-note-text {
  margin: 0;
  font-size: var(--text-body);
  color: var(--pearl);
  line-height: 1.45;
  /* Длинная заметка переносится по словам, не по буквам — телефон 320-390 px
     не режет русские слова пополам (владелец, п. 54). */
  overflow-wrap: break-word;
}

.uw-note-void {
  margin: 6px 0 0;
  font-size: var(--text-small);
  color: var(--ember);
}

.uw-note .subtle-btn {
  margin-top: 4px;
  padding: 4px 0;
  min-height: 32px;
  font-size: var(--text-small);
}

/* «Показать все» — тот же приём, что «Показать историю и настройки»
   (`.uw-more`): свёрнуто, заголовок читается ссылкой.

   UNI-7: общее правило `.detail-body details` (06-dialogs.css) давало этой
   строке фон, рамку и 15px полей — внизу окна получалась пустая панель в 90px
   с одними словами «Показать все». Сбрасываем то же самое, что уже сброшено у
   `.uw-status .rent-notice`: это строка-раскрытие, а не панель.

   EXP-HIST-1: «Показать за всё время» у истории расходов — тот же вид, тем
   же селектором на второй класс, второе правило не заводим. */
details.uw-notes-history,
details.uw-expense-history {
  margin-top: 12px;
  padding: 10px 0 0;
  background: none;
  border: 0;
  border-top: 1px solid var(--border-subtle);
  border-radius: 0;
}

/* POL-6 21.11 (units-19): `min-height: 0` гасит и общее
   `.detail-body summary { min-height: var(--tap) }` (06-dialogs.css:135), и
   собственное правило `@media (pointer: coarse)` из §2 этого файла — цель
   «Показать все» была 294×21, единственная меньше 44px во всём продукте.
   На мониторе строка остаётся низкой (владелец п. 94: окно не должно расти),
   а цель касания возвращает повтор правила в самом конце файла — тот же
   приём и по той же причине, что описан там для `.uw-meter input`. */
.uw-notes-history > summary,
.uw-expense-history > summary {
  min-height: 0;
  display: flex;
  align-items: center;
  cursor: pointer;
  color: var(--lavender);
  font-size: var(--text-small);
  font-weight: 700;
}

.uw-notes-history[open] > summary,
.uw-expense-history[open] > summary {
  margin-bottom: 8px;
}

.uw-notes-group {
  margin-top: 14px;
}

.uw-notes-group:first-of-type {
  margin-top: 12px;
}

.uw-notes-group-title {
  margin: 0 0 8px;
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--soft);
}

/* Записи группы идут без обёртки `.uw-note-list` (одна карточка за другой),
   поэтому отступ между ними — через соседей, а не через `gap` сетки. */
.uw-notes-group .uw-note + .uw-note {
  margin-top: 10px;
}

/* ============================================================
   4. Счётчики: прошлая цифра, поле, живой расчёт
   ============================================================ */

/* UNI-7 (решение владельца п. 94): шесть счётчиков — в две колонки, а не
   шестью карточками в столбик. Прежде форма «Счётчики» занимала два экрана
   прокрутки только на поля: каждая карточка держала 14px полей и три
   отдельные строки (подпись, «было», живой расчёт), а под ней стояло ещё
   два-три предложения объяснения. Объяснения ушли в подсказки (`uwMeterWas`),
   карточка стала плоской, и весь обход квартиры виден целиком.
   Ниже 780px раскладка возвращается в один столбец (§8). */
.uw-meters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 8px;
  margin-bottom: 12px;
}

.uw-meter {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 118px);
  gap: 3px 10px;
  align-items: start;
  padding: 8px 10px;
  background: var(--raised);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}

.uw-meter .field-label {
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--pearl);
}

.uw-meter input {
  grid-column: 2;
  grid-row: 1 / span 2;
  align-self: start;
  min-width: 0;
  min-height: 38px;
  border: 1px solid var(--border-field);
  background: var(--sunken);
  border-radius: var(--radius-md);
  padding: 8px 10px;
  color: var(--pearl);
  font-size: var(--text-body);
  font-variant-numeric: tabular-nums;
}

.uw-meter input:focus {
  border-color: var(--violet);
}

/* «было 6300 кВт·ч · 31 авг. 2026» — во всю ширину карточки: в колонке под
   подписью строка ломалась бы пополам (UNI-7, «меньше переносов»). */
.uw-meter-was {
  grid-column: 1 / -1;
  grid-row: 3;
  font-size: var(--text-small);
  color: var(--mist);
  line-height: 1.4;
}

/* Живой расчёт под полем: «+20 кВт·ч → 320,02 ₽». Считается на клиенте,
   без обращения к серверу: задержка ввода управляющему недопустима. */
.uw-live {
  grid-column: 1 / -1;
  grid-row: 4;
  min-height: 1.4em;
  font-size: var(--text-small);
  color: var(--window);
  font-variant-numeric: tabular-nums;
  line-height: 1.4;
}

.uw-live.is-warn {
  color: var(--ember);
}

.uw-live.is-saved {
  color: var(--soft);
}

.uw-meter.is-error {
  border-color: var(--ember);
}

.uw-meter-note {
  grid-column: 1 / -1;
  font-size: var(--text-small);
  color: var(--ember);
  line-height: 1.4;
}

.uw-meter-note:empty {
  display: none;
}

/* Итог начисления под счётчиками — факт и, отдельной строкой, что станет
   после сохранения. Две строки, а не одна: сумму, которой ещё нет в учёте,
   нельзя называть начисленной. */
.uw-total {
  padding: 14px;
  background: var(--sunken);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  margin-bottom: 16px;
}

.uw-total strong {
  display: block;
  font-size: var(--text-h3);
  color: var(--window);
  font-variant-numeric: tabular-nums;
}

.uw-total span {
  display: block;
  font-size: var(--text-small);
  color: var(--soft);
  margin-bottom: 6px;
}

.uw-total-next {
  margin-top: 8px;
  font-size: var(--text-small);
  color: var(--lavender);
  font-variant-numeric: tabular-nums;
}

.uw-total-next:empty {
  display: none;
}

/* ============================================================
   5. Оплаты месяца (UTIL-1A, REQUIREMENTS.md п. 97, 99)
   ============================================================ */

/* Список «Уже записано за этот месяц» (старые `.uw-payments`/`.record`)
   переехал из формы «Оплата» сюда: отдельным блоком под ней, теперь с
   «Изменить»/«Удалить» у каждой строки, — управляющая читала и правила его,
   а форма выше стала короче. Тот же вес, что у формы действия
   (padding 12/14, `--surface`, `--border-strong` — см. `.uw-form`
   выше по файлу): блок виден сразу, без раскрытия формы, и не читается
   вторичным довеском. */
.uw-payments-block {
  padding: 12px 14px;
  margin-bottom: 12px;
  background: var(--surface);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-lg);
}

/* Итог по видам под списком — тем же тихим видом, что заголовок списка
   расходов («Расходы за сентябрь: 5 000 ₽»), только снизу, а не сверху. */
.uw-payments-block .uw-list-title {
  margin: 10px 0 0;
}

/* Оплата прежнего жильца — тише обычной строки (ТЗ §2): деньги месяца не
   изменились, но жилец в шапке окна уже другой, и строка не должна спорить
   вниманием со строками текущего. Не путать с `.is-void` выше — там сумма
   зачёркнута, здесь нет: оплата действующая, просто чужая по жильцу. */
.uw-money-row.is-former {
  color: var(--mist);
}

.uw-money-row.is-former .money {
  color: var(--mist);
}

/* Вся дата вместе с календарём должна читаться: 130px обрезали год.
   Запас для неё берём у заметки, сохраняя кегль и четыре дорожки на мониторе;
   ниже 780px действует общая одноколоночная .uw-row-form. */
.uw-payment-row {
  grid-template-columns: minmax(100px, 120px) minmax(160px, 170px) minmax(80px, 1fr) auto;
}

/* Сводка месяца и депозит — одной строкой внизу окна. */
/* Сводка внизу окна отделена от блока «Показать историю и настройки» тем же
   шагом, каким отделён он сам, — иначе две одинаковые на вид полосы стояли
   на разном расстоянии друг от друга (VIS-1). */
.uw-summary {
  margin-top: 18px;
  padding: 14px;
  background: var(--sunken);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  font-size: var(--text-body);
  color: var(--soft);
  line-height: 1.5;
}

.uw-summary strong {
  color: var(--pearl);
  font-variant-numeric: tabular-nums;
}

.uw-deposit {
  display: block;
  margin-top: 8px;
  font-size: var(--text-small);
  color: var(--mist);
}

/* Когда депозита нет, в сводке остаётся одна строка-подсказка — и её отступ
   сверху делал рамку несимметричной: 22px над текстом против 14px под ним
   (VIS-1). */
.uw-deposit:first-child {
  margin-top: 0;
}

/* Условия квартиры — «Цена аренды» и «День оплаты» одной сеткой (UNI-7b,
   решения владельца п. 93 и 94). Прежде это были две панели `.hub-row`, в
   каждой заголовок, абзац и сноска: шесть строк текста ради двух чисел.
   Теперь подпись и значение стоят парой, подписи выровнены по одной левой
   границе, значения — по другой, и обе строки читаются сверху вниз одним
   движением глаза. Ниже 560 px пара складывается в две строки: колонка
   подписи съедала бы половину ширины телефона.

   Кегль — 14 px у подписи и 16 px у значения (`--text-small` сведён к 14 по
   решению владельца п. 57: мельче 14 на экране нет ничего).

   Плитка «Платит за месяц» (`.unit-fact--action`, `.unit-fact-act`) убрана
   отсюда вместе со всем блоком `unitSummary()`: цена стоит в шапке окна, и
   правится она формой «Изменить цену» полосы действий. Остатки `.unit-hub`,
   `.unit-who`, `.unit-facts` и `.unit-fact` лежат в 08-screens.css — файл
   чужой задачи, их уборка отдельной строкой на доске. */
.unit-terms {
  display: grid;
  gap: 8px;
  margin: 0;
}

.unit-terms > div {
  display: grid;
  grid-template-columns: 160px 1fr;
  align-items: baseline;
  gap: 4px 12px;
}

.unit-terms dt {
  font-size: var(--text-small);
  color: var(--mist);
}

.unit-terms dd {
  margin: 0;
  font-size: var(--text-body);
  color: var(--pearl);
}

/* Заголовок блока и «Изменить цену» — одна строка на мониторе и две на
   телефоне: `flex-wrap` роняет кнопку под заголовок целиком, вместо того
   чтобы ломать её надпись пополам (п. 94: переносов в кнопках не больше
   одного). Правило стоит после `.panel-head` в каскаде — та же одна метка
   класса, но файл читается позже. */
.unit-terms-head {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
}

.unit-terms-head > button {
  white-space: nowrap;
}

/* Счёт жильцу и переход в его карточку — одна строка, кнопки одной высоты и
   без переносов (п. 94). На телефоне строка складывается: кнопки встают одна
   под другой целыми надписями. */
.unit-more-acts {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 12px 0 16px;
}

.unit-more-acts > button {
  white-space: nowrap;
}

@media (max-width: 560px) {
  .unit-terms > div {
    grid-template-columns: 1fr;
  }
}

/* ============================================================
   6. Тарифы отдельной страницей
   ============================================================ */

.tariff-house {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: 12px;
  margin-bottom: 16px;
}

.tariff-house > div {
  padding: 12px 14px;
  background: var(--raised);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
}

.tariff-house span {
  display: block;
  font-size: var(--text-small);
  color: var(--soft);
  margin-bottom: 6px;
}

.tariff-house strong {
  display: block;
  font-size: var(--text-h3);
  color: var(--pearl);
  font-variant-numeric: tabular-nums;
}

.tariff-house strong.is-mixed {
  font-size: var(--text-body);
  color: var(--mist);
  font-weight: 400;
}

/* Плитка цены дома — кнопка (аудит А.7: человек ткнул в «16 ₽» и ничего не
   произошло). Внешне та же плитка, что и надпись рядом: разница в рамке
   поля и в отклике на наведение.
   POL-3: строка «Изменить для дома» под ценой убрана — она стояла шесть раз
   подряд. Полная фраза осталась в `title` и `aria-label` самой плитки, а
   действие целиком — на кнопке «Изменить тариф» под сеткой. */
.tariff-house-tile {
  display: block;
  width: 100%;
  min-height: var(--tap);
  padding: 10px 14px;
  text-align: left;
  background: var(--raised);
  border: 1px solid var(--border-field);
  border-radius: var(--radius-md);
  color: var(--pearl);
  transition:
    border-color 140ms ease,
    background 140ms ease;
}

.tariff-house-tile > span {
  display: block;
  font-size: var(--text-small);
  color: var(--soft);
  margin-bottom: 6px;
}

.tariff-house-tile > strong {
  display: block;
  font-size: var(--text-h3);
  color: var(--pearl);
  font-variant-numeric: tabular-nums;
}

.tariff-house-tile > strong.is-mixed {
  font-size: var(--text-body);
  color: var(--mist);
  font-weight: 400;
}

@media (hover: hover) and (pointer: fine) {
  .tariff-house-tile:hover {
    border-color: var(--violet-edge);
    background: var(--state-hover);
  }
  .tariff-house-tile:hover > span {
    color: var(--pearl);
  }
}

.tariff-house-actions {
  align-items: center;
  margin-bottom: 16px;
}

/* Строка аренды — одно предложение, а не подпись поля: носитель подсказки
   (`.field-label`, 04-components.css) по умолчанию `display: flex` и уводил
   величину на свою строку, оставляя тире в начале второй (POL-3). */
.tariff-house-plain .field-label {
  display: inline-flex;
  vertical-align: baseline;
}

.tariff-units-toggle > summary {
  min-height: var(--tap);
  display: flex;
  align-items: center;
  cursor: pointer;
  color: var(--lavender);
  font-size: var(--text-body);
  margin-bottom: 8px;
}

/* Настройки дома под ценами (TAR-3, решение владельца п. 93): «Управляющий» и
   «Инвесторы и доли» теми же строками `.hub-row`, какими они стояли в окне
   квартиры, — вид знакомый, изменилось только место. Отбиты от таблицы цен
   линией: это другой разговор о том же доме. */
.tariff-house-settings {
  margin-top: 16px;
  padding-top: 12px;
  border-top: 1px solid var(--border-subtle);
}

.tariff-house-settings h3 {
  margin: 0 0 4px;
}

.tariff-house-settings p {
  margin: 0 0 2px;
  color: var(--soft);
}

/* «Назначена 1 из 13 квартир» — оговорка под ценой дома, не второй заголовок. */
.tariff-house-part {
  display: block;
  margin-top: 4px;
  font-size: var(--text-small);
  font-style: normal;
  color: var(--soft);
}

/* ============================================================
   7. Таблица тарифов по квартирам — уложить в панель на 1440 (FIX-15)
   ============================================================ */

/* Цифры не пляшут при обновлении и совпадают по ширине символа с символом. */
.tariff-unit-table .data-table td.money,
.tariff-unit-table .data-table th.money {
  font-variant-numeric: tabular-nums;
}

/* TAR-2 (REQUIREMENTS.md п. 91): таблица сократилась до двух колонок —
   «Квартира» и «Аренда». Прежний `table-layout: fixed` в процентах решал
   тесноту восьми колонок на 1440 (FIX-15); с двумя колонками обычная
   раскладка `.data-table` (04-components.css) и так укладывается в панель на
   любой ширине, специальных правил здесь больше не нужно. */

/* Верх значения совпадает с верхом номера квартиры — то же правило, по
   которому выровнен лист месяца (XLS-1c): ячейка с номером, датой и кнопкой
   высокая, и при выравнивании по центру «20 000 ₽» уезжало на середину
   строки, в пустоту между двумя строками соседней колонки (VIS-1). */
.tariff-unit-table .data-table td {
  vertical-align: top;
}

.tariff-unit-table .data-table th {
  vertical-align: bottom;
}

/* ============================================================
   7б. Хаб «Настройки дома» (HOUSE-SETTINGS-1, REQUIREMENTS.md п. 135)
   ============================================================ */

/* Чипы-якоря наверху хаба: обычные ссылки на разделы этого же экрана
   (`#tariff-hub-*`), переход — мгновенный переход браузера, без прокрутки
   `scroll-behavior: smooth` — на рабочих экранах управляющего анимация не
   должна задерживать ввод (REQUIREMENTS.md, «Графика и анимация»), а на
   витрину инвестора этот хаб не попадает вовсе. Цели касания — `--tap`
   (44px), как просило задание. */
.tariff-hub-nav {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 16px;
}

.tariff-hub-chip {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap);
  padding: 0 16px;
  background: var(--raised);
  border: 1px solid var(--border-field);
  border-radius: var(--radius-pill);
  color: var(--lavender);
  font-size: var(--text-small);
  font-weight: 600;
  text-decoration: none;
  transition:
    border-color 140ms ease,
    background 140ms ease;
}

@media (hover: hover) and (pointer: fine) {
  .tariff-hub-chip:hover {
    border-color: var(--violet-edge);
    background: var(--state-hover);
  }
}

@media (prefers-reduced-motion: reduce) {
  .tariff-hub-chip {
    transition: none;
  }
}

/* «Инвесторы и доли»: раздел хаба, а не отдельная `.panel` (чтобы не вложить
   рамку в рамку — внутри уже стоит своя `.panel` из `allocationPanel()`,
   13-investors.js). Тот же заголовок-строка, что и у панелей с кнопкой
   действия рядом (`accessPage()`, 15-access.js) — переиспользует `.panel-head`
   без переключателя `.panel-toggle`. */
.tariff-hub-section {
  margin-bottom: 22px;
}

.tariff-hub-section-head {
  margin-bottom: 12px;
}

/* Страница для жильцов: тексты вверху и внизу, «Сохранено: …» под формой. */
.tariff-public-updated {
  grid-column: 1/-1;
  margin: 0;
  color: var(--soft);
  font-size: var(--text-small);
}

#tariff-hub-public h3 {
  margin: 18px 0 8px;
}

/* Секретарь в Telegram (TG-SECRETARY-1): заголовок «Кто получает сводку» — тот же
   отступ, что у заголовков «Страница для жильцов» выше. Строка подключённого бота —
   абзацы с обычным зазором между собой, без своей рамки: она уже внутри `.panel`. */
#tariff-hub-telegram h3 {
  margin: 18px 0 8px;
}

.tariff-telegram-status p {
  margin: 0 0 10px;
}

/* «Открыть в Telegram» — ссылка, оформленная как кнопка (`.primary`, 04-components.css
   красит только цвет и фон, `display` у ссылки по умолчанию строчный): без этого
   правила подложка обрезалась бы по высоте строки текста, а не по всей кнопке. */
.tariff-telegram-open {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  margin-bottom: 10px;
  text-decoration: none;
}

/* ============================================================
   8. Телефон: полоса действий в один столбец, цели касания 48px
   ============================================================ */

@media (max-width: 780px) {
  .house-tools {
    grid-template-columns: minmax(0, 1fr);
    align-items: stretch;
  }
  .house-search {
    max-width: none;
  }
  .house-actions button {
    flex: 1 1 160px;
    /* Телефон: цель касания, но не 48px — строка панели управления не должна
       занимать экран больше сетки квартир (POL-3). */
    min-height: var(--tap);
    font-size: var(--text-small);
  }
  /* Единственная кнопка панели «Тарифы» шириной во весь экран выглядела бы
     полосой: растягиваются только кнопки панели управления «Квартир», где их
     три в ряд (POL-3, «ширина по содержимому»). Правило стоит после общего —
     вес селекторов одинаковый, решает порядок. */
  .tariff-house-actions button {
    flex: 0 0 auto;
  }
  /* POL-6 21.4 + критерий 9 (units-5, units-23): поперечный зазор был 6px —
     две соседние цели касания ближе минимальных 8px. Лестница отступов
     раздела 1 ТЗ знает только 4/8/12/16. */
  .house-filters {
    gap: 8px;
  }
  /* Шапка месяца в столбик: месяц уходит под заголовок, а не жмётся справа. */
  .uw-head-top {
    align-items: stretch;
    flex-direction: column;
  }
  .uw-month select {
    max-width: none;
    width: 100%;
  }
  /* Деньги месяца: название остаётся в строке с первой величиной, остальные
     переносятся сами. Две строки вместо четырёх — ровно та высота, которую
     полоса действий забирает себе, чтобы остаться на первом экране. */
  .uw-line {
    gap: 2px 10px;
    line-height: 1.35;
  }
  .uw-line-name {
    min-width: 0;
  }
  /* POL-6 21.8 (units-13): одно значение внутреннего поля на все блоки окна
     вместо шести разных (12/16, 12/13, 12, 8/10, 14, 12/14). */
  .uw-head {
    padding: 12px;
  }
  /* Подпись «За какой месяц» в 390 px переносится на две строки и сжимает
     список так, что название месяца обрезается. Поэтому здесь подпись стоит
     над списком, а список занимает всю ширину: месяц в нём читается целиком. */
  .uw-month {
    flex-direction: column;
    align-items: stretch;
    gap: 4px;
  }
  .uw-month .field-label {
    justify-content: flex-start;
  }
  .uw-month select {
    max-width: none;
    width: 100%;
  }
  /* Пять действий в два ряда 3 + 2 (UNI-7, решение владельца п. 94): в два
     столбца они занимали три ряда и отжимали форму за первый экран телефона.
     Кегль — 14px (нижний предел шкалы, CONVENTIONS §8): при 16px «Пересчёт»
     не помещался в дорожку 106px и переносился. */
  /* POL-6 21.7 + критерий 9 (units-10, units-23): при трёх дорожках пять
     действий вставали 3 + 2, третья ячейка второго ряда оставалась пустой —
     полоса читалась оборванной, а зазор 6px был ближе минимальных 8px между
     целями касания. Шесть дорожек и `span` по две дают тот же первый ряд из
     трёх, а второй ряд делится поровну на всю ширину. Счётчик потомков —
     на случай, когда прав меньше и кнопок не пять: `:nth-last-child`
     отличает «пятая из пяти» от «пятая из шести». */
  .uw-bar {
    grid-template-columns: repeat(6, minmax(0, 1fr));
    gap: 8px;
  }
  .uw-bar > .uw-action {
    grid-column: span 2;
  }
  /* Ровно пять кнопок: четвёртая и пятая занимают второй ряд пополам. */
  .uw-bar > .uw-action:nth-child(4):nth-last-child(2),
  .uw-bar > .uw-action:nth-child(5):nth-last-child(1) {
    grid-column: span 3;
  }
  /* Ровно четыре действия: два равных ряда по две кнопки. Количество
     проверяем на родителе, чтобы не менять раскладку при других правах. */
  .uw-bar:has(> .uw-action:nth-child(4):last-child) > .uw-action {
    grid-column: span 3;
  }
  .uw-action {
    min-height: var(--tap);
    font-size: var(--text-small);
    padding: 8px 6px;
  }
  /* Имена счётчиков в шапке: на телефоне только состояние, перечень читается
     в форме «Счётчики», которую открывает эта же кнопка. NQA1-SRF-02 (ночной
     аудит NIGHT-QA-1, REQUIREMENTS.md п. 140): это верно, только пока кнопка
     рядом действительно есть (`.uw-kind-btn` — «не сняты» у роли с
     meters.write, пока не всё снято). Без неё — роль без meters.write
     (`uwMeterKindsLine`, 22-unit-window.js: «чип остаётся подписью без
     кнопки — нажимать всё равно было бы некуда»), или когда всё уже снято и
     самой кнопки нет вовсе — раскрыть перечень больше негде, и на телефоне
     он должен остаться виден, как на мониторе. */
  .uw-kinds:has(.uw-kind-btn) .uw-kind-names {
    display: none;
  }
  /* Шапка на телефоне идёт столбиком, и прижимать срок оплаты вправо не к
     чему: строка начинается там же, где все остальные. */
  .uw-due {
    margin-left: 0;
  }
  /* Блок «Жилец» на телефоне — столбиком: имя и контакты сверху, кнопки во всю
     ширину под ними. Кнопка в пол-экрана рядом с длинным именем ужималась бы
     до двух строк, а «Внести данные жильца» — главное действие этого блока. */
  /* Внутреннее поле — 12, как у всех блоков окна (POL-6 21.8). */
  .uw-tenant {
    padding: 12px;
  }
  .uw-tenant-row {
    flex-direction: column;
    align-items: stretch;
  }
  /* Главная ось стала вертикальной, и `flex-basis` из настольного правила
     превратился бы в высоту в 320px пустоты под именем. Здесь высота — по
     содержимому; то же самое у чипа состояния в шапке месяца. */
  .uw-tenant-main,
  .uw-status {
    flex: 0 0 auto;
  }
  /* Кнопки жильца на телефоне остаются в ряд и по содержимому (UNI-5):
     «Внести данные жильца» и «Выселить» вместе занимают меньше ширины
     экрана, а во всю ширину каждая забирала бы две строки первого экрана. */
  .uw-tenant-btn {
    min-height: var(--tap);
    padding: 0 12px;
  }
  .uw-tenant-name {
    font-size: var(--text-h2);
  }
  /* Кнопки форм на телефоне — по содержимому, как на мониторе (UNI-5,
     владелец п. 72: «не делай большие кнопки там, где это не нужно»):
     прежнее `width: 100%` растягивало «Записать» во весь экран. Высота —
     44px, целью касания она остаётся. */
  .uw-tenant-form .detail-form .primary,
  .as-sheet .uw-form .primary,
  /* DEP-4: «Сохранить дату выезда» в «Он только предупредил» — единственная
     второстепенная кнопка формы окна, и на телефоне она оставалась 39px,
     ниже цели касания. Тот же размер, что у главной кнопки рядом. */
  .uw-tenant-form .uw-rare .secondary,
  .uw-notes .detail-form .primary {
    width: auto;
    min-height: var(--tap);
    justify-self: start;
  }
  /* Строчные формы (оплата, счётчики, заметка) на телефоне становятся
     столбиком — `.detail-form` здесь уже в одну дорожку (09-responsive.css),
     достаточно снять свои настольные дорожки. */
  .uw-row-form,
  .uw-meters-foot,
  .uw-note-row,
  .uw-floor-row,
  .uw-price-row {
    grid-template-columns: minmax(0, 1fr);
  }
  /* Цель касания у кнопки этажа — как у остальных кнопок окна на телефоне. */
  .uw-floor-row > button {
    min-height: var(--tap);
  }
  .uw-form {
    padding: 12px;
  }
  .uw-meters,
  .uw-meter {
    grid-template-columns: minmax(0, 1fr);
  }
  .uw-meter input,
  .uw-live,
  .uw-meter-was {
    grid-column: 1;
  }
  /* На телефоне карточка снова одностолбцовая, и жёсткие номера строк из
     настольного правила (подпись → поле → «было» → расчёт) мешали бы порядку
     разметки: пусть строки встают сами. */
  .uw-meter input,
  .uw-live,
  .uw-meter-was {
    grid-row: auto;
  }
  .uw-meter input {
    /* 16px, а не токен: на меньшем кегле iOS увеличивает страницу при фокусе */
    font-size: 16px;
  }
  /* Заметки — карточки столбиком. */
  .uw-notes {
    padding: 12px;
  }
  .uw-kinds {
    gap: 8px;
  }
  /* На телефоне чип-кнопка «не внесено» и строка-раскрытие «Сумма изменена
     управляющим» остаются целями касания в 44px: низкими они сделаны только
     для мыши (CONVENTIONS §8). */
  .uw-kinds button.chip,
  .uw-status .rent-notice > summary {
    min-height: var(--tap);
  }
}

/* Уменьшенное движение отдельным правилом здесь не нужно: 09-responsive.css
   гасит анимации и переходы во всей системе через `!important`, а каскад окон
   ведёт .sc-play, который 21-transitions.js ставит только при разрешённом
   движении. Поэтому конечное состояние каждого элемента этого файла —
   и есть состояние по умолчанию: без единой анимации экран виден целиком. */

/* ============================================================
   9. Компактные экраны волны POL-3 (REQUIREMENTS.md п. 78)
   ============================================================ */

/* Слова управляющего: «очень сложно разобраться в кнопках, слишком много
   текста, всё сливается». Кнопка на рабочем экране — 34px, а не 46–48:
   ширина по содержимому, высота в размер строки. Класс `page-compact`
   ставят только экраны этой волны («Выезды», «Напоминания», «Пользователи»,
   «Тарифы», «Инвесторы», «Вознаграждение», «Оплата аренды», «Счётчики»,
   «Журнал событий»). Рабочий стол (.page.desk), витрина инвестора
   (.page.showcase) и главная (.page.home-page) считают размеры сами и этот
   класс не получают — их размеры уже приняты владельцем.

   Диалоги живут вне .page, поэтому кнопки форм в окнах остаются полной
   высоты: там нажимают один раз и наверняка.

   Пальцем цель добирается правилом `pointer: coarse` ниже — CONVENTIONS §8
   про 44px касания не нарушено. */
.page-compact .primary,
.page-compact .secondary {
  min-height: 34px;
  padding: 5px 12px;
  font-size: var(--text-small);
}

.page-compact .subtle-btn {
  min-height: 30px;
}

/* Название квартиры в строке таблицы — ссылка, а не кнопка действия: полная
   цель касания растягивала каждую из тринадцати строк «Оплаты аренды». */
.page-compact .unit-link {
  min-height: 30px;
}

/* «Сохранить обход» — единственное завершающее действие экрана счётчиков, и
   оно стоит в прилипшей полосе внизу: 36px, а не 48 (#walk-save в
   17-mobile-input.css). Полоса тем самым перестаёт съедать строку списка. */
.page-compact #walk-save {
  min-height: 36px;
  padding: 5px 18px;
  font-size: var(--text-small);
}

/* Заголовок панели и её кнопка стоят в одной строке: когда кнопка стала
   ниже заголовка, её надо вернуть на общую базовую линию. */
.page-compact .panel-head > .primary,
.page-compact .panel-head > .secondary {
  align-self: center;
}

@media (pointer: coarse) {
  .page-compact .primary,
  .page-compact .secondary,
  .page-compact .subtle-btn,
  .page-compact .unit-link {
    min-height: var(--tap);
  }
  .page-compact #walk-save {
    min-height: var(--tap-lg);
  }
}

/* HOUSE-SETTINGS-2 (REQUIREMENTS.md п. 136 (4), ТЗ `TZ-R5-FOLLOWUPS.md` §D.3):
   qa нашла кнопки хаба «Настройки дома» («Скопировать», «Сохранить»,
   «Добавить», «Убрать» — .primary/.secondary/.subtle-btn правилами выше,
   34px) на ширине 390. Правило `pointer: coarse` над этим блоком уже поднимает
   их к цели касания, но только сенсорному экрану — на 390 нередко смотрят и
   мышью (удалённый рабочий стол, узкое окно), а CONVENTIONS §8 просит 44px как
   цель независимо от указателя. Тот же приём, что уже применён на телефонной
   ширине к кнопкам форм окна квартиры чуть выше по каскаду (`.uw-tenant-form
   .detail-form .primary` и соседи, `@media (max-width: 780px)` §8) — правило
   по ширине экрана, а не по типу указателя, и оно обязано стоять позже
   `.page-compact .primary/.secondary/.subtle-btn` выше (та же специфичность —
   без этого порядка её 34px выигрывали бы каскад и на телефонной ширине).
   Все разделы хаба (включая «Секретарь в Telegram», TG-SECRETARY-1) несут `id`,
   начинающийся с `tariff-hub-` — один селектор на всю панель, без перечисления
   имён. */
@media (max-width: 560px) {
  [id^='tariff-hub-'] .primary,
  [id^='tariff-hub-'] .secondary,
  [id^='tariff-hub-'] .subtle-btn {
    min-height: var(--tap);
  }
}

/* ============================================================
   5б. «За счётчики»: начислено по строкам (UTIL-1B, п. 92, 97)
   ============================================================ */

/* Блок стоит между формой действия и «Оплатами месяца» и весит меньше их:
   он ничего не спрашивает, он объясняет, из чего сложилась сумма месяца.
   Отсюда `--sunken` и тонкая рамка вместо поднятой поверхности `--surface`
   у блоков, в которых что-то делают (`.uw-form`, `.uw-payments-block`). */
.uw-util-block {
  padding: 12px 14px;
  margin-bottom: 12px;
  background: var(--sunken);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
}

.uw-util-block .uw-floor-title {
  margin-bottom: 6px;
}

/* Строка разбивки: имя слева, сумма справа, цифры всех строк на одной
   вертикали (`tabular-nums` плюс своя дорожка) — как в столбце учётной
   книги. Шаг 8 px, кегль 14 — по п. 94 и 104. */
.uw-util-line {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: 4px 12px;
  margin: 0;
  padding: 4px 0;
  font-size: var(--text-small);
  color: var(--soft);
  line-height: 1.4;
}

.uw-util-name {
  min-width: 0;
}

.uw-util-line .money {
  color: var(--pearl);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Итог — над чертой от строк разбивки, одной строкой из трёх частей и тихой
   ссылки «оплаты». На телефоне части переносятся столбиком сами: flex-wrap,
   а не фиксированная сетка. */
.uw-util-total {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 14px;
  margin: 6px 0 0;
  padding-top: 8px;
  border-top: 1px solid var(--border-subtle);
  font-size: var(--text-small);
  color: var(--soft);
  line-height: 1.5;
}

.uw-util-total b {
  color: var(--pearl);
  font-variant-numeric: tabular-nums;
}

.uw-util-left {
  color: var(--pearl);
}

/* «оплаты» — одно слово-ссылка вместо второго списка оплат: сам список стоит
   ниже своим блоком, и повторять его здесь значило бы поставить два
   одинаковых списка подряд (п. 94). */
.uw-util-link {
  min-height: 24px;
  padding: 0;
  font-size: var(--text-small);
}

@media (pointer: coarse) {
  .uw-util-link {
    min-height: var(--tap);
  }
}

/* Тихая строка прежнего жильца — и у счётчиков, и у аренды. Она НЕ добавка к
   месяцу, а разбивка того же числа, поэтому и весит меньше строки месяца:
   меньший кегль, вспомогательный цвет, никакой заливки. Тон предупреждения
   (амбра) — только когда за прежним остался долг: иначе это просто факт
   истории, а не повод звонить (DESIGN.md, «одно значение — один цвет»). */
.uw-former {
  margin: 6px 0 0;
  font-size: var(--text-small);
  color: var(--mist);
  line-height: 1.45;
  font-variant-numeric: tabular-nums;
}

.uw-former.is-warn {
  color: var(--ember);
}

/* Начислений одного вида за месяц несколько: вместо поля — список строк со
   своими кнопками. Карточка счётчика при этом перестаёт быть сеткой «подпись
   слева, поле справа» и становится одним столбцом. */
.uw-meter--list {
  grid-template-columns: minmax(0, 1fr);
}

/* В одностолбцовой карточке жёсткие номера строк настольной раскладки
   (подпись → поле → «было» → расчёт) ставили итог «Начислено 800 ₽ · 2 записи»
   ПОД список. Пусть строки встают в порядке разметки: подпись, итог, список. */
.uw-meter--list .uw-meter-was {
  grid-row: auto;
}

.uw-meter--list .uw-money-list {
  grid-column: 1 / -1;
  margin-top: 4px;
}

.uw-meter--list .uw-money-row {
  padding: 6px 0;
}

/* Строка правки внутри списка начислений — две дорожки (сумма и дата) плюс
   кнопки: описание у начисления не меняется, спрашивать его негде. */
.uw-meter--list .uw-row-form {
  grid-column: 1 / -1;
  grid-template-columns: minmax(100px, 130px) minmax(120px, 150px) auto;
}

/* Два слова «прежний жилец» на карточке квартиры в сетке дома: отметка
   оплаты взята от прежнего проживания, и молчать об этом нельзя — долг
   съехавшего читался бы как долг нынешнего. Тихо и без своего цвета: это не
   второе состояние квартиры, а уточнение, чьё оно. DEP-5 добавляет рядом
   «депозит неполный», LEASE-1 — пометку договора: три строки одним приёмом.

   HOUSE-CARD-1 (REQUIREMENTS.md п. 142): раньше каждая пометка была
   `flex: 1 1 100%` внутри строки-шапки с `flex-wrap: wrap` — на снимке
   владельца это и есть «депозит неполный съехала вправо» (`text-align:
   right`, унаследованный от чипа оплаты в углу). `.house-card-head` стал
   колонкой (раздел 1b выше по файлу) — пометки сами встают каждая своей
   строкой, `flex`/`flex-wrap`/`margin-top` здесь больше не нужны, gap
   колонки уже держит одинаковый отступ. Общий кегль (11px, «одинаковые
   кегли у одинаковых подписей») и левый край — вместо трёх раздельных
   POL-6/DEP-5/LEASE-1 версий одна общая. */
.house-card-former,
.house-card-deposit-mark,
.house-card-lease-mark {
  font-size: 11px;
  line-height: 1.3;
  white-space: nowrap;
  text-align: left;
}

.house-card-former {
  color: var(--soft);
}

/* Тон предупреждения — тот же `--ember`, что у чипа «съезжает …»
   (`house-card-leaving`) и у полосы просрочки на этой же карточке. */
.house-card-deposit-mark,
.house-card-lease-mark {
  color: var(--ember);
}

/* Цель касания у полей формы «Счётчики». Правило `@media (pointer: coarse)`
   для `.uw-meter input` стоит в разделе 3 этого файла — ВЫШЕ базового
   `.uw-meter input { min-height: 38px }` из раздела 4. Специфичность у них
   одинаковая, медиазапрос её не повышает, и побеждало то, что ниже: на
   телефоне поля счётчиков и сумм за месяц оставались 42 px вместо 44
   (CONVENTIONS §8). Повторяем правило последним — теперь оно и выигрывает. */
@media (pointer: coarse) {
  .uw-meter input {
    min-height: var(--tap);
  }
}

/* POL-6 21.11 (units-19). Ровно тот же приём и та же причина, что строкой
   выше: `.uw-notes-history > summary { min-height: 0 }` (§4 этого файла)
   стоит НИЖЕ обоих правил цели касания — и общего `.detail-body summary`
   (06-dialogs.css), и собственного `@media (pointer: coarse)` из §2. Вес
   селекторов одинаковый, медиазапрос его не повышает, побеждает то, что
   ниже. Повторяем правило последним — «Показать все» становится 44px.
   Второй медиазапрос — телефонная ширина под мышью (тот же довод, что у
   `.uw-row-acts .subtle-btn` в §5): цель касания на телефоне обязательна
   независимо от того, чем по экрану тычут (CONVENTIONS §8). */
@media (pointer: coarse) {
  .uw-notes-history > summary,
  .uw-expense-history > summary {
    min-height: var(--tap);
  }
}

@media (max-width: 780px) {
  .uw-notes-history > summary,
  .uw-expense-history > summary {
    min-height: var(--tap);
  }
}

/* ============================================================
   10. POL-6, пачка 4а — телефон: шкала и вертикаль окна квартиры
   ============================================================ */

/* Цвет прежнего жильца с долгом — только на цифрах (POL-6 21.13, units-21).
   Прежде вся строка в три строки была набрана `--ember`, и тлеющий цвет
   переставал значить «вот сюда смотреть»: он значил «здесь есть строка».
   Слова остаются вспомогательным цветом, тревогу несут суммы — DESIGN.md,
   «одно значение — один цвет». Правило вне медиазапроса: цвет одинаково
   неверен был на любой ширине, а геометрии он не меняет. */
.uw-former.is-warn {
  color: var(--mist);
}

.uw-former.is-warn .money {
  color: var(--ember);
}

/* «Удалить» выглядела ровно как «Изменить» — обе лавандой (POL-6 21.18,
   units-31). Отдельный цвет у необратимого действия — тот же `--ember`, что
   уже держит `.danger` (04-components.css): другого цвета для «этого не
   вернуть» в системе нет, и заводить седьмой незачем. Выбираются кнопки по
   своему же признаку действия, без правки разметки. */
.uw-row-acts .subtle-btn[data-uw-row-void],
.uw-row-acts .subtle-btn[data-uw-charge-void],
.uw-meter-acts .subtle-btn[data-uw-reading-void] {
  color: var(--ember);
}

@media (max-width: 780px) {
  /* --- 21.2 (units-4), снята HOUSE-CARD-1 (REQUIREMENTS.md п. 142) --- */
  /* Было: `max-width: 60%` в правом углу шапки держал перенос чипа, но
     «просрочено на 18 дней» не помещалось и на телефоне вываливалось за
     рамку карточки. Сейчас чип — своя строка на всю ширину шапки при любой
     ширине экрана (`.chip.chip--compact.house-card-pay`, раздел 1b выше),
     мобильного исключения больше не нужно. */

  /* --- 21.5 (units-8): пустой провал в более короткой карточке ряда --- */
  /* `align-items: stretch` сетки тянул обе карточки ряда до общей высоты, а
     `margin-top: auto` у низа прижимал строку счётчиков к краю — в более
     короткой карточке между содержимым и низом оставалось до 79px пустоты.
     На телефоне карточка высотой по содержимому: ряд из двух остаётся рядом,
     но пустоты внутри карточки нет. */
  .house-cards {
    align-items: start;
  }

  .house-card-foot {
    margin-top: 8px;
  }

  /* --- 21.4 (units-5, units-23): путь до первой карточки квартиры --- */
  /* Отступы панели управления — по лестнице 4/8/12/16 раздела 1 ТЗ. */
  .house-tools {
    gap: 8px 12px;
    margin-bottom: 12px;
  }

  .house-tiles {
    gap: 8px;
    margin-bottom: 12px;
  }

  .house-tile {
    min-height: 0;
    padding: 12px;
    gap: 4px;
  }

  .house-filters {
    margin-bottom: 12px;
  }

  .house-count {
    margin-bottom: 8px;
  }

  /* Поиск — подпись и поле одной строкой. Подпись «Поиск» (SEARCH-1, короче
     прежней «Найти квартиру») не переносится (`nowrap`), поэтому 44px её
     цели касания перестают стоить отдельной строки: они и есть высота строки
     поля. −49px до первой карточки квартиры. */
  .house-search {
    flex-direction: row;
    align-items: center;
    gap: 8px;
  }

  .house-search > .field-label {
    flex: 0 0 auto;
    white-space: nowrap;
  }

  .house-search input {
    flex: 1 1 auto;
    min-width: 0;
  }

  /* NQA-D1-U-1 (владелец, REQUIREMENTS.md п. 140: «кнопки ровные по размеру...
     ничего не накладывалось»): прежнее правило (`flex: 1 1 0; min-width: 0`)
     держало «Обойти счётчики» и «Тарифы» в одном ряду с переключателем
     `.house-sort` (249px, не сжимается — он не флекс-дитя со своим `flex`) и
     сжимало обе кнопки до ~31px при доступных на 390px 332px — тексту нужно
     65–75px, читать было нельзя. `.house-actions` уже `flex-wrap: wrap`
     (раздел 1): кнопки больше не сжимаются ниже своего текста, и когда ряд не
     помещается целиком, первым переносится переключатель сортировки — обе
     кнопки остаются вместе на следующей строке, читаются целиком на любой
     ширине. */
  .house-actions button {
    flex: 0 0 auto;
    white-space: nowrap;
  }

  /* --- 21.8 (units-13): одно внутреннее поле у всех блоков окна --- */
  .uw-notes,
  .uw-form,
  .uw-util-block,
  .uw-payments-block,
  .uw-total,
  .uw-preview {
    padding: 12px;
  }

  .uw-meter {
    padding: 12px;
  }

  /* --- 23.1: строки шапки месяца в одну линию, где помещаются --- */
  /* Столбиком стояли три строки подряд: месяц, чип состояния, срок оплаты.
     Месяцу своя строка нужна (подпись над списком — иначе название месяца
     обрезается, правило выше по файлу), а чип и срок — короткие, и рядом
     они занимают одну строку вместо двух. */
  .uw-head-top {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: 8px 12px;
  }

  .uw-head-top > .uw-month {
    flex: 1 1 100%;
  }

  /* Подпись месяца и список — тоже одной строкой (−44px). Прежнее правило
     выше по файлу ставило подпись НАД списком, потому что «За какой месяц»
     переносилась на две строки и сжимала список так, что название месяца
     обрезалось. Перенос запрещён прямо (`nowrap`), ширина подписи
     фиксирована содержимым, остаток ширины целиком у списка: на 360 это
     184px при «Сентябрь 2026» в 140 — месяц читается целиком. */
  .uw-head .uw-month {
    flex-direction: row;
    align-items: center;
    gap: 8px;
  }

  .uw-head .uw-month .field-label {
    flex: 0 0 auto;
    white-space: nowrap;
  }

  .uw-head .uw-month select {
    flex: 1 1 auto;
    min-width: 0;
  }

  /* --- 21.9 (units-14): самый громкий текст окна свободной квартиры --- */
  /* «Кто здесь живёт, пока не внесено в систему» набиралось 18px/700 в две
     строки — крупнее всего остального в окне. Это не имя жильца, а ответ
     «имени нет»: подпись, а не заголовок. */
  .uw-tenant-name.is-empty {
    font-size: var(--text-small);
    font-weight: 400;
    line-height: 1.4;
    color: var(--soft);
  }

  /* --- 21.10 (units-15): «Не хватает: телефон, Телеграм» --- */
  /* 16px/700 читалось наравне с именем жильца, то есть как второй заголовок.
     Вес и кегль подписи — сам список пробелов от этого не пропадает. */
  .uw-tenant-gap.is-gap {
    font-size: var(--text-small);
    font-weight: 400;
  }

  /* --- 21.6 (units-9, units-24): две денежные таблицы одним кеглем --- */
  /* «Оплаты месяца» шли 16px, «За счётчики» рядом — 14px; тихие кнопки так же
     врозь (`.uw-util-link` 14, `.uw-row-acts .subtle-btn` 16). Ниже — 14
     обеим таблицам и обеим кнопкам: это списки-разбивки, а не основной текст
     экрана. Цель касания у кнопок держится min-height, кегль на неё не
     влияет (тот же довод, что у `.subtle-btn` в 09-responsive.css). */
  .uw-money-row {
    font-size: var(--text-small);
  }

  .uw-row-acts .subtle-btn,
  .uw-meter-acts .subtle-btn {
    font-size: var(--text-small);
  }

  /* --- 21.12 (units-22): 129px на одну оплату, из них 39 — «кто записал» --- */
  /* Отдельная строка «записал … 14 сентября в 10:55» под каждой оплатой
     давала три строки там, где дело описывают две. На телефоне её нет, а
     сами слова остаются в `title` строки (22-unit-window.js) — тот же приём,
     что уже стоит у `.uw-meter-was` в этом файле. На мониторе строка видна
     как была: там места достаточно. Класс `--who` отделяет отметку «кто
     записал» от смысловых отметок того же вида («прежний жилец», «уже в
     остатке по книге»), которые остаются видимыми. */
  .uw-money-mark--who {
    display: none;
  }

  /* --- 21.14 (desk-12): плитка тарифа дома в одну строку --- */
  /* Название блоком и цена блоком под ним давали 73px на плитку, шесть
     услуг — 498px на дом. Название слева, цена справа: 73 → ≈44px. */
  .tariff-house-tile {
    display: flex;
    flex-wrap: wrap;
    align-items: baseline;
    justify-content: space-between;
    gap: 2px 12px;
    padding: 8px 12px;
  }

  .tariff-house-tile > span {
    margin-bottom: 0;
  }

  /* «Цена не назначена» — не цифра, а её отсутствие: кеглем подписи, чтобы
     плитка укладывалась в одну строку и на 360. Числа остаются 16px. */
  .tariff-house-tile > strong.is-mixed {
    font-size: var(--text-small);
  }
}

/* ============================================================
   PHOTO-1. Фотографии жильца (REQUIREMENTS.md п. 130)
   ============================================================ */

/* Разметка сетки, миниатюр и формы добавления — общая для профиля жильца
   (`.panel` вокруг раздела, 07-tenants.js:showTenant) и блока жильца в окне
   квартиры (`.uw-photos` ниже): оба зовут одну и ту же tenantPhotosSection().
   5 миниатюр в ряд на мониторе, 3 — на телефоне (задание §«Интерфейс»):
   `minmax(0, 120px)` у каждой колонки не даёт миниатюре вырасти больше
   120px, а когда всех колонок вместе не помещается — они сжимаются поровну
   до ширины контейнера, не вызывая горизонтальной прокрутки ни в узкой
   панели профиля, ни в листе окна квартиры на телефоне. */
.tenant-photos-grid {
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 120px));
  gap: 8px;
  margin: 0 0 12px;
}

.tenant-photo {
  margin: 0;
  display: grid;
  gap: 4px;
}

.tenant-photo-open {
  display: block;
  width: 100%;
  aspect-ratio: 1;
  padding: 0;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-md);
  background: var(--sunken);
  overflow: hidden;
}

/* `:not([hidden])` — та же оговорка, что у заглушки ниже: без неё `display:
   block` отменял бы `img.hidden = true`, которым 07-tenants.js прячет
   картинку на ошибке загрузки. */
.tenant-photo-open img:not([hidden]) {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Заглушка на ошибку загрузки — словами «фото», без картинки (задание
   §«Интерфейс»). На стенде предпросмотра видна всегда: `dev/preview/serve.py`
   отдаёт только файлы `web/`, адреса байтов фотографии у него нет. В системе
   встаёт только если файл действительно не открылся (`img.onerror`,
   07-tenants.js). Контраст текста: `--mist` на `--sunken` ≥ 5.7:1 (01-tokens.css).
   `:not([hidden])` — встроенное правило браузера `[hidden]{display:none}` того
   же веса, что обычный класс: без этой оговорки `display: flex` ниже отменяло
   бы `hidden`, и заглушка стояла бы поверх картинки всегда, а не только на
   ошибке (найдено на своём сервере 8794, задание TZ-PHOTO-1.md). */
.tenant-photo-broken:not([hidden]) {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 100%;
  height: 100%;
  color: var(--mist);
  font-size: var(--text-small);
  text-align: center;
}

/* Тихое «Убрать» — тем же приёмом, что у заметки рядом (`.uw-note .subtle-btn`
   выше): меньше высоты и поля, чем у обычной вторичной кнопки. */
.tenant-photo-remove {
  padding: 4px 0;
  min-height: 30px;
  font-size: var(--text-small);
}

/* Находка проверяющего PHOTO-1: 30px ниже обязательных 44 (`CONVENTIONS.md`
   §8). Та же пара правил и по той же причине, что у `.uw-row-acts .subtle-btn`
   и `.uw-meter-acts .subtle-btn` выше (комментарий у `@media (max-width:
   780px)` в §2 этого файла): `pointer: coarse` держит палец на мониторе и
   планшете, `max-width: 780px` — телефонную ширину, которую смотрят мышью
   (правило `pointer: coarse` там не срабатывает). Монитор мышью остаётся
   тихой строкой 30px — цель не растёт там, где по ней не тычут пальцем. */
@media (pointer: coarse) {
  .tenant-photo-remove {
    min-height: var(--tap);
  }
}

@media (max-width: 780px) {
  .tenant-photos-grid {
    grid-template-columns: repeat(3, minmax(0, 120px));
  }

  .tenant-photo-remove {
    min-height: var(--tap);
  }
}

/* Блок жильца в окне квартиры — лёгкая рамка вместо тяжёлой `.panel`, тем же
   приёмом оформления, что «Заметки» прямо над ним (`.uw-notes` выше): раздел
   не должен выглядеть тяжелее соседа, с которым он всегда идёт рядом. */
.uw-photos {
  padding: 12px 14px;
  margin-bottom: 12px;
  background: var(--surface);
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
}

.uw-photos-title {
  font-size: var(--text-h3);
  color: var(--pearl);
  margin: 0 0 10px;
}

/* Поле выбора файла — без своей кнопки «Отправить»: выбор снимка сразу
   отправляет его (07-tenants.js, bindTenantPhotoAddForm). */
.tenant-photo-add {
  margin: 0;
}

.tenant-photo-status {
  margin: 6px 0 0;
  font-size: var(--text-small);
  color: var(--mist);
}

.tenant-photo-status.error {
  color: var(--ember);
}

/* Просмотр одной фотографии — свой <dialog> (`#tenant-photo-dialog`,
   07-tenants.js), картинка во всю ширину без полей тела. */
.tenant-photo-dialog .tenant-photo-view-body {
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--sunken);
  min-height: 200px;
}

.tenant-photo-full:not([hidden]) {
  display: block;
  width: 100%;
  height: auto;
  max-height: calc(90vh - 90px);
  object-fit: contain;
}

.tenant-photo-view-body .tenant-photo-broken:not([hidden]) {
  width: 100%;
  min-height: 240px;
  font-size: var(--text-body);
}

/* NQA1-SRF-01 (лист «Обойти счётчики», web/js/18-meter-batch.js): полоса
   `.walk-actions` — `position: sticky; bottom: 0` (17-mobile-input.css, файл
   вне зоны этой правки) — последний элемент потока `.walk-list` перед ней.
   У списка нет своего запаса снизу, поэтому на любом доме больше пары
   квартир (лист выше окна) полоса «Пока пусто · Сохранить обход» с первого
   кадра стоит поверх нижней видимой строки, а самую последнюю квартиру
   долистать из-под неё нечем — конец списка ограничен собственной высотой
   контента. `.walk-actions` — не декорация: измерено вживую 75px на 1440,
   768 и 390 (padding 12px×2 + кнопка + рамка) — стабильно на всех трёх.
   Запас снизу даёт списку место закончиться выше полосы, а не под ней:
   долистав до конца, последняя квартира читается полностью, а не наполовину
   под кнопкой. Правило стоит в 18-house.css (зона lists-settings), а не в
   17-mobile-input.css (чужая зона) — той же цели служит правило позже
   в каскаде поверх чужого файла, ничего в нём не меняя. */
.walk-list {
  padding-bottom: 76px;
}
