/* Главная страница системы: «Обзор» — счёт месяца (DASH-4).
   Часть CRM аренды. ПОРЯДОК ПОДКЛЮЧЕНИЯ ВАЖЕН: последний в группе экранов,
   после 20-sheet.css. Только классы `.desk-*`: ничего прежнего файл не
   перекрывает.

   Разметку собирает web/js/27-desk.js.

   Четыре правила, от которых зависит всё остальное в файле:

   1. КОНЕЧНОЕ СОСТОЯНИЕ — СОСТОЯНИЕ ПО УМОЛЧАНИЮ. Полосы, дуги кольца и
      главная цифра нарисованы целиком без всякой анимации; движение только
      добавляет им появление под `html[data-motion='on']` (21-transitions.js
      ставит этот атрибут по выключателю атмосферы плюс prefers-reduced-motion),
      и играет оно один раз за открытие экрана — пока на витрине стоит класс
      `.is-entering`. Ничего видимого анимация не прячет.
   2. ШИРИНЫ ПОЛОС приходят переменными `--x` / `--w` из `data-vars`
      (18-data-table.js кладёт их правилом в конструируемую таблицу стилей).
      Ни одного `style="…"` в разметке: на боевом сервере стоит строгий CSP
      `style-src 'self'`. Геометрия кольца — атрибутами SVG.
   3. ЦВЕТ — только токены из 01-tokens.css. Тона источников дохода, дуг
      кольца и лент депозитов сделаны непрозрачностью одного токена, а не
      новыми значениями цвета. Ни одного hex в файле.
   4. НИ ОДНОЙ КАРТИНКИ. Фон витрины — градиенты и инлайн-SVG-узор линовки;
      `web/assets/objects` и `web/assets/art` здесь не используются вовсе
      (уточнение владельца 2026-09-18 17:40). Единственный `url()` в файле
      ссылается на узор внутри самой разметки, не на файл.

   Кегли после DASH-5 (п. 104, «слишком большие шрифты, слишком много
   отступа, много лишнего воздуха»): главная цифра clamp(30–38px) вместо
   56px, суммы ступеней 17px вместо 22, суммы долей и депозитов 17px вместо
   20, имена и слова ступеней 14px, подписи 13px. 13px — пол страницы:
   мельче нет ничего, а чипы и кнопки остаются на 13–14 (CONVENTIONS §8
   допускает 13–14 в плотных блоках по решениям владельца п. 77/78/104).
   Полосы 6px вместо 12, шаг строк лестницы 9px вместо 14, поля витрины
   14/18px вместо 24/26 — вся страница влезает в окно 1440×900 без
   вертикальной прокрутки. */

/* ============================================================
   1. Каркас страницы
   ============================================================ */

.page.desk {
  display: grid;
  gap: 10px;
  align-content: start;
}

/* Шапка: месяц крупно курсивом, под ним — тихая строка объекта и занятости
   (п. 101: «сколько заселено — просто сверху небольшим шрифтом, некричаще»).
   В разметке строка объекта идёт второй, чтобы печать заголовка
   (19-atmosphere.js) по-прежнему находила `.page-heading h1` и `p.muted`;
   местами их меняет раскладка, а не порядок узлов. */
.desk > .page-heading {
  /* 2px, а не 6: над шапкой уже стоит полоса месяца с собственными полями, а
     странице после SETTLE-1 нужен каждый пиксель до края экрана (п. 104). */
  margin: 2px 0 0;
  align-items: baseline;
}

/* DASH-5 (п. 104): месяц, строка «дом · заселено», чип «Пока предварительно»
   и кнопка «Записать расход» стоят одной строкой шапки — две строки отдавали
   витрине на 40px меньше первого экрана. Порядок узлов в разметке не тронут
   (`h1`, затем `p.muted`): печать заголовка в 19-atmosphere.js ищет именно
   его. Когда строка объекта длинная, она переносится под месяц сама. */
.desk > .page-heading > div:first-child {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 12px;
  min-width: 0;
}

.desk > .page-heading h1 {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 600;
  font-size: clamp(22px, 2.2vw, 27px);
  line-height: 1.15;
  /* «Сентябрь 2026» стоит одной строкой и не жмётся: в ряду шапки
     `text-wrap: balance` разрывал название месяца надвое («Сентябрь» и
     «2026»), а сжатие флексом обрезало бы его. */
  flex: 0 0 auto;
  white-space: nowrap;
}

.desk > .page-heading p.muted {
  margin: 0;
  font-size: 13px;
  line-height: 1.35;
}

/* NIGHT-QA-1 (D4-TYPE-VEIL-1): пока печатается заголовок и подпись
   (19-atmosphere.js), настоящий текст под накладкой обязан стать
   прозрачным — это делает `.atm-veil.atm-veil` (10-atmosphere.css, вес —
   два класса, специально удвоенных автором «на случай `.page-heading p`»).
   Оба правила выше — `.desk > .page-heading h1` и `.desk > .page-heading
   p.muted` — специфичнее того, что предвидел автор веила (два-три класса
   плюс сам тег), и побеждали оба: заголовок месяца и подпись «Инвесторам»/
   «Все объекты» оставались видны тем же цветом, пока сверху печаталась
   копия — обе строки читались одновременно и превращались в кашу («15квартир
   · ссентябрь…» вместо «15 квартир · сентябрь…»). Цвет вынесен сюда, в
   отдельные правила с `:not(.atm-veil)`: пока класса нет — красят как
   раньше; как только он появляется — не совпадают вовсе, и решает
   `.atm-veil.atm-veil`, как и было задумано. */
.desk > .page-heading h1:not(.atm-veil) {
  color: var(--lavender);
}

.desk > .page-heading p.muted:not(.atm-veil) {
  color: var(--mist);
}

/* POL-6 22.7: кнопка «Записать расход» одна на обе раскладки — второй,
   «телефонной» копии (`.desk-mobile-actions`) больше нет ни в разметке
   (27-desk.js), ни здесь. */
.desk-head-actions {
  display: flex;
  gap: 10px;
  flex: 0 0 auto;
}

.desk-head-actions button {
  min-height: 30px;
  padding: 4px 14px;
  font-size: 13px;
}

/* «Расходы дома» слева (ежедневная рука управляющего, п. 83), «Доходы»
   справа. Ниже этого ряда на странице ничего нет. */
.desk-row {
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  gap: 14px;
  align-items: start;
}

/* Шаг между блоками держит сетка страницы: свой margin-bottom у .panel дал бы
   двойной отступ в ряду и рваный ритм в столбце. */
.desk .panel {
  margin: 0;
  padding: 10px 14px 12px;
}

.desk .panel-head {
  margin-bottom: 6px;
  flex-wrap: wrap;
}

/* Дорога обратно со страницы вознаграждения: пункта меню у неё больше нет
   (п. 67), и открывается она ссылкой с «Обзора». Класс живёт здесь, потому
   что «Обзор» — единственный, кто туда ведёт. */
.management-back {
  margin: 18px 0 -10px;
  padding: 6px 4px;
}

/* FIX-N6 §1: второй вход на ту же страницу — тихая ссылка в блоке
   «Управляющий» на «Тарифах» (24-tariffs-page.js). Правило стоит рядом с
   дорогой обратно по той же причине, по которой здесь живёт `.management-back`:
   обе двери ведут в одну комнату, и держать их в разных файлах значило бы
   править их порознь. Левое поле снято, чтобы ссылка встала по одному краю с
   именем управляющего строкой выше; высота у неё общая, кнопочная (44px). */
.tariff-fee-link {
  padding-left: 0;
}

/* Тихая строка под цифрой: то, без чего сама цифра непонятна. */
.desk-quiet {
  margin: 3px 0 0;
  font-size: 13px;
  color: var(--mist);
}

/* Ключ-квадратик тональной лесенки. Тон — непрозрачность одного токена:
   лаванда на этой странице значит «управляющий», глина — «расход», зелёный —
   «приход», и красить ими источники или людей нельзя (DESIGN.md, «One
   Meaning»). */
.desk-tone {
  display: inline-block;
  width: 8px;
  height: 8px;
  flex: 0 0 auto;
  border-radius: 2px;
}

.desk-tone--leaf0 {
  background: var(--leaf);
}

.desk-tone--leaf1 {
  background: var(--leaf);
  opacity: 0.72;
}

/* Пол лесенки: ниже 55 % зелёный на подложке панели даёт меньше 3:1. */
.desk-tone--leaf2 {
  background: var(--leaf);
  opacity: 0.55;
}

.desk-tone--window0 {
  background: var(--window);
}

.desk-tone--window1 {
  background: var(--window);
  opacity: 0.82;
}

.desk-tone--window2 {
  background: var(--window);
  opacity: 0.66;
}

.desk-tone--window3 {
  background: var(--window);
  opacity: 0.5;
}

/* ============================================================
   2. Витрина: «бумага счёта»
   ============================================================ */

/* Панель непрозрачна намеренно: текст не должен зависеть от того, что
   нарисовал холст частиц под ней. Золотая черта сверху — как у бланка. */
/* Поля витрины 12px сверху и снизу вместо 14 и 16: столбец долей у дома с
   четырьмя инвесторами после SETTLE-1 стал выше на строку хранителя, и эти
   шесть пикселей возвращают странице край экрана (п. 104). По горизонтали
   18px не тронуты — там воздух виден. */
.desk-stage {
  position: relative;
  overflow: hidden;
  padding: 12px 18px;
  border: 1px solid var(--border-subtle);
  border-top-color: var(--window-edge);
  border-radius: var(--radius-xl);
  background: var(--surface);
  box-shadow: var(--shadow-2);
}

/* Тёплый свет в левом верхнем углу — тот же приём, что у `.sc-hero::before`
   в витрине инвестора: две главные страницы системы узнаются как одной
   крови. */
.desk-stage::before {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(72% 76% at 18% 6%, var(--window-tint), transparent 66%);
}

/* Холодный отсвет в правом нижнем углу — там, где лежат депозиты. Он
   уравновешивает амбру и отделяет зону долей от зоны главной цифры без
   линии. */
.desk-stage::after {
  content: '';
  position: absolute;
  inset: 0;
  pointer-events: none;
  background: radial-gradient(62% 70% at 4% 104%, var(--tide-tint), transparent 62%);
}

/* Линовка ведомости. Это УЗОР, а не картинка: он ничего не изображает, только
   снимает с большой тёмной плоскости ощущение пустого прямоугольника. Шаг
   30px совпадает с шагом строк лестницы, поэтому линовка не спорит с текстом;
   книзу гаснет маской. Цвет линии — жемчужный токен в 3 % (color-mix), а не
   новое значение цвета. */
.desk-paper {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  pointer-events: none;
  mask-image: linear-gradient(180deg, var(--pearl) 0%, transparent 72%);
}

.desk-paper line {
  stroke: color-mix(in srgb, var(--pearl) 3%, transparent);
  stroke-width: 1;
}

.desk-stage-grid {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  align-items: start;
}

.desk-stage-grid--single {
  grid-template-columns: minmax(0, 1fr);
}

.desk-stage-bill,
.desk-stage-side {
  position: relative;
  min-width: 0;
}

/* Разделитель половин — не рамка, а вертикальная черта с растушёвкой сверху и
   снизу. Рамок на витрине минимум: каждая линия на экране либо полоса с
   суммой, либо разделитель блока. */
.desk-stage-side {
  margin-left: 20px;
  padding-left: 20px;
}

.desk-stage-side::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 1px;
  background: var(--border-subtle);
  mask-image: linear-gradient(180deg, transparent, var(--pearl) 14%, var(--pearl) 86%, transparent);
}

/* Подпись группы в правой половине: «Доли», «Депозиты». */
.desk-side-title {
  margin: 0 0 4px;
  font-size: 13px;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--mist);
}

/* Строка «Цифры не обновились» появляется только тогда, когда перечитывание
   не прошло: прежние числа при этом не трогаются вовсе. */
.desk-stale {
  position: relative;
  margin: 10px 0 0;
  color: var(--ember);
}

/* ============================================================
   3. Лестница-водопад
   ============================================================ */

/* Одна дорожка на каждую ступень, все одинаковой ширины: проценты сходятся по
   вертикали, и глаз видит, что каждый следующий отрез начинается там, где
   кончился предыдущий. */
.desk-bill {
  position: relative;
  display: grid;
  gap: 9px;
}

.desk-bill-row {
  position: relative;
}

.desk-bill-head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
}

/* 14px: слово ступени стоит рядом с суммой и читается вместе с ней, а
   16px после DASH-5 уводили лестницу под сгиб (п. 104). */
/* FIX-N6 §1: строка в ряд, а не абзац. Подпись ступени — носитель подсказки
   (`fieldLabel`), а он сам по себе `display: flex`, то есть блок; стрелка
   перехода рядом с ним падала на вторую строку и добавляла ступени 19px —
   ровно то, чего витрине нельзя (п. 104). */
.desk-bill-name {
  display: flex;
  align-items: baseline;
  font-size: var(--text-small);
  font-weight: 600;
  color: var(--soft);
  min-width: 0;
}

.desk-bill-sum {
  font-size: 17px;
  font-weight: 800;
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.01em;
  white-space: nowrap;
  color: var(--pearl);
}

/* FIX-N6 §1: стрелка перехода в строке «Управляющему». Высоту ступени она не
   меняет: общий `.subtle-btn` с его 44px разогнал бы лестницу под сгиб
   (п. 104), поэтому цель касания добирается невидимой областью вокруг
   (`::after`) — тем же приёмом, что у «кому →» в лентах депозитов. */
.desk-bill-goto {
  position: relative;
  display: inline;
  min-height: 0;
  padding: 0 0 0 6px;
  font-size: 13px;
  line-height: 1.3;
  white-space: nowrap;
}

.desk-bill-goto::after {
  content: '';
  position: absolute;
  left: 0;
  right: -6px;
  top: 50%;
  height: var(--tap);
  transform: translateY(-50%);
}

.desk-bill-track {
  position: relative;
  display: block;
  height: 6px;
  margin-top: 5px;
  border-radius: 3px;
  background: var(--sunken);
  border: 1px solid var(--border-subtle);
}

.desk-bill-seg {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--x);
  width: var(--w);
  border-radius: 3px;
}

/* Ненулевая величина тоньше 4px получает ровно 4px; `--x` при этом не
   меняется — шов остаётся на месте, а погрешность не превышает 1 % дорожки.
   Нулевая величина не рисуется вовсе, и строки у неё нет. */
.desk-bill-seg--thin {
  min-width: 4px;
}

/* Шов: короткий пунктир у левого края отрезанного куска, вверх и вниз. Он и
   делает из четырёх полос водопад. */
.desk-bill-track--cut::before,
.desk-bill-track--cut::after {
  content: '';
  position: absolute;
  left: var(--x);
  height: 6px;
  border-left: 1px dashed var(--border-strong);
}

.desk-bill-track--cut::before {
  bottom: 100%;
}

.desk-bill-track--cut::after {
  top: 100%;
}

/* Цвета ступеней. Расход — не авария и не просрочка: тёплая глина стоит рядом
   с золотом по температуре и читается как «то же тепло, но ушло». Тлеющий
   (--ember) остаётся только отрицательным величинам. */
.desk-bill-row--in .desk-bill-sum {
  color: var(--leaf);
}

.desk-bill-row--in .desk-bill-seg {
  background: var(--leaf);
}

.desk-bill-row--out .desk-bill-sum {
  color: var(--clay);
}

.desk-bill-row--out .desk-bill-seg {
  background: var(--clay);
}

.desk-bill-row--fee .desk-bill-sum {
  color: var(--lavender);
}

.desk-bill-row--fee .desk-bill-seg {
  background: var(--lavender);
}

/* «Неизвестно»: зазор заштрихован, а не залит, и ширина его нигде не названа
   числом. Форма несёт смысл наравне с цветом; светящегося или залитого
   «Неизвестно» на витрине нет — это был бы обман. */
.desk-bill-row--hatch .desk-bill-sum {
  color: var(--soft);
}

.desk-bill-row--hatch .desk-bill-seg {
  background: repeating-linear-gradient(45deg, var(--mist) 0 3px, transparent 3px 6px);
  border: 1px solid var(--border-field);
}

/* Налоги и реклама: потрачено, но долю инвестора не уменьшает — поэтому под
   итоговой чертой, с отступом и без соединительного шва. */
.desk-bill-row--aside {
  margin-left: 18px;
}

.desk-bill-row--aside .desk-bill-sum {
  color: var(--clay);
}

.desk-bill-row--aside .desk-bill-seg {
  background: repeating-linear-gradient(45deg, var(--clay) 0 3px, transparent 3px 6px);
  border: 1px solid var(--clay-edge);
}

/* Из чего сложилось «Пришло». Сама полоса «Пришло» не дробится: пропорции
   95/5 нечитаемы, а суммы стоят рядом словами. */
.desk-bill-sources {
  display: flex;
  flex-wrap: wrap;
  gap: 0 14px;
  margin: 4px 0 0;
  font-size: 13px;
  color: var(--mist);
}

.desk-bill-src {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
}

.desk-bill-src b {
  font-weight: 600;
  color: var(--soft);
  font-variant-numeric: tabular-nums;
}

/* Итоговая черта счёта: слева, у слова «Инвесторам», золото; дальше гаснет. */
.desk-bill-line {
  display: block;
  height: 1px;
  margin: 6px 0 2px;
  background: linear-gradient(90deg, var(--window-edge), var(--border-subtle) 62%, transparent);
}

.desk-bill-net {
  position: relative;
}

.desk-bill-net-label {
  position: relative;
  margin: 0;
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 600;
  font-size: 15px;
  line-height: 1.25;
  color: var(--lavender);
}

/* Одно эллиптическое пятно на всю страницу — за главной цифрой. */
.desk-bill-net::before {
  content: '';
  position: absolute;
  left: -18px;
  top: 0;
  width: 330px;
  max-width: 120%;
  height: 96px;
  pointer-events: none;
  background: radial-gradient(52% 120% at 12% 52%, var(--window-tint), transparent 70%);
}

.desk-bill-net-value {
  position: relative;
  margin: 0 0 6px;
  font-family: var(--font-ui);
  font-size: clamp(30px, 2.6vw, 38px);
  font-weight: 800;
  line-height: 1.05;
  letter-spacing: -0.03em;
  color: var(--window);
  font-variant-numeric: tabular-nums;
  /* Число не рвётся посреди разряда: витрина инвестора на этом уже
     обжигалась. Длинная сумма вместо переноса опускает кегль. */
  overflow-wrap: normal;
  word-break: normal;
  text-shadow: var(--glow-window-text);
}

.desk-bill-net-value.is-long {
  font-size: clamp(26px, 2.2vw, 33px);
}

/* Золотая полоса «Инвесторам» — часть диаграммы, а не отдельное украшение.
   Свечение приглушено до 42 %: полоса широкая, и полный ореол размазал бы её
   край. */
.desk-bill-net .desk-bill-seg {
  background: var(--window);
  box-shadow: 0 0 18px -6px color-mix(in srgb, var(--window) 42%, transparent);
}

.desk-bill-net--loss .desk-bill-net-value {
  color: var(--ember);
  text-shadow: none;
}

.desk-bill-net--loss .desk-bill-seg {
  background: var(--ember);
  box-shadow: none;
}

/* «Неизвестно» и «Пока пусто» — слова, а не суммы: ни золота, ни свечения.
   Светящееся «Неизвестно» было бы обманом. */
.desk-bill-net-value--words {
  font-size: 26px;
  font-weight: 750;
  letter-spacing: normal;
  color: var(--soft);
  text-shadow: none;
}

/* ============================================================
   4. Кольцо долей
   ============================================================ */

/* RING-1: кольцо с именами и долями по обеим сторонам. Высота для четырёх
   участников остаётся 160px; на узком экране рисунок уменьшается, кегль
   HTML-подписей остаётся 13px. Текст всегда вне золотых дуг. */
.desk-ring {
  position: relative;
  width: 320px;
  max-width: 100%;
  aspect-ratio: 2;
  /* Поле под кольцом 4px: у кольца и так 16px собственного воздуха сверху и
     снизу (коробка 160px на рисунок 128px), а столбцу долей эти пиксели
     нужнее — SETTLE-1 добавил в него вторую строку хранителя (п. 104). */
  margin: 0 auto 4px;
}

.desk-ring svg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}

/* Мягкое амбровое пятно в отверстии. Ни числа, ни слова в центре нет:
   «2 доли» ничего не добавляет к списку рядом. */
.desk-ring::before {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  width: 74px;
  height: 74px;
  margin: -37px 0 0 -37px;
  border-radius: 50%;
  background: radial-gradient(60% 60% at 50% 50%, var(--window-tint), transparent 70%);
}

/* Ореол — дубль дуг более толстой линией под ними, БЕЗ `filter: drop-shadow`:
   размытие поверх живого холста частиц пересчитывается каждый кадр и греет
   телефон управляющего (REDESIGN Б.10). */
.desk-ring-halo {
  fill: none;
  stroke: var(--window-tint);
  stroke-width: 24;
}

.desk-ring-track {
  fill: none;
  stroke: color-mix(in srgb, var(--pearl) 8%, transparent);
  stroke-width: 16;
}

.desk-ring-arc {
  fill: none;
  stroke: var(--window);
  stroke-width: 16;
}

.desk-ring-arc--t1 {
  opacity: 0.82;
}

.desk-ring-arc--t2 {
  opacity: 0.66;
}

/* Пол лесенки: 50 % амбры на подложке панели даёт 3,78:1 — выше 3:1,
   требуемых для графики. */
.desk-ring-arc--t3 {
  opacity: 0.5;
}

.desk-ring-arc.is-lit {
  stroke-width: 20;
}

.desk-ring-mark {
  position: absolute;
  width: 23%;
  transform: translateY(-50%);
  font-size: 13px;
  line-height: 16px;
  font-weight: 700;
  color: var(--pearl);
  font-variant-numeric: tabular-nums;
  overflow-wrap: anywhere;
}

.desk-ring-mark--left {
  left: 0;
  text-align: right;
}

.desk-ring-mark--right {
  right: 0;
  text-align: left;
}

.desk-ring-name,
.desk-ring-percent {
  display: block;
}

.desk-ring-percent {
  color: var(--soft);
  white-space: nowrap;
}

.desk-ring-guide {
  fill: none;
  stroke: var(--mist);
  stroke-width: 1;
}

/* ============================================================
   5. Доли инвесторов
   ============================================================ */

/* Шаг списка 5px, а не 6: у дома с четырьмя инвесторами вторая строка
   хранителя (SETTLE-1) добирает высоту столбца до прокрутки, и каждый
   пиксель шага здесь стоит трёх на странице (п. 104). */
.desk-inv-list {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 5px;
}

/* DASH-5 (п. 104): карточка — ОДНА строка «● имя · доля % · сумма ·
   [Выплатить]». Четыре строки в столбик давали 130px на инвестора и уводили
   витрину под сгиб. Имя тянется и обрезается многоточием, всё остальное
   держит свою ширину; «Хранит депозиты» стоит тихой подписью в той же
   строке. Приписки про дома и частичную выплату переносятся второй строкой
   сами — `flex-wrap` и основа 100 % у них. */
.desk-inv {
  position: relative;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 2px 10px;
  /* 3px по вертикали: кнопка внутри 30px, и на первой строке отступ всё равно
     не виден, а у четырёх карточек эти 8px решают, будет ли у витрины
     прокрутка (п. 104). */
  padding: 3px 10px;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--sunken);
}

.desk-inv.is-lit {
  background: var(--state-hover);
  border-color: var(--window-edge);
}

.desk-inv:focus-visible {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-offset);
}

.desk-inv-name {
  display: flex;
  align-items: center;
  gap: 7px;
  flex: 1 1 auto;
  min-width: 0;
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--pearl);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.desk-inv-share {
  flex: 0 0 auto;
  font-size: 13px;
  font-weight: 600;
  color: var(--mist);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.desk-inv-sum {
  flex: 0 0 auto;
  font-size: 17px;
  font-weight: 800;
  color: var(--window);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Приписки — своей строкой под главной: они редки (режим «все объекты»,
   частичная выплата) и не должны сдвигать кнопку с первой строки. */
.desk-inv-house,
.desk-inv-note {
  flex: 1 1 100%;
  font-size: 13px;
  color: var(--mist);
}

.desk-inv-reason {
  flex: 0 1 auto;
  margin-left: auto;
  font-size: 13px;
  color: var(--mist);
}

/* SETTLE-1 (п. 102): вторая строка карточки хранителя — «на руки N ₽» и
   тихое «хранит депозиты» вместе. Своей строкой, а не рядом с «Выплатить»:
   рядом с кнопкой подпись читается как вторая кнопка, а лишняя величина на
   первой строке сдвинула бы кнопку с неё на 390 (§3.1 задания). */
.desk-inv-foot {
  flex: 1 1 100%;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 10px;
}

/* Вторая величина хранителя — тем же кеглем, что «заработал», но тоном
   тише: это тот же месяц того же человека, а не вторая, спорящая цифра.

   Межстрочное расстояние прижато к кеглю: строка одна, переносов в ней не
   бывает, а наследованные 1,5 давали строке 25,5px вместо 20px — шесть
   пикселей, которых витрине не хватало до края экрана (п. 104). */
.desk-inv-hand {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 13px;
  line-height: 1.2;
  color: var(--mist);
}

.desk-inv-hand b {
  font-size: 17px;
  line-height: 1.2;
  font-weight: 700;
  color: var(--soft);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Единственный холодный акцент в списке: он стоит ровно там, где лежат чужие
   деньги. */
.desk-inv-keep {
  flex: 0 1 auto;
  font-size: 13px;
  color: var(--tide);
}

/* Отрицательный итог — редкий и важный случай: деньги отдаёт инвестор.
   Тёплая глина, тот же цвет, которым на этой странице помечено «ушло». */
.desk-inv-note.desk-inv-back {
  color: var(--clay);
}

/* RENT-CHANNEL-1 (REQUIREMENTS.md п. 133 (7)): «осталось отдать наличными»
   меньше нуля — инвестор получил на счёт больше своей доли. Та же глина, что
   у «инвестор передаёт управляющему» выше на этой же карточке — оба случая
   про деньги, идущие непривычным путём. */
.desk-inv-duenow-warn {
  color: var(--clay);
}

.desk-inv .desk-inv-paid {
  flex: 0 0 auto;
  margin-left: auto;
  color: var(--leaf);
  background: var(--leaf-tint);
  border-color: var(--leaf-edge);
  font-weight: 700;
}

/* Кнопка вторичная и без движения: ни подъёма, ни масштабирования — только
   кромка и подложка под курсором. 30px — мышь (п. 104), 44px — палец: цель
   касания добирается ниже, по `pointer: coarse` и по ширине телефона. */
.desk-inv .desk-inv-pay {
  flex: 0 0 auto;
  margin-left: auto;
  min-height: 30px;
  padding: 0 13px;
  width: auto;
  font-size: 13px;
  font-weight: 700;
  white-space: nowrap;
  background: transparent;
  border: 1px solid var(--window-edge);
  color: var(--window);
}

@media (pointer: coarse) {
  .desk-inv .desk-inv-pay {
    min-height: var(--tap);
    padding: 0 16px;
  }
}

@media (hover: hover) and (pointer: fine) {
  .desk-inv .desk-inv-pay:hover {
    border-color: var(--window);
    background: var(--window-tint);
  }
}

/* FIX-N6 §7: «Отменить расчёт» — тихое действие, а не вторая кнопка рядом с
   «Рассчитаться»: оно нужно редко и только чтобы исправить ошибку. Поэтому
   тот же вид, что у «Изменить»/«Удалить» у записи расхода, и место — правый
   край ВТОРОЙ строки карточки, рядом с «хранит депозиты»: на первой строке
   рядом с чипом «Выплачено» ему не хватало ширины узкой половины витрины на
   1440, и карточка уходила на третью строку (п. 104). Высота строки от него
   не растёт: 21px при строке 20, а не 44px общей кнопки. Цель касания
   добирается на телефоне, ниже в этом файле. */
.desk-inv .desk-inv-undo {
  flex: 0 0 auto;
  margin-left: auto;
  min-height: 0;
  padding: 0 2px;
  width: auto;
  font-size: 13px;
  line-height: 1.2;
  white-space: nowrap;
}

/* Подтверждение стоит на месте, под строкой карточки: два нажатия на самой
   кнопке (`confirmTwice`) вставляют эту строку сразу после неё. Своей строки
   витрина не отдаёт — строка живёт ровно те секунды, пока кнопка взведена. */
.desk-inv .confirm-note {
  flex: 1 1 100%;
  font-size: 13px;
  line-height: 1.3;
  color: var(--mist);
}

/* ============================================================
   6. Ленты депозитов
   ============================================================ */

/* Депозит — не доход и не расход (CONVENTIONS §4), поэтому он стоит за
   разделителем и в водопад не входит: полосы идут от левого края и без шва.
   Шкала общая с лестницей — именно так видно, что жильцам отдали больше, чем
   дом заработал (п. 102).

   DASH-5 (п. 104): «приняты · возвращены · удержано» — ОДНА строка из трёх
   значений, слово «Депозиты» стоит слева от неё, а не над ней. Столбиком три
   ленты занимали 198px и уводили конец витрины под сгиб. Столбцов ровно
   столько, сколько значений: `grid-auto-flow: column` — при двух значениях
   третьей пустой колонки не появляется. */
.desk-dep {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr);
  column-gap: 14px;
  align-items: start;
  margin-top: 10px;
  padding-top: 10px;
  border-top: 1px solid var(--border-subtle);
}

.desk-dep > .desk-side-title {
  margin: 0;
  padding-top: 2px;
}

/* Пояснение сервера и «за закрытый месяц не перенесены» — своей строкой под
   словом «Депозиты», а не в колонке значений: это фраза, а не цифра. */
.desk-dep > .desk-quiet {
  grid-column: 1 / -1;
  margin: 2px 0 0;
}

.desk-dep-rows {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  column-gap: 16px;
}

/* В узкой колонке подпись и сумма не встают в строку (« возвращены » и
   « 25 000 ₽ » вдвоём шире трети половины витрины) — поэтому здесь сумма
   стоит под словом, а не справа от него. */
.desk-dep .desk-bill-head {
  display: block;
}

.desk-dep-name {
  display: block;
  font-size: 13px;
  line-height: 1.3;
  color: var(--mist);
}

/* DEP-4 §3.3: переход «кому →» стоит на строке слова «возвращены» и высоту
   блока не меняет — общий `.subtle-btn` с его 44px и 16px здесь разогнал бы
   витрину под сгиб (п. 104). Цель касания добирается невидимой областью вокруг
   (`::after`), а не высотой строки: на телефоне блок депозитов тот же. */
.desk-dep-who {
  position: relative;
  display: inline;
  min-height: 0;
  padding: 0 0 0 6px;
  font-size: 13px;
  line-height: 1.3;
  white-space: nowrap;
}

.desk-dep-who:after {
  content: '';
  position: absolute;
  left: 0;
  right: -6px;
  top: 50%;
  height: var(--tap);
  transform: translateY(-50%);
}

/* На сенсорном экране цель касания — сама кнопка, а не невидимая область
   вокруг: там витрина и так прокручивается, и три лишних десятка пикселей у
   блока депозитов ничего не уводят за сгиб. */
@media (pointer: coarse) {
  .desk-dep-who {
    display: inline-flex;
    align-items: center;
    min-height: var(--tap);
  }

  .desk-dep-who:after {
    content: none;
  }
}

.desk-dep-sum {
  display: block;
  font-size: 17px;
  font-weight: 700;
  color: var(--tide);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.desk-dep .desk-bill-track {
  height: 4px;
  margin-top: 4px;
  border-radius: 2px;
}

.desk-dep .desk-bill-seg {
  border-radius: 2px;
}

.desk-dep-row--t0 .desk-bill-seg {
  background: var(--tide);
}

/* Тон, не новый цвет: 62 % бирюзы на подложке дорожки даёт 4,6:1. */
.desk-dep-row--t1 .desk-bill-seg {
  background: var(--tide);
  opacity: 0.62;
}

/* Пол лесенки: 50 % бирюзы на подложке дорожки даёт 3,45:1 — выше 3:1,
   требуемых для графики. Ниже опускаться нельзя. */
.desk-dep-row--t2 .desk-bill-seg {
  background: var(--tide);
  opacity: 0.5;
}

/* SETTLE-1: четвёртая лента — «к передаче». Это не ещё одно движение, а их
   итог, поэтому она отделена чертой слева: слева слагаемые, справа сумма.
   Цвет тот же бирюзовый, во всю силу, и сумма набрана жирнее — на неё
   смотрят на встрече. */
.desk-dep-row--net {
  padding-left: 13px;
  border-left: 1px solid var(--border-strong);
}

.desk-dep-row--net .desk-dep-sum {
  font-weight: 800;
  color: var(--tide);
}

.desk-dep-row--net .desk-bill-seg {
  background: var(--tide);
}

/* Состояние расчёта: чип с датой и «ещё не рассчитано» одной тихой строкой
   под лентами, во всю ширину блока. */
.desk-dep-state {
  grid-column: 1 / -1;
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 10px;
  margin: 6px 0 0;
  font-size: 13px;
  color: var(--mist);
}

.desk-dep .desk-dep-done {
  color: var(--leaf);
  background: var(--leaf-tint);
  border-color: var(--leaf-edge);
  font-weight: 700;
}

.desk-dep-pending b {
  margin-left: 4px;
  font-weight: 700;
  color: var(--soft);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* «Хранитель не записан» — не авария, а пробел в данных: тёплая глина, тот же
   тон, каким на этой странице помечено всё, что требует руки человека. */
.desk-dep-nobody {
  color: var(--clay);
}

/* ============================================================
   6б. Движение депозитов за месяц (SETTLE-1)
   ============================================================ */

/* Список свёрнут по умолчанию и на мониторе тоже (§3.1 задания): развёрнутым
   он возвращает витрине вертикальную прокрутку, от которой уходит п. 104.
   Поэтому это `<details>`, а не сворачиваемая панель из 18-panel-collapse.css:
   та на мониторе всегда открыта. Свёрнутый список стоит одной строкой в 26px
   и виден как дверь, а не как заголовок. */
.desk-moves {
  grid-column: 1 / -1;
  margin-top: 6px;
}

.desk-moves-head {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 26px;
  padding: 2px 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
  list-style: none;
  font-size: 13px;
  color: var(--soft);
}

.desk-moves-head::-webkit-details-marker {
  display: none;
}

.desk-moves-head:focus-visible {
  outline: var(--focus-width) solid var(--focus);
  outline-offset: var(--focus-offset);
}

/* Шеврон рисуется рамками, а не знаком шрифта: знак «▾» в Manrope сидит
   выше базовой линии и не совпадает по цвету с текстом. */
.desk-moves-head::before {
  content: '';
  flex: 0 0 auto;
  width: 6px;
  height: 6px;
  margin-right: 2px;
  border-right: 1.5px solid var(--mist);
  border-bottom: 1.5px solid var(--mist);
  transform: rotate(-45deg) translate(-1px, -1px);
}

.desk-moves[open] > .desk-moves-head::before {
  transform: rotate(45deg) translate(-1px, -1px);
}

/* Шеврон поворачивается за 160 мс общей кривой входа; выключатель движения и
   prefers-reduced-motion снимают `data-motion`, и поворот становится
   мгновенным. Само содержимое не выезжает: высота списка меняется сразу —
   задержка показа на витрине недопустима. */
html[data-motion='on'] .desk-moves-head::before {
  transition: transform 160ms var(--t-ease-out);
}

.desk-moves-title {
  font-weight: 700;
}

.desk-moves-count {
  color: var(--mist);
  font-variant-numeric: tabular-nums;
}

.desk-moves-body {
  padding-top: 4px;
}

.desk-moves-list {
  margin: 0;
  padding: 0;
  list-style: none;
}

/* Строка на событие: слова слева, деньги справа — тот же строй, что у записей
   расхода. Две строки одной квартиры идут подряд, порядок задаёт сервер. */
.desk-move {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 3px 0;
  border-bottom: 1px solid var(--border-subtle);
  font-size: 13px;
  color: var(--soft);
}

.desk-move:last-child {
  border-bottom: 0;
}

.desk-move-line {
  min-width: 0;
}

.desk-move b {
  flex: 0 0 auto;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Принято — деньги пришли, возвращено и удержано — ушли. Цвет берётся тот же,
   что у лент выше, чтобы строка и лента читались как одно. */
.desk-move--received b {
  color: var(--tide);
}

.desk-move--returned b,
.desk-move--withheld b {
  color: var(--clay);
}

/* Итог списка — то же равенство, что считают на бумаге. Стоит под чертой,
   как «Итого» в расходах дома. */
.desk-move-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 5px 0 0;
  padding-top: 5px;
  border-top: 1px solid var(--border-strong);
  font-size: 13px;
  color: var(--mist);
}

.desk-move-total b {
  font-weight: 700;
  color: var(--tide);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ============================================================
   7. Расходы дома и Доходы: общее
   ============================================================ */

/* Кромка сверху 2px — единственное, чем два блока отличаются друг от друга
   издалека: глина «потратили», зелёный «пришло». */
.desk-expenses {
  display: flex;
  flex-direction: column;
  border-top: 2px solid var(--clay-edge);
}

.desk-income {
  border-top: 2px solid var(--leaf-edge);
}

.desk-expenses .panel-head h2,
.desk-income .panel-head h2 {
  font-family: var(--font-display);
  font-style: italic;
  font-weight: 600;
  font-size: 17px;
  line-height: 1.25;
}

.desk-expenses .panel-head h2 {
  color: var(--clay);
}

.desk-income .panel-head h2 {
  color: var(--leaf);
}

/* Итог в заголовке блока — всегда виден, а не только у свёрнутой панели. */
.desk-sum {
  margin-left: 10px;
  font-size: 16px;
  font-weight: 700;
  color: var(--window);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.desk-total {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin: 8px 0 0;
  padding-top: 7px;
  border-top: 1px solid var(--border-strong);
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--soft);
}

.desk-total b {
  font-size: 17px;
  color: var(--window);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ============================================================
   8. Расходы дома: записи месяца
   ============================================================ */

.desk-more {
  margin: 5px 0 2px;
  padding: 4px 2px;
}

.desk-more .desk-more-close {
  display: none;
}

.desk-more.is-open .desk-more-open {
  display: none;
}

.desk-more.is-open .desk-more-close {
  display: inline;
}

/* Записи месяца (EXP-2/EXP-3, REQUIREMENTS.md п. 81–82): своими словами, за
   что был расход, когда и в какой квартире или на весь дом. Список — не
   таблица: строка складывается из слов через « · ». */
/* Зазора между записями нет: их и так разделяет черта (`border-bottom`), а
   на пяти записях каждые 2px — это 10px первого экрана (п. 104). */
.desk-expense-rows {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0;
}

/* DASH-5 (п. 104): «Изменить» и «Удалить» стоят в той же строке, справа от
   суммы, а не отдельным подвалом под записью: подвал добавлял каждой записи
   26px, и пять записей уводили итог блока под сгиб. Строка происхождения
   остаётся под записью — её не сокращают никогда (п. 81). */
.desk-expense-row {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  column-gap: 12px;
  align-items: baseline;
  padding: 5px 0;
  border-bottom: 1px solid var(--border-subtle);
}

.desk-expense-row > .desk-expense-line,
.desk-expense-row > .desk-feed-origin {
  grid-column: 1;
}

.desk-expense-row > .desk-expense-acts {
  grid-column: 2;
  grid-row: 1;
}

.desk-expense-row:last-child {
  border-bottom: 0;
}

/* Восьмая запись и глубже — за «Показать все (N)». */
.desk-expense-row.is-rest {
  display: none;
}

.desk-expenses.is-open .desk-expense-row.is-rest {
  display: grid;
}

.desk-expense-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: var(--text-small);
  color: var(--soft);
}

.desk-expense-line .money {
  color: var(--pearl);
  font-weight: 700;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Тихая строка происхождения записи (EXP-2, REQUIREMENTS.md п. 81):
   «перенесено из учётной книги, лист 09.26…». Она не сокращается никогда —
   это единственный ответ на вопрос «откуда взялись эти 14 698 ₽». */
.desk-feed-origin {
  display: block;
  margin: 1px 0 0;
  font-size: 13px;
  color: var(--mist);
}

.desk-expense-acts {
  display: flex;
  flex-wrap: wrap;
  gap: 0 12px;
  margin-top: 0;
}

.desk-expense-acts .subtle-btn {
  min-height: 26px;
  padding: 2px 2px;
  font-size: 13px;
}

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

/* ============================================================
   8б. Расходы дома: строки шаблонов (EXP-5)
   ============================================================ */

/* Слова владельца (REQUIREMENTS.md п. 100, самый плотный список экрана —
   п. 104): пустая строка шаблона 28px высотой, поле суммы 26px, шаг между
   строками 8px, кегли как у соседей (14px название, 13px поле и кнопка).
   Заполненный шаблон печатается тем же `.desk-expense-row`, что и обычная
   запись (`deskExpenseEntryRow` в 27-desk.js), — вторая копия его стилей
   здесь не заводится, список просто держит их в одном ритме через общий
   `gap`. */
.desk-template-rows {
  margin: 0 0 6px;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 8px;
}

.desk-template-row {
  min-height: 28px;
}

/* Форма несёт класс `.field` (18-hints.js/hintAudit — см. 27-desk.js,
   deskTemplateEmptyRow), а `.field` по умолчанию стоит столбиком
   (04-components.css) — здесь правило той же специфичности, но позже в
   каскаде, возвращает строку. */
.desk-template-row form {
  display: flex;
  flex-direction: row;
  align-items: center;
  gap: 8px;
}

/* Имя шаблона — оно же носитель единственной подсказки блока (`field-label`
   от fieldLabel(), см. 27-desk.js): свой класс только достраивает размер и
   усечение поверх типовых стилей подписи. */
.desk-template-name {
  flex: 1 1 auto;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--text-small);
  color: var(--soft);
}

.desk-template-name > span {
  overflow: hidden;
  text-overflow: ellipsis;
}

.desk-template-row input {
  flex: 0 0 90px;
  min-width: 0;
  min-height: 26px;
  padding: 2px 8px;
  border: 1px solid var(--border-field);
  border-radius: var(--radius-sm);
  background: var(--raised);
  color: var(--pearl);
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

.desk-template-row input:focus {
  border-color: var(--violet);
}

.desk-template-go {
  flex: 0 0 auto;
  min-height: 26px;
  padding: 2px 10px;
  font-size: 13px;
  color: var(--lavender);
  background: none;
  border: 0;
}

.desk-template-go:hover {
  color: var(--pearl);
}

.desk-template-row .inline-error {
  margin: 4px 0 0;
  font-size: 13px;
}

/* Восьмая строка и глубже — за той же «Показать все (N)», что и обычные
   записи: второе правило рядом с прежним для `.desk-expense-row.is-rest`
   (27-desk.js, deskTemplateRows()/deskExpenseEntries() ведут общий счёт). */
.desk-template-row.is-rest {
  display: none;
}

.desk-expenses.is-open .desk-template-row.is-rest {
  display: block;
}

@media (pointer: coarse) {
  .desk-template-row input,
  .desk-template-go {
    min-height: var(--tap);
  }
}

/* ============================================================
   9. Доходы: откуда пришли деньги
   ============================================================ */

.desk-income-rows {
  margin: 0;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 0;
}

.desk-income-row {
  padding: 5px 0;
  border-bottom: 1px solid var(--border-subtle);
}

.desk-income-row:last-child {
  border-bottom: 0;
}

.desk-income-line {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: var(--text-small);
}

.desk-income-name {
  display: flex;
  align-items: center;
  gap: 8px;
  min-width: 0;
  color: var(--soft);
}

.desk-income-line .money {
  font-weight: 700;
  color: var(--pearl);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.desk-income-more > summary {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 26px;
  font-size: 13px;
  color: var(--lavender);
  cursor: pointer;
}

.desk-income-more > summary::-webkit-details-marker {
  display: none;
}

.desk-income-more > summary::marker {
  content: '';
}

/* Уголок раскрытия — фигурой, а не символом шрифта: «▸» в Manrope нет, и
   браузер подставлял бы его из запасного шрифта другого кегля. */
.desk-caret {
  width: 0;
  height: 0;
  flex: 0 0 auto;
  border-style: solid;
  border-width: 4px 0 4px 6px;
  border-color: transparent transparent transparent currentcolor;
}

html[data-motion='on'] .desk-caret {
  transition: transform 120ms var(--t-ease-out);
}

.desk-income-more[open] > summary .desk-caret {
  transform: rotate(90deg);
}

@media (pointer: coarse) {
  .desk-income-more > summary {
    min-height: var(--tap);
  }
}

.desk-income-units {
  margin: 0 0 2px 16px;
  padding: 0;
  list-style: none;
  display: grid;
  gap: 2px;
}

/* NIGHT-QA-1 (тот же дефект, что gap2-F5, — найден при собственной проверке
   этого экрана, не в списке находок): `display: grid` тут тоже безусловный,
   как раньше было у `.detail-form` (06-dialogs.css). У закрытой раскрывашки
   «по квартирам» (`details.desk-income-more`, без [open]) список квартир всё
   равно был grid’ом реальных размеров — 690×49px на 768 — и накладывался на
   следующую строку начислений под ним (li.desk-income-row). Тот же приём,
   что в 06-dialogs.css: гасим только вложенный случай, у открытой
   раскрывашки `[open]` это правило не совпадает и список остаётся видимым. */
details:not([open]) .desk-income-units {
  display: none;
}

.desk-income-units li {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 2px 0;
  font-size: 13px;
  color: var(--mist);
}

.desk-income-units b {
  color: var(--soft);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ============================================================
   10. Полоса быстрого расхода (EXP-1, EXP-3, EXP-4)
   ============================================================ */

/* Решение владельца п. 73: «одним-двумя щелчками добавить расход и
   комментарий». Полоса выглядит как строка ввода, а не как карточка: рамка
   акцентом, поля в один ряд, кнопка справа. Поля — обычные `.field`, поэтому
   подсказки, ошибки и цели касания те же, что во всех формах системы.
   Полоса и её поля не анимируются никогда: задержка отклика на ввод
   недопустима. */
.desk-quick {
  padding: 7px 11px 9px;
  margin-bottom: 8px;
  border: 1px solid var(--violet-edge);
  border-radius: var(--radius-lg);
  background: var(--surface);
}

.desk-quick-form {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-end;
  gap: 4px 8px;
}

/* DASH-5 (п. 104): полоса записи — ОДНА строка высотой 36px. Раньше поля
   переносились на второй ряд и полоса занимала 232px из первого экрана.
   Подпись поля 13px, зазор до поля 3px, само поле 36px на мыши. Цель касания
   44px возвращается ниже — по `pointer: coarse` и по ширине телефона. */
.desk-quick .field {
  gap: 3px;
  font-size: 13px;
  /* Без этого `min-width: auto` берёт собственную ширину `<input>` (20
     знаков, 183px) за минимум поля, и «Записать» с «Ещё» уезжают на второй
     ряд даже там, где места хватает. Поля и так не сжимаются ниже своей
     основы: она задана ниже каждому из них. */
  min-width: 0;
}

.desk-quick .field input,
.desk-quick .field select {
  min-height: 36px;
  padding: 6px 10px;
  font-size: var(--text-small);
}

.desk-quick-house,
.desk-quick-unit {
  flex: 1 1 124px;
  max-width: 170px;
}

.desk-quick-sum {
  flex: 0 1 96px;
}

.desk-quick-note {
  flex: 3 1 150px;
}

.desk-quick-form > .primary {
  flex: 0 0 auto;
  min-height: 36px;
  padding: 6px 14px;
  font-size: 13px;
}

/* «Ещё: дата и статья» — тихой ссылкой в той же строке (п. 104), а не пятым
   полем в ряду: расход по всему дому и сегодняшним числом — обычный случай.
   Раскрытая, она забирает всю ширину: два редких поля в одну строку с
   четырьмя обычными не встанут. */
.desk-quick-more {
  flex: 0 1 auto;
  align-self: flex-end;
  margin: 0;
  padding: 0 2px;
}

.desk-quick-more[open] {
  flex: 1 1 100%;
  padding: 6px 10px;
}

.desk-quick-more .detail-form {
  gap: 6px 12px;
}

.desk-quick-more > summary {
  display: flex;
  align-items: center;
  min-height: 36px;
  font-size: 13px;
}

@media (pointer: coarse) {
  .desk-quick-more > summary {
    min-height: var(--tap);
  }
}

/* Ошибка сервера — над всей полосой, а не в одном её поле. */
.desk-quick .inline-error {
  flex: 1 1 100%;
  margin: 0;
}

@media (pointer: coarse) {
  .desk-quick-form > .primary,
  .desk-head-actions button {
    min-height: var(--tap);
  }
}

/* ============================================================
   11. Движение
   ============================================================ */

/* Волна появления играет один раз за открытие экрана: класс `.is-entering`
   снимает 27-desk.js по таймеру, длиннее самой волны. Пересчёт после записи
   расхода ничего не проигрывает — только изменившееся число коротко
   вспыхивает ореолом. Конечное состояние стоит в правилах выше, поэтому при
   выключенном движении витрина просто нарисована целиком. */
@keyframes desk-bill-grow {
  from {
    width: 0;
  }
}

/* Дуга растёт от своего начала: `stroke-dasharray` интерполируется, а неявный
   кадр 100 % берёт значение из атрибута SVG — поэтому конечное состояние
   остаётся тем, что нарисовал сервер, и переменных на это не нужно. */
@keyframes desk-arc-draw {
  from {
    stroke-dasharray: 0 402.12;
  }
}

/* Вспышка посадки главной цифры — один раз, после набега. */
@keyframes desk-net-land {
  0%,
  100% {
    text-shadow: var(--glow-window-text);
  }

  35% {
    text-shadow:
      var(--glow-window-text),
      0 0 34px var(--window-edge);
  }
}

/* Ореол пересчёта: 200 мс подтверждения «вот что изменилось». Это не анимация
   суммы — цифра уже стоит новая, набега при пересчёте нет. */
@keyframes desk-flash {
  from {
    background: var(--window-tint);
    box-shadow: 0 0 0 6px var(--window-tint);
  }

  to {
    background: transparent;
    box-shadow: 0 0 0 6px transparent;
  }
}

html[data-motion='on'] .desk-stage.is-entering .desk-bill-seg {
  animation: desk-bill-grow 520ms var(--t-ease-out) both;
}

html[data-motion='on'] .desk-stage.is-entering .desk-bill-row--out .desk-bill-seg {
  animation-delay: 60ms;
}

html[data-motion='on'] .desk-stage.is-entering .desk-bill-row--fee .desk-bill-seg {
  animation-delay: 120ms;
}

html[data-motion='on'] .desk-stage.is-entering .desk-bill-net .desk-bill-seg {
  animation-delay: 180ms;
}

html[data-motion='on'] .desk-stage.is-entering .desk-bill-row--aside .desk-bill-seg,
html[data-motion='on'] .desk-stage.is-entering .desk-dep-row .desk-bill-seg {
  animation-delay: 240ms;
}

html[data-motion='on'] .desk-stage.is-entering .desk-ring-arc {
  animation: desk-arc-draw 700ms var(--t-ease-out) both;
}

/* Первые два круга — ореол и дорожка, дуги начинаются с третьего. */
html[data-motion='on'] .desk-stage.is-entering .desk-ring-arc:nth-child(4) {
  animation-delay: 60ms;
}

html[data-motion='on'] .desk-stage.is-entering .desk-ring-arc:nth-child(5) {
  animation-delay: 120ms;
}

html[data-motion='on'] .desk-stage.is-entering .desk-ring-arc:nth-child(6) {
  animation-delay: 180ms;
}

html[data-motion='on'] .desk-stage.is-entering .desk-ring-arc:nth-child(7) {
  animation-delay: 240ms;
}

html[data-motion='on'] .desk-stage.is-entering .desk-ring-arc:nth-child(8) {
  animation-delay: 300ms;
}

html[data-motion='on'] .desk-stage.is-entering .desk-bill-net-value {
  animation: desk-net-land 700ms var(--t-ease-out) 900ms both;
}

html[data-motion='on'] .desk-ring-arc {
  transition: stroke-width 120ms var(--t-ease-out);
}

html[data-motion='on'] [data-desk-cell].is-updated {
  animation: desk-flash 200ms var(--t-ease-out) both;
  border-radius: var(--radius-sm);
}

/* Кнопка «Записать расход» подсвечивает полосу на секунду: видно, куда
   привели. Конечное состояние — обычная рамка, поэтому выключенное движение
   ничего не ломает. */
html[data-motion='on'] .desk-quick.is-picked {
  animation: desk-quick-pick 1000ms var(--t-ease-out) both;
}

@keyframes desk-quick-pick {
  from {
    border-color: var(--window-edge);
    box-shadow: 0 0 0 3px var(--window-tint);
  }

  to {
    border-color: var(--violet-edge);
    box-shadow: 0 0 0 3px transparent;
  }
}

/* ============================================================
   12. Планшет и узкий монитор: 1200
   ============================================================ */

@media (max-width: 1200px) {
  .desk-row {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Витрина в один столбец: лестница → доли → депозиты. Порядок здесь не тот,
     что на мониторе: там депозиты стоят под лестницей в левой половине, а в
     столбик их надо пропустить вперёд долей нельзя — после главной цифры
     человек ищет, кому она достанется. `display: contents` у левой половины
     распускает её содержимое в общий столбик, и порядок задаётся честно. */
  .desk-stage-grid {
    display: flex;
    flex-direction: column;
    /* `align-items: start` из правила для монитора в столбике означал бы
       «по левому краю, шириной по содержимому» — половины витрины сжались бы
       до ширины самой длинной строки. */
    align-items: stretch;
  }

  .desk-stage-bill {
    display: contents;
  }

  .desk-stage-bill > * {
    order: 1;
  }

  .desk-stage-bill > .desk-dep {
    order: 3;
  }

  .desk-stage-side {
    order: 2;
    margin: 12px 0 0;
    padding: 10px 0 0;
  }

  .desk-stage-side::before {
    left: 0;
    right: 0;
    top: 0;
    bottom: auto;
    width: auto;
    height: 1px;
    mask-image: linear-gradient(
      90deg,
      transparent,
      var(--pearl) 14%,
      var(--pearl) 86%,
      transparent
    );
  }
}

/* Промежуток 780–1200: кольцо и список долей стоят рядом — места хватает, а
   столбиком кольцо уводило бы список под сгиб. */
@media (min-width: 781px) and (max-width: 1200px) {
  .desk-stage-side {
    display: grid;
    grid-template-columns: minmax(0, 320px) minmax(0, 1fr);
    column-gap: 18px;
    align-items: start;
  }

  .desk-stage-side .desk-side-title {
    grid-column: 1 / -1;
  }

  .desk-ring {
    margin: 0;
  }
}

/* ============================================================
   12б. Монитор: список расходов прокручивается внутри панели
   ============================================================ */

/* FIX-N6 §6 и §7 («Бюджет высоты витрины», п. 104): страница управляющего по
   одному дому обязана открываться без вертикальной прокрутки. До сих пор это
   держалось на том, что записей мало: пять обычных записей уводили страницу
   на 176px за край экрана, пять «книжных» (со строкой происхождения) — на
   470px. Резать сами записи нельзя — строку «откуда взялись эти деньги» не
   сокращают никогда (п. 81). Поэтому за край уходит не страница, а список
   внутри панели.
   Считает высоту раскладка, а не число в разметке:
   `#content` растянут ровно от нижней кромки топбара до нижнего поля `main`
   (78 + 40 = 118px, `03-shell.css:220` и `:227`), страница — по нему,
   ряд «Расходы · Доходы» забирает остаток, панель расходов — высоту ряда, и
   до `.desk-expense-scroll` доходит ровно то, что осталось. Полоса записи
   сверху и «Итого» снизу остаются на месте: управляющий не ищет их
   прокруткой.
   Витрины это не касается вовсе — она выше по странице и свою высоту
   сохраняет; если она сама переросла экран, страница прокручивается
   по-прежнему.
   Порог 1201px, а не 781: ниже него витрина идёт одним столбцом (§12), блок
   расходов уезжает под неё, и страница длиннее экрана в любом случае — там
   внутренняя прокрутка только прятала бы записи, ничего не выигрывая. */
@media (min-width: 1201px) {
  #content:has(> .page.desk) {
    height: calc(100vh - 118px);
  }

  .page.desk {
    display: flex;
    flex-direction: column;
    height: 100%;
  }

  .page.desk > * {
    flex: none;
  }

  /* `0 1 auto` — не растёт, но сжимается: пока места хватает, ряд стоит своей
     высотой и ничего не меняется ни на пиксель. Селектор с родителем — не
     украшение: `.page.desk > *` выше весит два класса и без него перекрыл бы
     это правило. */
  .page.desk > .desk-row {
    flex: 0 1 auto;
    min-height: 0;
    /* Строка ряда — ровно по высоте ряда, а не по содержимому: иначе
       «100 %» у панели расходов означало бы «сколько получилось», и
       ограничивать было бы нечего. `minmax(0, …)` разрешает строке быть
       меньше содержимого — на этом всё и держится. */
    grid-template-rows: minmax(0, 1fr);
  }

  .desk-row > .desk-expenses {
    max-height: 100%;
  }

  .desk-expenses > .panel-body {
    display: flex;
    flex-direction: column;
    min-height: 0;
  }

  .desk-expenses > .panel-body > .panel-body-inner {
    display: flex;
    flex-direction: column;
    min-height: 0;
  }

  .desk-expense-scroll {
    flex: 0 1 auto;
    /* Пол — две строки списка: на низком экране (800px и меньше) витрина
       забирает столько, что на записи не остаётся ничего, и список схлопнулся
       бы в ноль. Тогда лучше вернуть странице прокрутку, чем спрятать записи
       совсем: пустое место на экране — не то же самое, что пустой список. */
    min-height: 56px;
    overflow-y: auto;
    /* Полоса прокрутки тихая и узкая: она здесь признак «список длиннее
       панели», а не орган управления, которым пользуются каждый день. */
    scrollbar-width: thin;
    scrollbar-color: var(--border-strong) transparent;
    /* Справа от полосы — воздух, иначе суммы упираются в неё. */
    padding-right: 4px;
    margin-right: -4px;
    /* Полосы прокрутки в браузере бывают накладными (места в раскладке не
       занимают и появляются только под курсором) — тогда о спрятанных
       записях ничто бы не говорило, а «Итого» под списком считало бы больше,
       чем видно. Поэтому у края стоит своя тень: два слоя-«крышки» цвета
       панели привязаны к содержимому (`local`) и уезжают вместе с ним, два
       слоя тени привязаны к рамке (`scroll`) и стоят на месте. Пока список
       не долистан, крышка ушла — видна тень; долистали до конца — крышка
       вернулась и тень закрыта. Приём чисто табличный, без скриптов и без
       движения, поэтому он не спорит с `prefers-reduced-motion`. */
    background:
      linear-gradient(var(--surface) 40%, rgb(20 24 48 / 0)) top / 100% 12px no-repeat local,
      linear-gradient(rgb(20 24 48 / 0), var(--surface) 60%) bottom / 100% 12px no-repeat local,
      linear-gradient(rgb(0 0 0 / 0.42), rgb(0 0 0 / 0)) top / 100% 10px no-repeat scroll,
      linear-gradient(rgb(0 0 0 / 0), rgb(0 0 0 / 0.42)) bottom / 100% 10px no-repeat scroll;
  }
}

/* ============================================================
   13. Телефон: столбик
   ============================================================ */

@media (max-width: 780px) {
  .page.desk {
    gap: 10px;
  }

  /* POL-6 22.7: 09-responsive.css разворачивает шапку экрана в столбец, и
     кнопка «Записать расход» стояла под ней отдельной строкой 44 + 6px —
     при свободных 182px из 358 в самой строке заголовка. Здесь шапка
     «Обзора» остаётся строкой: месяц с объектом слева, кнопка справа. */
  /* Раскладка сеткой, а не строкой: кнопке нужна первая строка рядом с
     месяцем, а строке объекта — вся ширина. Строкой (flex) они делили ширину
     втроём, и «Заселено 15 из 15» рвалось посреди числа. `display: contents`
     распускает обёртку месяца и строки объекта, чтобы оба попали в сетку
     по отдельности; разметку это не трогает, и печать заголовка
     (19-atmosphere.js) по-прежнему находит `h1` и `p.muted` на своих местах. */
  .desk > .page-heading {
    margin: 8px 0 0;
    display: grid;
    grid-template-columns: minmax(0, 1fr) auto;
    align-items: baseline;
    gap: 4px 10px;
  }

  .desk > .page-heading > div:first-child {
    display: contents;
  }

  .desk > .page-heading h1 {
    grid-column: 1;
  }

  .desk > .page-heading p.muted {
    grid-column: 1 / -1;
  }

  .desk-head-actions {
    grid-column: 2;
    grid-row: 1;
  }

  /* Кнопка записи — главное дело управляющего на объекте, поэтому она
     остаётся целью в 44px (REQUIREMENTS.md п. 71); кегль 13, как на
     мониторе, — в строке заголовка она подпись к действию, а не заголовок. */
  .desk-head-actions button {
    min-height: var(--tap);
    padding: 6px 14px;
    font-size: 13px;
  }

  .desk-stage {
    padding: 12px 13px 14px;
  }

  /* Все подписи помещаются по ширине панели, включая маленькие доли. */
  .desk-ring {
    width: 320px;
  }

  /* POL-6 22.6: «Пока пусто» 24px было самой крупной надписью экрана — при
     заголовке экрана 22 и заголовке панели 17 пустое состояние кричало
     громче всего, о чём говорить нечего. 18 — ступень заголовка панели по
     шкале раздела 1 POL-6. */
  .desk-bill-net-value--words {
    font-size: 18px;
  }

  /* POL-6 22.5, пересмотрено NIGHT-QA-1 (D1-O-1): тихие пояснения набирали
     восемь строк и 156px. Одна строка резала смысл — у «Вознаграждение
     управляющего известно не по всем объектам» обрезалось именно «Откройте
     объект — там оно есть» (что делать), а у «В расчёт вошли только
     объекты с назначенными долями» пропадал сам список домов, то есть суть
     сноски. `title` эту потерю не покрывает: по тапу на телефоне/планшете
     он не всплывает. Три строки — тот же потолок, что у `.banner`
     (04-components.css, 7.10): короткие двухпредложенческие пояснения
     помещаются целиком, а длинные сцепленные сноски всё равно не
     растягивают панель на восемь строк. Текст по-прежнему дублирован в
     `title` для мыши и читалки. */
  .desk-quiet {
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
  }

  /* NIGHT-QA-1 (D1-O-2): цель касания стрелки «→» перехода на «Моё
     вознаграждение» была 17×17 — `::after` набирал только высоту `--tap`,
     ширину не трогал (`right: -6px`), а сам layout-audit.mjs меряет
     `getBoundingClientRect()` настоящей кнопки, псевдоэлемент ему не виден.
     Здесь кнопка сама становится квадратом `--tap`, а отрицательные поля
     справа и сверху/снизу забирают лишнее место обратно — ступень лестницы
     по-прежнему не растёт (п. 104), стрелка на глаз остаётся той же
     стрелкой. Левое поле — 0, не отрицательное: первая правка сдвигала
     рамку кнопки на 8px влево, и она находила на подпись «Управляющему»
     (свой носитель подсказки, `field-label`) — тап по концу слова уводил на
     «Моё вознаграждение» вместо подсказки. Справа же после стрелки почти
     100px пустого места до суммы — есть куда расти без риска задеть цифру. */
  .desk-bill-goto {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: var(--tap);
    height: var(--tap);
    margin: -13px -27px -13px 0;
    padding: 0;
  }

  .desk-bill-goto::after {
    content: none;
  }

  /* Три значения депозитов на 390 в одну строку не встают: «возвращены» и
     «25 000 ₽» столбиком требуют 78px, трём столбцам нужно 260px, а слово
     «Депозиты» слева забирает ещё 80. Поэтому на телефоне слово встаёт над
     строкой, а сами значения делят ширину втроём. */
  .desk-dep {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 4px;
  }

  .desk-dep-rows {
    column-gap: 10px;
  }

  /* POL-6 22.4: «кому →» набирало по `pointer: coarse` высоту 44px прямо в
     подписи столбца «возвращены» — подпись становилась 61px против 17px у
     соседей, и её сумма садилась на 44px ниже двух других: три числа
     переставали читаться одной линией. Здесь возвращается тот же приём, что
     на мониторе: кнопка стоит в строку, а цель касания набирает невидимая
     область вокруг неё. Правило идёт после блока `pointer: coarse` выше и
     потому перекрывает его на ширине телефона. */
  .desk-dep-who {
    display: inline;
    align-items: initial;
    min-height: 0;
  }

  .desk-dep-who:after {
    content: '';
  }

  .desk-quick {
    padding: 8px 10px 10px;
  }

  /* На телефоне полоса становится столбиком, и это именно сетка, а не флексы:
     у флексов с основой 100 % минимальная ширина считается по содержимому, и
     полоса растягивала весь экран до 533px — на 390 появлялась боковая
     прокрутка (`REQUIREMENTS.md` п. 56: прокрутки быть не должно).
     `minmax(0, 1fr)` этого не позволяет по построению. */
  /* POL-6 22.2: зазор 4px между селектом «Квартира или дом?» (44px) и кнопкой
     «Записать» (44px) — промах по селекту отправлял форму. 8px — ступень
     лестницы отступов раздела 1 POL-6. */
  .desk-quick-form {
    display: grid;
    grid-template-columns: minmax(0, 1fr);
    gap: 8px;
  }

  .desk-quick-house,
  .desk-quick-unit,
  .desk-quick-sum,
  .desk-quick-note {
    max-width: none;
  }

  /* Цель касания 44px, а не 48: полоса стала плотнее, и запас в 4px — это
     ещё одна строка расходов на первом экране телефона (п. 104, «те же
     уменьшения, но цели касания 44px»). */
  .desk-quick-form > .primary {
    min-height: var(--tap);
  }

  /* POL-6 22.1: единственные поля системы мельче 16px — на iPhone экран
     приближался на каждом касании «Сколько, ₽» и «За что?», и управляющий
     возвращал масштаб руками после каждой записи расхода. 16px — пол шкалы
     для полей ввода (CONVENTIONS §8, комментарии в 17-mobile-input.css:117
     и :521). На мониторе остаются 14. */
  .desk-quick .field input,
  .desk-quick .field select {
    min-height: var(--tap);
    font-size: var(--text-body);
  }

  /* Кнопка карточки остаётся справа своей ширины: на всю ширину она добавляла
     каждому инвестору отдельную строку. */
  .desk-inv .desk-inv-pay {
    width: auto;
    margin-left: auto;
    min-height: var(--tap);
    padding: 0 14px;
  }

  /* FIX-N6 §7: цель касания «Отменить расчёт» — 44px, но набранная невидимой
     областью вокруг, а не высотой кнопки: кнопка стоит во второй строке
     карточки хранителя, и от её высоты выросла бы сама карточка. Приём тот
     же, что у «кому →» и у марки в шапке. */
  .desk-inv .desk-inv-undo {
    position: relative;
  }

  .desk-inv .desk-inv-undo::after {
    content: '';
    position: absolute;
    left: -6px;
    right: -2px;
    top: 50%;
    height: var(--tap);
    transform: translateY(-50%);
  }

  /* POL-6 22.3: карточка инвестора разваливалась на три строки — «имя · доля ·
     сумма» (308 из 310), «Выплатить» одна на второй и название дома на
     третьей; шесть инвесторов режима «все объекты» = 618px. Порядком узлов
     название дома переставлено на вторую строку, слева от кнопки: сама
     разметка не трогается (там порядок чтения — имя, доля, сумма, действие,
     приписки), меняется только порядок показа на телефоне. 103 → ≈72px. */
  .desk-inv-house {
    order: 1;
    flex: 0 1 auto;
    align-self: center;
  }

  .desk-inv .desk-inv-pay,
  .desk-inv .desk-inv-paid,
  .desk-inv .desk-inv-reason {
    order: 2;
  }

  .desk-inv-foot {
    order: 3;
  }

  .desk-inv-note,
  .desk-inv .confirm-note {
    order: 4;
  }

  /* Цели касания на телефоне добираются по ширине экрана, а не по `pointer:
     coarse`: на 390 это телефон, чем бы браузер ни назвал указатель, и
     приёмка DASH-4 мерит именно эту ширину. Правило ниже — последнее в файле,
     поэтому перекрывает и собственные 36px выше. */
  .desk-quick-more > summary,
  .desk-income-more > summary,
  .desk-expense-acts .subtle-btn {
    min-height: var(--tap);
  }

  /* На телефоне «Изменить» и «Удалить» возвращаются под запись: в правой
     колонке они забирали треть ширины, и «за что был расход» рвалось на пять
     строк. Экономия места на мониторе здесь ничего не даёт — страница на 390
     всё равно длиннее экрана. */
  .desk-expense-row {
    grid-template-columns: minmax(0, 1fr);
  }

  .desk-expense-row > .desk-expense-acts {
    grid-column: 1;
    grid-row: auto;
  }

  /* EXP-5 (п. 104: «те же уменьшения, но цели касания 44px»): строка
     шаблона в две линии — название переносится на всю ширину и уходит
     наверх, поле и «Записать» остаются вместе строкой ниже. Без переноса
     первая же длинная услуга («Уборка мест общего пользования») толкала бы
     поле за край экрана. */
  .desk-template-row form {
    flex-wrap: wrap;
  }

  .desk-template-name {
    flex: 1 1 100%;
    white-space: normal;
  }

  .desk-template-row input {
    flex: 1 1 auto;
    min-height: var(--tap);
  }

  .desk-template-go {
    flex: 0 0 auto;
    min-height: var(--tap);
  }
}

/* ============================================================
   14. Форма расчёта с хранителем депозитов (SETTLE-1)
   ============================================================ */

/* Форма — та же `ledgerEditor` из 10-ledger.js (второй формы для расчёта не
   заводится, §3.1 задания), и живёт она в общем диалоге. Стили стоят здесь, а
   не в 06-dialogs.css, по двум причинам: блок нужен ровно одной форме, которую
   открывает «Обзор», и 06-dialogs.css сейчас правит соседняя задача. Файл
   подключён позже диалогов, поэтому каскад складывается сам. */

.settle-sums {
  /* Диалог раскладывает поля в две колонки; блок величин идёт во всю ширину —
     иначе половина строки «Итого к передаче на встрече» висит в пустоте, а
     подпись и сумма жмутся друг к другу. */
  grid-column: 1 / -1;
  margin: 2px 0 0;
  padding: 10px 12px;
  border: 1px solid var(--border-subtle);
  border-radius: var(--radius-lg);
  background: var(--sunken);
}

.settle-sums-head {
  margin: 0 0 6px;
  font-size: var(--text-small);
  font-weight: 700;
  color: var(--soft);
}

.settle-sums dl {
  margin: 0;
}

/* Строка «подпись — сумма»: подпись тянется, сумма держит правый край.
   Точечного пунктира между ними нет — он читается как таблица, а здесь
   четыре величины, а не ведомость. */
.settle-sum {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 3px 0;
  font-size: var(--text-small);
  color: var(--soft);
}

.settle-sum dt {
  min-width: 0;
}

.settle-sum dd {
  margin: 0;
  font-weight: 700;
  color: var(--pearl);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Возвращённые депозиты уходят от хранителя — тот же знак и тот же цвет, что
   у «Расходов» на витрине. */
.settle-sum--out dd {
  color: var(--clay);
}

/* Итог встречи — то, ради чего форму открыли. Отделён чертой, набран крупнее
   слагаемых. Минус здесь обычное дело: платит инвестор, и слова об этом стоят
   строкой ниже на самой витрине. */
.settle-sum--total {
  margin-top: 4px;
  padding-top: 6px;
  border-top: 1px solid var(--border-strong);
  font-weight: 700;
  color: var(--pearl);
}

.settle-sum--total dd {
  font-size: 17px;
  color: var(--window);
}

.settle-note {
  margin: 6px 0 0;
  font-size: 13px;
  line-height: 1.35;
  color: var(--mist);
}

/* ============================================================
   15. Телефон: расчёт и движения депозитов (SETTLE-1)
   ============================================================ */

@media (max-width: 780px) {
  /* Четыре значения депозитов в одну строку на 390 не встают: трём уже нужно
     260px. Поэтому на телефоне слагаемые идут парами, а итог — своей строкой
     во всю ширину под чертой: он и есть ответ, ради которого читают блок. */
  .desk-dep-rows {
    grid-auto-flow: row;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    row-gap: 8px;
  }

  /* Черта слева на узком экране отрезала бы итог от соседней колонки, а не от
     слагаемых: здесь её место сверху и на всю ширину блока. */
  .desk-dep-row--net {
    grid-column: 1 / -1;
    padding-left: 0;
    padding-top: 7px;
    border-left: 0;
    border-top: 1px solid var(--border-strong);
  }

  /* На 390 карточка хранителя занимает три строки: «имя · доля · заработал»,
     кнопка и «на руки · хранит депозиты». Четырём величинам и кнопке одной
     строки не хватает по арифметике, а не по вёрстке: 32 + 40 + 100 + 119 и
     три промежутка по 10 — это 321px при доступных 308. Сжимать имя до
     многоточия ради одной строки хуже, чем перенести кнопку: имя человека
     читают, а кнопка и так остаётся целью в 44px прямо под суммой. */

  /* Цель касания у двери списка — 44px по ширине экрана, как и у остальных
     переключателей стола. */
  .desk-moves-head {
    min-height: var(--tap);
  }

  /* Строка движения на 390: слова переносятся, сумма остаётся справа на
     первой строке — её ищут глазами, а не читают. */
  .desk-move {
    flex-wrap: wrap;
    padding: 5px 0;
  }

  .desk-move-line {
    flex: 1 1 60%;
  }
}
