/* ЭЛИДОМ · ЛК собственника — мобильный адаптивный интерфейс.
   Дизайн-система на CSS-переменных, тёмная/светлая тема, интеграция темы
   Telegram (переменные --tg-* переопределяются из env.js). Без зависимостей. */

:root {
  --brand: #1f6feb;
  --brand-600: #1a5fd0;
  --ok: #1f9d55;
  --warn: #c98a00;
  --danger: #d9432f;
  /* Сиреневый: сумма начисления, закрытая приходом на расчётный счёт юрлица (ООО). */
  --bezn: #6b46c1;
  --bezn-bg: #ece3ff;

  --bg: #f2f4f7;
  --surface: #ffffff;
  --surface-2: #f7f8fa;
  --text: #16202c;
  --muted: #6a7684;
  --line: #e6e9ef;
  --shadow: 0 1px 2px rgba(16, 24, 40, .06), 0 6px 20px rgba(16, 24, 40, .05);

  --radius: 16px;
  --radius-sm: 10px;
  --bar-h: 56px;
  --tab-h: 62px;
  --maxw: 640px;

  --safe-top: env(safe-area-inset-top, 0px);
  --safe-bottom: env(safe-area-inset-bottom, 0px);
}

/* Тёмная тема — по атрибуту (мессенджер/тумблер) и по системной настройке */
:root[data-theme="dark"] {
  --bg: #0f141a; --surface: #171e27; --surface-2: #1e2732;
  --text: #e8edf3; --muted: #93a1b1; --line: #263140;
  --bezn: #d7c6ff; --bezn-bg: #352a52;
  --shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.35);
}
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0f141a; --surface: #171e27; --surface-2: #1e2732;
    --text: #e8edf3; --muted: #93a1b1; --line: #263140;
    --bezn: #d7c6ff; --bezn-bg: #352a52;
    --shadow: 0 1px 2px rgba(0,0,0,.4), 0 8px 24px rgba(0,0,0,.35);
  }
}

* { box-sizing: border-box; -webkit-tap-highlight-color: transparent; }
html, body { margin: 0; height: 100%; }
/* Полосу прокрутки окна не показываем — кабинет мобильный, прокрутка работает
   колесом/жестом (01.11.2026, просьба заказчика). Полосы внутри окон и таблиц
   остаются. */
html { scrollbar-width: none; -ms-overflow-style: none; }
html::-webkit-scrollbar { display: none; }
body {
  font-family: -apple-system, "Segoe UI", Roboto, "Montserrat", system-ui, sans-serif;
  background: var(--bg); color: var(--text);
  font-size: 15px; line-height: 1.4;
  overscroll-behavior-y: none;
}
a { color: inherit; text-decoration: none; }
h1, h2, h3, p { margin: 0; }
button, input { font: inherit; }

/* ── Каркас ─────────────────────────────────────────────────────────────── */
.app { max-width: var(--maxw); margin: 0 auto; min-height: 100%; position: relative; }

.app-bar {
  position: sticky; top: 0; z-index: 20;
  height: calc(var(--bar-h) + var(--safe-top)); padding-top: var(--safe-top);
  display: flex; align-items: center; gap: 6px; padding-inline: 8px;
  background: color-mix(in srgb, var(--surface) 88%, transparent);
  backdrop-filter: saturate(150%) blur(10px);
  border-bottom: 1px solid var(--line);
}
.app-bar h1 { flex: 1; font-size: 17px; font-weight: 700; letter-spacing: -.01em; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; min-width: 0; }
.app-bar-spacer { flex: 0 0 0; }
.icon-btn {
  border: 0; background: transparent; color: var(--text);
  width: 40px; height: 40px; border-radius: 12px; display: grid; place-items: center;
}
.icon-btn:active { background: var(--surface-2); }

/* `hidden` обязан побеждать собственный `display` кнопки.
   Браузерное правило [hidden] { display: none } — это обычный стиль, и `display: grid` выше
   его перебивает: скрытая кнопка продолжала показываться. Так и вышло со стрелкой «Назад» —
   на главной код честно ставил `back.hidden = true` (см. setHeader в js/views/owner.js), а
   стрелка оставалась на экране и вела в историю браузера, то есть из приложения наружу. */
.icon-btn[hidden] { display: none; }

.view {
  min-height: calc(100vh - var(--bar-h) - var(--tab-h));
  padding-bottom: calc(var(--tab-h) + var(--safe-bottom) + 12px);
}
.wrap { padding: 14px 14px 4px; display: flex; flex-direction: column; gap: 14px; }

/* ── Нижняя навигация ───────────────────────────────────────────────────── */
.tabbar {
  position: fixed; left: 0; right: 0; bottom: 0; z-index: 20;
  max-width: var(--maxw); margin: 0 auto;
  height: calc(var(--tab-h) + var(--safe-bottom)); padding-bottom: var(--safe-bottom);
  /* Колонок столько, сколько пунктов: у управляющего их пять (добавились
     «Заявки»), у остальных кабинетов четыре — жёсткие четыре роняли пятый
     пункт на вторую строку (25.09.2026). */
  display: grid; grid-auto-flow: column; grid-auto-columns: 1fr;
  background: color-mix(in srgb, var(--surface) 92%, transparent);
  backdrop-filter: saturate(150%) blur(10px);
  border-top: 1px solid var(--line);
}
.tabbar a {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  color: var(--muted); font-size: 11px; font-weight: 600;
}
.tabbar a.active { color: var(--brand); }
.tabbar a:active { opacity: .6; }

/* ── Главная ────────────────────────────────────────────────────────────── */
.greeting { display: flex; align-items: center; gap: 12px; }
.greeting-id { display: flex; align-items: center; gap: 12px; flex: 1; min-width: 0; color: inherit; text-decoration: none; }
.greeting-id:active { opacity: .7; }
.greeting-info { flex: 1; min-width: 0; }
.request-btn { flex: none; align-self: flex-start; gap: 4px; white-space: nowrap; }
.request-btn .ic { width: 16px; height: 16px; }
.greeting-name { font-size: 18px; font-weight: 700; }
.greeting-sub { color: var(--muted); font-size: 13px; }
.ok-text { color: var(--ok); }
.muted-text { color: var(--muted); }

.avatar {
  width: 46px; height: 46px; border-radius: 50%; flex: none;
  display: grid; place-items: center; font-weight: 700; color: #fff;
  background: linear-gradient(135deg, var(--brand), #7aa2ff);
}
.avatar.lg { width: 64px; height: 64px; font-size: 24px; }
.avatar.sm { width: 42px; height: 42px; font-size: 15px; }

.stat-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
/* Три числа в ряд — сводки, где четвёртой плитки не будет: на телефоне
   колонки узкие, поэтому отступы и шрифт числа чуть меньше. */
.stat-grid.stat-3 { grid-template-columns: repeat(3, 1fr); }
.stat-3 .stat { padding: 12px 10px; }
.stat-3 .stat-value { font-size: 18px; }
.stat-3 .stat-label { font-size: 12px; line-height: 1.25; }
.stat {
  position: relative;
  background: var(--surface); border-radius: var(--radius); padding: 14px;
  box-shadow: var(--shadow); border: 1px solid var(--line);
}
.stat-ic { position: absolute; top: 12px; right: 12px; color: var(--muted); opacity: .55; }
.stat-ic .ic { width: 22px; height: 22px; }
.stat-value { font-size: 20px; font-weight: 800; letter-spacing: -.02em; }
.stat-label { font-size: 13px; margin-top: 2px; }
.stat-sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.stat-breakdown { margin-top: 6px; display: flex; flex-direction: column; gap: 2px; }
.stat-breakdown div { display: flex; justify-content: space-between; gap: 6px; font-size: 12px; }
.stat-breakdown span { color: var(--muted); }
.stat-breakdown b { font-weight: 700; }
.stat.ok .stat-value { color: var(--ok); }
.stat.warn .stat-value { color: var(--warn); }
.stat.danger .stat-value { color: var(--danger); }

/* Кнопок в ряду стало шесть, и на телефоне они сжимались до неразборчивых
   столбиков — поэтому ряд переносится, а у кнопки есть минимальная ширина. */
.quick { display: flex; gap: 10px; flex-wrap: wrap; }
.quick .quick-btn { flex: 1 1 96px; }
.quick-btn {
  border: 1px solid var(--line); background: var(--surface); color: var(--text);
  border-radius: var(--radius-sm); padding: 12px 6px; display: flex; flex-direction: column;
  align-items: center; gap: 6px; font-size: 12px; font-weight: 600; cursor: pointer;
  box-shadow: var(--shadow);
}
.quick-btn:active { transform: scale(.97); }
.quick-btn .ic { color: var(--brand); }
.quick-btn span { display: flex; flex-direction: column; align-items: center; gap: 2px; }
/* Счётчик под подписью — только когда есть срочное: сколько регистраций
   истекает или уже просрочено. Кнопка при этом получает тревожный тон. */
.quick-btn small { font-size: 11px; font-weight: 600; color: var(--warn); }
.quick-btn.warn { border-color: var(--warn); }
.quick-btn.warn .ic { color: var(--warn); }

.section-title { font-size: 14px; font-weight: 700; color: var(--muted); margin-top: 4px; }

/* Широкая плитка «Лента событий» под 4 плитками.
   Светло-зелёная: оттенок замешивается на --ok поверх --surface, поэтому
   в тёмной теме тон приглушается сам. Первая строка — запасная для
   вебвью без color-mix. */
.feed-tile {
  display: flex; align-items: center; gap: 12px; padding: 16px 14px;
  background: #eaf7ee;
  background: color-mix(in srgb, var(--ok) 12%, var(--surface));
  border: 1px solid #c8e6d2;
  border-color: color-mix(in srgb, var(--ok) 28%, var(--line));
  border-radius: var(--radius);
  box-shadow: var(--shadow); font-weight: 700; font-size: 15px;
}
.feed-tile:active {
  background: #dcf0e3;
  background: color-mix(in srgb, var(--ok) 20%, var(--surface));
}
.feed-tile .ic { color: var(--ok); }
.feed-tile-label { flex: 1; }
.feed-tile > .ic:last-child { color: var(--muted); }

.feed-link {
  display: inline-flex; align-items: center; gap: 4px; align-self: center;
  color: var(--brand); font-size: 14px; font-weight: 600; padding: 6px 4px; margin-top: 2px;
}
.feed-link .ic { width: 16px; height: 16px; }

/* ── Списки / строки ────────────────────────────────────────────────────── */
.list { display: flex; flex-direction: column; gap: 8px; }
.list.menu { gap: 6px; }
.row {
  display: flex; align-items: center; gap: 12px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 12px; box-shadow: var(--shadow);
}
.row.link:active { background: var(--surface-2); }
.row-ic {
  width: 40px; height: 40px; flex: none; border-radius: 12px; display: grid; place-items: center;
  background: var(--surface-2); color: var(--brand);
}
.row-ic.tone-ok { color: var(--ok); }
.row-ic.tone-warn { color: var(--warn); }
.row-ic.tone-danger { color: var(--danger); }
.row-ic.tone-muted { color: var(--muted); }
.row-ic.tone-info { color: var(--brand); }
/* Карточки-строки часто сделаны кнопками, а у кнопки текст по умолчанию
   центрируется — из-за этого содержимое карточки лида стояло по центру. */
.row-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; text-align: left; }
.row-title { font-weight: 600; }
.row-sub { color: var(--muted); font-size: 13px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-end { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; text-align: right; }
.row-end small { color: var(--muted); font-weight: 500; }

/* ── Карточки объектов ──────────────────────────────────────────────────── */
.cards { gap: 12px; }
.card {
  display: block; background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden; box-shadow: var(--shadow);
}
.card.link:active { transform: scale(.99); }
.card-photo {
  height: 150px; background-size: cover; background-position: center; background-color: var(--surface-2);
  position: relative; display: flex; align-items: flex-start; gap: 6px; padding: 10px;
}
.card-body { padding: 12px; display: flex; flex-direction: column; gap: 4px; }
.card-title { font-weight: 700; font-size: 16px; }
.card-addr { color: var(--muted); font-size: 13px; }
.card-meta { font-size: 13px; color: var(--muted); }
/* Вторая строка характеристик (собственник) — ещё мельче: заголовок карточки
   называет объект, всё остальное только уточняет. */
.card-meta + .card-meta { font-size: 12px; }
.card-foot { display: flex; align-items: center; justify-content: space-between; margin-top: 6px; }
/* Плитки в ряду — одной высоты: карточка занимает всю ячейку сетки, содержимое
   растягивается, а цена с шильдиками прижата к низу. Иначе соседние плитки
   разъезжались из-за разной длины адреса и числа шильдиков состояния. */
.cards { align-items: stretch; }
.cards .card { display: flex; flex-direction: column; height: 100%; }
.cards .card > .card-body { flex: 1 1 auto; }
.cards .card > .card-body > .card-foot { margin-top: auto; }
.card-photo { flex: none; }
/* Объект без снимков: заглушка той же высоты — пустое место в ряду читается
   как сломанная вёрстка, а не как «фотографий ещё нет». */
.card-photo.empty { background: var(--surface-2); color: var(--muted); font-size: 12px; }
.card-photo .cover-none { position: absolute; inset: 0; display: grid; place-items: center; }
/* Шильдики состояния поверх обложки — левым верхним углом; справа сверху стоит
   кнопка «⋮», поэтому ширина ограничена так, чтобы длинные («Поиск 2,3,4,6» +
   «покомнатно») переносились вниз, а не под кнопку. Тень нужна на светлых
   снимках: без неё бледный шильдик тонул в фотографии. */
.card-chips {
  display: flex; flex-wrap: wrap; justify-content: flex-start;
  gap: 4px; max-width: calc(100% - 34px);
}
.card-chips .chip { box-shadow: 0 1px 4px rgba(0, 0, 0, .28); }
.card-foot-chips { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 4px; }
/* Плитка с обложкой: состояние показываем только сверху, внизу оно дублировало бы себя. */
.card.has-cover .card-foot-chips { display: none; }
/* Список строками: снимок узкий, шильдики возвращаются к цене. */
.cards.rows .card.has-cover .card-chips { display: none; }
.cards.rows .card.has-cover .card-foot-chips { display: flex; }
/* Обложка объекта в списке — в полтора раза выше обычного превью (150 → 225):
   квартиру выбирают по снимку, и в общей ленте он должен читаться. Отдельный
   класс, чтобы не тянуть за собой превью комнат и карточки других кабинетов. */
.card-photo.cover { height: 225px; }

/* ── Карта объектов ───────────────────────────────────────────────────────
   Портфель — это точки на местности: по списку адресов район в голове держат
   только те, кто в нём работает. Высота задана явно: у контейнера карты нет
   своего содержимого, и без неё Mapbox рисует полосу в ноль пикселей. */
/* Ширину задаём явно: Mapbox рисует полотно по размеру контейнера, и без
   `width: 100%` в широком режиме карта занимала левую половину блока. Высота
   тоже обязательна — своего содержимого у контейнера нет. */
.map-box { width: 100%; height: 420px; border-radius: var(--radius); overflow: hidden; border: 1px solid var(--line); }
.map-box.small { height: 260px; }
/* На мониторе карту смотрят как карту: в полосе 420 px район не разглядеть. */
@media (min-width: 900px) {
  .map-box { height: 520px; }
  .map-box.small { height: 320px; }
}
/* Само полотно карты растягивать стилями НЕЛЬЗЯ: у canvas есть свой размер в
   пикселях, и `width: 100%` не перерисует карту, а размажет её. Ширину
   выправляет `map.resize()` в js/map.js — он пересчитывает полотно по-честному. */
.map-box .mapboxgl-map { width: 100%; height: 100%; }
.map-load, .map-none {
  height: 100%; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; text-align: center; padding: 16px; background: var(--surface-2); color: var(--muted);
}
.map-none b { color: var(--ink); }
.map-none span { font-size: 13px; max-width: 420px; }
/* Маркер: кружок с обводкой — на снимке карты он читается и на светлом, и на
   тёмном; цвет говорит о состоянии объекта. */
.map-pin {
  width: 16px; height: 16px; border-radius: 50%; border: 2px solid #fff;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .35); cursor: pointer;
}
.map-pop { min-width: 180px; }
.map-pop-title { font-weight: 700; margin-bottom: 2px; }
.map-pop-sub { color: var(--muted); font-size: 12px; }
.map-pop-price { margin-top: 4px; font-weight: 600; }
.map-pop-link { display: inline-block; margin-top: 6px; }
/* Легенда под общей картой: цвет маркера сам по себе ничего не говорит. */
/* Ряд под картой: «показать все» и прочие действия. */
.map-actions { display: flex; gap: 8px; margin-top: 8px; }
.map-legend { display: flex; flex-wrap: wrap; gap: 10px; margin: 8px 0 4px; font-size: 12px; color: var(--muted); }
.map-legend i { display: inline-block; width: 10px; height: 10px; border-radius: 50%; margin-right: 4px; }

/* ── Адрес по справочнику ─────────────────────────────────────────────────
   Поле адреса само не набирается: оно открывает окно с пошаговым выбором
   (город → населённый пункт → улица → дом). Введённый руками адрес не находит
   ни геокодер площадки, ни поиск в кабинете, поэтому ввод строкой оставлен
   только внутри окна, отдельной кнопкой. */
.addr-pick { display: flex; gap: 8px; align-items: center; }
.addr-pick .fld-input { flex: 1 1 auto; min-width: 0; cursor: pointer; background: var(--surface); }
.addr-pick .btn { flex: none; }
.ap-step { margin-bottom: 12px; }
.ap-step.off { opacity: .5; }
.ap-label { font-size: 13px; color: var(--muted); margin-bottom: 4px; }
.ap-picked { display: flex; align-items: center; justify-content: space-between; gap: 8px;
  background: var(--surface-2); border-radius: var(--radius); padding: 8px 10px; }
.ap-wait { font-size: 13px; color: var(--muted); padding: 6px 2px; }
/* Список подсказок: короткий, с прокруткой — на «мал» по Петербургу приходит
   два десятка улиц, и окно от них уезжало бы за экран. */
.ap-list { max-height: 210px; overflow-y: auto; }
.ap-list:not(:empty) { border: 1px solid var(--line); border-radius: var(--radius); margin-top: 6px; }
.ap-opt {
  display: flex; flex-direction: column; gap: 2px; width: 100%; text-align: left;
  background: none; border: 0; border-bottom: 1px solid var(--line); cursor: pointer;
  padding: 9px 10px; font: inherit; color: inherit;
}
.ap-opt:last-child { border-bottom: 0; }
.ap-opt:hover, .ap-opt:focus-visible { background: var(--surface-2); }
.ap-opt small { color: var(--muted); font-size: 12px; }
/* Собранная строка — под шагами: видно, что именно уйдёт в карточку. */
.ap-preview { margin: 10px 0 4px; }
.ap-line { background: var(--surface-2); border-radius: var(--radius); padding: 10px; font-weight: 600; }
.ap-map-wrap { margin: 6px 0 2px; }
.ap-map-wrap .block { width: 100%; }
.ap-map { height: 240px; margin-top: 8px; border-radius: var(--radius); overflow: hidden; }
.ap-map[hidden] { display: none; }
.ap-map-note { font-size: 12px; margin-top: 6px; }

/* Лента снимков прямо в плитке списка: обложка листается стрелками на
   компьютере и свайпом на телефоне. Прокрутка нативная со «снимком по месту»
   (scroll-snap) — жест тогда обрабатывает сам браузер и не превращается в
   переход по ссылке карточки. */
.card-photo.gal { padding: 0; overflow: hidden; }
.gal-track {
  position: absolute; inset: 0; display: flex; overflow-x: auto; overflow-y: hidden;
  scroll-snap-type: x mandatory; scrollbar-width: none; -ms-overflow-style: none;
  /* Горизонтальный жест — ленте, вертикальный — странице: без этого список
     переставал прокручиваться пальцем, попавшим на снимок. */
  touch-action: pan-x pan-y;
}
.gal-track::-webkit-scrollbar { display: none; }
.gal-slide {
  flex: 0 0 100%; width: 100%; height: 100%; object-fit: cover;
  scroll-snap-align: center; scroll-snap-stop: always; user-select: none;
}
/* Стрелки — по краям снимка, поверх ленты. Кружок с подложкой: на светлой
   фотографии белая стрелка тонет, на тёмной — тёмная. */
.gal-nav {
  position: absolute; top: 50%; transform: translateY(-50%); z-index: 2;
  width: 30px; height: 30px; border: 0; border-radius: 50%; cursor: pointer;
  background: rgba(20, 24, 30, .5); color: #fff; font-size: 20px; line-height: 1;
  display: grid; place-items: center; padding: 0 2px 2px;
}
/* Пока на карточку не навели, стрелки приглушены: в ряду плиток десяток
   снимков, и десяток ярких кнопок поверх них читается как рябь. */
.gal-nav { opacity: .45; transition: opacity .15s ease, background .15s ease; }
.card:hover .gal-nav, .gal-nav:focus-visible { opacity: 1; }
.gal-nav:hover { background: rgba(20, 24, 30, .72); }
.gal-nav.prev { left: 6px; }
.gal-nav.next { right: 6px; }
/* На сенсорных экранах стрелок нет: там листают пальцем, а кнопки только
   закрывают снимок. */
@media (hover: none) {
  .gal-nav { display: none; }
}
.gal-count {
  position: absolute; right: 8px; bottom: 8px; z-index: 2;
  background: rgba(20, 24, 30, .55); color: #fff; border-radius: 10px;
  padding: 2px 8px; font-size: 12px; line-height: 1.5;
}
/* Шильдики состояния лежат поверх ленты — им нужен свой отступ: у самой
   обложки padding снят, иначе снимки не занимали бы её целиком. */
.card-photo.gal > .card-chips { position: absolute; top: 10px; left: 10px; z-index: 2; }

/* Список строками: обложка узкой колонкой слева, длинные адреса не переносятся —
   в таком виде портфель просматривают глазами сверху вниз. */
.list.cards.rows { display: flex; flex-direction: column; gap: 8px; }
.cards.rows .card { flex-direction: row; align-items: stretch; }
.cards.rows .card-photo { width: 156px; height: auto; min-height: 144px; }
/* В режиме списка снимок — узкая колонка 156 px: стрелки и счётчик в ней
   закрывают собой фотографию, поэтому листается он только пальцем. */
.cards.rows .gal-nav, .cards.rows .gal-count { display: none; }
.cards.rows .card-body { min-width: 0; flex: 1 1 auto; padding: 10px 44px 10px 12px; }
.cards.rows .card-title, .cards.rows .card-addr, .cards.rows .card-meta {
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.cards.rows .card-foot { flex-wrap: wrap; gap: 6px; }

/* Строка «Найдено …» и переключатель вида. */
.list-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.view-switch { display: flex; gap: 4px; flex: none; }
.vs-btn {
  width: 32px; height: 28px; border-radius: 8px; cursor: pointer; line-height: 1;
  border: 1px solid var(--line); background: var(--surface); color: var(--muted); font-size: 14px;
}
.vs-btn.active { background: var(--brand); border-color: var(--brand); color: #fff; }
.price { font-weight: 800; font-size: 17px; }
.price small { color: var(--muted); font-weight: 600; font-size: 12px; }
/* Доход собственника — вторая строка под ценой: цифра внутренняя, не для объявления. */
.price-sub { display: block; font-size: 11px; font-weight: 600; color: var(--muted); }
.hero-sub { font-size: 12px; color: var(--muted); margin: -2px 0 10px; padding: 0 2px; }

.chip {
  font-size: 11px; font-weight: 700; padding: 4px 9px; border-radius: 999px;
  background: rgba(0,0,0,.55); color: #fff;
}
/* Размытие фона — только шильдикам поверх снимков (обложка, постер). У общего
   .chip backdrop-filter на Android Chrome размывал САМ текст в обычных карточках
   (материалы объекта: название, метка, чипы «С / Ар» — 29.09.2026). */
.hero .chip, .card-photo .chip, .card-chips .chip { backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); }
.chip.ok { background: var(--ok); }
.chip.warn { background: var(--warn); }
.chip.danger { background: var(--danger); }
.chip.muted { background: rgba(0,0,0,.45); }
/* Синий — «в работе»: документы собраны, заявление подано. Без него такие
   шильдики рисовались обычным тёмным и не отличались от прочих. */
.chip.info { background: var(--brand); }
.chip.room { background: #8b5cf6; }

.badge { font-size: 11px; font-weight: 700; padding: 3px 8px; border-radius: 999px; background: var(--surface-2); color: var(--muted); }
.badge.ok { background: color-mix(in srgb, var(--ok) 16%, transparent); color: var(--ok); }
.badge.warn { background: color-mix(in srgb, var(--warn) 18%, transparent); color: var(--warn); }
.badge.danger { background: color-mix(in srgb, var(--danger) 15%, transparent); color: var(--danger); }
.badge.info { background: color-mix(in srgb, var(--brand) 15%, transparent); color: var(--brand); }
.rating { color: var(--warn); font-size: 12px; font-weight: 700; }

/* ── Карточка объекта: hero + под-вкладки ───────────────────────────────── */
.hero {
  height: 200px; border-radius: var(--radius); overflow: hidden; position: relative;
  background-size: cover; background-position: center; background-color: var(--surface-2);
  display: flex; align-items: flex-end;
}
.hero-grad { position: absolute; inset: 0; background: linear-gradient(to top, rgba(0,0,0,.72), rgba(0,0,0,0) 60%); }
/* Объект без снимка (06.11.2026, скрин заказчика): на светлой заглушке с
   затемнением снизу белое название и шильдики сливались с фоном. */
.hero.no-photo { background-color: #56636f; }
.hero.no-photo .hero-grad { display: none; }
/* Трубка в кружке справа внизу обложки — контакты объекта и звонок (06.11.2026). */
.hero-call { position: absolute; right: 12px; bottom: 12px; z-index: 3;
  width: 44px; height: 44px; border-radius: 50%; border: 0; cursor: pointer;
  display: grid; place-items: center; color: #fff; background: rgba(0,0,0,.42);
  backdrop-filter: blur(2px); -webkit-backdrop-filter: blur(2px); transition: background .15s; }
.hero-call:hover, .hero-call:active { background: var(--brand); }
.hero-call svg { width: 20px; height: 20px; }
/* Полоса снимков в шапке объекта (16.10.2026, просьба заказчика): сколько
   кадров влезло по ширине, столько и показано. Минимальная ширина кадра
   решает, сколько их будет: на телефоне два, на мониторе четыре-пять;
   лишние обрезаются краем полосы. */
.hero.strip { align-items: stretch; gap: 4px; background: none; }
.hero-shot { position: relative; flex: 1 0 min(100%, 260px); min-width: 0;
  background-size: cover; background-position: center; background-color: var(--surface-2); cursor: zoom-in; }
.hero-shot.first { display: flex; align-items: flex-end; }
.hero-info { position: relative; padding: 14px; color: #fff; display: flex; flex-direction: column; gap: 6px; flex: 1; min-width: 0; }
/* Шильдики состояния на обложке — одним рядом и по содержимому. Прямыми детьми
   колонки они растягивались на всю ширину постера: «покомнатно» превращалось в
   фиолетовую полосу через весь снимок. Ряд прижат влево (`align-self`), сами
   шильдики одной длины (`min-width` + центр) — вразнобой они читаются как
   случайные метки, а не как состояние объекта. */
.hero-chips { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; align-self: flex-start; max-width: calc(100% - 34px); }
.hero-chips .chip { display: inline-flex; align-items: center; justify-content: center; min-width: 104px; text-align: center; }
.hero-chips .chip-switch { display: inline-flex; gap: 6px; }
/* Шильдик, который переключает статус. Отдельный класс, а не `.chip-btn`: тот
   в кабинете давно занят кнопкой-таблеткой с рамкой, и шильдики состояния
   получали от неё обводку и белый фон. Здесь кнопка — прозрачная обёртка: весь
   вид даёт сам `.chip` внутри. Обводку фокуса тоже убираем — на цветном чипе
   она читается как рамка вокруг статуса. */
.chip-switch {
  background: none; border: 0; padding: 0; margin: 0; font: inherit; color: inherit;
  cursor: pointer; outline: none; -webkit-tap-highlight-color: transparent;
  display: inline-flex; align-items: center; gap: 6px;
}
.chip-switch:hover .chip { filter: brightness(1.08); }
/* Строка списка, которая сама действие: выбор комнаты в окне «Чей статус
   меняем». Вид строки, поведение кнопки — поэтому ни рамки, ни фона кнопки. */
.row-btn {
  display: flex; align-items: center; justify-content: space-between; gap: 10px;
  width: 100%; text-align: left; background: none; border: 0; border-bottom: 1px solid var(--line);
  padding: 10px 2px; font: inherit; color: inherit; cursor: pointer;
}
.row-btn:last-child { border-bottom: 0; }
/* Панель над матрицей размещения: слева корзины, справа поиск. На телефоне
   поиск уходит под шильдики — в строку они вдвоём не помещаются. */
.am-bar { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 10px 0 6px; }
.am-bar .filter-chips { margin: 0; flex: 1 1 auto; }
.am-search { flex: 0 1 260px; min-width: 180px; }
.row-btn:hover { background: var(--surface-2); }

/* Действия на постере, справа внизу: слайдшоу, рекламное видео, 3D-тур.
   Не absolute, а сосед .hero-info в той же flex-строке — тогда длинный
   адрес не заезжает под кнопки, а ужимается. */
.hero-actions { position: relative; padding: 14px; display: flex; gap: 8px; flex: 0 0 auto; }
.hero-act {
  width: 38px; height: 38px; padding: 0; border: 0; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(0, 0, 0, .45); color: #fff; cursor: pointer;
  backdrop-filter: blur(6px); -webkit-backdrop-filter: blur(6px);
}
.hero-act:active { background: rgba(0, 0, 0, .68); transform: scale(.94); }
.hero-act .ic { width: 20px; height: 20px; }

/* Слайдшоу по фото квартиры */
.lightbox {
  position: fixed; inset: 0; z-index: 60; background: rgba(0, 0, 0, .94);
  display: flex; align-items: center; justify-content: center;
  padding-top: var(--safe-top); padding-bottom: var(--safe-bottom);
}
.lb-img { max-width: 100%; max-height: 100%; object-fit: contain; display: block; }
.lb-counter {
  position: absolute; top: calc(12px + var(--safe-top)); left: 50%; transform: translateX(-50%);
  color: #fff; font-size: 13px; font-weight: 600; opacity: .85;
}
.lb-close, .lb-nav {
  position: absolute; width: 40px; height: 40px; padding: 0; border: 0; border-radius: 999px;
  display: inline-flex; align-items: center; justify-content: center;
  background: rgba(255, 255, 255, .14); color: #fff; cursor: pointer;
}
.lb-close { top: calc(10px + var(--safe-top)); right: 12px; }
.lb-close .ic { transform: rotate(45deg); }
.lb-nav.prev { left: 10px; top: 50%; margin-top: -20px; }
.lb-nav.next { right: 10px; top: 50%; margin-top: -20px; }
.lb-close:active, .lb-nav:active { background: rgba(255, 255, 255, .28); }
.hero-title { font-size: 20px; font-weight: 800; }
.hero-addr { font-size: 13px; opacity: .92; }
/* Отступы обязательны: без них шильдики стояли вплотную к шапке и сливались с ней. */
.hero-meta { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 8px; }
.pill { font-size: 12px; font-weight: 600; padding: 6px 10px; border-radius: 999px; background: var(--surface); border: 1px solid var(--line); }

.subtabs {
  display: flex; flex-wrap: wrap; gap: 6px; padding-bottom: 2px;
}
.subtabs a {
  flex: none; font-size: 13px; font-weight: 600; color: var(--muted);
  padding: 8px 12px; border-radius: 999px; background: var(--surface); border: 1px solid var(--line);
}
.subtabs a.active { color: #fff; background: var(--brand); border-color: var(--brand); }
/* Пометка «(есть действующий)» рядом с неподписанным агентским договором. */
.doc-active-warn { color: var(--danger); font-weight: 700; font-size: 12px; white-space: nowrap; }
/* Договор «на подпись» — выделяем и поднимаем наверх списка документов объекта. */
.card-flat.doc-sent { border-left: 3px solid var(--warn); }
/* Модалка «Договоры на подписи» (по баннеру на главной управляющего). */
.tosign-list { display: flex; flex-direction: column; gap: 10px; max-height: 62vh; overflow-y: auto; margin: 4px 0 10px; }
.tosign-card { display: block; text-decoration: none; color: inherit; }
.tosign-card:active { transform: translateY(1px); }
.cc-open { display: flex; align-items: center; gap: 6px; margin-top: 10px; color: var(--brand); font-weight: 600; font-size: 13px; }
.cc-open .ic { color: var(--brand); }

.card-flat { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px; box-shadow: var(--shadow); }
.para { margin: 0 0 8px; }
.mini-title { font-size: 13px; font-weight: 700; color: var(--muted); margin: 10px 0 6px; }
.kv { margin-top: 10px; border-top: 1px solid var(--line); }
.kv-row { display: flex; justify-content: space-between; gap: 12px; padding: 9px 0; border-bottom: 1px solid var(--line); font-size: 14px; }
.kv-row span { color: var(--muted); }

/* ── Счётчики ───────────────────────────────────────────────────────────── */
.meter-card { display: flex; flex-direction: column; gap: 4px; }
.meter-card .kv { margin-top: 6px; }
.meter-awaiting {
  display: flex; align-items: center; gap: 8px; margin-top: 4px;
  background: color-mix(in srgb, var(--warn) 14%, transparent); color: var(--warn);
  border-radius: var(--radius-sm); padding: 9px 12px; font-size: 13px; font-weight: 600;
}
.meter-awaiting .ic { width: 18px; height: 18px; }
.meter-note-head { display: flex; align-items: center; justify-content: space-between; margin-top: 12px; }
.hint { font-weight: 500; color: var(--muted); }
.hist-badges { display: flex; flex-wrap: wrap; gap: 4px; justify-content: flex-end; align-items: center; flex: none; max-width: 50%; }
.row-pending { background: color-mix(in srgb, var(--danger) 7%, var(--surface)); border-color: color-mix(in srgb, var(--danger) 30%, var(--line)); }
.await-dot { color: var(--danger); font-size: 10px; vertical-align: 1px; }
.link-btn {
  border: 0; background: transparent; color: var(--brand); cursor: pointer;
  display: inline-flex; align-items: center; gap: 4px; font-size: 13px; font-weight: 600; padding: 4px;
}
.link-btn .ic { width: 15px; height: 15px; }
.histRow-photo { color: var(--muted); }
.row-sub .ic { display: inline-block; width: 13px; height: 13px; vertical-align: -2px; }

/* ── Кнопки ─────────────────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  border: 0; border-radius: 12px; padding: 10px 14px; font-weight: 700; cursor: pointer;
  background: var(--brand); color: #fff;
}
.btn[hidden] { display: none; }
.btn:active { background: var(--brand-600); }
.btn.sm { padding: 7px 11px; font-size: 13px; border-radius: 10px; }
.btn.ghost { background: var(--surface-2); color: var(--text); border: 1px solid var(--line); }
.btn.block { width: 100%; margin-top: 8px; }
/* Зелёная кнопка-статус: приход распределён целиком (раздел «Распределение по
   начислениям»). Обычная кнопка — брендовая синяя; .ok делает её зелёной. */
.btn.ok { background: var(--ok); }
.btn.ok:active { background: color-mix(in srgb, var(--ok) 85%, #000); }

/* ── Профиль ────────────────────────────────────────────────────────────── */
.profile-head { display: flex; align-items: center; gap: 14px; padding: 4px 0 6px; }
/* «Изменить имя» — к правому краю строки с именем и ролью. */
.profile-edit { margin-left: auto; flex: 0 0 auto; }
.profile-name { font-size: 19px; font-weight: 800; }

/* ── Чат ────────────────────────────────────────────────────────────────── */
.chat-screen { display: flex; flex-direction: column; height: calc(100vh - var(--bar-h) - var(--tab-h) - var(--safe-top)); }
.chat-log { flex: 1; overflow-y: auto; padding: 14px; display: flex; flex-direction: column; gap: 8px; }
.bubble { max-width: 78%; padding: 9px 12px; border-radius: 16px; box-shadow: var(--shadow); }
.bubble-text { font-size: 14px; }
.bubble-time { font-size: 10px; color: var(--muted); margin-top: 3px; text-align: right; }
.bubble.them { align-self: flex-start; background: var(--surface); border: 1px solid var(--line); border-bottom-left-radius: 5px; }
.bubble.me { align-self: flex-end; background: var(--brand); color: #fff; border-bottom-right-radius: 5px; }
.bubble.me .bubble-time { color: rgba(255,255,255,.75); }
.chat-input {
  display: flex; gap: 8px; padding: 10px 12px calc(10px + var(--safe-bottom));
  border-top: 1px solid var(--line); background: var(--surface);
}
.chat-input input {
  flex: 1; border: 1px solid var(--line); background: var(--surface-2); color: var(--text);
  border-radius: 999px; padding: 11px 16px; outline: none;
}
.chat-input button { border: 0; background: var(--brand); color: #fff; width: 44px; border-radius: 50%; display: grid; place-items: center; }

.dot-badge { min-width: 20px; height: 20px; padding: 0 6px; border-radius: 999px; background: var(--brand); color: #fff; font-size: 11px; font-weight: 700; display: grid; place-items: center; }

/* ── Окно расчётов / баланс ─────────────────────────────────────────────── */
.stat.link { display: block; }
/* Подпись плитки не обрезаем: лучше перенос в две строки, чем «Квит». */
.stat.link .stat-label { display: inline-flex; align-items: center; gap: 2px; flex-wrap: wrap; }
.stat-label, .stat-sub { overflow-wrap: anywhere; }
.stat-breakdown div { min-width: 0; }
.stat-breakdown span { overflow-wrap: anywhere; }
.stat.link .stat-label .ic { width: 15px; height: 15px; color: var(--muted); }

.balance-total {
  background: linear-gradient(135deg, var(--brand), #4d8bff); color: #fff;
  border-radius: var(--radius); padding: 18px; box-shadow: var(--shadow);
}
.balance-total-label { font-size: 13px; opacity: .9; }
.balance-total-value { font-size: 30px; font-weight: 800; letter-spacing: -.02em; margin-top: 2px; }
.balance-total-sub { font-size: 12px; opacity: .85; margin-top: 2px; }

/* Переключатель разделов (квартиры / счётчики): переносится на второй ряд */
.obj-switch { display: flex; flex-wrap: wrap; gap: 8px; padding: 2px 0 4px; }
.obj-chip {
  flex: 1 1 104px; display: flex; flex-direction: column; align-items: flex-start; gap: 2px;
  min-width: 104px; padding: 10px 12px; cursor: pointer; text-align: left;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  color: var(--text); box-shadow: var(--shadow);
}
.obj-chip-title { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 100%; }
.obj-chip.active { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand) inset; }
/* Квитанция без начисления — работа, которую видно, не открывая каждую. */
/* Права на модуль — две галочки в строке дерева модулей ЛКК. */
.mod-rights { display: flex; gap: 10px; flex: none; align-items: center; }
.mod-rights .fld-check { border-bottom: none; padding: 0; gap: 6px; font-size: 13px; white-space: nowrap; }
.mod-rights .fld-check input { width: 16px; height: 16px; }
/* Долг и пени по квитанции в приёмке — два узких поля в строке. */
.acc-debt-row { gap: 6px; flex: none; }
.acc-debt-row .fld-input { width: 92px; padding: 8px 10px; font-size: 14px; }
.obj-chip.pending { border-color: color-mix(in srgb, var(--warn) 55%, transparent);
  background: color-mix(in srgb, var(--warn) 8%, transparent); }
.obj-chip.pending .obj-chip-bal { color: var(--warn); }
.obj-chip.pending.active { border-color: var(--warn); box-shadow: 0 0 0 1px var(--warn) inset; }
.obj-chip-title { font-size: 13px; font-weight: 600; white-space: nowrap; }
.obj-chip-bal { font-size: 15px; font-weight: 800; color: var(--brand); }
.obj-chip-sub { font-size: 12px; font-weight: 600; color: var(--muted); }
.obj-chip.active .obj-chip-bal { color: var(--brand); }

.settle { display: flex; flex-direction: column; gap: 10px; }
.settle-head { display: flex; justify-content: space-between; align-items: flex-start; gap: 10px; }
.settle-expected { display: flex; flex-direction: column; align-items: flex-end; text-align: right; flex: none; max-width: 48%; }
.settle-expected-label { font-size: 11px; color: var(--muted); line-height: 1.2; }
.settle-expected-amount { font-size: 16px; font-weight: 800; color: var(--ok); margin-top: 2px; }
.settle-expected-after { font-size: 11px; color: var(--muted); margin-top: 1px; }
.settle-title { font-weight: 700; font-size: 16px; }
.settle-balance {
  display: flex; justify-content: space-between; align-items: baseline;
  padding: 10px 12px; background: var(--surface-2); border-radius: var(--radius-sm);
}
.settle-balance span { color: var(--muted); font-size: 13px; }
.settle-balance b { font-size: 18px; font-weight: 800; }
/* Отрицательный баланс ЛКС (id=1049) — красным. */
.balance-total-value.neg, .obj-chip-bal.neg, .obj-chip.active .obj-chip-bal.neg, .settle-balance b.neg { color: var(--danger); }
/* Задолженность второй цифрой (id=1050). */
.balance-total-debt { display: flex; justify-content: space-between; align-items: baseline; gap: 8px; margin-top: 10px; padding-top: 10px; border-top: 1px solid rgba(255,255,255,.3); }
.balance-total-debt span { font-size: 13px; opacity: .9; }
.balance-total-debt b { font-size: 20px; font-weight: 800; color: #ffd6d6; }
.obj-chip-debt { font-size: 12px; font-weight: 700; color: var(--danger); }
.settle .btn .ic { width: 18px; height: 18px; }
.btn[disabled] { opacity: .5; pointer-events: none; }

.settle-note { font-size: 13px; color: var(--muted); background: var(--surface-2); border-radius: var(--radius-sm); padding: 10px 12px; }
/* Пустая строка сообщения не рисуется серой полосой (09.10.2026: под «Приложить файл» в задаче висела пустая плашка). */
.settle-note:empty, .settle-note[hidden] { display: none; }
/* Выбор при коллизии телефона: крупные кнопки с пояснением под заголовком. */
.coll-opts { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.coll-opt { display: block; width: 100%; text-align: left; cursor: pointer;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 10px 12px; color: var(--text); }
.coll-opt:hover { border-color: var(--brand); background: var(--surface-2); }
.coll-opt b { display: block; font-size: 14px; }
.coll-opt .coll-sub { display: block; font-size: 12px; color: var(--muted); margin-top: 3px; white-space: normal; }
.settle-list { display: flex; flex-direction: column; gap: 6px; border-top: 1px solid var(--line); padding-top: 8px; }
.wd { display: flex; align-items: center; gap: 10px; }
.wd-ic { width: 34px; height: 34px; flex: none; border-radius: 10px; display: grid; place-items: center; background: var(--surface-2); color: var(--brand); }
.wd-ic.tone-ok { color: var(--ok); }
.wd-ic.tone-warn { color: var(--warn); }
.wd-ic.tone-info { color: var(--brand); }
.wd-ic.tone-muted { color: var(--muted); }

/* ── Квитанции: сводка по текущему периоду ──────────────────────────────── */
.receipt-summary { border-radius: var(--radius); padding: 14px; border: 1px solid var(--line); box-shadow: var(--shadow); }
.receipt-summary.warn { background: color-mix(in srgb, var(--warn) 10%, var(--surface)); border-color: color-mix(in srgb, var(--warn) 30%, var(--line)); }
.receipt-summary.ok { background: color-mix(in srgb, var(--ok) 10%, var(--surface)); border-color: color-mix(in srgb, var(--ok) 30%, var(--line)); }
.rs-period { font-weight: 700; font-size: 14px; margin-bottom: 8px; }
.rs-grid { display: flex; gap: 10px; }
.rs-cell { flex: 1; display: flex; flex-direction: column; gap: 2px; }
.rs-cell span { font-size: 12px; color: var(--muted); }
.rs-cell b { font-size: 17px; font-weight: 800; }
.rs-note { margin-top: 8px; font-size: 12px; color: var(--muted); }
.receipt-summary [data-rec-distribute] { margin-top: 10px; }
.rec-late { display: flex; align-items: flex-start; gap: 8px; margin: 8px 0 2px; font-size: 13px; color: var(--text); cursor: pointer; }
.rec-late input { margin-top: 2px; }
.rec-del { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 35%, var(--line)); }
/* Разбивка начисления в карточке квитанции: все суммы с пояснениями, когда они
   расходятся (начислено ≠ к оплате поставщику, часть на собственнике) — 21.10.2026. */
.rec-split { margin: 8px 0 2px; padding: 8px 10px; background: color-mix(in srgb, var(--accent) 5%, transparent); border: 1px solid var(--line); border-radius: 10px; }
.rec-split .mini-title { margin: 0 0 4px; }
.rec-split .mini-title.mini-title-row { align-items: center; }
.rec-split .kv { margin: 0; }
/* Карандаш распределения на три стороны (С / Ар / АСЭ) — на правом краю заголовка
   «Как распределяется» (26.10.2026). */
.split-edit { background: none; border: none; padding: 2px; margin: 0; cursor: pointer; color: var(--muted);
  display: inline-flex; align-items: center; border-radius: 6px; }
.split-edit:hover { color: var(--brand); background: color-mix(in srgb, var(--brand) 12%, transparent); }
.split-edit svg { width: 16px; height: 16px; }
/* Разбивка начисления + карандаш распределения в окне «Начисление» (28.10.2026). */
.ae-split-row { display: flex; align-items: flex-start; gap: 8px; }
.ae-split-row .settle-note { flex: 1 1 auto; margin: 0; }
.ae-split-row .split-edit { flex: 0 0 auto; margin-top: 2px; }
/* Подсвеченное поле «общая сумма» в окне распределения. */
.fld-input.fld-hot { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 7%, transparent); font-weight: 700; }
/* Раздел «Распределение по начислениям» в карточке платежа (28.10.2026). */
.pa-list { display: flex; flex-direction: column; gap: 6px; margin: 6px 0; }
.pa-row { display: flex; align-items: center; justify-content: space-between; gap: 10px;
  padding: 6px 8px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.pa-row .pa-pick { flex: 1 1 auto; min-width: 0; display: flex; align-items: flex-start; gap: 8px; cursor: pointer; margin: 0; }
.pa-row .pa-check { margin-top: 2px; flex: 0 0 auto; }
.pa-row .pa-name { flex: 1 1 auto; min-width: 0; font-size: 13px; line-height: 1.3; }
.pa-row .pa-sum { flex: 0 0 110px; width: 110px; text-align: right; }
/* Отмечена и закрывает начисление целиком — зелёная, частично — жёлтая. */
.pa-row.pa-full { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 10%, transparent); }
.pa-row.pa-part { border-color: var(--warn); background: color-mix(in srgb, var(--warn) 12%, transparent); }
.pa-foot { display: flex; align-items: center; justify-content: space-between; gap: 10px; flex-wrap: wrap; margin: 8px 0; }
.pa-foot .pa-note { font-size: 13px; }
/* Окно распределения: недостающая квитанция (нет суммы) и неподгруженный скриншот
   подсвечены, но распределение не останавливают (20.10.2026). */
.list .row.rec-wait { background: color-mix(in srgb, var(--danger) 6%, transparent); border-left: 3px solid var(--danger); padding-left: 9px; }
.list .row.rec-noshot { background: color-mix(in srgb, var(--warn) 8%, transparent); border-left: 3px solid var(--warn); padding-left: 9px; }
.receipt-includes { font-size: 13px; color: var(--muted); margin: 8px 0; display: flex; flex-wrap: wrap; align-items: center; gap: 4px; }
.tag { display: inline-block; font-size: 11px; font-weight: 700; padding: 2px 7px; border-radius: 6px; background: var(--surface-2); color: var(--text); border: 1px solid var(--line); }

/* ── Лента событий (истории с подэтапами) ───────────────────────────────── */
.filter-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 4px; }
.filter-chips[hidden] { display: none; }
/* Люди объекта шильдиками в форме заявки (28.10.2026): список виден сразу, в том
   числе на телефоне, — в отличие от datalist, который раскрывается при наборе. */
.rq-ppl { margin: 6px 0 2px; }
.rq-ppl .fchip { font-weight: 500; }
.fchip {
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
  border-radius: 999px; padding: 6px 12px; font-size: 13px; font-weight: 600; cursor: pointer;
}
.fchip.active { background: var(--brand); border-color: var(--brand); color: #fff; }
/* Вкладки «Деньги по объекту»: заголовок в одну строку без переносов, кнопки
   ниже; кнопки мелкие — в один ряд, если влезают, иначе переносятся на второй. */
.money-title, .cc-money-tabs-l { white-space: nowrap; }
.money-tabs { flex-wrap: wrap; gap: 4px; width: 100%; }
.cc-money-tabs { margin-top: 8px; }
.cc-money-tabs-l { display: block; font-size: 12px; color: var(--muted); margin-bottom: 4px; }
.money-tabs .fchip { flex: 1 1 auto; display: inline-flex; align-items: center; justify-content: center; gap: 1px; padding: 3px 8px; font-size: 12px; white-space: nowrap; }
.money-tabs .fchip.link { text-decoration: none; color: var(--brand); border-color: color-mix(in srgb, var(--brand) 35%, var(--line)); }
.money-tabs .fchip.link svg { width: 12px; height: 12px; opacity: .6; flex: none; }
/* Число или код внутри шильдика: у невыбранного приглушено, у выбранного
   светлее заливки — иначе на синем фоне оно сливается. */
.fchip-n { opacity: .6; font-weight: 700; margin-left: 2px; }
.fchip.active .fchip-n { opacity: .85; }

.event-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 14px; box-shadow: var(--shadow); }
.event-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.event-date { color: var(--muted); font-size: 12px; margin-left: auto; }
.event-status { font-size: 11px; font-weight: 700; padding: 2px 8px; border-radius: 999px; background: var(--surface-2); color: var(--muted); }
.event-apt { display: flex; align-items: center; gap: 4px; margin-top: 6px; font-size: 12px; color: var(--muted); }
.event-apt .ic { width: 14px; height: 14px; }
.event-title { font-weight: 700; font-size: 16px; margin-top: 6px; }
.event-expand {
  margin-top: 10px; border: 1px solid var(--line); background: var(--surface-2); color: var(--brand);
  border-radius: 10px; padding: 8px 12px; font-size: 13px; font-weight: 600; cursor: pointer; width: 100%;
}
.event-expand:active { transform: scale(.99); }

.event-timeline { margin: 12px 0 2px; padding-left: 6px; }
.subev { position: relative; display: flex; gap: 12px; padding: 0 0 14px 14px; border-left: 2px solid var(--line); }
.subev:last-child { border-left-color: transparent; padding-bottom: 2px; }
.subev-dot { position: absolute; left: -6px; top: 3px; width: 10px; height: 10px; border-radius: 50%; background: var(--brand); box-shadow: 0 0 0 3px var(--surface); }
.subev-body { flex: 1; min-width: 0; }
.subev-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.subev-date { color: var(--muted); font-size: 11px; }
.subev-title { font-size: 14px; margin-top: 3px; }

/* Шильдики типов событий */
.ev-badge { font-size: 11px; font-weight: 700; padding: 3px 9px; border-radius: 999px; white-space: nowrap; }
.ev-badge.sm { font-size: 10px; padding: 2px 7px; }
.ev-acceptance { background: color-mix(in srgb, #1f6feb 15%, transparent); color: #1f6feb; }
.ev-rental     { background: color-mix(in srgb, #8b5cf6 16%, transparent); color: #8b5cf6; }
.ev-service    { background: color-mix(in srgb, #0ea5a4 16%, transparent); color: #0ea5a4; }
.ev-technical  { background: color-mix(in srgb, #c98a00 18%, transparent); color: #c98a00; }
.ev-financial  { background: color-mix(in srgb, #1f9d55 16%, transparent); color: #1f9d55; }
.ev-contract   { background: color-mix(in srgb, #64748b 18%, transparent); color: #64748b; }

/* ── Арендатор ──────────────────────────────────────────────────────────── */
.pay-hero {
  display: block; background: linear-gradient(135deg, var(--brand), #4d8bff); color: #fff;
  border-radius: var(--radius); padding: 18px; box-shadow: var(--shadow);
}
.pay-hero:active { filter: brightness(.97); }
/* Оборот ведёт в таблицу объектов — показываем это стрелкой, как у остальных
   переходов; сама плитка остаётся блоком, поэтому позиционируем абсолютом. */
a.pay-hero { position: relative; display: block; color: inherit; text-decoration: none; }
.pay-hero-go { position: absolute; top: 50%; right: 12px; transform: translateY(-50%); opacity: .85; }
.pay-hero-go .ic { width: 20px; height: 20px; }
.pay-hero-label { font-size: 13px; opacity: .9; }
.pay-hero-value { font-size: 30px; font-weight: 800; letter-spacing: -.02em; margin-top: 2px; }
.pay-hero-sub { font-size: 12px; opacity: .85; margin-top: 2px; }

.banner-btn {
  display: flex; align-items: center; gap: 10px; width: 100%; cursor: pointer; text-align: left;
  background: color-mix(in srgb, var(--warn) 12%, var(--surface)); color: var(--text);
  border: 1px solid color-mix(in srgb, var(--warn) 35%, var(--line)); border-radius: var(--radius-sm);
  padding: 12px 14px; font-size: 14px; font-weight: 600; box-shadow: var(--shadow); font-family: inherit;
}
.banner-btn > span { flex: 1; }
.banner-btn > span.ic { flex: 0 0 auto; }  /* иконка — по содержимому, текст занимает свободное место */
.banner-btn .ic { color: var(--warn); }
/* Красный баннер: не «обратите внимание», а «нарушение длится сейчас» —
   истёкшая регистрация, за которую отвечает принимающая сторона. */
.banner-btn.alert {
  background: color-mix(in srgb, var(--danger) 12%, var(--surface));
  border-color: color-mix(in srgb, var(--danger) 35%, var(--line));
}
.banner-btn.alert .ic { color: var(--danger); }
/* Назначенная встреча или приёмка (01.11.2026): это не требование к
   собственнику, а сообщение — спокойный зелёный, не тревожный жёлтый. */
.banner-btn.meet {
  background: color-mix(in srgb, var(--ok) 10%, var(--surface));
  border-color: color-mix(in srgb, var(--ok) 32%, var(--line)); cursor: default;
}
.banner-btn.meet .ic { color: var(--ok); }
.banner-btn.meet + .banner-btn.meet { margin-top: 8px; }
/* Возврат к подборке (П.3): фирменный акцент — это главный путь подбор-клиента,
   а не предупреждение; выделяем синим, а не жёлтым. */
.banner-btn.podbor-banner {
  background: color-mix(in srgb, var(--brand) 12%, var(--surface));
  border-color: color-mix(in srgb, var(--brand) 35%, var(--line));
}
.banner-btn.podbor-banner .ic { color: var(--brand); }
/* Кнопка загрузки документа — это <label> со скрытым полем файла. */
/* Модуль, которого этому типу кабинета не полагается: строка тусклая, но
   живая — рядом кнопка заявки. Глухая серая строка читается как поломка. */
.row.mod-off .row-title { color: var(--muted); }
.row.mod-off .row-ic { opacity: .45; }

/* Сворачиваемый блок документов: шапка — кнопка во всю ширину, стрелка
   поворачивается при раскрытии. Нужен потому, что документы принимающей
   стороны смотрят в день подачи, а список жильцов — каждый день. */
.reg-fold {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 0; margin: 0;
  background: none; border: 0; font: inherit; color: inherit; cursor: pointer; text-align: left;
}
.reg-fold > b { flex: 1; }
.reg-fold .ic { color: var(--muted); transition: transform .15s; }
.card.open > .reg-fold .ic { transform: rotate(90deg); }
.reg-fold-body { margin-top: 10px; }
/* Пояснение под документом собственника: он один на все его объекты. */
.reg-host-note { margin: -6px 0 10px; padding-left: 12px; }
.reg-upload { cursor: pointer; }
.reg-upload input { display: none; }
/* Набор снимков одного документа в ЛК арендатора: раскрывается под кнопкой вида. */
.reg-kind.open { border-color: var(--brand); color: var(--brand); }
.reg-pack { display: flex; flex-direction: column; gap: 8px; padding: 8px 10px 12px; margin: -4px 0 8px; border-left: 3px solid var(--brand); }
.reg-pack[hidden] { display: none; }
.reg-pack-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.reg-pack-grid:empty { display: none; }
/* Класс `.reg-thumb` занят миниатюрами документов у сотрудника (64×64, без
   потомков) — у набора жителя свой, `.reg-shot`, иначе правила перебивали друг друга
   и стрелки уезжали под кнопку «Добавить». */
.reg-shot { position: relative; width: 84px; display: flex; flex-direction: column; gap: 4px; }
.reg-shot img, .reg-shot-pdf { width: 84px; height: 84px; object-fit: cover; border-radius: 8px; background: var(--surface-2, #eef1f5); display: flex; align-items: center; justify-content: center; font-weight: 700; color: var(--muted); }
.reg-shot-n { position: absolute; top: 4px; left: 4px; min-width: 20px; height: 20px; padding: 0 5px; border-radius: 10px; background: rgba(0,0,0,.6); color: #fff; font-size: 12px; line-height: 20px; text-align: center; }
.reg-shot-mv { display: flex; gap: 4px; }
.reg-shot-mv button { flex: 1; height: 28px; border-radius: 6px; border: 1px solid var(--line, #d9dee5); background: var(--surface, #fff); color: var(--text); font-size: 16px; line-height: 1; cursor: pointer; }
.reg-shot-mv button:disabled { opacity: .35; cursor: default; }
.reg-shot-x { position: absolute; top: -6px; right: -6px; width: 22px; height: 22px; border-radius: 50%; border: 0; background: #d9432f; color: #fff; font-size: 14px; line-height: 22px; cursor: pointer; z-index: 1; }

.meter-banner {
  display: flex; align-items: center; gap: 12px; padding: 12px 14px; border-radius: var(--radius-sm);
  border: 1px solid var(--line); box-shadow: var(--shadow);
}
.meter-banner.warn { background: color-mix(in srgb, var(--warn) 12%, var(--surface)); border-color: color-mix(in srgb, var(--warn) 30%, var(--line)); }
.meter-banner.ok { background: color-mix(in srgb, var(--ok) 10%, var(--surface)); border-color: color-mix(in srgb, var(--ok) 30%, var(--line)); }
.meter-banner .ic { color: var(--brand); flex: none; }
/* Текст баннера — предложение, оно переносится, а не режется: у `.row-sub`
   стоит `nowrap` для строк списка, а флекс-колонка без `min-width: 0`
   растягивается за карточку, и строка вылезала наружу (Mini App, 11.09.2026). */
.meter-banner > div { min-width: 0; flex: 1; }
.meter-banner .row-sub { white-space: normal; overflow: visible; }

.info-note {
  display: flex; align-items: flex-start; gap: 10px; padding: 12px 14px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--brand) 8%, var(--surface)); border: 1px solid color-mix(in srgb, var(--brand) 25%, var(--line));
  font-size: 13px; color: var(--text); box-shadow: var(--shadow);
}
.info-note .ic { color: var(--brand); flex: none; margin-top: 1px; }
.chip-mini { display: inline-block; font-size: 10px; font-weight: 700; padding: 1px 7px; border-radius: 999px; background: color-mix(in srgb, var(--brand) 14%, transparent); color: var(--brand); vertical-align: 1px; }

.contract-card { display: flex; flex-direction: column; gap: 10px; }
.contract-no { font-size: 15px; font-weight: 800; margin: 1px 0 2px; }

/* Админ-перелинковка кабинетов (в меню «Ещё») */
.admin-switch { margin-top: 8px; }
.admin-switch .row-ic { color: var(--brand); }
.admin-note { font-size: 12px; color: var(--muted); margin: 6px 2px 2px; }
.contract-actions { display: flex; gap: 10px; }
.contract-actions .btn { flex: 1; }
.contract-actions .btn.block { flex: 1 1 100%; }

.ul { margin: 6px 0; padding-left: 18px; }
.ul li { margin: 3px 0; font-size: 14px; }
.kv-row.total { border-bottom: 0; padding-top: 10px; }
.kv-row.total b { font-size: 17px; }
.row-sub.due { color: var(--warn); font-weight: 600; margin: 6px 0; }

/* ── Управляющий: редактирование ────────────────────────────────────────── */
.edit-hint {
  display: flex; align-items: flex-start; gap: 8px; font-size: 12px; color: var(--muted);
  background: color-mix(in srgb, var(--brand) 7%, var(--surface)); border: 1px dashed color-mix(in srgb, var(--brand) 30%, var(--line));
  border-radius: var(--radius-sm); padding: 10px 12px; margin-bottom: 10px;
}
.edit-hint .ic { color: var(--brand); flex: none; width: 16px; height: 16px; margin-top: 1px; }
.card-actions { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.vis-row { display: flex; align-items: center; gap: 6px; margin-top: 6px; font-size: 11px; color: var(--muted); }
.vis-chip {
  border: 1px solid var(--line); background: var(--surface-2); color: var(--muted);
  border-radius: 999px; padding: 2px 10px; font-size: 11px; font-weight: 700; cursor: pointer;
}
.vis-chip.on { background: var(--brand); border-color: var(--brand); color: #fff; }
/* Глазик «кому видно» (30.10.2026): вместо шильдика «С» — иконка, под ней
   меню с шильдиками «Ар» (арендатор) и «С» (собственник). */
.vis-eye-wrap { position: relative; display: inline-flex; flex: none; }
.vis-eye { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 26px; padding: 0;
  border: 1px solid var(--line); background: var(--surface-2); color: var(--muted); border-radius: 999px; cursor: pointer; }
.vis-eye svg { width: 17px; height: 17px; }
.vis-eye.on { color: var(--brand); border-color: color-mix(in srgb, var(--brand) 45%, var(--line)); background: color-mix(in srgb, var(--brand) 10%, var(--surface)); }
.vis-eye.off svg { opacity: .55; }
.vis-menu { position: absolute; top: calc(100% + 4px); right: 0; z-index: 30; display: flex; align-items: center; gap: 6px;
  padding: 6px 8px; background: var(--surface); border: 1px solid var(--line); border-radius: 10px; box-shadow: var(--shadow); white-space: nowrap; }
.vis-menu[hidden] { display: none; }
.vis-menu-h { font-size: 11px; color: var(--muted); }
/* Вложения отчёта — скрепка с числом (вместо шильдика «вложений N»). */
.att-n { display: inline-flex; align-items: center; gap: 2px; color: var(--muted); font-size: 12px; font-weight: 700; flex: none; }
.att-n svg { width: 15px; height: 15px; }
.owner-found { font-size: 13px; padding: 10px 12px; border-radius: var(--radius-sm); margin-bottom: 10px; }
.owner-found.ok { background: color-mix(in srgb, var(--ok) 12%, transparent); color: var(--text); border: 1px solid color-mix(in srgb, var(--ok) 30%, var(--line)); }
.owner-found.muted { background: var(--surface-2); color: var(--muted); border: 1px solid var(--line); }
.chk { display: flex; align-items: center; gap: 8px; font-size: 14px; margin: 8px 0; cursor: pointer; }
.chk input { width: 18px; height: 18px; }
.field select { width: 100%; border: 1px solid var(--line); background: var(--surface-2); color: var(--text); border-radius: 12px; padding: 12px 14px; outline: none; font: inherit; font-size: 15px; }

.filters-row { display: flex; gap: 10px; }
/* `display: flex` перебивает браузерное [hidden] { display: none } — та же грабля,
   что была с палитрой смайлов. Прячем явно: в карточке лида поле выбора объекта и
   кнопка «+ Объект» подменяют друг друга. */
.filters-row[hidden] { display: none; }
.fld { flex: 1; display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.fld > span { font-size: 12px; color: var(--muted); }
.fld select {
  width: 100%; border: 1px solid var(--line); background: var(--surface); color: var(--text);
  border-radius: 12px; padding: 10px 12px; outline: none; font: inherit; font-size: 14px;
  -webkit-appearance: none; appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='16' viewBox='0 0 24 24' fill='none' stroke='%236a7684' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center; padding-right: 30px;
}
.fld select:focus { border-color: var(--brand); }
.fld-input {
  width: 100%; border: 1px solid var(--line); background: var(--surface); color: var(--text);
  border-radius: 12px; padding: 10px 12px; outline: none; font: inherit; font-size: 14px;
}
.fld-input:focus { border-color: var(--brand); }
.combo { position: relative; }
.combo .fld-input { padding-right: 34px; }
.combo-clear {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  width: 24px; height: 24px; border: 0; border-radius: 50%; cursor: pointer;
  background: var(--surface-2); color: var(--muted); font-size: 18px; line-height: 1;
  display: grid; place-items: center; padding: 0;
}
.combo-clear:hover { background: var(--line); color: var(--text); }
.combo-clear[hidden] { display: none; }
/* Значок в поле: открыть справочник (база контактов у сотрудника, 24.09.2026).
   Тот же угол, что у крестика сброса, — в одном поле они не встречаются. */
.combo-ic {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  width: 26px; height: 26px; border: 0; border-radius: 8px; cursor: pointer;
  background: var(--surface-2); color: var(--muted);
  display: grid; place-items: center; padding: 0;
}
.combo-ic svg { width: 16px; height: 16px; }
.combo-ic:hover { background: var(--line); color: var(--text); }

/* Сообщения жильцов об оплате на главной управляющего: оранжевая рамка —
   это работа (сверить с выпиской), а не авария, красный здесь был бы лишним. */
.pay-reports { border-left: 3px solid var(--warn); }
.pay-reports .settle-title { display: flex; align-items: center; gap: 6px; }

/* Таблица шире остального кабинета. Данных в строке много — адрес, собственник,
   жилец, суммы, — а по бокам от контейнера (1400px) на мониторе остаётся пустое
   поле. Поэтому экран таблицы «расползается» за контейнер до 15 % его ширины в
   каждую сторону, но не дальше края экрана: `min` берёт меньшее из «15 %» и
   «сколько места есть», а `max(0px, …)` не даёт правилу сузить таблицу, когда
   экран уже самого контейнера. Только в режиме ПК и только на широком экране —
   на телефоне таблица и так по ширине экрана. */
@media (min-width: 900px) {
  body.desk .wrap.tbl-page {
    margin-inline: calc(-1 * max(0px, min(15%, (100vw - 100%) / 2 - 8px)));
  }
}

/* ── Подчинённые таблицы ────────────────────────────────────────────────────
   Панель связанных записей стоит под основной таблицей и делит с ней экран:
   высоту задаёт человек, потянув верхнюю границу (`--sub-h`). */
.sub-panel {
  --sub-h: 240px;
  position: relative; display: flex; flex-direction: column;
  height: var(--sub-h); min-height: 0; margin-top: 8px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface); overflow: hidden;
}
/* Ручка на верхней границе: узкая полоса во всю ширину. `touch-action: none`
   обязателен на самой ручке — жест иначе уходит в прокрутку страницы. */
.sub-grip {
  height: 10px; flex: none; cursor: ns-resize; touch-action: none;
  background: var(--surface-2); border-bottom: 1px solid var(--line);
}
.sub-grip::after {
  content: ''; display: block; width: 42px; height: 3px; margin: 3px auto;
  border-radius: 2px; background: var(--line);
}
.sub-grip.drag::after, .sub-grip:hover::after { background: var(--brand); }
.sub-head { display: flex; align-items: center; gap: 8px; padding: 6px 8px; flex: none;
  border-bottom: 1px solid var(--line); }
.sub-tabs { display: flex; gap: 4px; overflow-x: auto; flex: 1 1 auto; }
.sub-tab {
  flex: none; border: 1px solid var(--line); background: var(--surface-2); color: var(--text);
  border-radius: 999px; padding: 5px 10px; font: inherit; font-size: 12.5px; cursor: pointer;
}
.sub-tab.active { background: var(--brand); border-color: var(--brand); color: #fff; }
.sub-tab .sub-n { opacity: .75; font-weight: 700; }
/* Несведённые кандидаты в панели (12.09.2026): счётчик со знаком вопроса,
   пояснение над таблицей и шильдик «не сведено» в первой ячейке каждой строки. */
.sub-tab .sub-n.loose::after { content: '?'; }
.sub-note { padding: 6px 10px; font-size: 12px; color: var(--warn); background: color-mix(in srgb, var(--warn) 8%, transparent); border-bottom: 1px solid var(--line); }
.tbl.sub-loose tbody td.first::before {
  content: 'не сведено'; display: inline-block; margin-right: 6px; padding: 1px 6px; border-radius: 999px;
  font-size: 10px; font-weight: 700; line-height: 14px; vertical-align: middle;
  background: color-mix(in srgb, var(--warn) 16%, transparent); color: var(--warn);
}
.sub-act { display: flex; gap: 4px; flex: none; }
/* На телефоне у кнопок панели остаётся только значок — подписи не помещались и
   налезали на вкладки. На ПК (от 620px) подписи возвращаются. */
.sub-act .tbl-btn { display: inline-flex; align-items: center; }
.sub-act .tbl-btn .lbl { display: none; }
@media (min-width: 620px) { .sub-act .tbl-btn .lbl { display: inline; } }
/* Переход из таблицы в её модуль (11.10.2026): на телефоне остаётся один
   значок — панель таблицы прокручивается вбок, и длинная подпись съедала место
   у «Поля» и «Фильтры». На ПК (от 620px) подпись возвращается. */
.tbl-btn.mod-link { display: inline-flex; align-items: center; text-decoration: none; }
.tbl-btn.mod-link .lbl { display: none; }
@media (min-width: 620px) { .tbl-btn.mod-link .lbl { display: inline; } }
.sub-sel { padding: 5px 8px; font-size: 12px; color: var(--muted); flex: none;
  border-bottom: 1px solid var(--line); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Остаток прихода к разнесению — заметным цветом в шапке панели. */
.sub-rest { color: var(--warn); font-weight: 700; }
/* Шапка панели нажимается — открывает список её полей; ползунок на границе
   меняет ширину. Курсор об этом и говорит. */
.sub-wrap .tbl th { cursor: pointer; }
.sub-wrap .tbl th .th-grip { cursor: col-resize; }
/* Своя прокрутка: у панели фиксированная высота, а записей может быть много. */
.sub-wrap { flex: 1 1 auto; min-height: 0; overflow: auto; }
.sub-empty { padding: 14px 10px; color: var(--muted); font-size: 13px; }
/* Выбранная строка хозяина — по ней и собрана панель. */
.tbl tbody tr.sel { background: color-mix(in srgb, var(--brand) 12%, transparent); }
.tbl tbody tr.sel td { border-color: var(--line); }
/* Первая колонка липкая и непрозрачная — подсветку выбора красим и ей, иначе
   выделенная строка выглядит выделенной со второй колонки. */
.tbl tbody tr.sel td.first { background: color-mix(in srgb, var(--brand) 12%, var(--surface)); }
/* Обводка выбранной строки (12.09.2026): на строках с цветовыделением (красные
   долги, зелёные оплаты, жёлтые заготовки) заливка выбора тонет в цвете и
   фокуса не видно. Рамка рисуется тенями внутри ячеек — у строки таблицы своей
   обводки нет: верх и низ у всех ячеек, левый край у первой, правый у последней. */
.tbl tbody tr.sel td { box-shadow: inset 0 2px 0 var(--brand), inset 0 -2px 0 var(--brand); }
.tbl tbody tr.sel td:first-child { box-shadow: inset 2px 0 0 var(--brand), inset 0 2px 0 var(--brand), inset 0 -2px 0 var(--brand); }
.tbl tbody tr.sel td:last-child { box-shadow: inset -2px 0 0 var(--brand), inset 0 2px 0 var(--brand), inset 0 -2px 0 var(--brand); }
.tbl tbody tr.sel td.first:not(:first-child) { box-shadow: 1px 0 0 var(--line), inset 0 2px 0 var(--brand), inset 0 -2px 0 var(--brand); }

/* Выбор числа записей на странице: подпись и узкий список одной строкой справа
   от счётчика — там же, где в списке объектов стоит переключатель вида. */
/* Ряд состояний в базе контактов идёт вторым и подписан: два одинаковых ряда
   шильдиков подряд читаются как один длинный список. */
.cb-states-label { font-size: 11.5px; color: var(--muted); margin: 6px 0 -2px; }
.per-page { display: flex; align-items: center; gap: 6px; flex: none; font-size: 12px; color: var(--muted); }
.per-page .fld-input { width: auto; min-width: 0; padding: 4px 6px; font-size: 12px; }
.pager { display: flex; flex-wrap: wrap; align-items: center; justify-content: center; gap: 6px; padding: 6px 0; }
.pager .pg {
  min-width: 34px; height: 34px; padding: 0 8px; border: 1px solid var(--line); background: var(--surface); color: var(--text);
  border-radius: 10px; font-weight: 700; font-size: 14px; cursor: pointer;
}
.pager .pg.active { background: var(--brand); border-color: var(--brand); color: #fff; }
.pager .pg[disabled] { opacity: .4; pointer-events: none; }
.pager .pg-dots { color: var(--muted); padding: 0 2px; }

/* ── Модальное окно ─────────────────────────────────────────────────────── */
/* Скролл-лок под модалкой. Без position: fixed — оно роняет фон в начало
   страницы при открытии; позицию удерживает ui.js (см. «Модалки и прокрутка»). */
body.modal-open { overflow: hidden; }
.modal-overlay {
  position: fixed; inset: 0; z-index: 50; display: flex; align-items: flex-end; justify-content: center;
  background: rgba(8, 12, 18, .5); backdrop-filter: blur(2px); animation: fade .15s ease;
}
.modal {
  width: 100%; max-width: var(--maxw); background: var(--surface);
  border-radius: 20px 20px 0 0; padding: 18px 16px calc(18px + var(--safe-bottom));
  box-shadow: 0 -8px 40px rgba(0,0,0,.35); animation: slideUp .22s ease;
  /* Высокое окно (договор, карточка) не должно вылезать за экран: ограничиваем
     высоту и прокручиваем само окно — иначе верх и низ недоступны. dvh учитывает
     адресную строку мобильного браузера, vh — запасной вариант. */
  max-height: 92vh; max-height: 92dvh;
  overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
}
/* Кнопки окна всегда под рукой: прилипают к низу при прокрутке содержимого. */
.modal > .modal-actions:last-child {
  position: sticky; bottom: calc(-1 * var(--safe-bottom));
  background: var(--surface); padding-top: 10px; margin-top: 10px;
  box-shadow: 0 -10px 16px -12px rgba(0,0,0,.35);
}
.modal-head { margin-bottom: 12px; }
.modal-title { font-size: 18px; font-weight: 800; }
.modal-sub { color: var(--muted); font-size: 13px; }
.field { display: flex; flex-direction: column; gap: 6px; margin-bottom: 12px; }
/* Поля, которые показываются по условию (родитель у ребёнка, дата выезда у
   комнаты), прячутся атрибутом `hidden` — а `display: flex` в классе сильнее
   него, и поле висело всегда. Та же грабля, что была с палитрой смайлов. */
.field[hidden], .fld[hidden] { display: none; }
.field > span { font-size: 13px; color: var(--muted); }
.field input, .field textarea {
  border: 1px solid var(--line); background: var(--surface-2); color: var(--text);
  border-radius: 12px; padding: 12px 14px; outline: none; font-size: 15px;
  font-family: inherit; resize: vertical;
}
.field input:focus, .field textarea:focus { border-color: var(--brand); }
.field input[type="file"] { padding: 9px 12px; }
.modal-actions { display: flex; gap: 10px; margin-top: 4px; }
.modal-actions .btn { flex: 1; }
@keyframes slideUp { from { transform: translateY(100%); } to { transform: translateY(0); } }
@keyframes fade { from { opacity: 0; } to { opacity: 1; } }

@media (min-width: 560px) {
  .modal-overlay { align-items: center; }
  .modal { border-radius: 20px; margin: 0 12px; }
}

/* ── Состояния ──────────────────────────────────────────────────────────── */
.state { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 12px; padding: 60px 20px; color: var(--muted); text-align: center; }
.state-emoji { font-size: 40px; }
.spinner { width: 30px; height: 30px; border-radius: 50%; border: 3px solid var(--line); border-top-color: var(--brand); animation: spin .8s linear infinite; }
@keyframes spin { to { transform: rotate(360deg); } }

.ic { display: block; }

/* планшет / широкий экран — карточки в 2 колонки */
@media (min-width: 560px) {
  .cards { display: grid; grid-template-columns: 1fr 1fr; }
  .cards.rows { display: flex; }
}

/* ── Поле вложений (фото + видео-ссылка) ────────────────────────────────── */
.media-field { margin: 10px 0; }
.media-label { font-size: 13px; color: var(--muted); margin-bottom: 6px; }
.media-grid { display: flex; flex-wrap: wrap; gap: 8px; }
.media-grid:not(:empty) { margin-bottom: 8px; }
.media-thumb { position: relative; width: 72px; height: 72px; border-radius: var(--radius-sm); background: var(--surface-2) center/cover no-repeat; border: 1px solid var(--line); }
/* Нажатие по миниатюре раскрывает снимок на весь экран (28.10.2026). */
.media-thumb { cursor: zoom-in; }
.media-rm { position: absolute; top: -6px; right: -6px; width: 22px; height: 22px; border-radius: 50%; border: none; background: var(--danger); color: #fff; font-size: 15px; line-height: 1; cursor: pointer; box-shadow: var(--shadow); }
/* Две кнопки загрузки: снять камерой и выбрать файлы (24.09.2026). */
.media-adds { display: flex; flex-wrap: wrap; gap: 8px; }
.media-add { display: inline-flex; align-items: center; gap: 6px; padding: 9px 14px; border: 1px dashed var(--line); border-radius: var(--radius-sm); color: var(--brand); font-size: 14px; font-weight: 600; cursor: pointer; }
.media-add:active { background: var(--surface-2); }
/* Перетаскивание файлов в область (ПК, 26.10.2026): подсветка зоны при заносе
   файла и подсказка — только там, где есть мышь (на телефоне drag не бывает). */
.drop-hint { display: none; }
@media (hover: hover) and (pointer: fine) {
  .drop-hint { display: block; margin-top: 6px; font-size: 12px; color: var(--muted); }
  [data-dropzone] { border-radius: var(--radius-sm); transition: outline-color .12s, background .12s; outline: 1.5px dashed transparent; outline-offset: 3px; }
}
[data-dropzone].drop-hover { outline: 1.5px dashed var(--brand); background: color-mix(in srgb, var(--brand) 7%, transparent); }
.media-drop.drop-hover { outline-offset: 6px; }
.media-video { display: block; margin-top: 10px; }

/* ── Плитка комнаты (обложка) ───────────────────────────────────────────── */
.card-photo { height: 120px; background: var(--surface-2) center/cover no-repeat; border-radius: var(--radius) var(--radius) 0 0; }

/* ── Фотографии: миниатюры + слайд-шоу (лайтбокс) ───────────────────────── */
.photo-strip { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.photo-cell { display: flex; flex-direction: column; align-items: center; gap: 3px; width: 84px; }
/* Подпись под миниатюрой: мелко, в две строки максимум — она поясняет кадр, а не спорит с ним. */
.photo-cap { font-size: 10.5px; line-height: 1.2; color: var(--muted); text-align: center;
  max-width: 84px; overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.photo-thumb { width: 84px; height: 84px; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--surface-2) center/cover no-repeat; cursor: pointer; padding: 0; }
.photo-thumb:active { opacity: .85; }
.photo-add { display: inline-flex; align-items: center; gap: 6px; padding: 9px 14px; border: 1px dashed var(--line); border-radius: var(--radius-sm); color: var(--brand); font-size: 14px; font-weight: 600; cursor: pointer; margin-top: 4px; }
.photo-add:active { background: var(--surface-2); }
.room-photos { margin-bottom: 12px; }
.room-photos-label { display: inline-flex; align-items: center; gap: 4px; font-weight: 600; font-size: 14px; color: var(--text); text-decoration: none; }
.room-photos-label .ic { width: 16px; height: 16px; color: var(--muted); }

.lb-overlay { position: fixed; inset: 0; z-index: 1000; background: rgba(0,0,0,.92); display: flex; align-items: center; justify-content: center; }
/* Галерея вложений (22.10.2026): стрелки и счётчик поверх снимка. Кнопки
   крупные — ими листают пальцем на телефоне. */
.lb-gal .lb-nav { font-size: 28px; line-height: 1; font-weight: 700; width: 44px; height: 44px; }
.lb-gal .lb-counter { bottom: calc(14px + var(--safe-bottom)); top: auto; }
.lb-img { max-width: 92vw; max-height: 82vh; border-radius: 8px; }
.lb-nav { position: absolute; top: 50%; transform: translateY(-50%); width: 48px; height: 48px; border-radius: 50%; border: none; background: rgba(255,255,255,.15); color: #fff; display: flex; align-items: center; justify-content: center; cursor: pointer; }
.lb-prev { left: 12px; } .lb-next { right: 12px; }
.lb-close { position: absolute; top: 14px; right: 16px; width: 40px; height: 40px; border-radius: 50%; border: none; background: rgba(255,255,255,.15); color: #fff; font-size: 22px; line-height: 1; cursor: pointer; }
/* Низ полного экрана: подпись снимка и счётчик одной колонкой по центру.
   Подпись здесь и нужна — когда фотографию разглядывают, а не когда она
   миниатюрой в сетке. */
.lb-foot { position: absolute; bottom: 18px; left: 50%; transform: translateX(-50%);
  display: flex; flex-direction: column; align-items: center; gap: 6px; max-width: 92vw; }
.lb-cap { color: #fff; font-size: 15px; line-height: 1.3; text-align: center;
  background: rgba(0, 0, 0, .55); padding: 6px 14px; border-radius: 10px; }
.lb-count { color: #fff; font-size: 14px; background: rgba(0,0,0,.5); padding: 4px 12px; border-radius: 999px; }
/* Редактор подписи и комнаты прямо на большом фото (08.10.2026). */
.lb-edit { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; max-width: 92vw; }
.lb-edit-cap, .lb-edit-room { font-size: 14px; border: 1px solid rgba(255,255,255,.35); background: rgba(0,0,0,.6); color: #fff; border-radius: 10px; padding: 8px 12px; max-width: 86vw; }
.lb-edit-cap { min-width: 180px; }
.lb-edit-room { max-width: 60vw; }
.lb-edit-room option { color: #111; }
/* «Фото и видео в объект»: на большом файле — те же поля, что в карточке файла
   (09.10.2026). Полей пять, поэтому снимок поднимаем выше и уменьшаем, а поля
   ставим колонкой во всю ширину. */
.lb-overlay:has(.lb-share) { align-items: flex-start; padding-top: 56px; }
.lb-overlay:has(.lb-share) .lb-img { max-height: 44vh; }
.lb-share { flex-direction: column; align-items: stretch; width: min(420px, 90vw); gap: 6px; }
.lb-share .lb-edit-cap, .lb-share .lb-edit-room { max-width: none; width: 100%; min-width: 0; }
.lb-share .lb-edit-room.invalid { border-color: #e5484d; }
.lb-share-name { color: #fff; font-size: 13px; text-align: center; opacity: .85; word-break: break-all; }
.lb-share-sel { color: #fff; font-size: 14px; display: flex; align-items: center; gap: 8px; justify-content: center; }
.lb-share-sel input { width: 18px; height: 18px; }

/* ── История показаний/начислений (модалка, 3 столбца) ──────────────────── */
.hist-filter { display: flex; gap: 10px; margin: 4px 0 10px; }
.hist-filter .fld { flex: 1; }
.hist-table-wrap { max-height: 52vh; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.hist-table { width: 100%; border-collapse: collapse; font-size: 14px; }
.hist-table th { position: sticky; top: 0; background: var(--surface-2); color: var(--muted); font-weight: 600; font-size: 12.5px; text-align: left; padding: 8px 10px; border-bottom: 1px solid var(--line); }
.hist-table td { padding: 9px 10px; border-bottom: 1px solid var(--line); vertical-align: middle; }
.hist-table tbody tr:last-child td, .hist-table tr:last-child td { border-bottom: none; }
.hist-val { font-weight: 600; white-space: nowrap; }
.hist-photo { width: 44px; text-align: center; color: var(--brand); }
.hist-photo .ic { display: inline-block; }
.hist-tag { font-size: 11px; font-weight: 600; color: var(--warn); border: 1px solid var(--warn); border-radius: 999px; padding: 0 6px; margin-left: 4px; }
.hist-opening { background: color-mix(in srgb, var(--warn) 8%, transparent); }
.hist-opening .hist-tag { color: var(--brand); border-color: var(--brand); }
.hist-empty { text-align: center; color: var(--muted); padding: 16px; }
.hist-num { background: none; border: none; padding: 0; font: inherit; color: var(--brand); font-weight: 700; cursor: pointer; text-decoration: underline dotted; text-underline-offset: 3px; }
.hist-num.sm-link { font-size: 12.5px; font-weight: 600; }
.mini-title-row { display: flex; align-items: baseline; justify-content: space-between; gap: 8px; }

/* ── Профиль арендатора: сегменты + слоты документов ────────────────────── */
.seg { display: flex; gap: 6px; background: var(--surface-2); border-radius: var(--radius-sm); padding: 4px; margin: 6px 0 10px; }
.seg.sm { margin: 6px 0; }
.seg-btn { flex: 1; border: none; background: none; padding: 9px 8px; border-radius: calc(var(--radius-sm) - 2px); font: inherit; font-size: 13.5px; color: var(--muted); cursor: pointer; }
.seg-btn.active { background: var(--surface); color: var(--text); font-weight: 600; box-shadow: var(--shadow); }
.doc-slots { display: flex; flex-direction: column; gap: 10px; margin: 4px 0 6px; }
.doc-slot { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 10px 12px; }
.doc-slot.filled { border-color: color-mix(in srgb, var(--ok) 45%, var(--line)); }
.doc-slot-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-bottom: 8px; }
.doc-slot-label { font-size: 13.5px; font-weight: 600; }
.doc-slot-label .req { color: var(--danger); }
.doc-thumbs { display: flex; flex-wrap: wrap; gap: 8px; }
.doc-thumb { position: relative; width: 72px; height: 72px; border-radius: var(--radius-sm); border: 1px solid var(--line); background: var(--surface-2) center/cover no-repeat; display: flex; align-items: center; justify-content: center; overflow: hidden; }
.doc-file { display: flex; flex-direction: column; align-items: center; gap: 2px; font-size: 9px; color: var(--muted); text-align: center; padding: 2px; line-height: 1.1; }
.doc-file .ic { width: 20px; height: 20px; }
.doc-rm { position: absolute; top: -6px; right: -6px; width: 20px; height: 20px; border-radius: 50%; border: none; background: var(--danger); color: #fff; font-size: 14px; line-height: 1; cursor: pointer; }
.doc-rm.rel { position: static; }
.doc-add { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; width: 72px; height: 72px; border: 1px dashed var(--line); border-radius: var(--radius-sm); color: var(--brand); font-size: 10px; cursor: pointer; }
.resident-card .seg { margin: 6px 0; }
.fld-label-row { display: flex; align-items: center; gap: 6px; }
.hint-q { width: 18px; height: 18px; border-radius: 50%; border: 1px solid var(--brand); background: none; color: var(--brand); font-size: 12px; font-weight: 700; line-height: 1; cursor: pointer; padding: 0; }
/* Заявка: кнопка блока, справа «?» с раскрывающимся пояснением (service.js, addRow). */
.rq-add { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.rq-add .btn { flex: 1; min-width: 0; }
.rq-add .hint-q { flex: none; width: 30px; height: 30px; font-size: 15px; }
.rq-add-n { flex: none; font-size: 12.5px; color: var(--muted); white-space: nowrap; }
.email-row { display: flex; gap: 8px; align-items: stretch; }
.email-row .fld-input { flex: 1; }
.email-row .btn { flex: none; white-space: nowrap; }
.field-hint { font-size: 12.5px; color: var(--muted); background: var(--surface-2); border-radius: var(--radius-sm); padding: 8px 10px; margin-top: 6px; }
/* Подсказка у поля с проверкой суммы: зелёная — сходится, жёлтая — нет. */
.field-hint.cf-hint.ok { color: var(--ok); border-left: 3px solid var(--ok); }
.field-hint.cf-hint.warn { color: var(--warn); border-left: 3px solid var(--warn); }
.util-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 2px 12px; }
.util-grid .chk { margin: 4px 0; font-size: 13.5px; }

/* ── Форма договора: аккордеон + подразделы ─────────────────────────────── */
.acc { border: 1px solid var(--line); border-radius: var(--radius-sm); margin-bottom: 8px; background: var(--surface); overflow: hidden; }
.acc-head { display: flex; align-items: center; justify-content: space-between; width: 100%; padding: 13px 14px; background: var(--surface-2); border: none; cursor: pointer; color: var(--text); font-weight: 700; font-size: 14px; letter-spacing: .02em; text-transform: uppercase; }
.acc-ic { width: 26px; height: 26px; border-radius: 50%; border: 1.5px solid var(--brand); color: var(--brand); display: flex; align-items: center; justify-content: center; font-size: 18px; line-height: 1; flex: none; }
.acc-body { padding: 12px 14px; }
.cf-sub { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 10px 12px; margin: 10px 0; }
.cf-sub-title { font-size: 12.5px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; margin-bottom: 6px; }
.cf-sub-title-row { display: flex; align-items: center; justify-content: space-between; gap: 8px; flex-wrap: wrap; }
.cf-doc-toggle { font-weight: 400; font-size: 12px; color: var(--muted); text-transform: none; letter-spacing: 0; display: inline-flex; align-items: center; gap: 6px; cursor: pointer; }
.cf-doc-toggle input { margin: 0; }
.cf-inst { border-top: 1px dashed var(--line); padding-top: 8px; margin-top: 8px; }
.cf-inst:first-child { border-top: none; padding-top: 0; margin-top: 0; }
.cf-inst-h { font-size: 13px; font-weight: 600; margin-bottom: 4px; }
.cf-inline { display: flex; gap: 8px; align-items: center; margin: 4px 0; }
.cf-inline .fld-input { flex: 1; }
.cf-phone-actions { display: flex; flex-wrap: wrap; gap: 14px; margin: 2px 0 8px; }
.link-btn { background: none; border: none; padding: 0; color: var(--brand); font: inherit; font-size: 13.5px; font-weight: 600; cursor: pointer; display: inline-flex; align-items: center; gap: 4px; }
.link-btn .ic { width: 16px; height: 16px; }
.link-btn.danger { color: var(--danger); }
.cf-toggle { display: flex; align-items: center; justify-content: space-between; gap: 10px; margin: 8px 0; cursor: pointer; }
.cf-toggle input { display: none; }
.cf-switch { position: relative; width: 44px; height: 24px; border-radius: 999px; background: var(--line); transition: background .2s; flex: none; }
.cf-switch::after { content: ''; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%; background: #fff; box-shadow: var(--shadow); transition: transform .2s; }
.cf-toggle input:checked + .cf-switch { background: var(--brand); }
.cf-toggle input:checked + .cf-switch::after { transform: translateX(20px); }
.cf-summary { font-size: 12.5px; color: var(--text); background: var(--surface-2); border-radius: var(--radius-sm); padding: 10px 12px; margin: 10px 0; font-weight: 600; }
.take-list { max-height: 54vh; overflow-y: auto; }
.take-row { display: grid; grid-template-columns: 28px 1fr 1fr; gap: 8px; align-items: start; padding: 8px 0; border-bottom: 1px solid var(--line); }
.take-chk { width: 20px; height: 20px; margin-top: 4px; }
.take-lbl { font-size: 11px; color: var(--muted); }
.take-val { font-size: 13px; }
.cf-section { border: 1px solid var(--line); border-radius: var(--radius-sm); margin-bottom: 8px; background: var(--surface); overflow: hidden; }
.cf-section-h { padding: 13px 14px; background: var(--surface-2); font-weight: 700; font-size: 14px; text-transform: uppercase; letter-spacing: .02em; }
.cf-section-b { padding: 12px 14px; }
.cf-bal-wrap { margin-top: 8px; border-top: 1px dashed var(--line); padding-top: 8px; }
.cf-bal { font-size: 12.5px; padding: 3px 0; font-weight: 600; }
.cf-bal.ok { color: var(--ok); }
.cf-bal.warn { color: var(--warn); }

/* под-вкладки (Текущий договор / Архив) */
/* Внутренние подвкладки — всегда пара: «Собственник / Арендаторы», «Текущий
   договор / Архив». Поэтому они делят ширину пополам и читаются как выбор из
   двух; шильдиками у левого края они выглядели случайными метками, и половина
   раздела оставалась незамеченной. */
.subtabs.inner { margin-bottom: 10px; flex-wrap: nowrap; gap: 8px; }
.subtabs.inner a {
  flex: 1 1 0; min-width: 0; text-align: center; cursor: pointer;
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}

/* ── Карточка подписанного договора (read-only, шильды, мелкий шрифт) ────── */
.cc { border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); padding: 14px; box-shadow: var(--shadow); font-size: 13px; }
.cc-head { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.cc-title { font-size: 15px; font-weight: 700; }
.cc-sub { font-size: 12px; color: var(--muted); margin-top: 2px; }
.cc-badges { display: flex; flex-wrap: wrap; gap: 6px; }
.cc-chip { font-size: 11px; font-weight: 600; padding: 3px 9px; border-radius: 999px; background: var(--surface-2); color: var(--muted); white-space: nowrap; }
.cc-chip.ok { background: color-mix(in srgb, var(--ok) 16%, transparent); color: var(--ok); }
.cc-chip.info { background: color-mix(in srgb, var(--brand) 14%, transparent); color: var(--brand); }
.cc-block { margin: 12px 0; padding: 10px 12px; background: var(--surface-2); border-radius: var(--radius-sm); }
.cc-h { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); margin-bottom: 6px; }
.cc-client { font-size: 12.5px; line-height: 1.5; margin-top: 6px; }
.cc-reg { font-size: 12px; color: var(--muted); margin-top: 3px; }
.cc-sub2 { font-size: 12px; color: var(--muted); margin-top: 6px; }
.cc-grid { display: grid; grid-template-columns: 1fr; gap: 0; margin: 10px 0; }
.cc-row { display: flex; justify-content: space-between; gap: 10px; padding: 5px 0; border-bottom: 1px solid var(--line); font-size: 12.5px; }
.cc-row:last-child { border-bottom: none; }
.cc-k { color: var(--muted); flex: none; }
.cc-v { text-align: right; font-weight: 600; }
.cc-tags { font-size: 12px; color: var(--muted); margin: 6px 0; }
.cc-agr { font-size: 12px; color: var(--muted); background: var(--surface-2); border-radius: var(--radius-sm); padding: 8px 10px; margin: 6px 0; }
/* Изменения аренды в карточке договора: сумма слева, дата справа, строками. */
.cc-rentchg { display: flex; justify-content: space-between; align-items: baseline; gap: 10px; padding: 4px 0; border-bottom: 1px solid var(--line); }
.cc-rentchg:last-child { border-bottom: none; padding-bottom: 0; }
.cc-rentchg .cc-v { text-align: left; }
.cc-rentchg .cc-sub2 { margin-top: 0; white-space: nowrap; }
.cc-lock { display: flex; align-items: center; gap: 6px; font-size: 12px; color: var(--ok); margin: 10px 0; }
.cc-lock .ic { width: 16px; height: 16px; }
.cc-lock.warn { color: var(--warn); }
@media (min-width: 480px) { .cc-grid { grid-template-columns: 1fr 1fr; gap: 0 18px; } }
.cc-head-r { display: flex; align-items: center; gap: 6px; }
.settle-head-r { display: flex; align-items: center; gap: 6px; }
.badge.draft { background: color-mix(in srgb, var(--warn) 18%, transparent); color: var(--warn); }
.cf-mt { margin-top: 12px; }

/* меню договора (⋮) */
.cmenu { position: relative; }
.cmenu-btn { width: 30px; height: 30px; border: none; background: none; color: var(--muted); font-size: 20px; line-height: 1; cursor: pointer; border-radius: 8px; }
.cmenu-btn:active { background: var(--surface-2); }
.cmenu-list { display: none; position: absolute; right: 0; top: 34px; z-index: 30; min-width: 172px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm); box-shadow: var(--shadow); overflow: hidden; }
.cmenu.open .cmenu-list { display: block; }
.cmenu-item { display: block; width: 100%; text-align: left; padding: 11px 14px; background: none; border: none; font: inherit; font-size: 14px; color: var(--text); cursor: pointer; }
.cmenu-item:active { background: var(--surface-2); }
.cmenu-item.danger { color: var(--danger); }
.cmenu-item + .cmenu-item { border-top: 1px solid var(--line); }

/* ── Экран входа/регистрации (по образцу боевого lk.elidom.ru) ───────────── */
body.login-mode .app-bar,
body.login-mode .tabbar { display: none; }
body.login-mode { overflow: hidden; }

.login {
  position: fixed; inset: 0; z-index: 1200;
  background: #eef1f5; color: var(--text);
  display: flex; align-items: flex-start; justify-content: center;
  overflow: auto;
}
.login-panel {
  width: 100%; max-width: 560px; min-height: 100%;
  padding: calc(28px + var(--safe-top)) 16px calc(24px + var(--safe-bottom));
  display: flex; flex-direction: column; align-items: center; gap: 22px;
}
.login-logo { display: flex; align-items: center; justify-content: center; padding: 4px; }
.login-logo-img { display: block; width: auto; height: 68px; }

.login-card {
  width: 100%; background: #fff; border: 1px solid #e6e9ef; border-radius: 14px;
  box-shadow: 0 6px 24px rgba(16, 24, 40, .06); padding: 22px;
}
.login-tabs {
  display: flex; gap: 4px; background: #f2f4f7; border: 1px solid #e6e9ef;
  border-radius: 10px; padding: 4px; margin-bottom: 20px;
}
.login-tab {
  flex: 1; border: none; background: transparent; padding: 10px 6px; border-radius: 8px;
  font-size: 14px; font-weight: 600; color: #6a7684; cursor: pointer; font-family: inherit;
  /* Вкладок три («Демо-режим» добавлен 25.09.2026) — на узком экране подписи
     жмём, но не ломаем на две строки: полоска должна оставаться в одну. */
  white-space: nowrap;
}
@media (max-width: 400px) { .login-tab { font-size: 13px; padding: 10px 4px; } }
.login-tab.active { background: #fff; color: var(--text); box-shadow: 0 1px 3px rgba(16, 24, 40, .12); }

.login-form { display: flex; flex-direction: column; }
.login-lbl { font-size: 14px; font-weight: 600; color: var(--text); margin: 14px 0 6px; }
.login-form > .login-lbl:first-child { margin-top: 0; }
.login-input {
  width: 100%; background: #fff; color: var(--text);
  border: 1px solid #d0d5dd; border-radius: 9px; padding: 12px 13px;
  font-size: 15px; font-family: inherit;
}
.login-input::placeholder { color: #9aa4b2; }
.login-input:focus { outline: none; border-color: #8fb6e6; box-shadow: 0 0 0 3px rgba(33, 150, 243, .18); }
.login-pass { position: relative; }
.login-pass .login-input { padding-right: 44px; }
.login-eye {
  position: absolute; right: 6px; top: 50%; transform: translateY(-50%);
  width: 34px; height: 34px; display: flex; align-items: center; justify-content: center;
  background: none; border: none; color: #9aa4b2; cursor: pointer; border-radius: 8px;
}
.login-eye.on { color: var(--brand); }
.login-info {
  background: #e7f3fb; color: #1d6fb8; border-radius: 9px;
  padding: 11px 13px; font-size: 13px; line-height: 1.5; margin: 14px 0 4px;
}
.login-info b { color: #155a97; }
.login-radios { display: flex; flex-direction: column; gap: 12px; margin: 6px 0 2px; }
.login-radio, .login-check { display: flex; align-items: flex-start; gap: 9px; font-size: 14px; line-height: 1.4; color: var(--text); cursor: pointer; }
.login-radio input, .login-check input { margin-top: 2px; width: 16px; height: 16px; accent-color: var(--brand); flex: none; }
/* Пояснение под выбором роли: от него зависит, каким откроется кабинет, —
   поэтому текст полноценный, а не подпись в одну строку. */
.login-hint { display: block; margin-top: 3px; font-size: 12.5px; line-height: 1.45; color: var(--muted); }
/* Уточняющий вопрос внутри списка ролей (сколько квартир). */
.login-sub { margin: -4px 0 4px 25px; padding: 10px 12px; border-radius: var(--radius-sm);
  background: var(--surface-2); display: flex; flex-direction: column; gap: 10px; }
/* Без этого правила блок виден всегда: `display: flex` в классе сильнее
   атрибута `hidden`. Та же грабля уже ловилась на палитре смайлов. */
.login-sub[hidden] { display: none; }
.login-sub .login-lbl { margin: 0; }
.login-check { margin-top: 10px; }
.login-check a { color: var(--brand); text-decoration: none; }
.login-err { color: var(--danger); min-height: 18px; font-size: 13px; margin: 10px 0 2px; }
.login-btn {
  width: 100%; margin-top: 16px; background: #4b56d6; color: #fff; border: none;
  border-radius: 10px; padding: 14px; font-size: 15px; font-weight: 600; cursor: pointer;
  font-family: inherit; transition: background .15s, transform .05s;
}
.login-btn:hover { background: #3f49c4; }
.login-btn:active { transform: translateY(1px); }
.login-link { background: none; border: none; color: var(--brand); font-size: 13px; margin: 12px auto 0; cursor: pointer; font-family: inherit; }
.login-q {
  display: inline-flex; align-items: center; justify-content: center; vertical-align: middle;
  width: 16px; height: 16px; border-radius: 50%; border: 1px solid #b7c0cc; color: #7a8694; font-size: 11px;
}
.login-foot { font-size: 12px; color: #8a94a3; text-align: center; }

/* Модалка подтверждения по СМС */
.sms-box { padding: 4px 20px 4px; }
.sms-code { width: 100%; text-align: center; letter-spacing: .3em; font-size: 20px; }
.sms-demo { margin-top: 12px; font-size: 13px; color: var(--muted); text-align: center; }
.sms-demo b { color: var(--text); letter-spacing: .1em; }

.row.row-logout .row-title { color: var(--danger); }
.row.row-logout .row-ic { color: var(--danger); }

/* ── Управляющий: договоры и дебиторка ──────────────────────────────────── */
/* Плитки над лентой событий (те же пропорции, другой тон: синий и красный). */
.feed-tile.info {
  background: #eaf0fd;
  background: color-mix(in srgb, var(--brand) 10%, var(--surface));
  border-color: #c9d8f7;
  border-color: color-mix(in srgb, var(--brand) 26%, var(--line));
}
.feed-tile.info .ic { color: var(--brand); }
.feed-tile.alert {
  background: #fdecec;
  background: color-mix(in srgb, var(--danger) 10%, var(--surface));
  border-color: #f5c9c9;
  border-color: color-mix(in srgb, var(--danger) 26%, var(--line));
}
.feed-tile.alert .ic { color: var(--danger); }
.feed-tile.alert .feed-tile-value { color: var(--danger); }
/* Оранжевая плитка (реклама): не «всё хорошо» и не тревога, а работа, которую
   ведут постоянно — где висит каждая квартира и где недобираем показы. */
.feed-tile.warn {
  background: #fdf4e3;
  background: color-mix(in srgb, var(--warn) 12%, var(--surface));
  border-color: #f0dcb2;
  border-color: color-mix(in srgb, var(--warn) 30%, var(--line));
}
.feed-tile.warn .ic { color: var(--warn); }
.feed-tile.warn .feed-tile-value { color: var(--warn); }
.feed-tile-label small { display: block; font-size: 12px; font-weight: 500; color: var(--muted); margin-top: 2px; }
/* Ряд из двух плиток (Договоры + Дебиторка): значение крупно, подпись мелко. */
.tile-row { display: grid; grid-template-columns: 1fr 1fr; gap: 10px; }
.tile-row.one { grid-template-columns: 1fr; }   /* плитка без пары — во всю ширину */
.feed-tile.half { flex-direction: column; align-items: flex-start; gap: 4px; padding: 14px 12px; min-width: 0; }
.feed-tile.half .feed-tile-label { flex: none; width: 100%; font-size: 13px; }
.feed-tile.half b { display: block; font-size: 19px; font-weight: 800; letter-spacing: -.02em; margin-top: 2px; overflow-wrap: anywhere; }
.feed-tile.half small { font-size: 11.5px; }
.feed-tile.alert.half b { color: var(--danger); }
.feed-tile.warn.half b { color: var(--warn); }
.feed-tile-value { font-size: 15px; font-weight: 800; white-space: nowrap; }
.feed-tile > .ic:last-child { color: var(--muted); }
.pay-hero.danger { background: linear-gradient(135deg, var(--danger), #f0736b); }

/* Карточка договора: шапка, поля в две колонки, итоги, таблица начислений. */
.contract-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius);
  padding: 14px; box-shadow: var(--shadow);
}
.contract-card.debtor { border-color: color-mix(in srgb, var(--danger) 35%, var(--line)); }
.cc-obj {
  display: flex; align-items: center; gap: 6px; margin: 8px 0 10px;
  font-size: 12.5px; color: var(--muted);
}
.cc-obj span { flex: 1; }
.cc-obj .ic { width: 16px; height: 16px; flex: none; }
.cc-obj:active { color: var(--brand); }
.cc-fields { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 14px; }
.cc-fields > div { min-width: 0; }
.cc-fields span { display: block; font-size: 11px; color: var(--muted); }
.cc-fields b { display: block; font-size: 13.5px; font-weight: 600; overflow-wrap: anywhere; }
.cc-fields b small { font-weight: 500; color: var(--muted); }
.cc-money {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 8px; margin-top: 12px;
  padding: 10px 12px; background: var(--surface-2); border-radius: var(--radius-sm);
}
.cc-money span { display: block; font-size: 11px; color: var(--muted); }
.cc-money b { font-size: 14px; font-weight: 800; overflow-wrap: anywhere; }
.cc-debt {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  margin: 10px 0 6px; padding: 10px 12px; border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--danger) 9%, var(--surface-2));
}
.cc-debt span { font-size: 12px; color: var(--muted); }
.cc-debt b { font-size: 20px; font-weight: 800; }
.cc-note { display: flex; align-items: center; gap: 6px; font-size: 12px; margin-top: 8px; }
.cc-note .ic { width: 15px; height: 15px; flex: none; }
.cc-toggle {
  display: flex; align-items: center; gap: 6px; width: 100%; margin-top: 10px; padding: 9px 0;
  border: none; border-top: 1px solid var(--line); background: none; cursor: pointer;
  font: inherit; font-size: 13px; font-weight: 600; color: var(--brand);
}
.cc-toggle .ic { width: 16px; height: 16px; transform: rotate(90deg); transition: transform .15s; }
.cc-toggle.open .ic { transform: rotate(-90deg); }
/* Подробности договора под раскрытием (05.10.2026): клиент, расчёты, сервис,
   доп. поля и начисления. `[hidden]` пишем явно — у вложенных блоков свои
   правила с display, и атрибут они перебили бы (та же грабля, что с палитрой
   смайлов и полем даты освобождения). */
.cc-more[hidden] { display: none; }
.cc-table-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.cc-table { font-size: 12.5px; }
.cc-table th, .cc-table td { padding: 7px 9px; white-space: nowrap; }
.cc-table .num { text-align: right; }
/* Активная компактная таблица карточки объекта: кликабельные заголовки
   (сортировка) и колонка меню строки (⋮). */
.cc-table th.oc-sort { cursor: pointer; user-select: none; }
.cc-table th.oc-sort:hover { color: var(--brand); }
.cc-table .oc-dir { color: var(--brand); font-size: 10px; }
.cc-table .pick { width: 1%; padding: 3px 5px; text-align: center; }
.cc-table .pick .doc-btn.dots { width: 20px; height: 20px; }
.cc-table .row-debt { background: color-mix(in srgb, var(--danger) 7%, transparent); }
/* Окраска строки компактной таблицы — полной заливкой через --hl, как в
   основной таблице (слой поверх непрозрачного фона). */
.cc-table tbody tr[style*="--hl"] td { background: linear-gradient(var(--hl), var(--hl)), var(--surface); }
/* Кликабельная ячейка компактной таблицы (например «Чек» → открыть чек). */
.cc-table a.oc-act { color: var(--brand); text-decoration: underline; cursor: pointer; }
/* Подготовка собственника к договору: категории документов и поля. */
.prep-progress { background: color-mix(in srgb, var(--warn) 10%, var(--surface)); border: 1px solid color-mix(in srgb, var(--warn) 35%, var(--line));
  border-radius: var(--radius-sm); padding: 10px 12px; margin: 10px 0; }
.prep-cat { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 11px 12px; margin-bottom: 10px; background: var(--surface); }
.prep-cat-head { display: flex; align-items: center; gap: 8px; margin-bottom: 3px; }
.prep-req { font-size: 11px; font-weight: 700; color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, transparent);
  padding: 1px 6px; border-radius: 999px; }
.prep-files { display: flex; flex-wrap: wrap; gap: 8px; margin: 8px 0; }
.prep-file { position: relative; width: 72px; height: 72px; }
.prep-file .pic, .prep-file img { width: 72px; height: 72px; object-fit: cover; border-radius: var(--radius-sm); }
.prep-file-x { position: absolute; top: -6px; right: -6px; width: 20px; height: 20px; border-radius: 50%;
  border: none; background: var(--danger); color: #fff; font-size: 13px; line-height: 1; cursor: pointer; }
.prep-empty { font-size: 12px; color: var(--muted); align-self: center; }
.prep-adds { display: flex; gap: 8px; margin-top: 4px; }
.prep-adds .prep-add { flex: 1; margin-top: 0; }
.prep-add { margin-top: 4px; }
.prep-row .row-title { font-weight: 700; }
/* Ключи: описание словами, под ним шильдики назначений и количество
   (01.11.2026). Количество — узкое поле справа от ряда шильдиков, на узком
   экране уходит под него. */
.prep-keys { min-height: 86px; resize: vertical; }
.prep-keyadd { display: flex; align-items: flex-end; gap: 10px; flex-wrap: wrap; margin-top: 6px; }
.prep-keyadd .filter-chips { flex: 1 1 240px; }
.prep-keyqty { flex: 0 0 120px; margin: 0; }
@media (max-width: 420px) { .prep-keyqty { flex: 1 1 100%; } }
.field-check { display: flex; align-items: center; gap: 8px; padding: 6px 0; }
.field-check input { width: 18px; height: 18px; accent-color: var(--brand); }
.ok-note { background: color-mix(in srgb, var(--ok, #2f9e63) 10%, var(--surface)); border: 1px solid color-mix(in srgb, var(--ok, #2f9e63) 30%, var(--line)); }
/* Окно выбора при коллизии телефона: три крупных варианта с пояснением. */
.coll-opts { display: flex; flex-direction: column; gap: 8px; margin-top: 10px; }
.coll-opt { display: flex; flex-direction: column; gap: 3px; align-items: flex-start; text-align: left;
  padding: 11px 13px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface); cursor: pointer; width: 100%; }
.coll-opt:hover { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 6%, var(--surface)); }
.coll-opt b { font-size: 14px; }
.coll-opt .coll-sub { font-size: 12px; color: var(--muted); line-height: 1.35; }
.cc-actions { display: flex; gap: 8px; margin-top: 12px; }
.cc-actions .btn { flex: 1; }
.danger-text { color: var(--danger); }
.warn-text { color: var(--warn); }
/* Закрыто приходом на расчётный счёт юрлица (ООО): заливка ячейки сиреневым — как
   в старой системе (27.10.2026; 04.11.2026 сузили до Р/С юрлица, без карт/нала/
   кошельков). Красится сама ячейка, а не текст: человек ищет взглядом «что уже
   пришло на расчётный счёт», и заливка видна в длинной колонке сумм. */
.bank-text { background: var(--bezn-bg); color: var(--bezn); }
/* В таблице фон ячейки кладётся слоем поверх непрозрачного: иначе цвет строки
   (зелёный «оплачено целиком») перебил бы сиреневый, а липкая первая колонка
   просвечивала бы при горизонтальной прокрутке. */
.tbl tbody tr td.bank-text,
.tbl tbody tr[style*="--hl"] td.bank-text {
  background: linear-gradient(var(--bezn-bg), var(--bezn-bg)), var(--surface);
}
.link-a { color: var(--brand); font-weight: 600; }
/* Ссылкой бывает и кнопка — «указать» род деятельности прямо в строке списка
   (01.11.2026): собственный фон и рамка кнопки здесь лишние. */
button.link-a { background: none; border: 0; padding: 0; font: inherit; font-weight: 600; cursor: pointer; text-decoration: underline; }
.nowrap { white-space: nowrap; }
@media (max-width: 359px) { .cc-fields { grid-template-columns: 1fr; } }
.cc-table .row-due { background: color-mix(in srgb, var(--warn) 8%, transparent); }

/* Переговоры по задолженности (модалка): форма диалога + карточки истории. */
.talk-sum { font-size: 13px; color: var(--muted); margin: 2px 0 10px; }
.talk-form { margin-top: 10px; padding: 12px; background: var(--surface-2); border-radius: var(--radius-sm); }
.talk-form .field:last-of-type { margin-bottom: 8px; }
#talk-list { display: flex; flex-direction: column; gap: 8px; margin-top: 12px; max-height: 42vh; overflow-y: auto; }
.talk-card { border: 1px solid var(--line); border-left: 3px solid var(--brand); border-radius: var(--radius-sm); padding: 10px 12px; background: var(--surface); }
.talk-date { font-size: 11.5px; font-weight: 700; color: var(--muted); }
.talk-text { font-size: 13.5px; margin-top: 3px; white-space: pre-wrap; overflow-wrap: anywhere; }
.cc-mt { margin-top: 8px; }
.contract-card.debtor.ok { border-color: color-mix(in srgb, var(--warn) 35%, var(--line)); }
.contract-card.debtor.crit { border-color: var(--danger); }

/* ── Раздел «Таблицы» (управляющий) ─────────────────────────────────────── */
.row.soon { opacity: .62; }
.tbl-bar { display: flex; flex-direction: column; gap: 8px; }
.tbl-q { width: 100%; }
.tbl-objq { width: 100%; }
/* Поле «Месяц / Год» (03.11.2026): отбор по периоду одним полем — год
   стрелками, месяц плиткой, снизу «Сегодня» и «Сбросить». Стоит над таблицей
   справа от поиска по объекту и в окне «Фильтры» вместо списка значений. */
.mpick { position: relative; }
.tbl-bar .mpick { width: 100%; }
.mpick-btn { width: 100%; text-align: left; background: var(--surface-2); color: var(--muted); cursor: pointer; }
.mpick-btn.on { color: var(--text); font-weight: 600; border-color: var(--brand); }
.mpick-pop { position: absolute; z-index: 60; top: calc(100% + 6px); left: 0; min-width: 236px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 14px;
  box-shadow: var(--shadow); padding: 10px; }
.mpick-pop[hidden] { display: none; }
/* В окне «Фильтры» список прокручивается (.fields-box) — там панель
   раскрывается в потоке, иначе её обрезал бы край прокрутки. */
.fields-box .mpick-pop { position: static; margin-top: 6px; min-width: 0; }
.mpick-y { display: flex; align-items: center; justify-content: space-between; padding: 2px 4px 10px; }
.mpick-y b { font-size: 15px; }
.mpick-nav { border: 0; background: transparent; color: var(--text); font-size: 20px; line-height: 1;
  padding: 2px 12px; border-radius: 8px; cursor: pointer; }
.mpick-nav:hover { background: var(--surface-2); }
.mpick-m { display: grid; grid-template-columns: repeat(3, 1fr); gap: 4px; }
.mpick-mo { border: 0; background: transparent; color: var(--text); padding: 9px 4px;
  border-radius: 10px; font-size: 14px; cursor: pointer; }
.mpick-mo:hover { background: var(--surface-2); }
.mpick-mo.on { background: var(--brand); color: #fff; font-weight: 700; }
.mpick-mo.empty { color: var(--muted); opacity: .5; }
.mpick-bar { display: flex; justify-content: space-between; gap: 10px;
  margin-top: 10px; padding-top: 8px; border-top: 1px solid var(--line); }
.tbl-btns { display: flex; gap: 6px; overflow-x: auto; scrollbar-width: none; }
.tbl-btns::-webkit-scrollbar { display: none; }
.tbl-btn {
  display: inline-flex; align-items: center; gap: 5px; white-space: nowrap; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface); color: var(--text);
  border-radius: 999px; padding: 7px 12px; font: inherit; font-size: 13px; font-weight: 600;
}
.tbl-btn .ic { width: 15px; height: 15px; color: var(--muted); }
.tbl-btn.on { border-color: var(--brand); color: var(--brand); }
.tbl-btn.on .ic { color: var(--brand); }
.fchip.on { background: color-mix(in srgb, var(--brand) 12%, var(--surface)); border-color: var(--brand); color: var(--brand); }

/* Таблица: горизонтальная прокрутка, липкие шапка и первая колонка. */
/* Таблица прокручивается САМА, а не вместе со страницей: только у своего
   скроллера липнут заголовки колонок и строка итогов, и только так полоса
   прокрутки остаётся на экране, а не уезжает в конец списка. Высоту считает
   `fitTable()` в tables.js — над таблицей стоят панель, галочки и шильдики
   фильтров, и их высота у каждой таблицы своя. */
.tbl-wrap {
  overflow: auto; max-height: var(--tbl-h, none);
  border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface);
  -webkit-overflow-scrolling: touch;
  /* Полосу прокрутки показываем всегда: в таблице десяток колонок, и по ней
     видно, что вправо есть ещё. Там, где система рисует полосу поверх
     содержимого (macOS, iOS), эти правила не действуют — она появится в момент
     прокрутки, как везде в системе. */
  scrollbar-width: thin; scrollbar-color: color-mix(in srgb, var(--muted) 45%, transparent) transparent;
}
.tbl-wrap::-webkit-scrollbar { width: 10px; height: 10px; }
.tbl-wrap::-webkit-scrollbar-track { background: transparent; }
.tbl-wrap::-webkit-scrollbar-thumb {
  background: color-mix(in srgb, var(--muted) 45%, transparent);
  border-radius: 8px; border: 2px solid transparent; background-clip: padding-box;
}
.tbl-wrap::-webkit-scrollbar-thumb:hover { background: color-mix(in srgb, var(--muted) 70%, transparent); background-clip: padding-box; }
.tbl { border-collapse: separate; border-spacing: 0; width: max-content; min-width: 100%; font-size: 12.5px; }
.tbl th, .tbl td { padding: var(--rowpad, 8px) 10px; white-space: nowrap; border-bottom: 1px solid var(--line); text-align: left; }
/* Высота строки — только вертикальные отступы: шрифт остаётся прежним. */
.tbl.rh-xs { --rowpad: 3px; --iconbtn: 19px; --iconsvg: 12px; --pickw: 24px; --pickbox: 14px; }
.tbl.rh-sm { --rowpad: 8px; --iconbtn: 24px; --iconsvg: 14px; --pickw: 28px; --pickbox: 16px; }
.tbl.rh-md { --rowpad: 14px; --iconbtn: 28px; --iconsvg: 16px; --pickw: 32px; --pickbox: 17px; }
.tbl.rh-lg { --rowpad: 22px; }
.tbl th {
  position: sticky; top: 0; z-index: 2; cursor: pointer; user-select: none;
  background: var(--surface-2); color: var(--muted); font-weight: 600; font-size: 11.5px;
}
.tbl th.first, .tbl td.first {
  position: sticky; left: 0; z-index: 1; background: var(--surface);
  max-width: 190px; overflow: hidden; text-overflow: ellipsis;
  box-shadow: 1px 0 0 var(--line);
}
.tbl th.first { z-index: 3; background: var(--surface-2); }
.tbl td.num { text-align: right; font-variant-numeric: tabular-nums; }
.tbl tbody tr:active td { background: var(--surface-2); }
.tbl tbody tr:last-child td { border-bottom: none; }
.tbl-dir { margin-left: 4px; color: var(--brand); }
.tbl-empty { padding: 22px 12px; text-align: center; color: var(--muted); }

/* Модалки таблицы: поля, фильтры, представления. */
.fields-box { max-height: 52vh; overflow-y: auto; margin-bottom: 12px; }
.fields-group { margin-bottom: 12px; }
.fld-check { display: flex; align-items: center; gap: 10px; padding: 8px 2px; font-size: 14px; border-bottom: 1px solid var(--line); }
.fld-check input { width: 18px; height: 18px; accent-color: var(--brand); flex: none; }
.flt-item { margin-bottom: 12px; }
.flt-item .fld-input { width: 100%; }
/* Отбор «условие + значения»: селект условия и поля под ним друг под другом. */
.flt-item .flt-op { margin-bottom: 8px; }
.flt-item .flt-vals .fld { margin-bottom: 0; }
/* Компактная форма правила разнесения (16.10.2026, просьба заказчика): подпись
   и поле в одну строку, поля мельче — форма занимает меньше места. */
.rule-form .field { flex-direction: row; align-items: center; gap: 10px; margin-bottom: 7px; }
.rule-form .field > span { flex: 0 0 150px; font-size: 12px; }
.rule-form .field > .fld-input, .rule-form .field > select.fld-input, .rule-form .field > .addr-pick { flex: 1; min-width: 0; }
.rule-form .fld-input, .rule-form select.fld-input { padding: 6px 9px; font-size: 13px; }
.rule-form .addr-pick { gap: 6px; }
.rule-form .fld-row { gap: 8px; }
.rule-form .fld-row .field { flex-direction: column; align-items: stretch; margin-bottom: 0; }
.rule-form .fld-row .field > span { flex: none; font-size: 11px; }
.rule-form .cc-h { margin: 10px 0 5px; }
.rule-form > .field:first-child { margin-top: 0; }
@media (max-width: 460px) {
  .rule-form .field { flex-direction: column; align-items: stretch; gap: 3px; }
  .rule-form .field > span { flex: none; }
}
.vw-save { flex: none; align-self: flex-end; white-space: nowrap; }
.vw-row { display: flex; align-items: stretch; gap: 8px; margin-bottom: 8px; }
.vw-apply {
  flex: 1; text-align: left; cursor: pointer; font: inherit;
  border: 1px solid var(--line); background: var(--surface); color: var(--text);
  border-radius: var(--radius-sm); padding: 10px 12px;
}
.vw-apply b { display: block; font-size: 14px; }
.vw-apply small { color: var(--muted); font-size: 12px; }
.vw-del { flex: none; width: 40px; border: 1px solid var(--line); background: var(--surface); color: var(--danger); border-radius: var(--radius-sm); font-size: 20px; line-height: 1; cursor: pointer; }

/* ── Режим экрана «ПК» (переключатель в шапке) ──────────────────────────── */
/* Снимаем мобильную ширину и уплотняем вёрстку: за компьютером в таблицу
   помещается больше колонок и строк, ради этого режим и нужен.
   ВАЖНО: режим включают и на телефоне — кнопка одна на всех экранах, а выбор
   помнится в браузере. Раскладку «как на мониторе» на узком экране применять
   нельзя: четыре колонки на 360 px давали плитки шириной с палец, подписи
   обрезались до «Об», «С», «Квит», «Сч», а нижняя панель растягивалась во всю
   ширину. Поэтому всё, что требует места, живёт под медиазапросом по РЕАЛЬНОЙ
   ширине экрана, а не по одному лишь флагу режима. */
body.desk .app { max-width: 1400px; }
body.desk .app-bar { max-width: 1400px; }
.view-mode-btn { flex: none; }

/* Плитки: две колонки на телефоне, три на планшете, четыре на мониторе. */
body.desk .stat-grid { grid-template-columns: repeat(2, 1fr); }

@media (min-width: 620px) {
  body.desk .stat-grid { grid-template-columns: repeat(3, 1fr); }
  body.desk .wrap { padding: 16px 20px 6px; gap: 12px; }
  body.desk .app-bar { padding-left: 20px; padding-right: 20px; }
  body.desk .tile-row { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Одиночная плитка без пары — во всю ширину и на ПК: иначе правило выше (оно
     специфичнее, чем `.tile-row.one`) оставляло пустую вторую ячейку (06.10.2026). */
  body.desk .tile-row.one { grid-template-columns: 1fr; }
  body.desk .quick { max-width: 720px; }
  body.desk .filters-row { max-width: 720px; }
  /* Нижняя панель — по ширине основного поля, а не во весь экран: на широком
     мониторе четыре иконки разъезжались по углам, и до «Ещё» приходилось вести
     курсор через весь экран. Сама панель ограничена шириной приложения, а ряд
     иконок собран в центр — на 1400 px растягивать его не на что. */
  /* На мониторе ряд иконок собран в центр колонками по 190px — их столько же,
     сколько пунктов (в ЛКУ пять, в остальных кабинетах четыре). */
  body.desk .tabbar { max-width: 1400px; grid-auto-columns: minmax(0, 190px); justify-content: center; }
  body.desk .modal { max-width: 720px; border-radius: var(--radius); }
  body.desk .modal-overlay { align-items: center; }
  body.desk .fields-box { max-height: 60vh; }
  body.desk .fields-group { columns: 2; column-gap: 24px; }
  body.desk .fld-check { break-inside: avoid; }
  /* Таблица уплотняется тоже только на широком экране: на телефоне 13 px
     и узкие отступы делают её нечитаемой, а строк всё равно больше не влезет. */
  body.desk .tbl { font-size: 13px; }
  body.desk .tbl th, body.desk .tbl td { padding: var(--rowpad, 9px) 14px; }
  body.desk .tbl th.first, body.desk .tbl td.first { max-width: 420px; }
  /* На мониторе отступы шире, и место под ползунок нужно шире тоже: иначе
     полоска ложится на подпись колонки. */
  body.desk .tbl th[data-sort] { padding-right: 20px; }
  body.desk .tbl-bar { flex-direction: row; align-items: center; gap: 10px; }
  /* Поиск не сжимается кнопками: держит свою ширину, а кнопки при нехватке
     места прокручиваются вбок (раньше `flex-shrink` ужимал поиск до квадратика). */
  body.desk .tbl-q { flex: 0 0 300px; width: 300px; max-width: 340px; }
  body.desk .tbl-objq { flex: 0 0 240px; width: 240px; max-width: 280px; }
  body.desk .tbl-bar .mpick { flex: 0 0 160px; width: 160px; }
  body.desk .tbl-btns { margin-left: auto; min-width: 0; overflow-x: auto; }
}

@media (min-width: 900px) {
  body.desk .stat-grid { grid-template-columns: repeat(4, 1fr); }
  body.desk .list.cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(330px, 1fr)); align-items: stretch; }
  body.desk .list.cards.rows { display: flex; }
}

/* Цветовыделение строк: слой --hl поверх непрозрачного фона, иначе липкая
   первая колонка просвечивала бы при горизонтальной прокрутке. */
.tbl tbody tr[style*="--hl"] td { background: linear-gradient(var(--hl), var(--hl)), var(--surface); }
.tbl tbody tr[style*="--hl"] td.first { background: linear-gradient(var(--hl), var(--hl)), var(--surface); }

/* Крестик-кружок в поле фильтра. */
.fld-ctl { position: relative; display: block; }
.fld-ctl .fld-input { width: 100%; padding-right: 38px; }
.fld-ctl select.fld-input { padding-right: 56px; }
.fld-clear {
  position: absolute; top: 50%; right: 8px; transform: translateY(-50%);
  width: 22px; height: 22px; border-radius: 50%; border: 1px solid var(--line);
  background: var(--surface-2); color: var(--muted); font-size: 15px; line-height: 1;
  display: grid; place-items: center; cursor: pointer; padding: 0;
}
.fld-ctl select.fld-input ~ .fld-clear { right: 26px; }
.fld-clear:active { background: var(--line); color: var(--text); }

/* Правила цветовыделения — подкарточки со стрелками порядка. */
.clr-card {
  display: flex; align-items: center; gap: 8px; margin-bottom: 8px; padding: 8px 10px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: linear-gradient(var(--hl), var(--hl)), var(--surface);
}
.clr-dot { width: 14px; height: 14px; border-radius: 50%; flex: none; }
.clr-main { flex: 1; font-size: 13.5px; font-weight: 600; overflow-wrap: anywhere; }
.clr-ord { display: flex; flex-direction: column; gap: 2px; flex: none; }
.clr-btn { width: 26px; height: 18px; border: 1px solid var(--line); background: var(--surface); color: var(--muted); border-radius: 6px; font-size: 9px; line-height: 1; cursor: pointer; padding: 0; }
.clr-btn[disabled] { opacity: .35; }
.clr-del { flex: none; width: 28px; height: 28px; border: 1px solid var(--line); background: var(--surface); color: var(--danger); border-radius: 50%; font-size: 17px; line-height: 1; cursor: pointer; padding: 0; }
.clr-form { margin-top: 10px; padding: 12px; background: var(--surface-2); border-radius: var(--radius-sm); }
.clr-palette { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 12px; }
.clr-sw { width: 30px; height: 30px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; padding: 0; }
.clr-sw.on { border-color: var(--text); box-shadow: 0 0 0 2px var(--surface) inset; }

/* Строка итогов — в шапке, сразу над первой строкой данных; липнет под
   заголовками колонок (их высоту меряет tables.js и кладёт в --head-h). */
.tbl .tbl-totals:empty { display: none; }
.tbl .tbl-totals th {
  position: sticky; top: var(--head-h, 30px); z-index: 2; cursor: default;
  background: color-mix(in srgb, var(--brand) 7%, var(--surface));
  border-bottom: 1px solid var(--line);
  padding-top: 7px; padding-bottom: 7px; font-weight: 600;
}
.tbl .tbl-totals th.first { z-index: 4; }
.tbl .tbl-totals small { display: block; font-size: 10.5px; color: var(--muted); font-weight: 600; }
.tbl .tbl-totals b { font-size: 13px; font-weight: 800; color: var(--text); }

/* Ширина колонки: ползунок на правой границе заголовка. Полоска узкая, но
   область захвата шире самой полоски — попасть в неё пальцем иначе нельзя.
   Заголовок с заданной вручную шириной помечен точкой: видно, где ширина
   уже не «по содержимому». */
.th-grip {
  position: absolute; top: 0; right: 0; width: 14px; height: 100%;
  cursor: col-resize; touch-action: none; z-index: 2;
  display: flex; align-items: center; justify-content: flex-end;
}
.th-grip::before {
  content: ''; width: 2px; height: 58%; border-radius: 2px;
  background: var(--line); transition: background .12s, height .12s;
}
.th-grip:hover::before, .tbl th.resizing .th-grip::before { background: var(--brand); height: 100%; }
.tbl th[data-wset] .th-grip::before { background: color-mix(in srgb, var(--brand) 45%, var(--line)); }
.tbl th.resizing { background: color-mix(in srgb, var(--brand) 12%, var(--surface-2)); }
/* Заголовку нужна своя система координат под ползунок и место под него справа,
   чтобы полоска не наезжала на подпись колонки. */
.tbl th[data-sort] { position: sticky; padding-right: 16px; }
body.col-resizing { user-select: none; -webkit-user-select: none; cursor: col-resize; }
body.col-resizing .tbl tbody { pointer-events: none; }

/* Перестановка колонок: тянем заголовок вбок. */
.tbl th[data-sort] { touch-action: pan-y; }
.tbl th.dragging { opacity: .55; background: color-mix(in srgb, var(--brand) 18%, var(--surface-2)); }
.tbl th.drop-target { box-shadow: inset 3px 0 0 var(--brand); }
body.col-dragging { user-select: none; -webkit-user-select: none; cursor: grabbing; }
body.col-dragging .tbl tbody { pointer-events: none; }

/* Порядок колонок в окне «Поля». */
.ord-list { display: flex; flex-direction: column; gap: 6px; margin-bottom: 14px; max-height: 30vh; overflow-y: auto; }
.ord-row { display: flex; align-items: center; gap: 6px; padding: 7px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.ord-name { flex: 1; font-size: 13.5px; font-weight: 600; overflow-wrap: anywhere; }
.ord-row .clr-btn { height: 24px; }
.cc-h small { font-weight: 500; text-transform: none; letter-spacing: 0; }

/* Выделение строк таблицы и панель действий над выбранным. */
/* Служебные колонки (галочка, документ, карточка) масштабируются вместе с
   плотностью: в режиме «Плотно» строка не должна распирать иконками. */
.tbl th.pick, .tbl td.pick { width: var(--pickw, 30px); text-align: center; padding-left: 6px; padding-right: 2px; }
.tbl td.pick input, .tbl th.pick input { width: var(--pickbox, 16px); height: var(--pickbox, 16px); accent-color: var(--brand); }
.pick-bar[hidden] { display: none; }
.pick-bar {
  display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 8px 10px;
  border: 1px solid var(--brand); border-radius: var(--radius-sm);
  background: color-mix(in srgb, var(--brand) 9%, var(--surface));
}
.pick-count { font-size: 13px; font-weight: 700; }
.pick-sum { font-size: 13px; font-weight: 800; color: var(--brand); margin-right: auto; }
.btn.sm { padding: 7px 12px; font-size: 13px; }

/* Предпросмотр допсоглашения. */
.ag-doc { max-height: 44vh; overflow-y: auto; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 14px; margin: 12px 0; background: var(--surface); font-size: 13px; line-height: 1.5; }
.ag-doc h1 { font-size: 14px; text-align: center; margin-bottom: 10px; }
.ag-doc p { margin: 7px 0; }
.ag-doc table { width: 100%; border-collapse: collapse; margin: 10px 0; }
.ag-doc th, .ag-doc td { border: 1px solid var(--line); padding: 5px 7px; font-size: 12.5px; text-align: left; }
.ag-doc .num { text-align: right; font-variant-numeric: tabular-nums; }
.ag-doc .sign { display: flex; justify-content: space-between; gap: 12px; margin-top: 18px; font-size: 12px; color: var(--muted); }

/* Иконка формирования документа в строке таблицы и предпросмотр документа. */
.doc-btn { width: var(--iconbtn, 24px); height: var(--iconbtn, 24px); border: 1px solid var(--line); background: var(--surface); color: var(--brand); border-radius: 6px; cursor: pointer; display: grid; place-items: center; padding: 0; }
.doc-btn .ic { width: var(--iconsvg, 14px); height: var(--iconsvg, 14px); }
.doc-btn:active { background: var(--surface-2); }
.tbl th.pick .ic { width: var(--iconsvg, 14px); height: var(--iconsvg, 14px); vertical-align: middle; }
.doc-preview h1 { font-size: 14px; text-align: center; margin: 0 0 8px; }
.doc-preview h2 { font-size: 13px; margin: 12px 0 5px; }
.doc-preview .doc-lead { text-align: center; color: var(--muted); font-size: 12px; }
.doc-preview .doc-cols { display: flex; gap: 18px; margin-top: 8px; font-size: 12px; }
.doc-preview .doc-cols > div { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.doc-preview .doc-sign { display: flex; justify-content: space-between; gap: 12px; margin-top: 16px; font-size: 12px; color: var(--muted); }
.doc-preview .doc-table { width: 100%; border-collapse: collapse; margin: 8px 0; }
.doc-preview .doc-table th, .doc-preview .doc-table td { border: 1px solid var(--line); padding: 4px 6px; font-size: 12px; text-align: left; }
.doc-preview .doc-small { font-size: 11.5px; color: var(--muted); }
.doc-preview .doc-page { border-top: 2px dashed var(--line); margin-top: 18px; padding-top: 14px; }
.src-tag { margin-left: 6px; font-size: 10px; font-weight: 700; color: var(--brand); background: color-mix(in srgb, var(--brand) 12%, transparent); border-radius: 999px; padding: 1px 6px; }

/* Согласия перед подписанием документа собственником. */
.policy-box { margin: 12px 0; padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); }
.policy-box .fld-check { border-bottom: none; padding: 6px 2px; align-items: flex-start; }
.policy-box .fld-check span { font-size: 13px; line-height: 1.4; }
.policy-box .settle-note { margin-top: 6px; }

/* Разделы карточки: раскрытие по «+». */
.sec { border: 1px solid var(--line); border-radius: var(--radius-sm); margin-bottom: 8px; overflow: hidden; }
.sec-head { display: flex; align-items: center; gap: 10px; width: 100%; padding: 10px 12px; border: none; background: var(--surface-2); cursor: pointer; font: inherit; text-align: left; }
.sec-plus { width: 20px; height: 20px; flex: none; display: grid; place-items: center; border-radius: 6px; background: var(--surface); border: 1px solid var(--line); font-size: 14px; line-height: 1; color: var(--brand); font-weight: 700; }
.sec-title { flex: 1; font-size: 13.5px; font-weight: 700; }
.sec-count { font-size: 11px; color: var(--muted); }
.sec-body { padding: 12px 12px 2px; }
.sec.open .sec-head { background: color-mix(in srgb, var(--brand) 8%, var(--surface-2)); }
.tbl-btn.add { border-color: var(--brand); color: var(--brand); font-weight: 700; }
.tbl-btn.add .ic { color: var(--brand); }
.src-tag.alt { color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, transparent); }

/* Сверка изменённого значения, подтянутого из связанной таблицы. */
.field .fld-ctl { position: relative; display: block; }
.chg-btn { position: absolute; top: 50%; right: 8px; transform: translateY(-50%); width: 24px; height: 24px; border-radius: 50%; border: 1px solid var(--warn); background: color-mix(in srgb, var(--warn) 16%, var(--surface)); color: var(--warn); font-size: 13px; line-height: 1; cursor: pointer; padding: 0; }
.chg-btn[hidden] { display: none; }
.chg-rows { margin: 10px 0; }
.chg-row { display: flex; justify-content: space-between; gap: 12px; padding: 9px 11px; border: 1px solid var(--line); border-radius: var(--radius-sm); margin-bottom: 6px; }
.chg-row span { color: var(--muted); font-size: 12px; }
.chg-row b { font-size: 13.5px; overflow-wrap: anywhere; text-align: right; }
.chg-row.now { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 8%, var(--surface)); }
.chg-block { margin-bottom: 12px; }
.chg-cap { font-size: 12px; font-weight: 600; color: var(--muted); margin: 4px 0 6px; }
.subev-media { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.ev-thumb { width: 72px; height: 72px; border-radius: 8px; border: 1px solid var(--line); background-size: cover; background-position: center center; padding: 0; display: block; }
button.ev-thumb { cursor: pointer; }
.modal-actions.wrap { flex-wrap: wrap; }
.modal-actions.wrap .btn { flex: 1 1 30%; min-width: 110px; }
.fld-hint { display: block; margin-top: 4px; font-size: 11.5px; color: var(--muted); }
.dict-multi { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 4px 10px; background: var(--surface); }
.dict-multi .fld-check { border-bottom: none; padding: 5px 0; }
.dict-multi .fld-check span { font-size: 13px; }

/* На телефоне внутренние области прокручиваем меньше — основной скролл у окна. */
@media (max-width: 640px) {
  .ag-doc, .doc-preview { max-height: 40vh; }
  .fields-box { max-height: none; }
  .ord-list { max-height: 24vh; }
}

/* Карандаш правки на карточке объекта в списке. */
.card { position: relative; }
.card-edit {
  position: absolute; top: 10px; right: 10px; z-index: 2;
  width: 30px; height: 30px; border-radius: 8px; padding: 0; cursor: pointer;
  border: 1px solid var(--line); background: color-mix(in srgb, var(--surface) 88%, transparent);
  color: var(--brand); display: grid; place-items: center;
}
.card-edit .ic { width: 16px; height: 16px; }
.card-edit:active { background: var(--surface-2); }

/* Меню строки (три точки): редактировать / дублировать / удалить. */
.card-edit.dots, .doc-btn.dots { font-size: 17px; line-height: 1; color: var(--muted); font-weight: 700; }
/* Облачко комментария в начале строки: голубое, без рамки, рядом с «⋮». */
.doc-btn.note-chip { border-color: transparent; background: transparent; color: var(--brand); }
.doc-btn.note-chip:active { background: var(--surface-2); }
/* Чекбокс / облачко / «⋮» — в один горизонтальный ряд: облачко и «⋮» лежат в
   одной ячейке, обёртка кладёт их бок о бок, а ячейка растёт по содержимому. */
.tbl td.menu-cell { width: auto; white-space: nowrap; }
.row-tools { display: inline-flex; align-items: center; gap: 2px; vertical-align: middle; }
/* Пустой слот под облачко: той же ширины, что кнопка облачка, — «⋮» не съезжает
   вправо на строках без комментария и стоит на одном уровне. */
.note-chip-slot { display: inline-block; width: var(--iconbtn, 24px); height: var(--iconbtn, 24px); }
.card-edit { font-size: 18px; line-height: 1; font-weight: 700; color: var(--muted); }
.row-menu {
  position: fixed; z-index: 60; min-width: 196px; padding: 4px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  box-shadow: 0 10px 30px rgba(0,0,0,.22);
}
.row-menu button {
  display: flex; align-items: center; gap: 8px; width: 100%; padding: 10px 12px;
  border: none; background: none; font: inherit; font-size: 14px; color: var(--text);
  text-align: left; cursor: pointer; border-radius: 8px;
}
.row-menu button:active { background: var(--surface-2); }
.row-menu button.danger { color: var(--danger); }
.row-menu .ic { width: 16px; height: 16px; color: var(--muted); }
.row-menu button.danger .ic { color: var(--danger); }
/* Заголовок группы и активный пункт в меню «⋮» карточки задачи/заявки. */
.row-menu-h { padding: 6px 12px 2px; font-size: 11px; color: var(--muted); text-transform: uppercase; letter-spacing: .3px; }
.row-menu button.on { color: var(--brand); font-weight: 700; }
.row-menu button.on::after { content: ' ✓'; }
/* Правый блок карточки задачи/заявки: иконки (скрепка · глазик · ⋮) в одну
   строку, статус отдельной строкой ниже (01.11.2026, просьба заказчика). */
.work-right { display: flex; flex-direction: column; align-items: flex-end; gap: 5px; flex: none; }
.work-icons { display: flex; align-items: center; gap: 6px; }

/* Комментарии к документу в окне просмотра. */
.doc-comments { margin: 12px 0; padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); }
.doc-comments[hidden] { display: none; }
.doc-comments .settle-note { margin-bottom: 10px; }
.doc-comments #dc-comment-list { display: flex; flex-direction: column; gap: 8px; max-height: 26vh; overflow-y: auto; margin-bottom: 10px; }
.doc-comments textarea.fld-input { width: 100%; }

/* Панель правки документа (управляющий). */
.doc-toolbar { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin: 10px 0 -6px; padding: 6px; background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius-sm); }
.doc-toolbar[hidden] { display: none; }
.doc-toolbar button { width: 32px; height: 30px; border: 1px solid var(--line); background: var(--surface); color: var(--text); border-radius: 7px; font-size: 14px; font-weight: 700; cursor: pointer; padding: 0; }
.doc-toolbar button:active { background: var(--surface-2); }
.doc-toolbar-hint { font-size: 11.5px; color: var(--muted); margin-left: auto; }
.doc-preview.editing { outline: 2px solid var(--brand); outline-offset: -2px; background: color-mix(in srgb, var(--brand) 4%, var(--surface)); }
.btn.ghost.on { border-color: var(--brand); color: var(--brand); }

/* Действия окна документа сеткой 2×2. */
.modal-actions.grid2 { display: grid; grid-template-columns: 1fr 1fr; gap: 8px; }
.modal-actions.grid2 .btn { width: 100%; }
.doc-signed { display: flex; align-items: center; justify-content: center; gap: 6px; font-size: 13px; font-weight: 700; color: var(--ok); }
.doc-signed .ic { width: 16px; height: 16px; }

/* Состояние документов на иконке договора. */
.doc-btn { position: relative; }
.doc-btn.st-draft { border-color: var(--brand); color: var(--brand); }
.doc-btn.st-sent { border-color: var(--warn); color: var(--warn); background: color-mix(in srgb, var(--warn) 12%, var(--surface)); }
.doc-btn.st-signed { border-color: var(--ok); color: var(--ok); }
.doc-dot { position: absolute; top: -2px; right: -2px; width: 8px; height: 8px; border-radius: 50%; background: var(--warn); border: 1.5px solid var(--surface); }
.doc-btn.st-draft .doc-dot { background: var(--brand); }

/* Значение-фильтр в ячейке (номер телефона, собеседник): по клику таблица
   показывает все строки с этим значением. Подчёркивание пунктиром — обычный
   способ показать, что это не просто текст. */
.cell-filter {
  border: 0; background: none; padding: 0; font: inherit; color: var(--brand);
  cursor: pointer; text-align: inherit;
  border-bottom: 1px dashed color-mix(in srgb, var(--brand) 45%, transparent);
}
.cell-filter:hover { border-bottom-style: solid; }
.cell-filter:active { opacity: .6; }

/* Объект, отмеченный агентом в подборке: его показывают клиенту первым. */
.pick-fav { border-color: color-mix(in srgb, var(--warn) 45%, var(--line)); }

/* Ссылка на XML-фид площадки: длинная, поэтому переносим и даём моноширинный шрифт. */
.feed-box { margin-top: 8px; }
.feed-url { margin: 6px 0; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-2); font-family: ui-monospace, SFMono-Regular, Menlo, monospace;
  font-size: 11.5px; line-height: 1.4; overflow-wrap: anywhere; }

/* Пошаговая инструкция по интеграции: нумерованный список внутри окна. */
.guide-list { margin: 8px 0 4px; padding-left: 20px; display: flex; flex-direction: column; gap: 6px; }
.guide-list li { font-size: 13px; line-height: 1.45; color: var(--text); }
.guide-list li::marker { color: var(--muted); font-weight: 600; }

/* Список уже сформированных документов в окне. */
.doc-list { display: flex; flex-direction: column; gap: 6px; margin: 8px 0 12px; max-height: 22vh; overflow-y: auto; }
.doc-row { display: flex; align-items: center; gap: 10px; padding: 8px 10px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); }
.doc-row-main { flex: 1; font-size: 13px; font-weight: 600; overflow-wrap: anywhere; }
.doc-row-main small { display: block; font-size: 11.5px; font-weight: 500; color: var(--muted); }

/* Уведомление собственнику: документ ждёт подписи. */
.banner-btn.sign {
  background: color-mix(in srgb, var(--warn) 14%, var(--surface));
  border: 1px solid color-mix(in srgb, var(--warn) 40%, var(--line));
}
.banner-btn.sign .ic { color: var(--warn); }
.banner-btn.sign small { display: block; font-size: 12px; font-weight: 500; color: var(--muted); margin-top: 2px; }
.row.row-alert { border-color: color-mix(in srgb, var(--warn) 45%, var(--line)); background: color-mix(in srgb, var(--warn) 8%, var(--surface)); }

/* Плашка действий внизу окна: компактные кнопки, липкая при прокрутке. */
.modal-bar {
  position: sticky; bottom: calc(-1 * var(--safe-bottom)); z-index: 3;
  display: flex; flex-direction: column; gap: 6px;
  margin-top: 12px; padding-top: 10px; background: var(--surface);
  box-shadow: 0 -10px 16px -12px rgba(0,0,0,.35);
}
/* Ряд кнопок переносится, а не уезжает за экран (03.10.2026): раньше колонки шли
   в одну строку (grid-auto-flow: column), и пятая кнопка в карточке задачи/заявки
   оказывалась за правым краем телефона. auto-fit делит ширину поровну, пока кнопки
   влезают от 110 px, дальше переносит на следующую строку. */
.mb-row { display: grid; grid-template-columns: repeat(auto-fit, minmax(min(110px, 100%), 1fr)); gap: 6px; }
.mb-row[hidden] { display: none; }
.modal-bar .btn {
  padding: 9px 8px; font-size: 12.5px; min-width: 0; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis;
}
.modal-bar .doc-signed { justify-content: center; font-size: 12.5px; }
.doc-row-act { display: flex; gap: 4px; flex: none; }
.doc-row-act .tbl-btn { padding: 5px 9px; font-size: 11.5px; }
.cc-actions .btn.sm { flex: 1 1 auto; }
.docs-box { margin: 10px 0; padding: 12px; border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface-2); }
.docs-box[hidden] { display: none; }
.docs-box .cc-h { margin-top: 10px; }
.docs-box .cc-h:first-child { margin-top: 0; }
.docs-box .doc-list { max-height: none; }

/* Плашка документа: цвет по состоянию — как иконки в таблице. */
.doc-card { border-left: 4px solid var(--line); }
.doc-card.st-draft { border-left-color: var(--brand); background: color-mix(in srgb, var(--brand) 4%, var(--surface)); }
.doc-card.st-sent { border-left-color: var(--warn); background: color-mix(in srgb, var(--warn) 7%, var(--surface)); }
.doc-card.st-signed { border-left-color: var(--ok); background: color-mix(in srgb, var(--ok) 5%, var(--surface)); }
/* Комментарий собственника прямо в плашке. */
.doc-comment { margin: 10px 0 0; padding: 9px 11px; border-radius: var(--radius-sm); background: var(--surface-2); border-left: 3px solid var(--brand); }
.doc-comment .talk-date { display: flex; align-items: center; gap: 5px; }
.doc-comment .ic { width: 14px; height: 14px; }
.doc-card.st-terminated { border-left-color: var(--muted); opacity: .75; }

/* Выбор начислений для допсоглашения. */
.charge-pick { display: flex; align-items: center; gap: 10px; padding: 9px 2px; }
.charge-pick .cp-main { flex: 1; font-size: 13.5px; font-weight: 600; overflow-wrap: anywhere; }
.charge-pick .cp-main small { display: block; font-size: 11.5px; font-weight: 500; color: var(--muted); }
.charge-pick b { white-space: nowrap; }
.charge-pick.done { opacity: .6; }
button.banner-btn { width: 100%; text-align: left; font: inherit; cursor: pointer; }

/* Крестик закрытия окна — вместо кнопки «Закрыть» в плашке. */
.modal { position: relative; }
.modal-x {
  position: absolute; top: 10px; right: 10px; z-index: 5;
  width: 34px; height: 34px; border-radius: 50%; padding: 0; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
  font-size: 20px; line-height: 1; display: grid; place-items: center;
}
.modal-x:active { background: var(--surface-2); color: var(--text); }
/* Стрелка «на уровень назад» в окне поверх окна (06.11.2026): пара крестику, слева. */
.modal-bk {
  position: sticky; top: 0; float: left; z-index: 5;
  width: 34px; height: 34px; margin: -8px 0 -34px -6px; padding: 0; cursor: pointer;
  border-radius: 50%; border: 1px solid var(--line); background: var(--surface); color: var(--text);
  display: grid; place-items: center; box-shadow: 0 2px 8px rgba(0,0,0,.12);
}
.modal-bk:active { background: var(--surface-2); }
.modal-bk svg { width: 20px; height: 20px; }
.modal-bk + .modal-head { padding-left: 36px; }
.modal-head { padding-right: 42px; }
.btn.ghost.warn { border-color: var(--warn); color: var(--warn); }

/* ── Кабинет компании ───────────────────────────────────────────────────── */
/* Строка «заголовок + шильдик» в карточках управляющих, объектов, модулей. */
.row-line { display: flex; align-items: flex-start; justify-content: space-between; gap: 10px; }
.row-line .card-title { min-width: 0; }
.kind-line { display: flex; align-items: center; gap: 8px; margin-top: 8px; font-size: 13.5px; font-weight: 600; }
.kv-row b small { display: block; font-weight: 500; font-size: 11.5px; color: var(--muted); }
.mod-desc { margin: 8px 0 0; font-size: 13.5px; color: var(--ink-soft, var(--text)); }
/* Шильдики типов управляющих: их шесть, поэтому ряд прокручивается вбок. */
.seg.scroll { overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
.seg.scroll::-webkit-scrollbar { display: none; }
.seg.scroll .seg-btn { flex: 0 0 auto; white-space: nowrap; }
/* Переключатель подключения модуля у управляющего. */
.mod-sw { flex: 0 0 auto; position: relative; width: 44px; height: 26px; }
.mod-sw input { position: absolute; opacity: 0; width: 100%; height: 100%; margin: 0; cursor: pointer; }
.mod-sw span {
  position: absolute; inset: 0; border-radius: 999px; background: var(--surface-2);
  border: 1px solid var(--line); transition: background .15s, border-color .15s; pointer-events: none;
}
.mod-sw span::after {
  content: ''; position: absolute; top: 2px; left: 2px; width: 20px; height: 20px; border-radius: 50%;
  background: #fff; box-shadow: var(--shadow); transition: transform .15s;
}
.mod-sw input:checked + span { background: var(--ok); border-color: var(--ok); }
.mod-sw input:checked + span::after { transform: translateX(18px); }
.mod-sw input:disabled + span { opacity: .5; }
/* Матрица «цикл работ × тип управляющего»: прокручивается вбок, первый столбец липкий. */
.mx-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); }
.mx-table { border-collapse: collapse; width: 100%; font-size: 12.5px; }
.mx-table th, .mx-table td { border-bottom: 1px solid var(--line); padding: 8px 6px; text-align: center; }
.mx-table th { position: sticky; top: 0; background: var(--surface-2); font-size: 12px; }
.mx-table th small { display: block; font-weight: 500; font-size: 10.5px; color: var(--muted); }
.mx-table .mx-stage {
  position: sticky; left: 0; z-index: 1; background: var(--surface);
  text-align: left; min-width: 190px; max-width: 220px;
}
.mx-table th.mx-stage { background: var(--surface-2); z-index: 2; }
.mx-table .mx-stage small { display: block; font-weight: 500; font-size: 11px; color: var(--muted); margin-top: 2px; }
.mx-cell { font-size: 14px; min-width: 44px; }
.mx-on { color: var(--ok); font-weight: 700; }
.mx-opt, .mx-off { color: var(--brand); }
.mx-self { color: var(--warn); font-size: 11px; font-weight: 600; }
.mx-na { color: var(--muted); }
.mx-legend { display: flex; flex-wrap: wrap; gap: 12px; margin: 8px 0; font-size: 12px; color: var(--muted); }
.mx-legend b { font-size: 13px; }
/* Подсказка о несостыковке настроек в кабинете компании (напр. линии общения без телефонии). */
.warn-note {
  display: flex; align-items: flex-start; gap: 8px; margin: 8px 0 10px; padding: 10px 12px;
  border-radius: var(--radius-sm); font-size: 13px;
  background: color-mix(in srgb, var(--warn) 12%, transparent);
  border: 1px solid color-mix(in srgb, var(--warn) 40%, var(--line));
}
.warn-note .ic { flex: 0 0 auto; color: var(--warn); }
/* Форма заявки лида: поля в две колонки на широком экране, в одну на телефоне. */
.lead-form { display: grid; grid-template-columns: 1fr 1fr; gap: 8px 10px; margin: 6px 0 4px; }
@media (max-width: 420px) { .lead-form { grid-template-columns: 1fr; } }
.lead-form[hidden] { display: none; }
/* Звонок в карточке лида: плеер и текст расшифровки. */
.call-item { padding: 10px 12px; display: flex; flex-direction: column; gap: 6px; }
.call-audio { width: 100%; height: 34px; }
.call-text {
  font-size: 13px; line-height: 1.5; white-space: pre-wrap; max-height: 220px; overflow-y: auto;
  background: var(--surface-2); border-radius: var(--radius-sm); padding: 10px 12px;
}
/* Длинный текст в таблице: свёрнутый — одна строка с многоточием, развёрнутый —
   переносится по словам, строка становится выше. Разворот делает стрелка в ячейке. */
td.cell-long { max-width: 80ch; white-space: nowrap; }
/* Текст длинной ячейки — кнопка: по нему открывается окно с полным содержимым.
   Выглядит обычным текстом, чтобы таблица не пестрела ссылками. */
td.cell-long .cell-long-text {
  display: inline-block; max-width: calc(100% - 28px); overflow: hidden;
  text-overflow: ellipsis; vertical-align: middle; text-align: left;
  border: none; background: none; padding: 0; margin: 0; cursor: pointer;
  font: inherit; color: inherit; white-space: inherit;
}
td.cell-long .cell-long-text:hover { color: var(--brand); }
td.cell-long.open { white-space: normal; }
td.cell-long.open .cell-long-text {
  display: block; max-width: none; overflow: visible; text-overflow: clip;
  line-height: 1.45; padding: 2px 0; white-space: normal;
}
/* Общий разворот колонки — стрелка в её заголовке. */
.th-expand {
  border: none; background: none; padding: 0 2px; margin-left: 6px; cursor: pointer;
  color: var(--muted); vertical-align: middle; line-height: 1;
}
.th-expand:hover { color: var(--brand); }
.th-expand .ic { width: 14px; height: 14px; }
.th-expand.on { color: var(--brand); }
.th-expand.on .ic { transform: rotate(90deg); }

/* Развёрнутая ячейка «прижимает» кнопки к верху строки, чтобы они не уезжали вниз. */
td.cell-long.open .cell-more { vertical-align: top; }
td.cell-long.open [data-expand] .ic { transform: rotate(90deg); }
.cell-more {
  border: none; background: none; padding: 0 2px; margin-left: 4px; cursor: pointer;
  color: var(--muted); vertical-align: middle; line-height: 1;
}
.cell-more:hover { color: var(--brand); }
.cell-more .ic { width: 16px; height: 16px; }
/* Окно с полным текстом ячейки. */
.long-text {
  white-space: pre-wrap; font-size: 14px; line-height: 1.55; max-height: 70vh;
  overflow-y: auto; padding: 4px 2px 8px;
}
/* Перелистывание резюме соседних звонков контакта. */
.long-nav { display: flex; align-items: center; justify-content: center; gap: 12px; margin: 2px 0 8px; }
.long-arrow {
  width: 32px; height: 32px; border-radius: 50%; border: 1px solid var(--line);
  background: var(--surface); color: var(--text); font-size: 18px; line-height: 1; cursor: pointer;
}
.long-arrow:disabled { opacity: .35; cursor: default; }
.long-arrow:not(:disabled):hover { border-color: var(--brand); color: var(--brand); }
.long-pos { font-size: 12.5px; color: var(--muted); }

/* Окна поверх экрана входа: код сотрудника при входе в кабинет компании и
   подтверждение по СМС при регистрации. Сам экран входа — position: fixed
   с z-index 1200, поэтому обычная модалка (z-index 50) открывалась ПОД ним
   и выглядела так, будто её нет. */
body.login-mode .modal-overlay { z-index: 1300; }
/* Блок перевода заявки в подбор объекта (режим агента). */
.search-box { padding: 12px; display: flex; flex-direction: column; gap: 8px; margin-bottom: 6px; }

/* Рекламные площадки: карточка подключения и статистика. */
.channel-card { border-left: 4px solid var(--line); }
.channel-card.st-on { border-left-color: var(--ok); }
.channel-card.st-error { border-left-color: var(--danger); }
.channel-card.st-off { border-left-color: var(--muted); opacity: .82; }
/* Карточка свёрнута до шапки: разворот по нажатию на неё же. */
.ch-head { display: flex; align-items: flex-start; gap: 10px; width: 100%; padding: 0; border: none; background: none; font: inherit; color: inherit; text-align: left; cursor: pointer; }
.ch-head-main { flex: 1; min-width: 0; }
.ch-head-main > span { display: block; }
.ch-head .badge { flex: none; }
.ch-sum { font-size: 12px; color: var(--muted); margin-top: 4px; }
.ch-chev { flex: none; display: flex; align-items: center; color: var(--muted); }
.ch-chev .ic { width: 18px; height: 18px; transform: rotate(90deg); transition: transform .15s; }
.channel-card.open .ch-chev .ic { transform: rotate(-90deg); }
.channel-card:not(.open) .ch-body { display: none; }
.channel-card.open .ch-sum { display: none; }
.ch-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(90px, 1fr)); gap: 8px; margin: 10px 0; padding: 10px 12px; background: var(--surface-2); border-radius: var(--radius-sm); }
.ch-stats span { display: block; font-size: 11px; color: var(--muted); }
.ch-stats b { font-size: 14px; font-weight: 800; }
/* Переписка с площадки. */
.chat-log { max-height: 42vh; overflow-y: auto; display: flex; flex-direction: column; gap: 8px; margin: 10px 0; padding: 10px; background: var(--surface-2); border-radius: var(--radius-sm); }
.chat-msg { max-width: 88%; padding: 8px 11px; border-radius: 12px; background: var(--surface); border: 1px solid var(--line); }
.chat-msg.out { align-self: flex-end; background: color-mix(in srgb, var(--brand) 10%, var(--surface)); border-color: color-mix(in srgb, var(--brand) 30%, var(--line)); }
.chat-who { font-size: 11px; color: var(--muted); font-weight: 600; }
.chat-text { font-size: 13.5px; margin-top: 2px; overflow-wrap: anywhere; }
/* Код привязки группы Telegram. */
.tg-code-row { display: flex; align-items: center; gap: 10px; margin: 6px 0 8px; }
.tg-code {
  font-family: ui-monospace, Menlo, Consolas, monospace; font-size: 18px; font-weight: 800;
  letter-spacing: .08em; background: var(--surface-2); border: 1px solid var(--line);
  border-radius: var(--radius-sm); padding: 6px 12px;
}
/* Пошаговое подключение группы Telegram. */
.tg-steps { margin: 4px 0 10px; padding-left: 20px; display: flex; flex-direction: column; gap: 10px; font-size: 14px; }
.tg-steps li { line-height: 1.5; }
.tg-step-act { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 6px; }

/* Две кнопки подключения — в один ряд, на телефоне переносятся. */
.tg-step-act .btn { flex: 1 1 46%; min-width: 150px; text-align: center; }
/* Сворачиваемая панель подключения группы Telegram. */
.tg-connect { margin: 6px 0 4px; border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 8px 12px; }
.tg-connect > summary {
  cursor: pointer; font-size: 13px; font-weight: 700; color: var(--muted);
  list-style: none; display: flex; align-items: center; justify-content: space-between;
}
.tg-connect > summary::-webkit-details-marker { display: none; }
.tg-connect > summary::after { content: '▾'; color: var(--muted); }
.tg-connect[open] > summary::after { content: '▴'; }
/* Ссылка-действие в заголовке блока. */
.link-btn { border: none; background: none; padding: 0; font: inherit; font-size: 12.5px; font-weight: 600; color: var(--brand); cursor: pointer; }
.link-btn:active { opacity: .6; }
/* Таблица расхождений при связке объекта с внешним источником. */
.modal.wide { max-width: 720px; }
.diff-head, .diff-row { display: grid; grid-template-columns: 1fr 1.2fr 1.2fr; gap: 8px; align-items: start; }
.diff-head { font-size: 12px; color: var(--muted); padding: 4px 2px; }
.diff-rows { display: flex; flex-direction: column; gap: 6px; max-height: 56vh; overflow-y: auto; }
.diff-row { padding: 8px; border: 1px solid var(--line); border-radius: var(--radius-sm); }
.diff-row.diff-new { background: color-mix(in srgb, var(--brand) 6%, transparent); }
.diff-label { font-size: 13px; color: var(--muted); }
.diff-cell { display: flex; gap: 8px; align-items: flex-start; font-size: 13.5px; cursor: pointer; }
.diff-cell input { margin-top: 3px; flex: 0 0 auto; }
.diff-cell span { overflow-wrap: anywhere; }
.diff-cell:has(input:checked) { color: var(--text); font-weight: 600; }
@media (max-width: 560px) {
  .diff-head { display: none; }
  .diff-row { grid-template-columns: 1fr; }
  .diff-label { font-weight: 700; color: var(--text); }
}

/* Обложка объявления с площадки: маленькая, поэтому и показываем маленькой. */
.av-cover { display: flex; align-items: center; gap: 10px; margin: 8px 0 2px; }
.av-cover img { width: 140px; height: 105px; object-fit: cover; border-radius: 8px; border: 1px solid var(--line); }

/* Подобранная по адресу группа Telegram: показываем её одну, остальные — под раскрытием. */
.tg-guess { margin-bottom: 10px; }
.tg-guess .tg-other { margin-top: 8px; }
.tg-guess .tg-other summary { font-size: 13px; color: var(--brand); cursor: pointer; }
.field .tg-find { margin-bottom: 6px; }
.tg-guess .tg-other .field { margin-top: 8px; }

/* Ссылки объекта: адрес показываем целиком, но он не должен рвать карточку. */
.link-url { overflow-wrap: anywhere; font-size: 12px; }

/* Просмотр фотографий перед добавлением: снимки не затемняются, выбранные
   отмечены кружком с номером (порядок в наборе), снятые — пустым кружком. */
.photo-review { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; margin: 4px 0 12px; }
.pr-cell { position: relative; padding: 0; border: 2px solid var(--line); border-radius: 12px; overflow: hidden;
  background: var(--surface-2); cursor: pointer; aspect-ratio: 4/3; }
.pr-cell img { width: 100%; height: 100%; object-fit: cover; display: block; }
.pr-cell.on { border-color: var(--brand); }
/* Галочка — отдельная кнопка поверх снимка: нажатие по самому снимку открывает
   его на весь экран, а отметка ставится только здесь. Поэтому у неё своя
   область (28 px под палец), свой курсор и слой выше миниатюры. */
.pr-mark { position: absolute; right: 5px; top: 5px; width: 26px; height: 26px; border-radius: 50%;
  display: grid; place-items: center; font-size: 13px; font-weight: 700; padding: 0; z-index: 3;
  border: 2px solid #fff; background: rgba(0, 0, 0, .28); color: #fff; cursor: pointer;
  box-shadow: 0 1px 4px rgba(0, 0, 0, .35); }
.pr-mark.on { background: var(--brand); border-color: var(--brand); color: #fff; }
/* Обложка снимка (16.10.2026): какие кадры идут в полосу шапки объекта. */
.pr-cover { position: absolute; left: 5px; top: 5px; z-index: 3; padding: 2px 7px; border-radius: 999px;
  font-size: 11px; font-weight: 700; border: 2px solid #fff; background: rgba(0, 0, 0, .32); color: #fff;
  cursor: pointer; box-shadow: 0 1px 4px rgba(0, 0, 0, .35); }
.pr-cover.on { background: var(--ok); border-color: var(--ok); }
.pr-cover:active { transform: scale(.94); }
.pr-mark:active { transform: scale(.94); }

/* Окно загрузки: под каждым снимком поле подписи. */
.pr-item { display: flex; flex-direction: column; gap: 4px; }
.pr-cap { width: 100%; padding: 5px 7px; border: 1px solid var(--line); border-radius: 8px;
  font: inherit; font-size: 12px; background: var(--surface); color: var(--text); }

/* Рекламный текст объекта: переносы строк из объявления сохраняем. */
.desc-text { white-space: pre-wrap; font-size: 14px; }

/* Кнопка действий «⋮» в шапке карточки: без обводки она читалась как часть
   заголовка, и её просто не замечали. Кружок делает её кнопкой. */
#app-action {
  border: 1px solid var(--line); border-radius: 50%; width: 34px; height: 34px;
  font-size: 19px; line-height: 1; font-weight: 700; color: var(--text); background: var(--surface);
}
#app-action:active { background: var(--surface-2); }
/* И то же самое у «⋮» в строке объекта: рамка у неё была, не хватало круга. */
.card-edit { border-radius: 50%; }

/* Перетаскивание миниатюр: первый снимок — обложка, её видно подписью. */
/* Палец по снимку листает окно (11.10.2026): перенос взводится удержанием, а
   взведённый жест скрипт гасит в touchmove. touch-action: none здесь запрещал
   прокрутку вовсе — листая окно, попадали на перенос. */
.pr-item { position: relative; }
.pr-cell, .pr-cell img { touch-action: manipulation; -webkit-user-drag: none; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; }
/* Удержали — снимок «взят»: теперь его можно вести пальцем. */
.pr-item.pr-armed { transform: scale(1.04); filter: drop-shadow(0 6px 12px rgba(0,0,0,.22)); transition: transform .12s ease; }
.pr-cell { cursor: zoom-in; }        /* нажатие открывает снимок на весь экран */
.pr-cell:active { cursor: grabbing; }
/* Снимок «в воздухе»: приподнят, чуть увеличен и с тенью — видно, что он у вас
   в руке, а не просто подсветился. Позицию задаёт скрипт (position: fixed). */
.pr-item.pr-dragging {
  transform: scale(1.06) rotate(-1.5deg); opacity: .95; cursor: grabbing;
  filter: drop-shadow(0 10px 18px rgba(0,0,0,.28));
}
/* Подпись в полёте гасим, но не убираем: иначе миниатюра меняет высоту прямо
   в руке, а пунктирная рамка остаётся прежнего размера — заметный скачок. */
.pr-item.pr-dragging .pr-cap { opacity: .45; pointer-events: none; }
/* Место, куда снимок встанет: пунктирная рамка ровно в размер миниатюры. */
.pr-slot {
  border: 2px dashed var(--brand); border-radius: 12px;
  background: color-mix(in srgb, var(--brand) 8%, transparent);
  transition: transform .18s ease;
}
.pr-slot.is-cover::after {
  content: 'сюда · обложка'; display: grid; place-items: center; height: 100%;
  font-size: 10px; font-weight: 700; color: var(--brand);
}
/* Пока снимок несут, соседи не должны реагировать на курсор. */
.photo-review.pr-moving .pr-cell { cursor: grabbing; }
.photo-review.pr-moving .pr-cap { pointer-events: none; }
.pr-item.is-cover .pr-cell { border-color: var(--brand); box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand) 35%, transparent); }
.pr-item.is-cover::after {
  content: 'обложка'; position: absolute; left: 6px; top: 6px; z-index: 2;
  padding: 2px 7px; border-radius: 999px; background: var(--brand); color: #fff;
  font-size: 10px; font-weight: 700; letter-spacing: .01em;
}
.cp-album .pr-item.is-cover::after { content: none; }
.cp-album .pr-item.is-cover .pr-cell { box-shadow: none; }
.cp-album .pr-item.cp-first::after {
  content: 'обложка'; position: absolute; left: 6px; top: 6px; z-index: 2;
  padding: 2px 7px; border-radius: 999px; background: var(--brand); color: #fff;
  font-size: 10px; font-weight: 700;
}
.photo-cell.is-cover .photo-thumb { border-color: var(--brand); box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand) 30%, transparent); }
.photo-cell.is-cover .photo-cap::before { content: 'обложка · '; color: var(--brand); font-weight: 700; }
/* Доход собственника рядом с арендой — мельче и приглушённо: главная цифра одна. */
.price-owner { color: var(--muted); font-weight: 600; }

/* Превью поста канала: показываем ровно тем же текстом, что уйдёт в Telegram. */
.tg-post {
  white-space: pre-wrap; font-size: 13.5px; line-height: 1.45;
  background: var(--surface-2); border: 1px solid var(--line); border-radius: 12px;
  padding: 12px; margin: 8px 0 6px; max-height: 46vh; overflow: auto;
}

/* Плашка демо-кабинета: где человек находится и как завести свой. Полоса
   закреплена сверху, поэтому содержимому добавляется отступ. */
/* Плашка обычным блоком, а не поверх страницы: шапка кабинета «липкая», и
   фиксированная полоса пришлось бы двигать её вручную на каждом экране. */
.demo-bar { display: flex; align-items: center; justify-content: center; gap: 10px; flex-wrap: wrap;
  padding: 7px 12px; background: var(--brand); color: #fff; font-size: 13px; }
.demo-bar-text { opacity: .92; }
.demo-bar-btn { border: 1px solid rgba(255,255,255,.55); background: rgba(255,255,255,.14); color: #fff;
  border-radius: 999px; padding: 4px 12px; font: inherit; font-size: 12.5px; font-weight: 700; cursor: pointer; }
.demo-bar-btn:active { background: rgba(255,255,255,.28); }
a.demo-bar-btn { text-decoration: none; }
@media (max-width: 420px) { .demo-bar { font-size: 12px; padding: 6px 10px; } }

/* Матрица размещения: объекты × площадки. Первый столбец не уезжает при
   горизонтальной прокрутке — без адреса строка нечитаема. */
.am-wrap { max-height: 72vh; }
.am-tbl th, .am-tbl td { vertical-align: top; padding: 6px; }
.am-tbl th { white-space: nowrap; }
/* Первый столбец не должен растекаться: длинные адреса раньше наезжали на
   соседние ячейки. Ширина фиксированная, лишнее — многоточием. */
.am-head { position: sticky; left: 0; z-index: 2; background: var(--surface);
  width: 200px; min-width: 200px; max-width: 200px; }
.am-head a { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.am-tbl thead .am-head { z-index: 3; }
.am-head a { color: var(--text); text-decoration: none; font-weight: 600; font-size: 13px; }
.am-sub { display: block; font-size: 11px; color: var(--muted); font-weight: 400; }
/* Иконка «Условия сдачи» в строке матрицы (комментарий отдела аренды, 06.10.2026):
   серая — комментария нет, зелёная — есть. */
.am-note { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px;
  margin-top: 4px; margin-left: 6px; vertical-align: middle; padding: 0; border: 1px solid var(--line);
  border-radius: 6px; background: transparent; color: var(--muted); cursor: pointer; }
.am-note svg { width: 14px; height: 14px; }
.am-note.has { border-color: var(--ok); color: var(--ok); background: color-mix(in srgb, var(--ok) 12%, transparent); }
.am-cell { min-width: 116px; border-radius: 10px; padding: 6px 8px; background: var(--surface-2); }
.am-cell.empty { background: none; color: var(--muted); text-align: center; padding: 10px 0; }
.am-cell.ok { background: color-mix(in srgb, var(--ok) 14%, transparent); }
.am-cell.wait { background: color-mix(in srgb, var(--warn) 16%, transparent); }
.am-cell.bad { background: color-mix(in srgb, var(--danger) 14%, transparent); }
.am-cell.mark { background: color-mix(in srgb, var(--brand) 10%, transparent); }
/* Архив и черновик — объявление есть, но клиент его не видит: отделяем от
   активного и от «на модерации», иначе архив выглядел как рабочее объявление. */
.am-cell.arch { background: color-mix(in srgb, var(--muted) 18%, transparent); color: var(--muted); }
.am-cell.draft { background: color-mix(in srgb, var(--brand) 14%, transparent); }
/* Неподключённая площадка — весь столбец серый: цветом отмечено только то, что
   работает, и на этом фоне видно, где мы теряем показы. */
.am-off { background: var(--surface-2); color: var(--muted); }
.am-off .am-cell { background: color-mix(in srgb, var(--muted) 12%, transparent); color: var(--muted); }
.am-off .am-cell.empty { background: none; }
.am-off .am-sub a { color: var(--brand); font-weight: 700; text-decoration: none; }
.am-state { font-size: 12px; font-weight: 700; }
.am-num { font-size: 11px; color: var(--muted); }

/* Состояние строки в матрице: цветная метка под названием и полоса слева.
   Одной полосы не хватало — её просто не замечали. */
.am-head.st-searching { box-shadow: inset 4px 0 0 var(--warn); }
.am-head.st-vacating { box-shadow: inset 4px 0 0 var(--warn); }
.am-head.st-rented { box-shadow: inset 4px 0 0 var(--ok); }
.am-head.st-hanging { box-shadow: inset 4px 0 0 var(--danger, #d9432f); }
.am-head.st-partial { box-shadow: inset 4px 0 0 var(--brand); }
.am-head.st-prep { box-shadow: inset 4px 0 0 var(--muted); }
.am-tag { display: inline-block; margin-top: 3px; vertical-align: middle; padding: 1px 8px; border-radius: 999px;
  font-size: 10.5px; font-weight: 700; color: #fff; background: var(--muted); }
.am-tag.searching, .am-tag.vacating { background: var(--warn); }
.am-tag.rented { background: var(--ok); }
.am-tag.hanging { background: var(--danger, #d9432f); }
.am-tag.partial { background: var(--brand); }
.am-tag.prep { background: var(--muted); }
/* Сданное приглушаем: рекламировать его не нужно, и внимание на нём не держим. */
.am-head.st-rented, .am-head.st-prep { opacity: .72; }

/* Дата и время обращения — отдельной строкой, чуть мельче остального. */
.lead-when { font-size: 12px; }
/* Плитка со ссылкой на объявление: нажатие уводит на площадку. */
a.am-cell { display: block; text-decoration: none; color: inherit; }
a.am-cell:hover { outline: 2px solid color-mix(in srgb, var(--brand) 45%, transparent); }
.am-open { font-size: 10.5px; color: var(--brand); font-weight: 700; margin-top: 2px; }

/* Строка истории выводов кликабельна — открывает карточку платежа. */
.wd.link { width: 100%; text-align: left; background: none; border: 0; padding: 10px 0; cursor: pointer;
  display: flex; align-items: center; gap: 10px; font: inherit; color: inherit; }
.wd.link + .wd.link { border-top: 1px solid var(--line); }
.wd.link:active { background: var(--surface-2); }
.wd.link .row-main { gap: 3px; }
.wd .wd-hint, .wd .wd-wrap { white-space: normal; overflow: visible; }
.wd .wd-hint { color: var(--danger); }
.wd .wd-badge { align-self: flex-start; white-space: normal; line-height: 1.3; margin-top: 2px; }
.wd .wd-go { flex: none; color: var(--muted); font-size: 22px; line-height: 1; }

/* Матрица «комната × площадка»: где объявление есть, где его нет. */
.unit-ads td { font-size: 12px; white-space: nowrap; }
.unit-ads .ok-cell { color: var(--ok); font-weight: 700; }
.unit-ads .warn-cell { color: var(--warn); font-weight: 600; }
.unit-ads .muted-cell { color: var(--muted); }

/* Комната, которая ищет жильца, помечена точкой в переключателе комнат. */
.seg-btn.seg-free::after { content: '•'; margin-left: 4px; color: var(--warn); font-weight: 700; }

/* Строка матрицы открывает комнату в том же разделе. */
.unit-ads tr.link { cursor: pointer; }
.unit-ads tr.link:active td { background: var(--surface-2); }

/* Явное предупреждение внутри карточки: без описания объявление не собрать. */
.warn-box { border-color: color-mix(in srgb, var(--danger) 45%, var(--line));
  background: color-mix(in srgb, var(--danger) 6%, var(--surface)); }
.warn-box .cc-note { margin: 0 0 8px; }

/* Выкладка альбома в превью канала: снимки помельче, номер показывает порядок. */
#cp-body .photo-review { grid-template-columns: repeat(auto-fill, minmax(74px, 1fr)); gap: 6px; }
#cp-body .pr-cell { aspect-ratio: 1/1; }
#cp-body .pr-mark { width: 24px; height: 24px; font-size: 12px; }
#cp-body .pr-cell.on .pr-mark { background: var(--brand); border-color: #fff; color: #fff; }
#cp-body .tg-post a { color: var(--brand); }

/* Статьи (Ещё → Статьи). Карточка — кнопка, поэтому текст выравниваем сами:
   у кнопки содержимое по умолчанию по центру. Аннотация в три строки —
   .row-sub режет её в одну строку с многоточием. */
.row.art { text-align: left; align-items: flex-start; width: 100%; font: inherit; color: inherit; cursor: pointer; }
.row.art .row-ic { margin-top: 2px; }
.art-lead {
  color: var(--muted); font-size: 13px; line-height: 1.45; margin-top: 2px;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.art-meta { color: var(--muted); font-size: 12px; margin-top: 4px; }

/* Вкладки карточки заявки («Заявка» / «Подбор объекта»). Окно длинное, поэтому
   переключатель липнет к верху окна: иначе, чтобы уйти в подбор, приходится
   листать обратно наверх. */
.lead-tabs { position: sticky; top: 0; z-index: 3; background: var(--surface-2); }

/* Строка объекта в шапке окна переписки: само окно оставлено под переписку и
   ответ, а привязка объекта ужата до одной строки с действиями. */
.chat-obj-line { margin-top: 2px; }
.chat-obj-line .link-btn { font-size: inherit; }

/* ── Панель ответа в переписке: шаблоны, смайлы, картинка ─────────────────── */
/* Быстрые ответы — чипами: их выбирают глазами, а не читают целиком, поэтому
   длинные обрезаны, а полный текст лежит в подсказке. */
.chat-tools { margin-top: 8px; display: flex; flex-direction: column; gap: 8px; }
.chat-quick { display: flex; flex-wrap: wrap; gap: 6px; }
.chat-quick[hidden] { display: none; }
/* Список быстрых ответов в окне: строка целиком кликабельна. */
.qr-pick { display: flex; flex-direction: column; gap: 6px; margin-bottom: 10px; }
.qr-pick button {
  text-align: left; border: 1px solid var(--line); background: var(--surface); color: var(--text);
  border-radius: var(--radius-sm); padding: 9px 11px; font: inherit; font-size: 13px; cursor: pointer;
  white-space: pre-wrap;
}
.qr-pick button:hover { border-color: var(--brand); }
.chip-btn {
  border: 1px solid var(--line); background: var(--surface); color: var(--text);
  border-radius: 999px; padding: 5px 11px; font: inherit; font-size: 12px; cursor: pointer;
  max-width: 100%; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.chip-btn:hover { border-color: var(--brand); color: var(--brand); }
.chip-btn.ghost { color: var(--muted); }
.chat-tool-row { display: flex; gap: 8px; flex-wrap: wrap; }
/* `hidden` перебивался классом с display:flex, и палитра стояла раскрытой. */
.emoji-grid { display: flex; flex-wrap: wrap; gap: 4px; }
.emoji-grid[hidden] { display: none; }
.emoji-btn {
  border: 1px solid var(--line); background: var(--surface); border-radius: 8px;
  width: 36px; height: 36px; font-size: 18px; line-height: 1; cursor: pointer; padding: 0;
}
.emoji-btn:hover { border-color: var(--brand); }
/* Окно правки шаблонов: строка — текст плюс «Убрать». */
.qr-row { display: flex; gap: 8px; align-items: flex-start; margin-bottom: 8px; }
.qr-row textarea { flex: 1 1 auto; }
/* Кнопки строки — столбиком, чтобы не растягивать поле по ширине. */
.qr-btns { display: flex; flex-direction: column; gap: 4px; flex: none; }
.qr-btns .btn { min-width: 34px; padding: 4px 8px; line-height: 1.2; }

/* Значки заявки столбиком: у одного человека бывает и переписка, и звонки —
   тогда в карточке два значка друг под другом, а не один «главный». */
.row-ic-multi { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 2px; padding: 4px 0; height: auto; }
.row-ic-multi .ic { width: 16px; height: 16px; }

/* Карточка заявки: три вкладки в одном окне. Высота фиксированная — иначе окно
   прыгало при переключении («Подбор» короче «Лида» вдвое), и кнопки уезжали
   из-под курсора. Прокрутка внутри окна, как и раньше. */
.modal.lead-modal { height: 88dvh; height: 88vh; display: flex; flex-direction: column; }

/* Способы завести объект: сеткой по две, строки компактные. В одну колонку пять
   плиток занимали весь экран, и форма ручного ввода уходила под сгиб. */
.add-ways { display: grid; gap: 8px; }
.add-ways .feed-tile { padding: 10px 12px; font-size: 14px; gap: 10px; text-align: left; }
.add-ways .feed-tile-label small { display: block; font-weight: 500; font-size: 11.5px; color: var(--muted); line-height: 1.3; }
@media (min-width: 620px) {
  .add-ways { grid-template-columns: 1fr 1fr; }
}

/* База контактов: как контакт будет назван в телефонной книге — первое, что
   проверяют в карточке, поэтому имя показано целиком и крупно. */
.gc-name { margin-bottom: 10px; }
/* Имя в книге — поле ввода, но выглядит как значение: его чаще читают, чем правят. */
.gc-name-val {
  margin-top: 4px; font-weight: 600; font-size: 15px; line-height: 1.35;
  color: var(--text); width: 100%;
}
.gc-help h4 { margin: 14px 0 4px; font-size: 14px; }
.gc-help p, .gc-help li { font-size: 13px; line-height: 1.45; }
.gc-help code {
  background: var(--bg-soft, #f0f2f5); padding: 1px 5px; border-radius: 4px;
  font-size: 12px; word-break: break-all;
}
/* «В телефонной книге» в карточке звонка — поле ввода: имя собирается по
   правилам, но остаётся редактируемым, как и в карточке контакта. */
#cl-book { font-weight: 600; }
/* Как запись будет выглядеть в телефонной книге — продолжением второй строки
   карточки контакта, поэтому inline и выделено цветом, а не отдельным блоком. */
.row-book { color: var(--brand); font-weight: 600; }
/* Число разговоров в строке контакта — ссылка в журнал телефонии. */
.row-calls { color: var(--brand); text-decoration: underline; text-underline-offset: 2px; cursor: pointer; }

/* Карточка контакта: имя и телефон одной строкой — это опознание человека. */
.cc-idrow-in { display: flex; gap: 8px; margin-top: 4px; }
.cc-idrow-in .fld-input { margin-top: 0; }
.cc-idrow-in #cc-name { flex: 1 1 auto; }
.cc-phone { flex: 0 0 170px; font-weight: 600; }
@media (max-width: 480px) { .cc-idrow-in { flex-direction: column; } .cc-phone { flex: 1 1 auto; } }
/* Шильдик «Настроить» в ряду статусов — не статус, а вход в справочник. */
.fchip-edit { border-style: dashed; }

/* Правка справочника статусов: строка = наименование, сокращение, признак, кнопки. */
.qr-row { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; margin-bottom: 6px; }
.qr-row .qr-name { flex: 1 1 160px; margin-top: 0; }
.qr-row .qr-code { flex: 0 0 90px; margin-top: 0; }
.qr-pref { display: flex; align-items: center; gap: 4px; font-size: 12px; color: var(--muted); }
.qr-btns { display: flex; gap: 4px; margin-left: auto; }

/* Синхронизации в базе контактов: две свёрнутые строки со сводкой на самой
   кнопке — блоки нужны редко, а место занимали постоянно. */
.sync-card { padding: 0; overflow: hidden; }
.sync-head {
  display: flex; align-items: center; gap: 10px; width: 100%;
  padding: 12px 14px; background: none; border: 0; cursor: pointer; text-align: left;
}
.sync-head .ic { margin-left: auto; transition: transform .15s; color: var(--muted); }
.sync-head.open .ic { transform: rotate(90deg); }
.sync-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--line); flex: 0 0 auto; }
.sync-dot.on { background: var(--ok); }
.sync-main { display: flex; flex-direction: column; min-width: 0; }
.sync-title { font-weight: 700; font-size: 14px; }
.sync-sub { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sync-body { padding: 0 14px 14px; }
.sync-sep { height: 1px; background: var(--line); }
/* Контакт, который в телефонную книгу не идёт: свой или личный номер. */
.row-skip { color: var(--muted); font-style: italic; }

/* Каналы — голубым, площадки остаются нейтральными: в канал публикует сам
   кабинет, а на площадке объявление подаёт человек. Разные действия — разный цвет,
   и в длинном списке видно, где что. */
.chan-card {
  background: color-mix(in srgb, var(--brand) 7%, var(--surface));
  border-color: color-mix(in srgb, var(--brand) 30%, var(--line));
}
.chan-card .settle-title { color: var(--brand); }
.chan-card .badge:not(.ok):not(.warn):not(.danger) {
  background: color-mix(in srgb, var(--brand) 12%, var(--surface));
  border-color: color-mix(in srgb, var(--brand) 28%, var(--line));
  color: var(--brand);
}

/* Поля объявления в форме объекта — под раскрытием: нужны не всем и не всегда,
   но лежать должны там же, где правят объект. */
.ads-fields { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 8px 10px; margin: 8px 0; }
.ads-fields > summary { cursor: pointer; font-weight: 600; font-size: 13px; }
.ads-fields[open] > summary { margin-bottom: 8px; }

/* ── Приёмка объекта (вкладка «События») ─────────────────────────────────
   Чек-лист регламента отдела сервиса: пункт — событие в ленте, подпункты —
   его этапы. Оформлен списком, а не карточками: пунктов два десятка, и по
   ним идут сверху вниз. */
.accept-box { margin-bottom: 12px; }
.accept-group { margin-top: 12px; }
.accept-gtitle {
  font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); margin-bottom: 6px;
}
.accept-item { border-top: 1px solid var(--line); }
.accept-item:first-of-type { border-top: 0; }
.accept-head {
  display: flex; align-items: center; gap: 8px; width: 100%;
  background: none; border: 0; padding: 10px 0; font: inherit; color: inherit;
  text-align: left; cursor: pointer;
}
.accept-mark {
  flex: none; width: 34px; height: 22px; border-radius: 11px; display: grid; place-items: center;
  font-size: 11px; font-weight: 700; color: var(--muted); background: var(--surface-2);
}
.accept-item.done .accept-mark { color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, var(--surface)); }
.accept-title { flex: 1; min-width: 0; font-weight: 600; font-size: 14px; }
.accept-item.done .accept-title { color: var(--muted); }
.accept-start { font-size: 12px; font-weight: 600; color: var(--brand); }
.accept-steps { padding: 2px 0 10px 42px; display: flex; flex-direction: column; gap: 2px; }
.accept-row { display: flex; align-items: center; gap: 6px; }
.accept-row .vis-chip { flex: none; }
.accept-step {
  display: flex; align-items: center; gap: 8px; flex: 1; min-width: 0;
  background: none; border: 0; padding: 7px 6px; border-radius: var(--radius-sm);
  font: inherit; font-size: 13px; color: inherit; text-align: left; cursor: pointer;
}
.accept-step:active { background: var(--surface-2); }
.accept-box-mark {
  flex: none; width: 18px; height: 18px; border-radius: 5px; display: grid; place-items: center;
  border: 1.5px solid var(--line); font-size: 12px; color: var(--ok); background: var(--surface);
}
.accept-row.done .accept-box-mark { border-color: var(--ok); }
.accept-row.done .accept-step-title { color: var(--muted); text-decoration: line-through; }
.accept-step-title { flex: 1; min-width: 0; }
.accept-when { font-size: 11px; color: var(--muted); }
.accept-foot { padding: 6px 6px 0; }
/* На телефоне подпункты без отступа под счётчик пункта: ширины мало, галочка встаёт
   вровень с «0/6», текст шага получает всю строку (31.10.2026, id=982). */
@media (max-width: 600px) {
  .accept-steps { padding-left: 0; }
  .accept-step { padding-left: 0; }
  .accept-row { gap: 4px; }
}
/* Событие приёмки в ленте — свёрнутая карточка-кнопка (этапы живут в чек-листе). */
.event-card.accept-ev { display: block; width: 100%; text-align: left; font: inherit; color: inherit; cursor: pointer; }
.event-card.accept-ev:active { background: var(--surface-2); }
/* Подпункты приёмки, сгруппированные по сущности (квитанция, счётчик, комната). */
.accept-unit { margin: 8px 0 4px; }
.accept-utitle {
  display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 12px; font-weight: 600; color: var(--text);
  padding: 4px 6px; background: var(--surface-2); border-radius: var(--radius-sm);
}
/* Комментарий в чек-листе приёмки: не задача, а обстоятельство — своя строка. */
.accept-row.note { align-items: flex-start; }
.accept-note {
  flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px;
  padding: 7px 8px; border-radius: var(--radius-sm);
  background: var(--surface-2); font-size: 13px;
}
.accept-note-line { display: flex; gap: 8px; align-items: flex-start; }
.accept-note .ic { flex: none; width: 15px; height: 15px; margin-top: 2px; color: var(--muted); }
.accept-note-text { flex: 1; min-width: 0; }
.accept-note .accept-when { flex: none; }
/* Недостатки на приёмке: наблюдения под галочками пункта и кнопка «+ Наблюдение». */
.accept-defects { display: flex; flex-direction: column; gap: 4px; margin-top: 6px; }
.accept-defects > .btn { align-self: flex-start; }
.net-pics { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.net-pic { position: relative; display: inline-flex; }
.net-x {
  position: absolute; top: -6px; right: -6px; width: 22px; height: 22px; padding: 0;
  border: 0; border-radius: 50%; background: var(--danger); color: #fff; line-height: 1; cursor: pointer;
}
.accept-defect {
  display: flex; align-items: center; gap: 8px; width: 100%; text-align: left; cursor: pointer;
  padding: 7px 8px; border: 0; border-left: 3px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface-2); font: inherit; font-size: 13px; color: inherit;
}
.accept-defect.imp { border-left-color: var(--danger); }
.accept-defect .ic { flex: none; width: 15px; height: 15px; color: var(--muted); }
.accept-defect-text { flex: 1; min-width: 0; }
.accept-defect .accept-when { flex: none; }
.accept-note-add {
  align-self: flex-start; background: none; border: 0; padding: 6px 6px 6px 0;
  font: inherit; font-size: 12.5px; font-weight: 600; color: var(--brand); cursor: pointer;
  display: inline-flex; align-items: center; gap: 4px;
}
.accept-note-add .ic { width: 14px; height: 14px; }

/* Матрица прав: раздел слева, четыре галочки справа. Столбцы узкие — их четыре,
   и подписи короткие, а место нужно названиям разделов. */
.perm-tbl td:not(.first), .perm-tbl th:not(.first) { text-align: center; width: 74px; }
.perm-tbl td.first { white-space: nowrap; }
.perm-tbl input[type=checkbox] { width: 18px; height: 18px; }
/* Матрица прокручивается ВМЕСТЕ С ОКНОМ, а шапка липнет к его верху
   (24.09.2026): `position: sticky` липнет к своему скроллеру, поэтому у обёртки
   его быть не должно — иначе таблица ездит в собственной рамке, а заголовки
   стоят посреди окна. Своей прокрутки нет — шапка доходит до верха окна и
   остаётся там, пока идёшь по дереву разделов. */
.perm-wrap { max-height: none; overflow: visible; }
.perm-tbl thead th {
  position: sticky; top: -18px; z-index: 4; cursor: default;
  box-shadow: 0 1px 0 var(--line);
}
.perm-tbl thead th.first { z-index: 5; }
/* Переход в таблицу того же раздела: значок в ряду шильдиков, прижат вправо
   (24.09.2026). Экран показывает карточки, таблица — поиск, итоги и выгрузку. */
.tbl-jump {
  margin-left: auto; width: 32px; height: 32px; border-radius: 10px;
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
  display: inline-grid; place-items: center; flex: 0 0 auto;
}
.tbl-jump svg { width: 17px; height: 17px; }
.tbl-jump:hover { background: var(--surface-2); color: var(--text); }
/* Строка «Все права»: ставит столбец целиком, поэтому отделена от дерева. */
.perm-tbl .perm-all td { background: var(--surface-2); border-bottom: 1px solid var(--line); }
.perm-tbl .perm-all td.first { background: var(--surface-2); }
/* Снимок, приложенный к шагу приёмки из группы объекта. */
.accept-pic {
  display: inline-block; vertical-align: -6px; margin-left: 6px;
  width: 26px; height: 26px; border-radius: 6px; border: 1px solid var(--line);
  background-size: cover; background-position: center;
}
/* Кнопка комментария у шага приёмки: обстоятельство почти всегда про шаг. */
.accept-cmt {
  flex: none; background: none; border: 0; padding: 4px; cursor: pointer;
  color: var(--muted); line-height: 0; border-radius: 8px;
}
.accept-cmt:active { background: var(--surface-2); }
/* Крупнее (31.10.2026, просьба заказчика): листочек с карандашом легко попасть пальцем. */
.accept-cmt .ic, .accept-cmt svg { width: 22px; height: 22px; }
/* Фотографии в окне комментария приёмки. */
/* Кнопки окна комментария приёмки — компактные, текст в одну строку (id=996). */
.an-btns > .btn { flex: 1; min-width: 0; min-height: 34px; padding: 6px 8px; font-size: 13px; white-space: nowrap; gap: 5px; }
.an-btns > .btn svg { width: 15px; height: 15px; }
.an-shots { display: flex; flex-wrap: wrap; gap: 8px; margin: 10px 0 4px; }
.an-shots:empty { display: none; }
/* Скрепка с числом фото у шага приёмки (слева от комментария). */
.accept-clip { flex: none; display: inline-flex; align-items: center; gap: 2px; color: var(--muted); font-size: 12px; font-weight: 700; }
.accept-clip .ic, .accept-clip svg { width: 14px; height: 14px; }
button.accept-clip { background: none; border: 0; padding: 4px 5px; border-radius: 6px; cursor: pointer; font-family: inherit; }
button.accept-clip:active { background: var(--surface-2); }
/* Свёрнуто: скрепка подсвечена — под шагом есть спрятанные снимки. */
button.accept-clip.off { color: var(--brand); background: var(--surface-2); }
.an-shot {
  position: relative; width: 74px; height: 74px; border-radius: 10px;
  background-size: cover; background-position: center; border: 1px solid var(--line);
}
.an-del {
  position: absolute; top: -6px; right: -6px; width: 22px; height: 22px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
  font-size: 15px; line-height: 1; cursor: pointer;
}
/* «?» у пункта приёмки: инструкция отдела сервиса под рукой. */
.accept-head-row { display: flex; align-items: center; gap: 4px; }
/* Назначение встречи и приёмки в пунктах «Подготовки» (01.11.2026): строка с
   датой и временем под заголовком пункта и кнопка «Назначить». */
.accept-plan { display: flex; align-items: center; gap: 10px; padding: 6px 10px 8px 34px; }
.accept-plan-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.accept-plan.set { background: color-mix(in srgb, var(--warn) 7%, transparent); border-radius: var(--radius-sm); }
.accept-plan .btn { flex: none; }
@media (max-width: 420px) { .accept-plan { padding-left: 12px; flex-wrap: wrap; } }
.accept-help {
  flex: none; width: 24px; height: 24px; border-radius: 50%; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
  font: inherit; font-size: 13px; font-weight: 700; line-height: 1;
}
.accept-help:active { background: var(--surface-2); color: var(--brand); }
/* Статьи собственнику в разделах кабинета: строка-кнопка плюс «поделиться». */
.art-row { align-items: flex-start; gap: 8px; }
.art-open {
  flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px;
  background: none; border: 0; padding: 0; font: inherit; color: inherit; text-align: left; cursor: pointer;
}
.art-open .row-title { font-weight: 600; }
/* Кнопка «поделиться» у статьи в кабинете собственника. */
.art-share {
  flex: none; width: 34px; height: 34px; border-radius: 10px; cursor: pointer;
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
  display: grid; place-items: center;
}
.art-share.done { color: var(--ok); border-color: color-mix(in srgb, var(--ok) 40%, var(--line)); }
.art-share .ic { width: 17px; height: 17px; }
/* «Модули кабинета» в «Ещё» — первым и заметно: пока разделы не включены,
   половины кабинета управляющий не видит, а пункт терялся в общем списке. */
.row.row-modules {
  background: color-mix(in srgb, var(--brand) 8%, var(--surface));
  border-color: color-mix(in srgb, var(--brand) 30%, var(--line));
  margin-bottom: 10px;
}
.row.row-modules .row-ic { background: color-mix(in srgb, var(--brand) 14%, var(--surface)); color: var(--brand); }
.row.row-modules .row-title { color: var(--brand); }
/* ФИО по договору в карточке контакта: в базе живёт обращение, полное имя — в портфеле. */
.cc-fio { font-size: 13px; color: var(--muted); padding: 2px 2px 6px; }
.cc-fio b { color: var(--text); font-weight: 600; }

/* Направление звонка — стрелкой: входящий вниз-влево (к нам), исходящий
   вверх-вправо (от нас). Цвет тот же, что у состояний в кабинете. */
.cell-mark { text-align: center; width: 56px; }
/* Ячейка с шильдиком: узкой ей быть нельзя — состояние пишется словами. */
.cell-chip { white-space: nowrap; }
.cell-chip .chip { display: inline-block; }
/* Направление звонка — коротким словом, цветом различаем входящие и исходящие. */
.dir-in, .dir-out, .dir-int { font-size: 12px; font-weight: 700; line-height: 1; }
.dir-in { color: var(--ok); }
.dir-out { color: var(--brand); }
.dir-int { color: var(--muted, #8a94a6); }
.call-pair { border-left: 3px solid var(--brand); }
.call-pair audio { width: 100%; margin-top: 6px; }
/* Заголовок узкой колонки значком: подпись словами была шире значений. */
.th-ic { display: inline-flex; vertical-align: middle; color: var(--muted); }
.th-ic .ic { width: 16px; height: 16px; }

/* Переключатели состава строк таблицы (гудки, недозвоны) — строкой под панелью. */
/* Галочки «Показать …» — раскрывающимся списком (10.10.2026) */
.tbl-count-l { display: flex; align-items: center; gap: 8px; min-width: 0; }
.tbl-tgl-btn { position: relative; display: inline-flex; align-items: center; justify-content: center; width: 32px; height: 32px; padding: 0; border: 1px solid var(--line, #dde3ea); border-radius: 8px; background: var(--surface, #fff); color: inherit; cursor: pointer; flex: none; }
.tbl-tgl-btn svg { width: 18px; height: 18px; }
.tbl-tgl-btn.on { border-color: var(--brand, #1f6feb); color: var(--brand, #1f6feb); }
.tbl-tgl-btn .tgl-n { position: absolute; top: -6px; right: -6px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 8px; background: var(--brand, #1f6feb); color: #fff; font-size: 10px; line-height: 16px; text-align: center; }
.modal .tt-list { display: flex; flex-direction: column; gap: 2px; margin: 4px 0 8px; }
.modal .tt-list .fld-check { margin: 0; font-size: 14px; padding: 8px 0; }
/* Короткая подпись колонки знаками — «↙↗» у направления звонка. */
.th-short { font-size: 15px; letter-spacing: 1px; }
/* Поле со значком-действием справа (например «собрать имя в книге заново»). */
.fld-with-btn { position: relative; display: flex; align-items: center; }
.fld-with-btn .fld-input { flex: 1; min-width: 0; padding-right: 38px; }
.fld-btn {
  position: absolute; right: 4px; width: 30px; height: 30px; border-radius: 8px; cursor: pointer;
  border: 0; background: none; color: var(--muted); display: grid; place-items: center;
}
.fld-btn:active { background: var(--surface-2); color: var(--brand); }
.fld-btn .ic { width: 17px; height: 17px; }

/* Своих полей у `.card` нет — их даёт `.card-body`, а карточки модуля рисуют
   содержимое прямо в карточке, и текст с шильдиками прилипал к краю. Поля чуть
   шире обычных двенадцати: в карточке человека много строк подряд, и на воздухе
   она читается лучше. */
.card.reg-box { padding: 16px; }
.card.reg-folder, .card.reg-person { padding: 12px 14px; }

/* ── Миграционный учёт ────────────────────────────────────────────────────
   Раскладка модуля регистраций: папки по адресам, люди на объекте и карточка
   человека с документами. Устройство повторяет то, как работу ведут сейчас в
   Telegram — «переход из папки в папку», — поэтому строки крупные и читаются
   как список файлов, а не как таблица. */
/* Адреса плитками или строками — тем же переключателем, что у объектов.
   Строками ищут нужный адрес в длинном списке, плитками смотрят, что вообще
   есть: в плитке помещаются все зарегистрированные, а в строке они обрезаются. */
.reg-list.tiles { display: grid; gap: 10px; grid-template-columns: 1fr; }
@media (min-width: 620px) { .reg-list.tiles { grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); } }
.reg-list.tiles .reg-folder { flex-direction: column; align-items: stretch; }
/* Значок дома в плитке ни к чему: он повторяется в каждой ячейке и только
   съедает место, которого в узкой колонке и так мало. */
.reg-list.tiles .reg-ic { display: none; }
.reg-list.tiles .reg-folder-side { margin-top: 8px; }
.reg-list.tiles .reg-folder > svg:last-child { display: none; }

.reg-folder, .reg-person { display: flex; align-items: center; gap: 10px; }
.reg-folder-main, .reg-person-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.reg-folder-main b, .reg-person-main b { font-size: 15px; }
.reg-folder-main small, .reg-person-main small { font-size: 12px; color: var(--muted); }
/* Действующая регистрация — то, ради чего в список и заходят, поэтому она
   читается как основной текст; истёкшая красится: это единственное, что требует
   действия прямо сейчас. */
.reg-folder-main small.reg-live { color: var(--text); }
.reg-folder-main small.reg-gone { color: var(--danger, #e5484d); }
.reg-folder-side, .reg-person-side { flex: none; }
.reg-ic { flex: none; width: 34px; height: 34px; display: grid; place-items: center;
  border-radius: 10px; background: var(--surface-2); color: var(--muted); }
/* Три даты одной строкой: въезд, начало и конец учёта. Дата «до» — главное
   число карточки, по ней считаются напоминания и сверка с участковым. */
.reg-folder-main small.reg-ask { color: var(--brand); font-weight: 600; }
.reg-lat { margin: 4px 0 2px; gap: 8px; }
.reg-lat-name { font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace; font-size: 14px; letter-spacing: .04em; word-break: break-word; }
.reg-dates { display: flex; gap: 14px; flex-wrap: wrap; margin: 8px 0 4px; }
.reg-dates > div { display: flex; flex-direction: column; }
.reg-dates span { font-size: 12px; color: var(--muted); }
.reg-dates b { font-size: 15px; }
/* Документ: заголовок с количеством, подсказка из справочника и миниатюры.
   Собранный подсвечен слева зелёным, недостающий — оранжевым: пакет
   проверяют взглядом, а не чтением. */
.reg-doc { border-left: 3px solid var(--warn); padding: 8px 0 8px 10px; margin: 10px 0; }
.reg-doc.have { border-left-color: var(--ok, #2f9e63); }
.reg-doc-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.reg-doc .muted-text { font-size: 12px; margin: 2px 0 6px; }
.reg-thumbs { display: flex; gap: 6px; flex-wrap: wrap; margin-bottom: 6px; }
.reg-thumb { width: 64px; height: 64px; border-radius: 8px; border: 1px solid var(--line);
  background-size: cover; background-position: center; cursor: pointer; padding: 0;
  /* Файл закрыт и подставляется после запроса — до этого стоит серый квадрат,
     а не пустая рамка: иначе кажется, что снимок не загрузился. */
  background-color: var(--surface-2); }
.reg-thumb.missing { border-style: dashed; opacity: .6; }
/* Страницы документа: снимок слева, действия справа. Порядок правится
   стрелками — страницы паспорта ставят по одной и на телефоне, там важнее
   попадать, чем листать. */
.reg-page { display: flex; gap: 10px; align-items: flex-start;
  padding-top: 10px; margin-top: 10px; border-top: 1px solid var(--line); }
.reg-page:first-child { border-top: 0; margin-top: 0; }
.reg-page .reg-thumb { width: 72px; height: 92px; flex: none; }
.reg-page-main { flex: 1 1 auto; min-width: 0; }
.reg-page-row { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0; }
.reg-page-pick { display: block; font-size: 12px; color: var(--muted); margin-bottom: 6px; }

/* Кадрирование по четырём углам: снимок холстом, поверх — SVG с тем же
   viewBox. Из-за одинакового viewBox координаты углов живут в пикселях снимка,
   а растягивание по ширине экрана берёт на себя браузер: иначе каждый жест
   пришлось бы пересчитывать вручную. */
/* Снимок вписывается в окно ЦЕЛИКОМ — и по ширине, и по высоте. Кадрируют по
   четырём углам, а до угла, уехавшего под нижний край, не дотянуться: прокрутка
   под пальцем занята перетаскиванием рамки. Вытянутый чек в полную ширину как
   раз и уводил нижние углы за экран. */
.crop-wrap { text-align: center; }
.crop-box { position: relative; display: inline-block; max-width: 100%; }
.crop-img { display: block; max-width: 100%; max-height: min(52vh, 520px);
  width: auto; height: auto; border-radius: var(--radius-sm); }
/* Жесты по рамке — только перетаскивание углов, иначе телефон уводит страницу. */
.crop-svg { position: absolute; inset: 0; width: 100%; height: 100%; overflow: visible;
  touch-action: none; }
.crop-svg polygon { fill: rgba(31,111,235,.18); stroke: #fff; stroke-width: 3; vector-effect: non-scaling-stroke; }
/* Угол крупный: рамку тянут пальцем, и точка в шесть пикселей под него не
   попадает. Размер задаётся в координатах снимка (см. `r` при отрисовке). */
.crop-p { fill: #fff; stroke: var(--brand); stroke-width: 3; vector-effect: non-scaling-stroke; cursor: grab; }
.crop-p:active { cursor: grabbing; }
/* Лупа висит поверх снимка, в углу, противоположном пальцу: иначе закрывает
   собой ровно то место, которое человек и хочет разглядеть. */
.crop-loupe { position: absolute; top: 8px; left: 8px; width: 110px; height: 110px;
  border-radius: 50%; border: 2px solid #fff; box-shadow: var(--shadow);
  background: var(--surface-2); pointer-events: none; z-index: 2; }
.crop-loupe.right { left: auto; right: 8px; }

/* Присланное ботом — снимок или файл рядом с выбором «куда положить». */
.reg-inbox { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.reg-inbox .fld-input { flex: 1 1 auto; min-width: 0; }
.reg-bot-row { margin-top: 10px; }

/* Шаблон сообщения в правке: название, текст и ряд действий. Порядок меняется
   стрелками — строк немного, а на телефоне они надёжнее перетаскивания. */
.reg-tpl { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.reg-tpl .fld-input + .fld-input { margin-top: 6px; }
.reg-tpl-row { display: flex; gap: 6px; margin-top: 6px; }

/* Примечания из договора найма: подпись мелким, сам текст — обычным, с
   переносами как их набрал менеджер. Внутреннее выделено слева: в текст
   договора оно не идёт, это записка тому, кто оформляет. */
.reg-note { margin-top: 10px; }
.reg-note > span { display: block; font-size: 12px; color: var(--muted); }
.reg-note > b { font-size: 14px; }
.reg-note > p { margin: 2px 0 0; font-size: 14px; white-space: pre-wrap; }
.reg-note.inner { border-left: 3px solid var(--brand); padding-left: 10px; }

/* PDF миниатюрой не показать — он рисуется плиткой-файлом рядом со снимками:
   значок формата и имя, под которым файл прислали. */
.reg-file { display: flex; align-items: center; gap: 8px; max-width: 220px;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 8px;
  background: var(--surface-2); color: var(--text); cursor: pointer; text-align: left; }
.reg-file-ic { flex: none; font-size: 11px; font-weight: 700; letter-spacing: .04em;
  color: #fff; background: var(--danger, #e5484d); border-radius: 5px; padding: 3px 5px; }
.reg-file-name { font-size: 12px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.reg-add-file { display: inline-block; cursor: pointer; }
.reg-log { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }
.reg-log-row { display: flex; gap: 10px; font-size: 13px; }
.reg-log-row .muted-text { flex: none; min-width: 132px; }
.reg-danger { color: var(--danger, #e5484d); border-color: var(--danger, #e5484d); }
/* Мелкие общие кусочки, которых в дизайн-системе не было. */
.row-between { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.field.checkbox { display: flex; flex-direction: row; align-items: center; gap: 8px; }
.field.checkbox input { width: auto; }
.settle-note.warn { color: var(--warn); background: color-mix(in srgb, var(--warn) 12%, transparent); }

/* Окно «Кто вы?» на экране входа: четыре роли крупными кнопками, выбирают
   пальцем; выбор уводит в свой кабинет. */
.login-pick { gap: 8px; }
.login-pick-title { font-size: 17px; font-weight: 600; margin-bottom: 0; }
.login-pick-sub { margin: -4px 0 6px; }
.login-role { display: flex; flex-direction: column; align-items: flex-start; gap: 3px; width: 100%; text-align: left;
  padding: 11px 14px; border: 1px solid var(--line); border-radius: 12px; background: var(--card); color: var(--text);
  font-family: inherit; cursor: pointer; }
.login-role:hover { border-color: var(--brand); }
.login-role b { font-size: 15px; }
.login-role small { font-size: 12.5px; line-height: 1.4; color: var(--muted); }
.kv-row .kv-wrap { text-align: right; white-space: normal; word-break: break-word; font-weight: 500; }

/* QR для оплаты счёта (ЛКА): квадрат по ширине окна, не шире 280px. */
.qr-box { display: flex; flex-direction: column; align-items: center; gap: 6px; margin: 6px 0 10px; }
.qr-box svg { width: min(100%, 280px); height: auto; background: #fff; border-radius: 10px; padding: 8px; box-sizing: border-box; border: 1px solid var(--line); }

/* ── Окно бота на компьютере ──────────────────────────────────────────────
   Mini App в Telegram Desktop и в вебе: ширина как у телефона (~400px), но
   смотрят с расстояния монитора — телефонная крупность читается как «очень
   крупно». Ужимаем базовый кегль и плитки, ничего не перестраивая. */
html.tg-desk body { font-size: 13px; }
html.tg-desk .app-bar h1 { font-size: 15px; }
html.tg-desk .greeting-name { font-size: 15px; }
html.tg-desk .greeting-sub { font-size: 12px; }
html.tg-desk .avatar { width: 38px; height: 38px; font-size: 14px; }
html.tg-desk .avatar.lg { width: 52px; height: 52px; font-size: 20px; }
html.tg-desk .feed-tile { padding: 10px 12px; }
html.tg-desk .feed-tile.half { padding: 10px 11px; gap: 2px; }
html.tg-desk .feed-tile.half .feed-tile-label { font-size: 12px; }
html.tg-desk .feed-tile.half b { font-size: 15px; }
html.tg-desk .feed-tile.half small { font-size: 11px; }
html.tg-desk .feed-tile-value { font-size: 13px; }
html.tg-desk .tile-row { gap: 8px; }
html.tg-desk .pay-hero-value { font-size: 20px; }
html.tg-desk .section-title { font-size: 13px; }
html.tg-desk .row-title { font-size: 13px; }
html.tg-desk .row-sub { font-size: 11.5px; }
html.tg-desk .btn { padding: 8px 12px; font-size: 13px; }
html.tg-desk .btn.sm { padding: 6px 10px; font-size: 12px; }
html.tg-desk .tabbar a { font-size: 10.5px; }
html.tg-desk .kv b, html.tg-desk .kv-row b { font-size: 13px; }

/* Длинный текст в шапке карточки: раньше блок с адресом растягивался вместе
   с текстом и уезжал за край карточки без многоточия — у flex-потомка нет
   `min-width: 0`, и обрезка не срабатывала. Адрес переносим на строки, прочие
   подписи режем многоточием. */
.settle-head > div:first-child { flex: 1 1 auto; min-width: 0; }
.settle-head > .badge, .settle-head > .settle-head-r { flex: 0 0 auto; }
.settle-head .row-sub { white-space: normal; overflow-wrap: anywhere; }
.settle-head .settle-title, .settle-head .contract-no { overflow: hidden; text-overflow: ellipsis; }

/* Плитка с адресом: текст, а не число — мельче и обычным весом, чтобы длинный
   адрес не занимал четыре строки крупным кеглем. Две–три строки, дальше «…». */
.stat-value.text {
  font-size: 14px; font-weight: 600; letter-spacing: 0; line-height: 1.25;
  padding-right: 26px;                    /* место под значок в углу плитки */
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
  overflow-wrap: anywhere;
}
html.tg-desk .stat-value { font-size: 17px; }
html.tg-desk .stat-value.text { font-size: 12.5px; }
html.tg-desk .stat-label { font-size: 12px; }
html.tg-desk .stat-sub { font-size: 11px; }
html.tg-desk .stat { padding: 10px 12px; }

/* Список таблиц: та, из которой вернулись, подсвечена — глаз сразу находит место. */
.list.menu .row.sel { background: color-mix(in srgb, var(--brand) 10%, var(--surface)); }
.list.menu .row.sel .row-title { color: var(--brand); }

/* ── Готовые интеграции под модулем (12.09.2026) ─────────────────────────
   Раскрывающийся список сервисов, к которым интеграция уже сделана: Банк
   Точка, Билайн АТС, СМС-Услуги, Комтет. Свёрнут по умолчанию — в списке
   модулей главное сам модуль; карточки тянутся из-под его строки. */
.mod-int { margin: -4px 0 0 52px; }
.mod-int > summary {
  list-style: none; cursor: pointer; display: flex; align-items: center; justify-content: space-between; gap: 8px;
  font-size: 13px; color: var(--brand); padding: 4px 0 4px 14px; position: relative;
}
.mod-int > summary::-webkit-details-marker { display: none; }
.mod-int > summary::before {
  content: ''; position: absolute; left: 2px; top: 50%; width: 6px; height: 6px;
  border-right: 1.5px solid currentColor; border-bottom: 1.5px solid currentColor;
  transform: translateY(-70%) rotate(-45deg); transition: transform .15s;
}
.mod-int[open] > summary::before { transform: translateY(-60%) rotate(45deg); }
.int-cards { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 8px; padding: 2px 0 8px; }
.int-card {
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  padding: 10px 12px; display: flex; flex-direction: column; gap: 4px; box-shadow: var(--shadow);
}
.int-card.on { border-color: color-mix(in srgb, var(--ok) 45%, var(--line)); }
.int-head { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.int-kind { font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--muted); }
.int-name { font-weight: 700; }
.int-what { font-size: 13px; color: var(--muted); }
.int-note { font-size: 12px; color: var(--muted); }
.int-bar { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: 4px; flex-wrap: wrap; }
.int-site { font-size: 12px; color: var(--muted); text-decoration: none; overflow: hidden; text-overflow: ellipsis; }
@media (max-width: 480px) { .mod-int { margin-left: 0; } }
.sub-link { margin-left: 6px; padding: 1px 8px; font-size: 12px; }

/* Счётчик строк и кнопка «Свести» для выделенной пары (13.09.2026). */
.tbl-count-row { display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.pair-bar { display: flex; align-items: center; gap: 10px; font-size: 13px; }
.pair-bar[hidden] { display: none; }

/* ── Оформление договора (анкета арендатора, 14.09.2026) ─────────────────── */
.doc-row + .doc-row { margin-top: 6px; }
.doc-row .row-main { flex: 1; min-width: 0; }
.doc-row .row-sub { white-space: normal; }
.doc-files { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 6px; }
.doc-chip { font-size: 12px; background: var(--surface-2); border-radius: 999px; padding: 2px 8px; }
.doc-chip .doc-x { color: var(--danger); text-decoration: none; margin-left: 2px; }
.doc-up { flex: none; cursor: pointer; }
.ob-res + .ob-res { margin-top: 8px; }
.card-flat + .card-flat { margin-top: 8px; }
/* Миниатюры документов анкеты (15.09.2026): в карточке управляющего и в анкете арендатора. */
/* Подпись поля с кнопкой подтверждения предзаполненного значения (08.10.2026):
   красная «подтвердить» → зелёная «верно». */
.fld-label-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.onb-confirm { flex: none; border: 1px solid var(--danger); background: color-mix(in srgb, var(--danger) 10%, var(--surface)); color: var(--danger); font-size: 11px; font-weight: 600; line-height: 1; padding: 4px 9px; border-radius: 999px; cursor: pointer; white-space: nowrap; }
.onb-confirm.ok { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 14%, var(--surface)); color: var(--ok); }
.onb-thumbs { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 8px; }
.onb-thumb { position: relative; width: 96px; display: flex; flex-direction: column; gap: 3px; }
.onb-thumb a { display: block; }
.onb-thumb img, .onb-thumb-pdf { width: 96px; height: 72px; object-fit: cover; border-radius: 8px; border: 1px solid var(--line); background: var(--surface-2); display: block; }
.onb-thumb-pdf { display: grid; place-items: center; font-weight: 700; font-size: 12px; color: var(--muted); }
/* Вложения в кабинете ПОДРЯДЧИКА крупнее (22.10.2026, жалоба: «видит мелко»).
   Он смотрит фото проблемы с телефона на месте работ, и 96 px — это марка, а
   не снимок: по такой картинке не понять, что чинить. Три в ряд на телефоне,
   по ширине экрана; у остальных кабинетов размер прежний. */
.rq-page .onb-thumbs { gap: 10px; }
.rq-page .onb-thumb { width: calc((100% - 20px) / 3); max-width: 190px; }
.rq-page .onb-thumb img, .rq-page .onb-thumb-pdf { width: 100%; height: auto; aspect-ratio: 4 / 3; }
.rq-page .onb-thumb small { font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
@media (max-width: 420px) { .rq-page .onb-thumb { width: calc((100% - 10px) / 2); } }
/* Превью ролика поверх серой плашки: картинка появляется, когда загрузилась. */
.onb-thumb .vthumb { position: absolute; top: 0; left: 0; width: 96px; height: 72px; object-fit: cover; border-radius: 8px; border: 1px solid var(--line); background: var(--surface-2); display: none; }
.onb-thumb .vthumb.on { display: block; }
.onb-thumb .vthumb-play { position: absolute; left: 5px; bottom: 5px; width: 20px; height: 20px; border-radius: 50%; background: rgba(0,0,0,.6); color: #fff; font-size: 10px; line-height: 20px; text-align: center; pointer-events: none; }
.rep-item .onb-thumb .vthumb { width: 132px; height: 96px; }
.onb-thumb small { font-size: 10.5px; color: var(--muted); line-height: 1.2; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Вложение, которое ещё грузится (видео на канал идёт минутами): миниатюры и
   ссылки у него нет, но в заявке оно уже есть — состояние должно быть видно. */
.onb-thumb-up { gap: 5px; color: var(--muted); font-weight: 600; }
.onb-thumb-err { color: var(--danger); border-color: var(--danger); }
.badge .btn-spin { margin-right: 5px; }
.onb-thumb-x { border: 0; padding: 0; cursor: pointer; position: absolute; top: -6px; right: -6px; width: 20px; height: 20px; border-radius: 50%; background: var(--danger); color: #fff; text-decoration: none; font-size: 13px; line-height: 20px; text-align: center; }
/* Незакрытые начисления под «Деньги по объекту» (16.09.2026). */
.open-ch-head { margin-top: 10px; display: flex; align-items: center; gap: 8px; }
.open-ch-head > .row-sub, .open-ch-head > .cc-money-tabs-l { flex: 1 1 auto; margin: 0; font-weight: 600; color: var(--text); }
.open-ch-head .cmenu { flex: none; margin-left: auto; }
.open-ch { margin-top: 6px; }
.open-ch .hist-table th { position: static; }
/* Начисления/Счета/Оплаты на странице договоров — подписи, не ссылки. */
.money-chip { color: var(--muted); cursor: default; }
/* Предложения подрядчикам в карточке заявки (22.09.2026): строка на подрядчика,
   справа состояние ответа и действия столбиком; строки разделены линией. */
.rq-offer { padding: 8px 0; border-top: 1px solid var(--line); }
.rq-offer:first-child { border-top: 0; padding-top: 0; }
.rq-offer .mb-col { display: flex; flex-direction: column; align-items: flex-end; gap: 6px; flex: none; }

/* Ход дела: кнопка «Отправляется…» и всплывающая строка (24.09.2026). Нажатие
   должно быть видно — иначе человек жмёт второй раз и шлёт дубль. */
.btn-spin { display: inline-block; width: 13px; height: 13px; margin-right: 7px; vertical-align: -2px;
  border: 2px solid currentColor; border-right-color: transparent; border-radius: 50%; animation: btn-spin .7s linear infinite; }
@keyframes btn-spin { to { transform: rotate(360deg); } }
.btn[data-busy] { opacity: .85; }
.app-toast { position: fixed; left: 50%; bottom: 88px; transform: translate(-50%, 14px); z-index: 1400;
  max-width: min(520px, 92vw); padding: 10px 14px; border-radius: 12px; font-size: 14px; line-height: 1.35;
  background: var(--text); color: var(--surface); box-shadow: 0 8px 24px rgba(0,0,0,.25);
  opacity: 0; pointer-events: none; transition: opacity .18s, transform .18s; }
.app-toast.on { opacity: 1; transform: translate(-50%, 0); }
.app-toast.err { background: var(--danger); color: #fff; }
/* Полоса отмены удаления (16.10.2026): пять секунд, чтобы вернуть удалённое.
   Стоит над нижней панелью и над окнами — удаляют и из модалки тоже. */
.undo-bar { position: fixed; left: 50%; bottom: 88px; transform: translate(-50%, 14px); z-index: 1450;
  display: flex; align-items: center; gap: 10px; max-width: min(560px, 94vw);
  padding: 8px 10px 8px 14px; border-radius: 12px; font-size: 14px;
  background: var(--text); color: var(--surface); box-shadow: 0 8px 24px rgba(0,0,0,.28);
  opacity: 0; pointer-events: none; transition: opacity .18s, transform .18s; }
.undo-bar.on { opacity: 1; transform: translate(-50%, 0); pointer-events: auto; }
.undo-text { flex: 1; min-width: 0; }
.undo-btn { flex: none; padding: 6px 10px; border-radius: 9px; border: 0; cursor: pointer;
  font: inherit; font-weight: 700; background: var(--brand); color: #fff; }
.undo-btn:disabled { opacity: .6; cursor: default; }
.undo-x { flex: none; width: 26px; height: 26px; border-radius: 50%; border: 0; cursor: pointer;
  font-size: 16px; line-height: 1; background: transparent; color: inherit; opacity: .7; }

/* ── Календарь кабинета (25.09.2026) ─────────────────────────────────────────
   Виды работы разного цвета, состояние — насыщенностью: оплачено/сделано
   приглушено, просрочено красным. Сетка месяца как в Google: неделя с
   понедельника, шесть строк, чужие дни бледные. */
.cal-page { --cal-pay: #2f9e63; --cal-ku: #3b82f6; --cal-meters: #06b6d4; --cal-payout: #8b5cf6;
  --cal-req: #f59e0b; --cal-task: #ec4899; --cal-reg: #14b8a6; --cal-dogovor: #6366f1; --cal-daily: #0ea5e9; }
.cal-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.cal-title { font-weight: 700; font-size: 16px; min-width: 150px; text-align: center; }
.cal-spacer { flex: 1 1 auto; }
.cal-dot { width: 8px; height: 8px; border-radius: 50%; background: currentColor; flex: 0 0 auto; }
.tone-pay { color: var(--cal-pay); } .tone-ku { color: var(--cal-ku); }
.tone-meters { color: var(--cal-meters); } .tone-payout { color: var(--cal-payout); }
.tone-req { color: var(--cal-req); } .tone-task { color: var(--cal-task); }
.tone-reg { color: var(--cal-reg); } .tone-dogovor { color: var(--cal-dogovor); }
.tone-daily { color: var(--cal-daily); }
.cal-cals .fchip { gap: 6px; }
/* Слои календаря на телефоне свёрнуты в раскрывающуюся строку — восемь чипов
   занимали полэкрана (26.09.2026). */
.cal-cals-wrap { margin-bottom: 4px; }
.cal-cals-wrap > summary { list-style: none; cursor: pointer; display: inline-flex; align-items: center;
  gap: 6px; padding: 6px 12px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface-2); font-size: 13px; font-weight: 600; user-select: none; }
.cal-cals-wrap > summary::-webkit-details-marker { display: none; }
.cal-cals-wrap > summary::after { content: '▾'; color: var(--muted); margin-left: 2px; }
.cal-cals-wrap[open] > summary { margin-bottom: 6px; }
.cal-cals-wrap[open] > summary::after { content: '▴'; }
/* На широком экране список слоёв виден всегда: строку-переключатель прячем. */
@media (min-width: 620px) {
  .cal-cals-wrap > summary { display: none; }
  .cal-cals-wrap > .cal-cals { display: flex !important; }
}
.cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 1px;
  background: var(--line); border: 1px solid var(--line); border-radius: var(--radius-sm); overflow: hidden; }
.cal-dow { background: var(--surface-2); color: var(--muted); font-size: 11.5px; font-weight: 600;
  text-align: center; padding: 6px 0; }
.cal-day { background: var(--surface); min-height: 92px; padding: 4px 5px 6px; display: flex; flex-direction: column; gap: 3px; }
.cal-day.out { background: var(--surface-2); opacity: .55; }
/* Число дня слева, счётчик событий справа: рядом они читались как одно число. */
.cal-num { display: flex; align-items: center; justify-content: space-between; gap: 6px;
  font-size: 12px; font-weight: 600; color: var(--muted); }
.cal-d { min-width: 20px; text-align: center; padding: 1px 5px; border-radius: 999px; }
.cal-day.now .cal-d { background: var(--brand); color: #fff; }
.cal-more { color: var(--muted); font-weight: 600; font-size: 11px;
  background: var(--surface-2); border-radius: 999px; padding: 0 6px; }
.cal-ev { display: flex; align-items: center; gap: 5px; width: 100%; border: 0; background: none;
  padding: 2px 3px; border-radius: 6px; cursor: pointer; text-align: left; font: inherit; font-size: 11.5px; }
.cal-ev:hover { background: var(--surface-2); }
.cal-ev-t { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--text); }
.cal-ev.st-ok { opacity: .55; }
.cal-ev.st-late .cal-ev-t { color: var(--danger); font-weight: 600; }
.cal-rest { border: 0; background: none; color: var(--muted); font: inherit; font-size: 11px; cursor: pointer; text-align: left; padding: 0 3px; }
.cal-week { display: flex; flex-direction: column; gap: 8px; }
/* «3 дня» и «Сегодня»: на мониторе дни встают в ряд — их мало, и колонкой
   они растягивали бы экран пустотой. На телефоне остаётся список. */
@media (min-width: 900px) {
  .cal-week.cal-few { display: grid; grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); align-items: start; }
}
.cal-wday { border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); padding: 8px 10px; }
.cal-wday.now { border-color: var(--brand); }
.cal-whead { font-weight: 600; font-size: 13px; margin-bottom: 6px; display: flex; gap: 6px; align-items: center; }
.cal-n { background: var(--surface-2); color: var(--muted); border-radius: 999px; padding: 0 6px; font-size: 11px; }
.cal-row, .cal-row-m { display: flex; align-items: center; gap: 8px; width: 100%; border: 0; background: none;
  font: inherit; text-align: left; padding: 6px 2px; cursor: pointer; border-top: 1px solid var(--line); }
.cal-row-main { display: flex; flex-direction: column; min-width: 0; }
.cal-row-t { font-size: 13.5px; color: var(--text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-row-s { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cal-row.st-ok { opacity: .6; } .cal-row.st-late .cal-row-t { color: var(--danger); font-weight: 600; }
.cal-row-m.st-ok { opacity: .6; } .cal-row-m.st-late .row-title { color: var(--danger); }
.cal-empty { color: var(--muted); font-size: 12.5px; }
.feed-pair { display: grid; gap: 8px; }
@media (min-width: 620px) { .feed-pair { grid-template-columns: 1fr 1fr; } }

/* Контекст работы (26.09.2026): строка истории — кнопка, за ней открывается сам
   разговор; выданные выдержки стоят блоком «Контекст». Кнопке снимаем её
   собственные умолчания — выглядеть она должна обычной строкой истории. */
.mc-row {
  display: block; width: 100%; text-align: left; cursor: pointer;
  background: none; border: 0; padding: 2px 0; font: inherit;
  color: var(--muted); font-size: 13px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.mc-row:hover { color: var(--text); }
.mc-row .badge { vertical-align: 1px; }
/* Выдержка: заголовок, дата и сам текст разговора — у управляющего и у
   подрядчика одинаково. */
.mc-item { display: flex; flex-direction: column; gap: 6px; padding: 8px 0; }
.mc-item + .mc-item { border-top: 1px solid var(--line); }

/* Вкладки карточки заявки (26.09.2026): те же «таблетки», что у разделов
   объекта, но кнопками — адрес меняет обработчик, а не сама ссылка. */
.subtabs button {
  flex: none; font-family: inherit; font-size: 13px; font-weight: 600; color: var(--muted);
  padding: 8px 12px; border-radius: 999px; background: var(--surface); border: 1px solid var(--line);
  cursor: pointer;
}
.subtabs button.active { color: #fff; background: var(--brand); border-color: var(--brand); }
.subtabs .tab-n { margin-left: 5px; opacity: .75; }
/* Подразделы подготовки — сегменты в своей плашке: вкладки карточки рядом
   выглядят «таблетками», и две одинаковые линейки друг под другом сливались в
   одну массу (29.09.2026). На узком экране сегменты не сжимаем до нечитаемых
   огрызков, а прокручиваем. */
.prep-seg { margin: 2px 0 12px; }
.prep-seg .tab-n { margin-left: 5px; font-size: 11.5px; opacity: .75; }
@media (max-width: 460px) {
  .prep-seg { overflow-x: auto; -webkit-overflow-scrolling: touch; scrollbar-width: none; }
  .prep-seg::-webkit-scrollbar { display: none; }
  .prep-seg .seg-btn { flex: 0 0 auto; white-space: nowrap; padding: 9px 12px; }
}
/* Подготовка: позиция списка покупок и заметка — текст слева, крестик справа. */
.prep-row { display: flex; align-items: flex-start; gap: 8px; padding: 6px 0; }
.prep-row + .prep-row { border-top: 1px solid var(--line); }
.prep-row > span { flex: 1; min-width: 0; }
.prep-check { display: flex; align-items: flex-start; gap: 8px; flex: none; cursor: pointer; }
.prep-check input { margin-top: 3px; }

/* Переписки: ссылки в репликах, голосовые и панель ответа (26.09.2026).
   Длинная ссылка обязана переноситься — иначе она растягивает окно по ширине
   и текст рядом становится нечитаемым. */
.chat-text a.chat-link { color: var(--brand); text-decoration: underline; overflow-wrap: anywhere; word-break: break-word; }
.chat-voice { display: flex; flex-direction: column; gap: 6px; }
.chat-voice-row { display: flex; flex-wrap: wrap; gap: 6px; }
.chat-voice-player[hidden] { display: none; }
.chat-voice-player audio { width: 100%; max-width: 320px; }

/* Клавиатура на телефоне (28.09.2026): layout viewport от неё не меняется, и
   `dvh` о ней не знает — высоту считает `keyboardFit` в ui.js и кладёт в `--kb`.
   Окно прижимается к верхнему краю клавиатуры и ужимается до видимой части,
   поэтому липкая панель с кнопками остаётся на экране: сохранить можно, не
   убирая клавиатуру. */
body.kb-open .modal-overlay { bottom: var(--kb, 0px); }
body.kb-open .modal { max-height: calc(100dvh - var(--kb, 0px) - 12px); }
/* Список покупок: группы пунктов и правка позиции нажатием на название. */
.prep-group { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin: 2px 0 6px; }
.prep-group .row-title { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
.prep-name {
  border: 0; background: none; padding: 0; margin: 0; font: inherit; color: inherit;
  text-align: left; flex: 1; min-width: 0;
}
/* Конструктор шаблона СМС (29.09.2026): блоки текста и корзиночки полей. */
.sms-blocks { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 10px; }
/* Конструктор правила разнесения: ряд кнопок под блоками текста платежа. */
.rf-acts { flex-wrap: wrap; gap: 6px; margin: 0 0 8px; }
.rf-acts .btn { flex: none; }
.sms-block { display: inline-flex; align-items: center; gap: 4px; padding: 4px 8px; border: 1px solid var(--line);
  border-radius: 8px; background: var(--surface); cursor: pointer; user-select: none; -webkit-user-select: none; -webkit-touch-callout: none; font-size: 13px; }
.sms-block.sel { border-color: var(--brand); box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand) 30%, transparent); }
.sms-block i { font-style: normal; font-size: 10px; font-weight: 700; color: #fff; background: var(--muted);
  border-radius: 4px; padding: 0 4px; }
.sms-block.b-date, .sms-basket.b-date { --bk: #2e7d32; }
.sms-block.b-time, .sms-basket.b-time { --bk: #00838f; }
.sms-block.b-amount, .sms-basket.b-amount { --bk: #ad6800; }
.sms-block.b-card, .sms-basket.b-card { --bk: #6a1b9a; }
.sms-block.b-note, .sms-basket.b-note { --bk: #37474f; }
.sms-block[class*="b-"] { border-color: var(--bk); }
.sms-block[class*="b-"] i { background: var(--bk); }
.sms-baskets { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 10px; }
.sms-basket { flex: 1; min-width: 120px; border: 1px dashed var(--line); border-radius: 10px; padding: 8px 10px;
  cursor: pointer; background: var(--surface); }
.sms-basket.over { border-style: solid; border-color: var(--brand); background: color-mix(in srgb, var(--brand) 8%, var(--surface)); }
.sms-basket[class*="b-"] { border-color: var(--bk); }
.sms-basket .bk-name { display: block; font-size: 11px; font-weight: 700; color: var(--bk, var(--muted)); text-transform: uppercase; }
.sms-basket .bk-cap { display: block; font-size: 13px; min-height: 18px; }
.sms-basket .bk-cap .ph { color: var(--muted); }
.sms-basket .bk-x { cursor: pointer; color: var(--danger); margin-left: 4px; }
/* «+ Ещё пример» рядом с закладками примеров: компактной кнопкой, не во всю долю. */
.subtabs.inner .sr-addex { flex: 0 0 auto; padding-inline: 12px; color: var(--brand); }
/* Статус очистки фото объявления (кисточка на карточке ОПК). */
.btn.cs-none { color: var(--warn, #ad6800); }
.btn.cs-noneed { color: var(--muted); }
.btn.cs-done { color: var(--ok, #1a9c5b); }
.btn.cs-cleaning { color: var(--brand); animation: cs-pulse 1.1s ease-in-out infinite; }
@keyframes cs-pulse { 0%, 100% { opacity: 1; } 50% { opacity: .45; } }
.sms-prev { border-top: 1px solid var(--line); padding-top: 8px; }
.sms-prev-row { font-size: 13px; padding: 2px 0; }
.sms-prev-row.ok b { color: var(--ok, #2e7d32); }
/* Строка списка подготовки — одна цель нажатия (28.09.2026): короткий тап
   открывает карточку позиции, долгое нажатие ставит и снимает отметку. Значит
   строка не должна выделяться текстом и вызывать меню «Копировать», а на
   сенсорном экране мелкий квадратик галочки нажатия не перехватывает: пальцем в
   16 px не попадают, и промах открывал карточку вместо снятия отметки. */
.prep-row[data-rq-row] {
  cursor: pointer; -webkit-user-select: none; user-select: none;
  -webkit-touch-callout: none; touch-action: pan-y;
}
.prep-row[data-rq-row]:active { background: var(--surface-2); }
.prep-hint { margin: -2px 0 6px; opacity: .75; }
@media (hover: none) {
  .prep-row[data-rq-row] .prep-check { pointer-events: none; }
}
.prep-check input { width: 18px; height: 18px; }
.prep-row.done .prep-name b { text-decoration: line-through; color: var(--muted); }
/* Задача и пункт работ заявки переносятся на несколько строк (29.09.2026).
   Ярлык с галочкой здесь держит и название, а у `.prep-check` стоит
   `flex: none` (в подготовке он держит одну галочку) — длинная задача
   вылезала за карточку. В карточке заявки подписи тоже не режем многоточием:
   их читают целиком («Видят исполнители…», «Подзадач нет…», адрес). */
.prep-check.wide { flex: 1; min-width: 0; }
.prep-check.wide > span { min-width: 0; overflow-wrap: anywhere; }
.rq-page .card-flat .row-sub { white-space: normal; overflow: visible; overflow-wrap: anywhere; }

/* Встроенная камера «Снять сейчас» (inAppCamera в ui.js, 29.09.2026) */
.cam-overlay { position: fixed; inset: 0; z-index: 3000; background: #000; display: flex; align-items: center; justify-content: center; }
.cam-view { width: 100%; height: 100%; object-fit: contain; background: #000; }
.cam-msg { position: absolute; left: 16px; right: 16px; top: 40%; color: #fff; text-align: center; font-size: 15px; line-height: 1.4; }
.cam-msg[hidden] { display: none; }
.cam-x { position: absolute; top: calc(12px + env(safe-area-inset-top, 0px)); right: 12px; width: 44px; height: 44px; border-radius: 50%; border: 0; background: rgba(0,0,0,.5); color: #fff; font-size: 28px; line-height: 1; }
.cam-bar { position: absolute; left: 0; right: 0; bottom: calc(64px + env(safe-area-inset-bottom, 0px)); display: flex; align-items: center; justify-content: space-around; }
.cam-shot { width: 72px; height: 72px; border-radius: 50%; border: 5px solid #fff; background: rgba(255,255,255,.35); }
.cam-shot:active { background: #fff; }
.cam-flip, .cam-rec, .cam-pause { min-width: 64px; height: 44px; border-radius: 22px; border: 0; background: rgba(0,0,0,.5); color: #fff; font-size: 15px; padding: 0 12px; }
.cam-flip { font-size: 22px; }
.cam-gap { min-width: 64px; }
.cam-bar > [hidden] { display: none; }
/* Режим видео: «Старт» на месте спуска, на записи он становится «Стоп»; сверху счётчик секунд. */
.cam-go { width: 72px; height: 72px; border-radius: 50%; border: 5px solid #fff; background: #e5484d; color: #fff; font-size: 14px; font-weight: 600; padding: 0; }
.cam-go.on { border-radius: 18px; }
.cam-timer { position: absolute; top: calc(18px + env(safe-area-inset-top, 0px)); left: 50%; transform: translateX(-50%); display: flex; align-items: center; gap: 8px; padding: 6px 14px; border-radius: 18px; background: rgba(0,0,0,.55); color: #fff; font-size: 18px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.cam-timer[hidden], .cam-paused[hidden] { display: none; }
.cam-timer i { width: 10px; height: 10px; border-radius: 50%; background: #8a8a8a; }
.cam-overlay.recording .cam-timer i { background: #e5484d; animation: cam-blink 1s steps(2, jump-none) infinite; }
.cam-overlay.rec-paused .cam-timer i { background: #f5a623; }
.cam-paused { font-size: 14px; font-weight: 600; color: #f5a623; }
@keyframes cam-blink { from { opacity: 1; } to { opacity: .25; } }
.cam-native { position: absolute; left: 50%; transform: translateX(-50%); bottom: calc(14px + env(safe-area-inset-bottom, 0px)); border: 0; background: none; color: #ddd; font-size: 14px; text-decoration: underline; }

/* Бирка комплекта ключей (30.09.2026): в руках она в две строки — улица словом,
   под ней цифры группами через точку, записанные задом наперёд. Показываем так
   же, чтобы найденную бирку можно было сверить глазами, не считая в уме. */
.key-tag {
  display: inline-flex; flex-direction: column; gap: 2px; margin: 6px 0;
  padding: 6px 10px; border: 1px dashed var(--line); border-radius: var(--radius-sm);
  background: var(--surface-2); line-height: 1.25;
}
.key-tag .key-digits { font-size: 15px; font-weight: 700; letter-spacing: .06em; font-variant-numeric: tabular-nums; }
/* Памятка «Как обозначать ключи» (16.10.2026). */
.key-rules .mini-title { margin-top: 14px; }
/* Пояснения правил — предложения, они переносятся, а не режутся: общий
   .row-sub (nowrap + ellipsis) оставил бы от каждой строки половину. */
.key-rules .row-sub { white-space: normal; overflow: visible; text-overflow: clip; line-height: 1.4; }
.key-rules .key-tag.sample .key-digits { letter-spacing: 0; font-weight: 600; color: var(--muted); }
.key-rules .key-tag-ex { margin: 6px 0; }
.key-rules-ul { margin: 6px 0 0; padding-left: 18px; }
.key-rules-ul li { margin: 3px 0; font-size: 13px; color: var(--text); line-height: 1.35; }
.key-marks { list-style: none; padding-left: 0; }
.key-marks li { display: flex; align-items: baseline; gap: 8px; }
.key-dot { flex: none; width: 12px; height: 12px; border-radius: 50%; margin-top: 3px; border: 1px solid rgba(0,0,0,.2); }
.key-dot.red { background: #e5484d; }
.key-dot.white { background: #fff; }
.key-dot.orange { background: #f2822c; }
.key-dot.blue { background: #3b6fe0; }
.key-dot.grey { background: #9aa3b2; }

/* Карточка объявления рынка (01.10.2026): миниатюра слева, сведения справа от
   неё, кнопки строкой ниже — так в выдаче помещается вдвое больше объявлений.
   Снимки берём прямой ссылкой с CDN площадок, к себе чужие фото не копируем. */
.mk-card { padding: 10px 12px 12px; }
.mk-row { display: flex; gap: 10px; align-items: flex-start; }
.mk-photo {
  position: relative; flex: 0 0 132px; width: 132px; height: 104px;
  border-radius: var(--radius-sm); overflow: hidden; background: var(--surface-2);
}
.mk-photo img { width: 100%; height: 100%; object-fit: cover; display: block; cursor: zoom-in; }
.mk-photo.empty { display: flex; align-items: center; justify-content: center; }
.mk-count {
  position: absolute; right: 4px; bottom: 4px; padding: 1px 6px; border-radius: 999px;
  background: rgba(8, 12, 18, .62); color: #fff; font-size: 11px; font-weight: 600;
}
.mk-info { flex: 1; min-width: 0; }
.mk-info .row-sub { white-space: normal; }
.mk-card .mb-row { margin-top: 8px; }
@media (max-width: 420px) { .mk-photo { flex-basis: 104px; width: 104px; height: 84px; } }

/* Разделы режима агента — плитками (01.10.2026): у каждого своё число, и его
   смотрят до того, как открыть раздел. Открытый выделен, остальные приглушены. */
.ag-tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: 8px; margin-bottom: 12px; }
@media (max-width: 720px) { .ag-tiles { grid-template-columns: repeat(2, 1fr); } }
.ag-tile {
  display: flex; flex-direction: column; gap: 2px; align-items: flex-start; text-align: left;
  padding: 12px; border-radius: var(--radius); border: 1px solid transparent; cursor: pointer;
  font: inherit; color: #fff; background: var(--brand); opacity: .55; min-width: 0;
}
.ag-tile.active { opacity: 1; box-shadow: var(--shadow); }
.ag-tile:hover { opacity: .8; }
.ag-tile.active:hover { opacity: 1; }
.ag-tile-label { font-size: 12.5px; font-weight: 600; opacity: .92; }
.ag-tile-value { font-size: 26px; font-weight: 800; line-height: 1.1; }
.ag-tile-sub { font-size: 11.5px; opacity: .85; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 100%; }

/* Вид выдачи рынка (01.10.2026): списком — миниатюра слева и сведения справа,
   плитками — снимок сверху во всю карточку. Списком ищут нужный адрес, плитками
   смотрят глазами по фотографиям; выбор помнится в браузере. */
/* Шапка выдачи рынка: значок фильтра перед строкой поиска (01.10.2026).
   Условий отбора полтора десятка — снаружи остаётся значок с их числом. */
.mk-search { display: flex; gap: 6px; align-items: center; margin-bottom: 6px; }
.mk-search .fld-input { flex: 1; min-width: 0; }
.mk-filter-btn { position: relative; flex: none; padding: 6px 9px; }
.mk-filter-btn.active { border-color: var(--brand); color: var(--brand); }
.mk-filter-n {
  position: absolute; top: -5px; right: -5px; min-width: 16px; height: 16px;
  padding: 0 3px; border-radius: 9px; background: var(--brand); color: #fff;
  font-size: 10.5px; line-height: 16px; font-weight: 700; text-align: center;
}
.mk-head-act { display: flex; align-items: center; gap: 8px; flex: none; }
.mk-list.rows { display: flex; flex-direction: column; gap: 8px; }
.mk-list.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(230px, 1fr)); gap: 8px; }
.mk-list.tiles .mk-card { padding: 0 0 12px; }
.mk-list.tiles .mk-row { flex-direction: column; gap: 0; }
.mk-list.tiles .mk-photo { flex: none; width: 100%; height: 170px; border-radius: var(--radius) var(--radius) 0 0; }
.mk-list.tiles .mk-info { padding: 10px 12px 0; }
.mk-list.tiles .mb-row { padding: 0 12px; grid-auto-flow: row; }
@media (max-width: 420px) { .mk-list.tiles { grid-template-columns: repeat(2, 1fr); } }

/* Карточка объявления кликабельна целиком, действия — в «⋮» справа вверху
   (01.10.2026): четыре кнопки в каждой строке съедали выдачу. */
.mk-card { position: relative; cursor: pointer; }
.mk-menu {
  position: absolute; top: 6px; right: 6px; z-index: 2; width: 28px; height: 28px;
  border-radius: 50%; border: 1px solid var(--line); background: var(--surface);
  color: var(--muted); font-size: 16px; line-height: 1; cursor: pointer;
}
.mk-menu:hover { color: var(--text); }
/* Фотографии в карточке объявления: лента, снимок открывается на весь экран. */
.mk-full-photos { display: flex; gap: 6px; overflow-x: auto; margin: 8px 0; padding-bottom: 4px; }
.mk-full-photos img {
  flex: 0 0 auto; width: 148px; height: 110px; object-fit: cover; cursor: zoom-in;
  border-radius: var(--radius-sm); background: var(--surface-2);
}

/* Сколько объявлений сейчас под картой — строкой прямо под ней (01.10.2026):
   смотрят туда же, куда двигают карту. */
/* Миниатюра фото показаний в строке счётчика (05.10.2026): по ней проверяют
   цифру, не открывая историю; нажатие — полный экран. */
.meter-pic {
  flex: none; width: 48px; height: 36px; margin-right: 8px; padding: 0;
  border: 1px solid var(--line); border-radius: 8px; background: var(--bg) center/cover no-repeat;
  cursor: zoom-in;
}
.meter-pic:hover { border-color: var(--brand); }

/* Сервис-чат (05.10.2026): диалог с арендатором — заявки, вопросы, текущие
   задачи. Наши реплики справа, жителя — слева, как в любом мессенджере. */
.sc-list { display: flex; flex-direction: column; gap: 6px; margin: 6px 0 10px; max-height: 46vh; overflow-y: auto; }
.sc-msg { max-width: 86%; padding: 8px 10px; border-radius: 12px; background: var(--surface); border: 1px solid var(--line); }
.sc-msg.out { align-self: flex-end; background: color-mix(in srgb, var(--brand) 10%, var(--surface)); border-color: color-mix(in srgb, var(--brand) 35%, var(--line)); }
.sc-text { font-size: 14px; white-space: pre-wrap; overflow-wrap: anywhere; }
.sc-at { margin-top: 3px; font-size: 11.5px; color: var(--muted); }
/* Недоставленная реплика: в истории видно, что житель её не получил, и почему. */
.sc-msg.fail { border-color: color-mix(in srgb, #d9432f 45%, var(--line)); }
.sc-fail { margin-top: 4px; font-size: 12px; color: #d9432f; }
.sc-fail .link-btn { font-size: 12px; color: inherit; text-decoration: underline; }

/* Счёт, открытый по ссылке из бота (05.10.2026): подсвечиваем ту карточку,
   о которой человеку написали, — в списке их бывает с десяток. */
.card-flat.inv-hl { outline: 2px solid var(--brand); outline-offset: 2px; }

/* Быстрые кнопки объявления (01.10.2026): карта, избранное и условия
   собственника прямо у адреса — агент правит карточку на ходу. */
.mkq-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.mkq-addr { flex: 1 1 180px; min-width: 0; }
.mkq { display: flex; align-items: center; gap: 4px; flex: none; }
.mkq-wrap { position: relative; display: inline-flex; }
.mkq-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 32px; height: 32px; padding: 0; border: 1px solid var(--line);
  border-radius: 8px; background: var(--surface); color: var(--muted); cursor: pointer;
}
.mkq-btn:hover { color: var(--text); }
.mkq-btn.on { border-color: var(--brand); color: var(--brand); background: color-mix(in srgb, var(--brand) 10%, var(--surface)); }
.mkq-btn.fav.on { border-color: #d9432f; color: #d9432f; background: color-mix(in srgb, #d9432f 10%, var(--surface)); }
.mkq-btn.fav.on svg { fill: currentColor; }
.mkq-menu {
  position: absolute; top: calc(100% + 4px); right: 0; z-index: 5;
  display: flex; flex-direction: column; min-width: 150px;
  background: var(--surface); border: 1px solid var(--line); border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, .16); overflow: hidden;
}
.mkq-menu[hidden] { display: none; }
.mkq-item {
  padding: 8px 12px; border: 0; background: none; text-align: left;
  font: inherit; font-size: 13.5px; color: var(--text); cursor: pointer;
}
.mkq-item:hover { background: var(--bg); }
.mkq-item.active { color: var(--brand); font-weight: 600; }
/* Сердечко в строке выдачи — рядом с «⋮», своей областью под палец. */
.mk-fav {
  position: absolute; top: 4px; right: 30px; width: 28px; height: 28px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center;
  border: 0; background: none; color: var(--muted); cursor: pointer;
}
.mk-fav.on { color: #d9432f; }
.mk-fav.on svg { fill: currentColor; }
.mk-map-count {
  margin: -2px 0 10px; padding: 8px 12px; border-radius: 0 0 var(--radius) var(--radius);
  background: var(--surface-2); color: var(--muted); font-size: 13px;
}
.mk-map-count[hidden] { display: none; }
.mk-map-count b { color: var(--text); font-size: 15px; }

/* Нулевой комплект — офисный основной, в нём оригиналы ключей (01.10.2026):
   его карточка зелёная, чтобы в списке из десятка записей он находился глазами. */
.card.key-zero { border-left: 3px solid var(--ok); background: color-mix(in srgb, var(--ok) 6%, var(--surface)); }

/* Отчёты о выполнении заявки (01.10.2026): у каждого снимка и ролика своя подпись. */
.rep-items { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 8px; }
.rep-item { display: flex; flex-direction: column; gap: 4px; width: 132px; }
.rep-item .onb-thumb, .rep-item .onb-thumb img, .rep-item .onb-thumb-pdf { width: 132px; }
.rep-item .onb-thumb img, .rep-item .onb-thumb-pdf { height: 96px; }
.rep-cap { font-size: 13px; line-height: 1.3; white-space: pre-wrap; overflow-wrap: anywhere; }
.rep-edit { display: flex; align-items: center; gap: 8px; margin-top: 6px; }
.rep-edit .fld-input { flex: 1; min-width: 0; }

/* Окно сотрудника (03.10.2026): пояснения под «Отдел» и «Роль» переносятся
   целиком — общий .row-sub режет строку многоточием, и на телефоне от фразы
   оставалось «…задача заводится на отдел, а…». И отступ до следующего поля:
   подпись «Роль» прилипала к пояснению. */
.row-sub.se-hint { white-space: normal; overflow: visible; text-overflow: clip; margin: 4px 0 10px; line-height: 1.35; }
.row-sub.se-hint:empty { margin: 0; }

/* Отделы сотрудника — мультивыбор (03.10.2026) */
.se-depts { display: grid; grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); gap: 4px 12px; margin-top: 4px; }
.se-depts .fld-check { margin: 0; }
.se-main { font-style: normal; font-size: 11px; color: var(--accent, #2b6cb0); margin-left: 4px; }

/* «Поделиться → ЭЛИДОМ»: входящие из галереи (03.10.2026) */
.share-item { display: flex; gap: 10px; align-items: flex-start; }
.share-item .prep-check { flex: none; padding-top: 4px; }
.share-thumb { flex: none; width: 76px; height: 76px; border-radius: 8px; object-fit: cover; background: var(--surface-2, #eef1f5); }
.share-ic { display: flex; align-items: center; justify-content: center; color: var(--muted, #667); }
.share-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 6px; }
.share-main .row-title { overflow-wrap: anywhere; }
/* Путь пункта («ЧКП: На объекте → Сервис → …»), заявка, наблюдение и подсказки в окнах
   выбора — читаются целиком: общий .row-sub резал их в строку с многоточием, и на
   телефоне от пути оставался один раздел (04.11.2026, id=1191). */
.share-main .row-sub, #sha-body .row-sub, #shq-body .row-sub, #shi-body .row-sub {
  white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; }

/* Не выбрано обязательное поле (напр. «МОП или комната» у снимка покомнатной
   квартиры, 03.10.2026). */
.fld-input.invalid, select.invalid, .pr-cap.invalid { border-color: var(--danger, #d9432f) !important; box-shadow: 0 0 0 2px rgba(217, 67, 47, .18); }

/* ── Посуточная аренда (03.10.2026) ──────────────────────────────────────────
   Сетка занятости: строки — номера, столбцы — дни; бронь растянута на свои
   ночи. Таблица прокручивается вбок сама, колонка номера липкая. */
.dl-nav, .dl-acts { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; margin: 8px 0; }
.dl-sp { flex: 1 1 auto; }
.dl-wrap { overflow-x: auto; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.dl-grid { border-collapse: collapse; font-size: 12px; min-width: 100%; }
.dl-grid th, .dl-grid td { border: 1px solid var(--line); padding: 4px; text-align: center; min-width: 34px; height: 30px; }
.dl-grid th { font-weight: 600; color: var(--muted); font-size: 11px; background: var(--surface-2); }
.dl-grid th.dl-we { color: var(--danger); }
.dl-grid th.dl-today { background: var(--brand); color: #fff; }
.dl-grid .dl-unit { position: sticky; left: 0; z-index: 1; background: var(--surface); text-align: left; min-width: 110px; white-space: nowrap; font-weight: 600; }
.dl-grid .dl-unit small { display: block; font-weight: 400; color: var(--muted); }
.dl-grid tr.dl-obj td { text-align: left; background: var(--surface-2); font-weight: 700; }
.dl-grid td.dl-free { cursor: pointer; }
.dl-grid td.dl-free:hover { background: var(--surface-2); }
.dl-grid td.dl-bk { cursor: pointer; color: #fff; font-weight: 600; overflow: hidden; white-space: nowrap; max-width: 0; }
.dl-grid td.dl-bk span { display: block; overflow: hidden; text-overflow: ellipsis; }
.dl-request, .dl-lg.dl-request { background: #f59e0b; }
.dl-confirmed, .dl-lg.dl-confirmed { background: #0ea5e9; }
.dl-in, .dl-lg.dl-in { background: #2f9e63; }
.dl-done, .dl-lg.dl-done { background: #94a3b8; }
.dl-block, .dl-lg.dl-block { background: #475569; }
.dl-legend { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 6px 0 4px; font-size: 12px; }
.dl-lg { color: #fff; border-radius: 6px; padding: 2px 8px; }
.dl-sum { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-bottom: 8px; }
@media (min-width: 620px) { .dl-sum { grid-template-columns: repeat(4, 1fr); } }
.dl-tile { border: 1px solid var(--line); border-radius: 12px; padding: 10px 12px; background: var(--surface); }
.dl-tile b { display: block; font-size: 20px; }
.dl-tile span { font-size: 12px; color: var(--muted); }
.dl-tile.warn { border-color: var(--warn); }
.dl-form { display: grid; grid-template-columns: 1fr 1fr; gap: 0 10px; }
.dl-check { display: flex; gap: 8px; align-items: center; margin: 6px 0; font-weight: 600; }
.dl-docs { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 6px; }
.card.dl-u { padding: 10px; margin-bottom: 8px; }
/* Метки брони: цвет и эмодзи (как в шахматке RealtyCalendar, 05.10.2026). */
/* Окно «Цены и доступность» (ценовая модель RC, 07.10.2026). */
.dp-units { margin-bottom: 8px; flex-wrap: wrap; }
.dp-cal-nav { display: flex; align-items: center; gap: 6px; margin: 6px 0; }
.dp-head { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; font-size: 11px; color: var(--muted); text-align: center; }
.dp-cal { display: grid; grid-template-columns: repeat(7, 1fr); gap: 3px; margin: 3px 0 8px; }
.dp-day { min-height: 46px; border: 1px solid var(--line); border-radius: 8px; background: var(--surface);
  display: flex; flex-direction: column; align-items: stretch; justify-content: space-between; padding: 3px 4px; cursor: pointer; position: relative; }
.dp-day.dp-empty { border: 0; background: transparent; cursor: default; }
.dp-day .dp-n { font-size: 11px; color: var(--muted); text-align: left; }
.dp-day .dp-p { font-size: 11px; font-weight: 600; text-align: right; }
.dp-day .dp-m { position: absolute; bottom: 2px; left: 4px; font-size: 9px; color: var(--muted); }
.dp-day.we { background: var(--surface-2); }
.dp-day.src-season { border-color: color-mix(in srgb, var(--brand) 45%, transparent); }
.dp-day.src-season .dp-p { color: var(--brand); }
.dp-day.src-special .dp-p { color: #b26a00; }
.dp-day.closed { background: color-mix(in srgb, var(--danger) 12%, transparent); }
.dp-day.closed .dp-p { color: var(--danger); }
.dp-day.on { outline: 2px solid var(--brand); outline-offset: -2px; }
.dp-apply { border-top: 1px solid var(--line); margin-top: 8px; padding-top: 8px; }
.dl-mark { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px; margin: 8px 0; }
.dl-mk-lbl { font-size: 12px; color: var(--muted); }
.dl-colors, .dl-emojis { display: inline-flex; flex-wrap: wrap; gap: 4px; }
.dl-col { width: 22px; height: 22px; border-radius: 50%; border: 2px solid transparent; cursor: pointer; padding: 0; }
.dl-col.on { border-color: var(--text); box-shadow: 0 0 0 1px var(--surface) inset; }
.dl-col-none { background: var(--surface-2); color: var(--muted); font-size: 13px; line-height: 1; }
.dl-emo { min-width: 26px; height: 26px; border: 1px solid var(--line); border-radius: 6px; background: var(--surface); cursor: pointer; font-size: 15px; padding: 0 4px; }
.dl-emo.on { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 12%, transparent); }
/* Зелёная полоса предоплаты на броне (как у RC). */
.dl-grid td.dl-bk.dl-paid { box-shadow: inset 0 -3px 0 #22c55e; }

/* ИИ-помощник в форме ключей (03.10.2026): верх окна, выделен фоном. */
.ai-box { background: color-mix(in srgb, var(--brand) 7%, transparent); border: 1px solid color-mix(in srgb, var(--brand) 25%, transparent); margin-bottom: 12px; }
.ai-box .settle-title { display: inline-flex; align-items: center; gap: 6px; }
.ai-box #kai-mic.active, .ai-box .ai-mic.active { color: #d9432f; border-color: #d9432f; }
/* Блок ИИ свёрнут по умолчанию (31.10.2026): видна строка заголовка, нажатие
   раскрывает (.open). Дублируется в js/ui.js (aiBoxCollapse) — на случай старого кэша. */
.ai-box:not(.open) > .row-line ~ * { display: none !important; }
.ai-box > .row-line { cursor: pointer; user-select: none; align-items: center; }
.ai-box > .row-line::after { content: "\25BE"; color: var(--muted); font-size: 16px; line-height: 1; transition: transform .15s; }
.ai-box:not(.open) > .row-line::after { transform: rotate(-90deg); }
.ai-box.open > .row-line { margin-bottom: 6px; }

/* Окно задачи не шире экрана (03.10.2026): всё содержимое ужимается по ширине
   окна, длинные строки переносятся, шильдики встают в несколько рядов. Только
   у окон с .fit-x — у матрицы прав окно прокручивается вбок намеренно. */
.modal.fit-x { overflow-x: hidden; }
.modal.fit-x > *, .modal.fit-x .lead-form > *, .modal.fit-x .field, .modal.fit-x .fld { min-width: 0; max-width: 100%; }
.modal.fit-x .fld-input { max-width: 100%; min-width: 0; box-sizing: border-box; }
.modal.fit-x .mini-title, .modal.fit-x .row-sub { white-space: normal; overflow-wrap: anywhere; }
.modal.fit-x .filter-chips { flex-wrap: wrap; }
.modal.fit-x .mb-row { flex-wrap: wrap; }
.row-sub.wrap, .row-sub.wrap > div { white-space: normal; overflow-wrap: anywhere; }
/* Закладки подготовки в карточке задачи: строка позиции с карандашом. */
.tk-pmiz .prep-seg { margin-top: 0; }
/* Четыре закладки в карточке задачи не помещались в ширину телефона и уезжали
   за край («Заметки» не видно) — на узком экране сеткой 2×2 (03.10.2026). */
@media (max-width: 460px) {
  .tk-pmiz .prep-seg.tk-pmiz-tabs { display: grid; grid-template-columns: 1fr 1fr; overflow: visible; }
  .tk-pmiz .prep-seg.tk-pmiz-tabs .seg-btn { flex: none; min-width: 0; padding: 9px 6px; }
}
.tk-pmiz .mb-row { flex-wrap: wrap; }
.tk-pmiz .mb-row > .btn { min-width: 0; white-space: normal; }
.tk-pm-row { display: flex; align-items: flex-start; gap: 8px; padding: 8px 0; border-top: 1px solid var(--line); }
.tk-pm-row:first-of-type { border-top: none; }
.tk-pm-row.done .tk-pm-txt b { text-decoration: line-through; color: var(--muted); }
.tk-pm-txt { flex: 1; min-width: 0; overflow-wrap: anywhere; font-size: 14px; }
.tk-pm-edit { flex: none; width: 34px; height: 34px; }

/* Ключи в комплекте: карандаш и крестик рядом, не растягиваются (03.10.2026) */
.ke-k-acts { display: flex; gap: 6px; flex: none; align-items: center; }
.ke-k-acts .btn svg { width: 16px; height: 16px; }
/* Фото-пример позиции и чек расхода в строке подготовки (03.10.2026) */
.prep-photos { margin-top: 4px; }
.prep-photos .onb-thumb img { max-height: 56px; }
/* ИИ-определение типа ключа в окне «Ключ в комплекте» — во всю ширину сетки (03.10.2026). */
.lead-form > #kk-ai { grid-column: 1 / -1; display: grid; gap: 6px; }

/* Подразделы группы вкладок объекта (Сервис, Аренда) — 03.10.2026: вторым
   рядом под группами, сегментами, чтобы не сливаться с верхним рядом. */
.obj-subtabs { flex-wrap: wrap; margin: 0 0 12px; }
.obj-subtabs .seg-btn { flex: 1 0 auto; text-align: center; text-decoration: none; white-space: nowrap; }
/* Активный подраздел объекта — СИНИМ (16.10.2026, просьба заказчика): ряд
   выше («Договоры · Посуточно · Поиск арендатора · Реклама») подсвечивался
   белой плашкой, а ряд ниже («Собственник · Арендаторы») — синей, и
   выбранное в верхнем ряду читалось как невыбранное. */
.obj-subtabs .seg-btn.active { background: var(--brand); color: #fff; font-weight: 700;
  box-shadow: 0 1px 3px rgba(0, 0, 0, .18); }

/* Экран «Фото и видео в объект»: куда грузим — плашкой над кнопкой (03.10.2026) */
.sh-dest { display: flex; align-items: center; gap: 10px; margin: 12px 0 8px; padding: 12px 14px;
  border-radius: 12px; border: 2px solid; font-size: 14px; line-height: 1.3; }
.sh-dest svg { width: 22px; height: 22px; flex: none; }
.sh-dest b { display: block; font-size: 16px; margin-top: 2px; }
.sh-dest.ok { background: rgba(34,160,90,.12); border-color: #22a05a; color: inherit; }
.sh-dest.ok svg { color: #22a05a; }
.sh-dest.no { background: rgba(229,72,77,.12); border-color: #e5484d; }
.sh-dest.no svg, .sh-dest.no a { color: #e5484d; }
.sh-dest.no a { text-decoration: underline; }

/* Область поиска заявки на подбор — рисуется пальцем (04.10.2026). */
.modal.zone-modal { width: min(920px, 96vw); }
.zone-map { height: 58vh; min-height: 300px; border-radius: 12px; overflow: hidden; margin: 8px 0; background: var(--tint, #f4f7fc); }
/* Карта зон в карточке заявки агента — компактнее, чем редактор зон в модалке. */
.zone-map.ag-zmap { height: 260px; min-height: 200px; }
#zd-pen.active { background: var(--accent, #1f6feb); color: #fff; border-color: var(--accent, #1f6feb); }

/* Заявка на подбор (04.10.2026): блоки анкеты, комнаты списком, стоимость «−/+ 1000». */
.rq-block { margin: 14px 0 4px; padding-top: 10px; border-top: 1px solid var(--line, #e3e6ea); }
.rq-block:first-of-type { border-top: 0; padding-top: 0; margin-top: 4px; }
.num-step { display: flex; gap: 4px; align-items: stretch; }
.num-step .fld-input { flex: 1; min-width: 0; text-align: center; }
.num-step .btn { flex: none; min-width: 34px; padding: 0 8px; font-size: 16px; }
.rq-dd { position: relative; }
.rq-dd > summary { list-style: none; cursor: pointer; display: block; }
.rq-dd > summary::-webkit-details-marker { display: none; }
.rq-dd > summary::after { content: '▾'; float: right; opacity: .6; }
.rq-dd[open] > summary::after { content: '▴'; }
.rq-dd-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(110px, 1fr)); gap: 2px 10px;
  padding: 8px 10px; margin-top: 4px; border: 1px solid var(--line, #e3e6ea); border-radius: 10px; background: var(--surface, #fff); }
.rq-dd-list .fld-check { border-bottom: 0; padding: 6px 2px; }

/* Обложка подобранной квартиры (04.10.2026): строку подборки узнают по снимку
   быстрее, чем по адресу. Нажатие открывает снимок на весь экран. */
.pick-thumb {
  flex: none; width: 72px; height: 56px; border-radius: var(--radius-sm); overflow: hidden;
  background: var(--surface-2); display: inline-flex; align-items: center; justify-content: center;
  margin-right: 10px; color: var(--text-muted, #8a94a3);
}
.pick-thumb img { width: 100%; height: 100%; object-fit: cover; display: block; cursor: zoom-in; }
.pick-thumb.empty svg { width: 22px; height: 22px; opacity: .6; }
.pick-head { display: flex; align-items: flex-start; }
.pick-head > .pick-body { flex: 1; min-width: 0; }
.pick-head > .badge { margin-left: 8px; }
/* На телефоне строка подборки — два столбца (04.10.2026, просьба заказчика): слева снимок,
   справа шильдик состояния над текстом. Третьей колонкой шильдик сжимал название и адрес
   до трёх-четырёх букв в строке. */
@media (max-width: 619px) {
  .pick-head { display: grid; grid-template-columns: auto minmax(0, 1fr); column-gap: 0; row-gap: 4px; }
  .pick-head > .pick-thumb { grid-column: 1; grid-row: 1 / span 2; }
  .pick-head > .badge { grid-column: 2; grid-row: 1; justify-self: start; margin-left: 0; }
  .pick-head > .pick-body { grid-column: 2; grid-row: 2; }
  .pick-head:not(:has(> .badge)) > .pick-body { grid-row: 1 / span 2; }
}

/* Карточка заявки на подбор: параметры «вкратце» и «Подробнее» (04.10.2026) */
.req-card { padding: 0; display: block; }
/* Карточки задач, заявок и отчётов — обычная карточка с полями (30.10.2026,
   замечание заказчика: «текст у самого края карточки»). Без отступа остаётся
   только карточка подбора, у неё внутри строка .row со своими полями. */
.req-card:not([data-req-card]) { padding: 12px 14px; }
/* Выполненная задача/заявка — лёгкая зелёная заливка и зелёная кромка слева. */
.req-card.done { background: color-mix(in srgb, var(--ok) 9%, var(--surface)); border-color: color-mix(in srgb, var(--ok) 30%, var(--line)); border-left: 3px solid var(--ok); }
/* Двойная плитка заявки (03.11.2026): большая часть — карточка, малая — кнопка
   переноса в задачу. Подсветка строки (перенесена — жёлтым, выполнена —
   зелёным) ложится на карточку. */
.req-tile { display: flex; align-items: stretch; gap: 8px; }
.req-tile > .req-card { flex: 1 1 auto; min-width: 0; }
.rq-tomove { flex: none; width: 66px; display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 4px;
  border: 1px solid var(--line); border-radius: 12px; background: color-mix(in srgb, var(--brand) 8%, var(--surface));
  color: var(--brand); cursor: pointer; font: inherit; padding: 6px; }
.rq-tomove:hover { background: color-mix(in srgb, var(--brand) 15%, var(--surface)); border-color: var(--brand); }
.rq-tomove-ic { display: inline-flex; }
.rq-tomove-ic svg { width: 26px; height: 26px; }
.rq-tomove-t { font-size: 11px; font-weight: 600; line-height: 1; }
.req-tile.rq-hl-moved > .req-card { background: color-mix(in srgb, #f2c200 9%, var(--surface)); border-color: color-mix(in srgb, #f2c200 38%, var(--line)); border-left: 3px solid #f2c200; }
.req-tile.rq-hl-done > .req-card { background: color-mix(in srgb, var(--ok) 9%, var(--surface)); border-color: color-mix(in srgb, var(--ok) 30%, var(--line)); border-left: 3px solid var(--ok); }
.req-card > .row { width: 100%; background: none; border: 0; text-align: left; }
/* Полная карточка заявки (с анкетой): свой внутренний отступ, иначе шапка с
   кнопками и поля упираются в край карточки. Бриф больше не индентит сам —
   отступ слева даёт карточка. */
.req-card[data-req-card] { padding: 12px 14px; }
.req-brief { padding: 0 0 2px; }
/* Поля ниже карты — двумя наглядными блоками: «Об объекте» и «О клиенте». */
.req-grp { background: var(--surface-2); border: 1px solid var(--line); border-radius: var(--radius); padding: 2px 12px 8px; margin-top: 10px; }
.req-grp .req-brief-h { margin: 8px 0 0; }
/* Данные блока — в два столбца (как в боевом кабинете МА): пары «метка →
   значение» ложатся сеткой по две в ряд. На телефоне тесно — одна колонка. */
.req-grp .kv { display: grid; grid-template-columns: 1fr 1fr; column-gap: 22px; margin-top: 6px; border-top: 0; }
.req-grp .kv-row { padding: 8px 0; }
@media (max-width: 619px) { .req-grp .kv { grid-template-columns: 1fr; } }
/* Бейдж подписки клиента на бота в шапке карточки заявки. */
.rq-badges { margin-top: 6px; }
.rq-bb { display: inline-block; font-size: 11.5px; font-weight: 600; padding: 2px 8px; border-radius: 999px; }
.rq-bb.warn { background: color-mix(in srgb, var(--warn) 16%, var(--surface)); color: var(--warn); }
.rq-bb.ok { background: color-mix(in srgb, var(--ok) 14%, var(--surface)); color: var(--ok); }
/* Действия над заявкой: подборы, правка, поделиться, удаление. */
.rq-acts { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.btn.rq-del { color: var(--danger); }
/* Записи разговоров на карточке. */
.rq-rec { padding: 8px 0; border-bottom: 1px solid var(--line); }
.rq-rec:last-child { border-bottom: 0; }
.req-brief-h { font-size: 12px; font-weight: 600; color: var(--muted, #6b7280); margin: 8px 0 4px; }
.req-chips { display: flex; flex-wrap: wrap; gap: 4px; }
.req-chip { font-size: 12px; line-height: 1.3; padding: 2px 8px; border: 1px solid var(--line, #d0d5dd); border-radius: 6px; background: var(--surface, #fff); }
.req-more { display: none; }
.req-card.open .req-more { display: block; }
.req-card.open .req-short { display: none; }
.req-more .kv-row { font-size: 13px; }
.req-note { white-space: normal; }
.req-more-btn { display: block; margin: 8px 0 0 auto; background: none; border: 0; font-size: 12px; color: var(--muted, #6b7280); cursor: pointer; }
/* Нижняя строка карточки заявки: слева «Подробнее», справа — правка и удаление
   (05.11.2026). Кнопки — свои, поверх строки-кнопки открытия (они её сиблинги). */
.req-foot { display: flex; align-items: center; gap: 8px; margin-top: 8px; flex-wrap: wrap; }
.req-foot .req-more-btn { margin: 0; }
.req-foot-acts { margin-left: auto; display: inline-flex; gap: 6px; }
/* Имя и телефон клиента в шапке окна заявки — ссылкой на карточку контакта. */
.req-contact-lnk { color: var(--brand); text-decoration: none; cursor: pointer; }
.req-contact-lnk:hover { text-decoration: underline; }
/* «Тихая отметка» группы гражданства — ряд значков-флагов (05.11.2026). */
.cit-pick { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.cit-flag { font-size: 19px; line-height: 1.1; padding: 4px 9px; border: 1px solid var(--line);
  border-radius: 10px; background: var(--surface); cursor: pointer; }
.cit-flag.cit-none { font-size: 14px; color: var(--muted); }
.cit-pick .cit-flag.on { border-color: var(--brand); background: color-mix(in srgb, var(--brand) 12%, var(--surface)); }
.fchip.cit-flag { font-size: 17px; }

/* Раздел «Сделки» режима агента (04.10.2026): карточка = заявка клиента, внутри объекты сделки */
.deal-card { margin-bottom: 12px; }
.deal-head { display: flex; gap: 10px; align-items: flex-start; justify-content: space-between; }
.deal-head > div { min-width: 0; }
.deal-head a { color: var(--brand); text-decoration: none; margin-right: 8px; }
.deal-obj { border-top: 1px solid var(--line, #e5e7eb); padding-top: 10px; margin-top: 10px; }
.deal-obj.closed, .deal-obj.hidden-deal { opacity: .62; }
.deal-chain { display: flex; flex-wrap: wrap; align-items: center; gap: 4px; margin: 6px 0 2px; }
.deal-arr { color: var(--muted); font-size: 12px; }
.deal-fn { font-size: 12px; color: var(--muted); margin-right: 2px; }
.deal-plus { width: 22px; height: 22px; border-radius: 50%; border: 0; background: var(--brand); color: #fff; font-weight: 700; line-height: 22px; padding: 0; cursor: pointer; }
.deal-st-pick { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 12px; }
.deal-st-pick .badge { border: 2px solid transparent; cursor: pointer; font-size: 12px; padding: 5px 10px; }
.deal-st-pick .badge.active { border-color: currentColor; }
.check-row { display: flex; gap: 8px; align-items: flex-start; padding: 6px 0; }
.settle-note.warn { border-left: 3px solid var(--warn); }

/* Карточка договора с арендатором — блоки с чипами, как в старой системе (05.10.2026).
   Название раздела и данные стоят в ОДНУ строку, промежутки сжаты: карточка на экран,
   а не на полтора (правка 05.10.2026 — было 1100 px высоты). */
.contract-card .cc-block { display: flex; align-items: baseline; gap: 8px;
  margin: 1px 0; padding: 3px 8px; background: var(--surface-2); border-radius: var(--radius-sm); }
.contract-card .cc-block .cc-h { flex: 0 0 auto; min-width: 78px; margin: 0; font-size: 10.5px; }
.cc-chips { display: flex; flex-wrap: wrap; gap: 3px; flex: 1 1 auto; min-width: 0; }
.cc-chips .cc-chip { background: var(--surface); border: 1px solid var(--line); color: var(--text);
  font-weight: 500; font-size: 11.5px; padding: 2px 8px; white-space: normal; line-height: 1.35; }
.cc-chip-k { color: var(--muted); font-weight: 600; }
.cc-client-line { font-size: 13px; margin: 4px 0 2px; }
.contract-card .cc-obj { margin: 4px 0; }
.contract-card .cc-money { margin-top: 6px; }
/* Остальные части карточки тоже поджаты: адрес в одну строку с многоточием,
   итоги и кнопки ниже ростом — список договоров листают, а не изучают по одной. */
.contract-card .cc-note { font-size: 11.5px; margin: 2px 0; }
.contract-card .cc-obj { padding: 4px 6px; gap: 6px; }
.contract-card .cc-obj span { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.contract-card .cc-money { padding: 6px 8px; }
.contract-card .cc-money > div > span { font-size: 10.5px; }
.contract-card .cc-money > div > b { font-size: 14px; }
.contract-card .cc-toggle { padding: 4px 0; font-size: 12px; }
.contract-card .cc-actions { margin-top: 6px; gap: 6px; }
.contract-card .cc-actions .btn { padding: 7px 10px; font-size: 12.5px; }
/* Узкий экран: подпись раздела уходит на свою строку, иначе чипам остаётся полполосы. */
@media (max-width: 560px) {
  .contract-card .cc-block { display: block; }
  .contract-card .cc-block .cc-h { margin-bottom: 3px; }
}

/* Материалы объекта (05.10.2026, жалоба «шильд обрезается, предложение
   обрывается»): шильдик в названии — целым блоком, без разрыва фона между
   строками; пояснения под названием переносятся, а не режутся многоточием. */
.mat-row .row-title .chip { display: inline-block; white-space: nowrap; line-height: 1.3; margin: 2px 0; vertical-align: 1px; }
.mat-row .row-sub { white-space: normal; overflow: visible; overflow-wrap: anywhere; }

/* Пустой кабинет роли, которой у человека нет (06.10.2026) */
.norole-box { text-align: center; }
.norole-box .section-title { justify-content: center; }
.norole-ic { font-size: 40px; margin: 6px 0; }
.norole-acts { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 10px; }

/* Список, спрятанный атрибутом (06.10.2026: объекты сотрудника в ЛКК) — класс .list с display сильнее [hidden]. */
.list[hidden] { display: none; }

/* Наблюдения осмотра: привязано к задаче — зелёным, «важно» — красным (07.10.2026) */
.insp-descr { margin-top: 4px; white-space: pre-wrap; overflow-wrap: anywhere; }
.insp-card.insp-linked { background: rgba(46, 160, 67, .12); border-color: rgba(46, 160, 67, .55); }
.insp-card.insp-imp { background: rgba(229, 72, 77, .12); border-color: rgba(229, 72, 77, .6); }
.insp-card.insp-linked.insp-imp { background: rgba(46, 160, 67, .12); border-left: 4px solid #e5484d; }

/* Встроенный плеер RuTube / YouTube (10.10.2026) */
.vplay-ov { z-index: 1400; flex-direction: column; padding: 12px; }
.vplay-box { width: min(960px, 100%); }
.vplay-frame { position: relative; width: 100%; aspect-ratio: 16 / 9; background: #000; border-radius: 10px; overflow: hidden; }
.vplay-frame iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.vplay-tabs { display: flex; flex-wrap: wrap; gap: 8px; justify-content: center; margin-top: 10px; }
.vplay-ext { background: rgba(255,255,255,.12); color: #fff; }
.vplay-tabs .chip { cursor: pointer; }
.rep-chip { cursor: pointer; white-space: nowrap; }
.rep-chip:hover { text-decoration: underline; }

/* «ЭЛИДОМ Чат» — пересылка из других приложений (11.10.2026) */
.share-pend { border-left: 3px solid var(--accent, #1f6feb); margin-bottom: 10px; }
.share-pend .row-sub { white-space: normal; overflow-wrap: anywhere; }

/* Групповое назначение подписи и комнаты в окне фото (11.10.2026): долгое нажатие —
   оранжевая отметка, чтобы не путать с синей галочкой «оставить». */
.pr-item.pr-grp-on .pr-cell { border-color: #f08c00; box-shadow: 0 0 0 3px color-mix(in srgb, #f08c00 45%, transparent); }
.pr-item.pr-grp-on::before { content: '●'; position: absolute; left: 6px; top: 6px; z-index: 3; width: 22px; height: 22px;
  border-radius: 50%; background: #f08c00; color: #fff; font-size: 12px; line-height: 22px; text-align: center; pointer-events: none; }
.pr-cell { -webkit-touch-callout: none; }
.pr-grp { position: sticky; bottom: 0; z-index: 5; display: flex; flex-direction: column; gap: 8px; margin: 0 0 12px;
  padding: 10px 12px; border: 2px solid #f08c00; border-radius: 12px; background: var(--surface, #fff); }
.pr-grp[hidden] { display: none; }
.pr-grp-head { font-size: 13px; }
.pr-grp-head b { color: #f08c00; }
.pr-grp-row { display: flex; gap: 8px; flex-wrap: wrap; }
.pr-grp-row .pr-cap { flex: 1 1 160px; min-width: 0; }

/* ── Загрузки поверх окон (11.10.2026, ui.js → ElidomUploads) ── */
.upl-widget { position: fixed; right: 14px; bottom: calc(var(--tab-h, 62px) + 14px + var(--safe-bottom, 0px)); z-index: 1250;
  width: 52px; height: 52px; border-radius: 50%; border: 0; padding: 0; cursor: pointer;
  background: conic-gradient(var(--brand, #1f6feb) var(--upl, 0%), rgba(127,127,127,.25) 0);
  box-shadow: 0 4px 14px rgba(0,0,0,.25); display: flex; align-items: center; justify-content: center; }
.upl-widget[hidden] { display: none; }
.upl-widget::before { content: ''; position: absolute; inset: 4px; border-radius: 50%; background: var(--surface, #fff); }
.upl-widget .upl-pct { position: relative; font-size: 13px; font-weight: 700; color: var(--text, #222); }
.upl-widget .upl-n { position: absolute; top: -4px; right: -4px; min-width: 18px; height: 18px; padding: 0 4px; border-radius: 9px;
  background: var(--brand, #1f6feb); color: #fff; font-size: 11px; line-height: 18px; font-weight: 700; }
.upl-widget.ok { background: #2fa36b; }
.upl-widget.ok .upl-pct { color: #2fa36b; }
.upl-widget.bad { background: #d9432f; }
.upl-widget.bad .upl-pct { color: #d9432f; }
/* Кнопка в шапке рядом с «телефон / ПК» (id=1181): кольцо — общий процент. */
.upl-bar-btn { flex: none; position: relative; }
.upl-bar-ring { position: relative; width: 32px; height: 32px; border-radius: 50%; display: grid; place-items: center; color: var(--brand, #1f6feb);
  background: conic-gradient(var(--brand, #1f6feb) var(--upl, 0%), rgba(127,127,127,.25) 0); }
.upl-bar-ring::before { content: ''; position: absolute; inset: 3px; border-radius: 50%; background: var(--surface, #fff); }
.upl-bar-ring > * { position: relative; }
.upl-bar-ring svg { width: 16px; height: 16px; }
.upl-bar-n { position: absolute; top: 0; right: 0; min-width: 16px; height: 16px; padding: 0 3px; border-radius: 8px;
  background: var(--brand, #1f6feb); color: #fff; font-size: 10px; line-height: 16px; font-weight: 700; }
.upl-bar-btn.ok .upl-bar-ring { background: #2fa36b; color: #2fa36b; }
.upl-bar-btn.bad .upl-bar-ring { background: #d9432f; color: #d9432f; }
/* Ничего не идёт (id=1184): обычный значок шапки, как «телефон / ПК», без кольца. */
.upl-bar-btn.idle .upl-bar-ring { background: none; color: var(--text); }
.upl-bar-btn.idle .upl-bar-ring::before { display: none; }
.upl-bar-btn.idle .upl-bar-ring svg { width: 22px; height: 22px; }
.upl-overlay { z-index: 1260; }
.upl-list { display: flex; flex-direction: column; gap: 10px; margin: 10px 0; }
.upl-row { padding: 8px 10px; border-radius: 10px; background: rgba(127,127,127,.08); }
.upl-top { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; }
.upl-name { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; font-size: 14px; }
.upl-st { flex: none; font-size: 13px; font-weight: 600; }
.upl-st.ok { color: #2fa36b; } .upl-st.bad { color: #d9432f; }
.upl-sub { font-size: 12px; opacity: .75; margin: 2px 0 6px; }
.upl-bar { height: 6px; border-radius: 3px; background: rgba(127,127,127,.22); overflow: hidden; }
.upl-bar i { display: block; height: 100%; background: var(--brand, #1f6feb); transition: width .3s; }
.upl-row.done .upl-bar i { background: #2fa36b; }
.upl-row.fail .upl-bar i { background: #d9432f; }
.upl-row.cancel { opacity: .7; }
.upl-row.cancel .upl-bar i { background: rgba(127,127,127,.5); }
.upl-act { display: flex; flex-wrap: wrap; justify-content: flex-end; gap: 6px; margin-top: 6px; }
.upl-act .btn.danger { color: #d9432f; border-color: #d9432f; }

/* Матрица «Сотрудники и отделы» на странице (11.10.2026): семь столбцов отделов
   не помещаются в телефон, а с `overflow: visible` (как у матрицы прав в окне)
   она растягивала ВСЮ страницу — браузер уменьшал масштаб, и окно «Права
   сотрудника» открывалось сдвинутым и обрезанным справа. Прокрутка вбок — своя. */
.sdm-wrap { overflow-x: auto; max-width: 100%; }
.staff-dept-tbl th:not(.first) { width: auto; min-width: 64px; font-size: 11.5px; white-space: normal; line-height: 1.2; }
.staff-dept-tbl td.first { white-space: normal; min-width: 120px; }
/* Окно прав: содержимое не шире окна, вбок прокручивается только матрица. */
.modal .perm-wrap { max-width: 100%; }
.modal .se-depts { grid-template-columns: repeat(auto-fill, minmax(150px, 1fr)); }

/* Материалы объекта: сворачиваемые разделы (11.10.2026) */
.mat-sec-head { width: 100%; background: none; border: 0; padding: 0; margin: 0; font: inherit; color: inherit; text-align: left; cursor: pointer; gap: 8px; align-items: center; }
.mat-sec-head .card-title { flex: 1; }
.mat-sec-arrow { display: inline-block; transition: transform .15s; color: var(--muted, #888); }
.mat-section.open .mat-sec-arrow { transform: rotate(90deg); }
.mat-sec-body { margin-top: 6px; }
.mat-sec-body[hidden] { display: none; }
.mat-fold-all { display: flex; gap: 8px; justify-content: flex-end; margin: 4px 0 8px; }
.mat-share-bar { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin: 6px 0 8px; }

/* Контакты объекта (11.10.2026): подзаголовок типа в списке. */
.oct-group { font-size: 12px; font-weight: 600; text-transform: uppercase; letter-spacing: .04em;
  color: var(--muted, #6b7280); padding: 10px 12px 4px; }
.oct-row .row-main.link { cursor: pointer; }
/* Меню «⋮» карточки материала — правый верхний угол (11.10.2026) */
.mat-row { position: relative; padding-right: 40px; }
.mat-row .mat-menu { position: absolute; top: 6px; right: 6px; }

/* Канал: сколько дней висит объявление и «Повторить» (12.10.2026) */
.chan-badges { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; justify-content: flex-end; }
.chip.chan-age { background: #e3f1e6; color: #1f7a3a; font-weight: 700; }
.chip.chan-age.warn { background: #fdf0d5; color: #9a6400; }
.chip.chan-age.bad { background: #fde3e1; color: #c0362c; }
.chip.chan-age.reset { background: #eceff3; color: var(--muted); }
.am-age { margin: 3px 0 1px; }
.am-age .chip { font-size: 10.5px; padding: 1px 7px; }
.am-cell a.am-open { display: block; text-decoration: none; }
.am-repub { display: inline-flex; align-items: center; gap: 4px; margin-top: 4px; padding: 2px 8px;
  border: 1px solid var(--line, #d7dde5); border-radius: 999px; background: #fff; color: var(--brand);
  font-size: 10.5px; font-weight: 700; cursor: pointer; }
.am-repub svg { width: 12px; height: 12px; }

/* Текст поста канала под фотографиями: правка окном с панелью оформления. */
.cp-text-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 2px 0 6px; }
.cp-text-bar .btn[hidden] { display: none; }
.tg-post.pt-edit { max-height: 56dvh; min-height: 160px; outline: none; margin-top: 14px; cursor: text; }
.tg-post.pt-edit:focus { border-color: var(--brand); box-shadow: 0 0 0 2px color-mix(in srgb, var(--brand) 25%, transparent); }
.tg-post.pt-edit a { color: var(--brand); }
.tg-post blockquote { margin: 4px 0; padding-left: 10px; border-left: 3px solid var(--brand); }
/* Выбор площадки видео: RuTube / YouTube (12.10.2026); нет ролика — серая кнопка. */
.vbtn.off { opacity: .45; cursor: default; pointer-events: none; }

/* Поиск по списку таблиц (12.10.2026). `.row` — flex, и атрибут `hidden` без
   явного правила он перебил бы (та же грабля, что с палитрой смайлов). */
.tbl-list-q { margin: 4px 0 8px; }
.tbl-list-q .fld-input { width: 100%; }
/* Строка над списком таблиц: поиск тянется, переключатель вида прижат справа. */
.tbl-list-top { display: flex; align-items: center; gap: 8px; margin: 4px 0 8px; }
.tbl-list-top .tbl-list-q { flex: 1; margin: 0; }
.tbl-list-top .view-switch { flex: none; }
.tl-group[hidden], .list.menu .row[hidden], .tl-tile[hidden], #tl-none[hidden] { display: none !important; }
/* Плитка списка таблиц: мелкие квадратные плитки с иконкой и названием (в две
   строки), по разделам; 6–8 столбцов на широком экране. */
.tl-tiles { display: grid; grid-template-columns: repeat(3, 1fr); gap: 6px; margin-top: 2px; }
.tl-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 3px;
  text-align: center; min-height: 46px; padding: 6px 5px;
  border: 1px solid var(--line); border-radius: 10px;
  background: var(--surface); color: var(--text); text-decoration: none;
}
.tl-tile .tl-tile-ic { font-size: 16px; line-height: 1; color: var(--brand); }
.tl-tile .tl-tile-name {
  font-size: 11px; font-weight: 600; line-height: 1.15;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
}
.tl-tile.sel { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand) inset; }
@media (min-width: 500px) { .tl-tiles { grid-template-columns: repeat(4, 1fr); } }
@media (min-width: 620px) { .tl-tiles { grid-template-columns: repeat(6, 1fr); } }
@media (min-width: 900px) { body.desk .tl-tiles { grid-template-columns: repeat(8, 1fr); } }
/* Разделы в режиме плитки подсвечиваем через один — белый панель / серый панель,
   иначе белые плитки на светлом фоне сливаются между соседними разделами. */
#tl-body .tl-group:has(.tl-tiles) { padding: 6px 10px 10px; border-radius: 12px; margin-bottom: 6px; }
#tl-body .tl-group:has(.tl-tiles):nth-of-type(odd) { background: var(--surface); }
#tl-body .tl-group:has(.tl-tiles):nth-of-type(even) { background: color-mix(in srgb, var(--muted) 9%, var(--surface)); }

/* Характеристики материала под большим фото (12.10.2026): поля колонкой,
   прокручиваются сами; снимок поднят выше. */
.lb-overlay:has(.lb-mat) { align-items: flex-start; padding-top: 48px; }
.lb-overlay:has(.lb-mat) .lb-img { max-height: 38vh; }
.lb-foot:has(.lb-mat) { max-height: 52vh; overflow-y: auto; bottom: 10px; }
.lb-mat { gap: 6px; }
.lb-mat .lb-mat-f { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.lb-mat .lb-mat-f small { color: rgba(255,255,255,.7); font-size: 12px; }
.lb-mat .lb-mat-f .lb-edit-cap, .lb-mat .lb-mat-f .lb-edit-room { max-width: none; width: 100%; min-width: 0; box-sizing: border-box; }
.lb-mat .lb-mat-row { display: flex; gap: 6px; }
.lb-mat [hidden] { display: none; }
/* Размеры позиции склада — три поля в ряд (12.10.2026). */
/* Подсказка правила в карточке платежа: текст слева, кнопка модуля справа. */
.cd-rules-row { align-items: flex-start; flex-wrap: wrap; }
.cd-rules-row .cd-rules-txt { flex: 1; min-width: 160px; }
.cd-rules-acts { display: flex; flex-direction: column; align-items: stretch; gap: 6px; flex: none; margin-left: auto; }
.cd-rules-acts .btn { white-space: nowrap; }
/* Ряд коротких полей в одну строку (суммы в правиле разнесения). */
.fld-row { display: flex; gap: 6px; }
/* Перевод между своими счетами: «откуда → куда» одной строкой (16.10.2026). */
/* Окно правил разнесения (16.10.2026): строка — одна на правило, коротко;
   плиткой — то же в две колонки. Нажатие открывает само правило окном. */
.br-top { display: flex; gap: 6px; align-items: center; margin: 4px 0 6px; }
.br-top .fld-input { flex: 1; min-width: 0; }
.br-list { display: flex; flex-direction: column; gap: 6px; }
.br-list.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 8px; }
.br-item { display: flex; flex-direction: column; gap: 3px; width: 100%; text-align: left;
  padding: 9px 11px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface);
  color: var(--text); font: inherit; cursor: pointer; position: relative; }
.br-item:active { transform: scale(.995); }
.br-item.fits { border-color: var(--ok); }
.br-name { font-weight: 700; font-size: 13px; }
.br-sub { font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; }
.br-list:not(.tiles) .br-sub { -webkit-line-clamp: 1; }
.br-apply { align-self: flex-start; margin-top: 4px; padding: 4px 10px; border-radius: 999px;
  font-size: 12px; font-weight: 700; background: var(--brand); color: #fff; }
.xfer-box { flex: 1; min-width: 0; }
.xfer-box .fld-hint { display: block; margin-top: 4px; }
.xfer-row { display: flex; align-items: center; gap: 6px; }
.xfer-row .fld-input { flex: 1; min-width: 0; }
.xfer-arrow { flex: none; font-weight: 700; color: var(--muted); }
.fld-row .field { flex: 1; min-width: 0; }
.fld-row .fld-input { width: 100%; min-width: 0; box-sizing: border-box; }
.size3 { display: flex; gap: 6px; }
.size3 label { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.size3 small { color: var(--muted, #888); font-size: 12px; }
.size3 .fld-input { width: 100%; min-width: 0; box-sizing: border-box; }

/* Упоминания объектов в карточке звонка (14.10.2026): строка раскрывается на месте. */
.cm-row { border: 1px solid var(--line, #e3e7ee); border-radius: 10px; margin: 6px 0; background: var(--card, #fff); }
.cm-row > summary { cursor: pointer; padding: 8px 10px; list-style: none; display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.cm-row > summary::-webkit-details-marker { display: none; }
.cm-row > summary::before { content: '▸'; color: var(--muted, #8a94a6); margin-right: 2px; }
.cm-row[open] > summary::before { content: '▾'; }
.cm-body { padding: 0 10px 10px; }
.cm-quote { font-style: italic; padding: 6px 8px; border-left: 3px solid var(--accent, #2f6fed); background: rgba(47,111,237,.06); margin: 4px 0 6px; white-space: pre-wrap; }
/* Упоминания по объектам (14.10.2026): блок раскрывается, внутри подкарточка на объект. */
.cm-block > summary { cursor: pointer; list-style: none; }
.cm-block > summary::-webkit-details-marker { display: none; }
.cm-block > summary::before { content: '▸ '; color: var(--muted, #8a94a6); }
.cm-block[open] > summary::before { content: '▾ '; }
.cm-obj { border: 1px solid var(--line, #e3e7ee); border-left: 3px solid var(--accent, #2f6fed); border-radius: 10px; margin: 8px 0; background: var(--card, #fff); }
.cm-obj > summary { cursor: pointer; padding: 9px 10px; list-style: none; display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.cm-obj > summary::-webkit-details-marker { display: none; }
.cm-obj > summary::before { content: '▸'; color: var(--muted, #8a94a6); margin-right: 2px; }
.cm-obj[open] > summary::before { content: '▾'; }
.cm-obj .cm-row { background: var(--bg, #f6f8fb); }
.cm-all { padding: 6px 8px; margin: 4px 0 6px; border-radius: 8px; background: rgba(47,111,237,.05); }

/* Настройка списка таблиц (шестерёнка на экране «Таблицы», 15.10.2026):
   разделы и плитки строками со стрелками — порядок правят ими, а не
   перетаскиванием: на телефоне стрелки надёжнее. */
.tls-group { border: 1px solid var(--line); border-radius: 12px; padding: 8px; margin-bottom: 10px; }
.tls-head { display: flex; gap: 6px; align-items: center; margin-bottom: 6px; }
.tls-head .tls-gname { font-weight: 600; }
.tls-row { display: flex; gap: 6px; align-items: center; padding: 4px 0; }
.tls-row + .tls-row { border-top: 1px dashed var(--line); }
.tls-row .tls-ic { flex: none; opacity: .7; display: inline-flex; }
.tls-row .tls-name { flex: 1 1 auto; min-width: 90px; }
.tls-row .tls-grp { flex: 0 1 150px; }
/* Спрятанная плитка видна приглушённой: её не выбросили, а убрали из списка. */
.tls-row.off .tls-name, .tls-row.off .tls-grp, .tls-row.off .tls-ic { opacity: .45; }

.th-hint { cursor: help; border-bottom: 1px dotted currentColor; }

/* Подпись снимка — окном-списком со своим вариантом (18.10.2026). Окно встаёт
   и поверх лайтбокса (z-index 1000), откуда подпись тоже задают. */
.modal-overlay.cap-pick { z-index: 1100; }
.cap-own { display: flex; gap: 8px; margin: 4px 0 12px; }
.cap-own .fld-input { flex: 1 1 auto; min-width: 0; }
.cap-list { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.cap-opt { padding: 12px 10px; border: 1px solid var(--line); border-radius: 10px; background: var(--card, #fff);
  color: inherit; font: inherit; text-align: left; cursor: pointer; }
.cap-opt.on { border-color: var(--accent, #2f6fed); background: rgba(47, 111, 237, .08); font-weight: 600; }
.cap-opt small { display: block; color: var(--muted); font-size: 11px; font-weight: 400; }
.cap-opt[hidden] { display: none; }
.cap-pickable { cursor: pointer; caret-color: transparent; }

/* Архив квитанций (03.11.2026): плашка архивной квитанции в карточке объекта
   бледная, галочка «Показать архивные» и ряд кнопок карточки. */
.obj-chip.arch { opacity: .6; border-style: dashed; }
.obj-chip.arch .obj-chip-bal { color: var(--muted); }
/* Штамп электронной подписи в предпросмотре договора (03.11.2026): синим,
   как печать. На печати тот же штамп повторяется на каждой странице — его
   стили уезжают в окно печати вместе с документом (SIGN_STAMP_CSS). */
.doc-preview .sign-stamp {
  margin-top: 18px; border: 1.5px solid #1b4ed8; border-radius: 6px; padding: 7px 10px;
  color: #1b4ed8; font: 11px/1.45 Arial, sans-serif; letter-spacing: .2px;
  background: rgba(27, 78, 216, .05);
}
.doc-preview .sign-stamp b { display: block; font-size: 11.5px; letter-spacing: .6px; }
.doc-preview .sign-stamp span { display: block; }
.doc-preview .sign-stamp.outside { border-style: dashed; }

/* Облачко внутреннего комментария на плашке квитанции (03.11.2026):
   есть комментарий — жирное красное, нет — тонкая зелёная обводка. */
.obj-chip-wrap { position: relative; flex: 1 1 104px; min-width: 104px; display: flex; }
.obj-chip-wrap .obj-chip { flex: 1 1 auto; width: 100%; min-width: 0; padding-right: 36px; }
.rec-note-btn {
  position: absolute; top: 6px; right: 6px; width: 26px; height: 26px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  background: var(--surface); border: 1px solid color-mix(in srgb, var(--ok) 55%, transparent);
  color: var(--ok); border-radius: 8px;
}
.rec-note-btn .ic { width: 15px; height: 15px; }
.rec-note-btn.has { border: 2px solid var(--danger); color: var(--danger);
  background: color-mix(in srgb, var(--danger) 10%, var(--surface)); }
.rec-note-btn.has .ic { stroke-width: 2.6; }
.rec-note-box { border-left: 3px solid var(--danger); }
.rec-note-box .ic { width: 15px; height: 15px; vertical-align: -2px; }

/* Строка действий квитанции: обе кнопки одного размера и мелкие, галочка
   «Показать архивные» справа от них в ту же строку (03.11.2026). */
.rec-acts { gap: 8px; margin-top: 10px; flex-wrap: wrap; align-items: center; }
.btn.xs { padding: 5px 9px; font-size: 12px; border-radius: 9px; line-height: 1.2; }
.rec-acts .rec-act { flex: 0 0 auto; min-width: 104px; text-align: center; justify-content: center; }
.rec-arch-sw { border-bottom: 0; padding: 0; margin-left: auto; font-size: 12.5px; gap: 6px; }

/* ── Плотность таблиц «Мобильно» (18.10.2026, просьба заказчика) ─────────────
   Для работы с таблицей с телефона и планшета в горизонтали: шрифт и отступы
   вдвое меньше обычных, колонки ужаты (длинное обрезается многоточием, ширина,
   заданная ползунком, по-прежнему главнее — у неё !important), служебные иконки
   мельче. Панель над таблицей, счётчик и переходы по страницам ужимаются вместе
   с ней (класс `rhp-mob` у страницы). Правила с `body` — чтобы перебить настольные
   `body.desk .tbl …`. */
body .tbl.rh-mob { font-size: 9.5px; --rowpad: 1px; --iconbtn: 15px; --iconsvg: 10px; --pickw: 16px; --pickbox: 11px; }
body .tbl.rh-mob th, body .tbl.rh-mob td { padding: var(--rowpad) 4px; line-height: 1.25; }
body .tbl.rh-mob td { max-width: 15em; overflow: hidden; text-overflow: ellipsis; }
body .tbl.rh-mob th { font-size: 9px; }
body .tbl.rh-mob th[data-sort] { padding-right: 10px; }
body .tbl.rh-mob th.first, body .tbl.rh-mob td.first { max-width: 130px; }
body .tbl.rh-mob th.pick, body .tbl.rh-mob td.pick { padding-left: 2px; padding-right: 1px; }
body .tbl.rh-mob .doc-btn { border-radius: 4px; }
body .tbl.rh-mob .row-tools { gap: 1px; }
body .tbl.rh-mob .tbl-totals th { padding-top: 2px; padding-bottom: 2px; }
body .tbl.rh-mob .tbl-totals small { font-size: 8px; }
body .tbl.rh-mob .tbl-totals b { font-size: 9.5px; }
body .tbl.rh-mob .chip { font-size: 8.5px; padding: 0 5px; min-height: 0; line-height: 1.5; }
body .tbl.rh-mob .ic { width: 10px; height: 10px; }
body .tbl.rh-mob input[type="checkbox"] { width: var(--pickbox); height: var(--pickbox); }
body .tbl.rh-mob .th-expand { width: 12px; height: 12px; }
.tbl-page.rhp-mob { gap: 4px; }
.tbl-page.rhp-mob .tbl-bar { gap: 4px; }
.tbl-page.rhp-mob .tbl-q,
.tbl-page.rhp-mob .tbl-objq,
.tbl-page.rhp-mob .mpick-btn { padding: 4px 8px; font-size: 11px; min-height: 0; height: 26px; }
.tbl-page.rhp-mob .tbl-btns { gap: 3px; }
.tbl-page.rhp-mob .tbl-btn { padding: 3px 7px; font-size: 10.5px; gap: 3px; }
.tbl-page.rhp-mob .tbl-btn .ic { width: 11px; height: 11px; }
.tbl-page.rhp-mob .tbl-count-row { gap: 6px; font-size: 10.5px; }
.tbl-page.rhp-mob #tbl-count { font-size: 10.5px; }
.tbl-page.rhp-mob .per-page { font-size: 10px; gap: 3px; }
.tbl-page.rhp-mob .per-page .fld-input { padding: 1px 3px; font-size: 10px; }
.tbl-page.rhp-mob .filter-chips .fchip { padding: 2px 7px; font-size: 10px; }
.tbl-page.rhp-mob .pager { gap: 3px; padding: 3px 0; }
.tbl-page.rhp-mob .pager .pg { min-width: 22px; height: 22px; padding: 0 5px; font-size: 10.5px; border-radius: 6px; }
.tbl-page.rhp-mob .pick-bar { padding: 4px 6px; gap: 4px; }
.tbl-page.rhp-mob .pick-bar .btn.sm { padding: 3px 7px; font-size: 10.5px; }
.tbl-page.rhp-mob .pick-count, .tbl-page.rhp-mob .pick-sum { font-size: 10.5px; }
body .tbl.rh-mob td.cell-long { max-width: 30ch; }
body .tbl.rh-mob td.cell-long.open { max-width: 60ch; overflow: visible; }
.tbl-page.rhp-mob .tbl-tgl-btn { width: 22px; height: 22px; border-radius: 6px; }
.tbl-page.rhp-mob .tbl-tgl-btn svg { width: 12px; height: 12px; }

/* Окончание договоров на главной ЛКУ (19.10.2026): просроченные — красным. */
.pay-reports.ending-over { border-left-color: var(--danger); }
.row.row-overdue { background: color-mix(in srgb, var(--danger) 8%, transparent); }
.row.row-overdue .row-title { color: var(--danger); }

/* Офлайн-режим (20.10.2026): строка состояния связи и экран настройки. */
.offline-bar { position: fixed; left: 50%; transform: translateX(-50%); top: calc(env(safe-area-inset-top, 0px) + 58px);
  z-index: 950; max-width: min(96vw, 640px); padding: 6px 12px; border-radius: 10px; font-size: 13px; line-height: 1.3;
  background: #3b4352; color: #fff; box-shadow: 0 4px 14px rgba(0,0,0,.18); cursor: pointer; text-align: center; }
.offline-bar.off { background: #b4472f; }
.offline-bar.queue { background: #b07a12; }
.offline-bar[hidden] { display: none; }
/* Значок офлайн-режима в шапке и быстрая панель (20.10.2026) */
.off-btn[hidden] { display: none; }
.off-btn.on { color: #2f9e5a; }
.off-btn.off { color: #b4472f; }
.off-btn.warn { color: #b07a12; }
.off-btn.busy { color: var(--accent, #2f6fde); animation: offPulse 1.2s ease-in-out infinite; }
@keyframes offPulse { 50% { opacity: .4; } }
.off-pop .modal { max-width: 460px; }
.off-switch { display: flex; gap: 10px; align-items: center; margin: 12px 0; cursor: pointer; }
.off-switch input { position: absolute; opacity: 0; pointer-events: none; }
.off-switch i { flex: none; width: 44px; height: 26px; border-radius: 13px; background: #c5cad3; position: relative; transition: background .15s; }
.off-switch i::after { content: ''; position: absolute; top: 3px; left: 3px; width: 20px; height: 20px; border-radius: 50%; background: #fff; transition: left .15s; }
.off-switch input:checked + i { background: #2f9e5a; }
.off-switch input:checked + i::after { left: 21px; }
.off-node { display: flex; gap: 10px; align-items: flex-start; padding: 10px 0; border-bottom: 1px solid var(--line, #e5e8ee); }
.off-node:last-child { border-bottom: 0; }
.off-node input { margin-top: 3px; }
.off-node .off-main { flex: 1; min-width: 0; }
.off-node .off-size { white-space: nowrap; font-size: 13px; color: var(--muted, #6b7380); text-align: right; }
.off-node.dis { opacity: .55; }
/* Экран «Офлайн-режим»: пояснения и строки объёма переносятся, а не обрываются многоточием */
.off-page .row-sub { white-space: normal; overflow: visible; text-overflow: clip; overflow-wrap: anywhere; line-height: 1.35; }
.off-meter { height: 8px; border-radius: 4px; background: var(--line, #e5e8ee); overflow: hidden; margin: 6px 0; }
.off-meter > i { display: block; height: 100%; background: var(--accent, #2f6fde); }

/* Снимок наблюдения, сделанный без связи: ждёт на телефоне (20.10.2026) */
.pend-pic { position: relative; display: inline-flex; flex-direction: column; align-items: flex-start; gap: 3px; }
.pend-pic img { width: 72px; height: 72px; object-fit: cover; border-radius: 8px; border: 2px dashed var(--warn); opacity: .85; }
.pend-pic .badge { font-size: 10px; }
/* Файл, снятый без связи (заглушка offline:<pid>): ждёт отправки — пунктир и метка */
.off-pend { outline: 2px dashed var(--warn); outline-offset: -2px; opacity: .9; }

/* Подзадачи задачи (20.10.2026): по каждой свой отчёт */
.sub-task { border-left: 3px solid var(--warn, #e0a100); }
.sub-task.done { border-left-color: var(--ok, #2e9e5b); }
.sub-task.new { border-left-color: var(--line, #c9ced6); }
/* Вернулись к подзадаче после перерисовки карточки (03.11.2026, см. restoreSub
   в js/views/tasks.js): рамка только для клавиатуры, короткая подсветка — чтобы
   глаз сразу нашёл место, с которым работали. */
.sub-task:focus, #tk-subs:focus { outline: none; }
.sub-task:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.sub-flash { animation: subFlash 1.4s ease-out; }
@keyframes subFlash { 0%, 25% { background: rgba(31, 111, 235, .12); } 100% { background: var(--surface); } }
.sub-st { display: flex; flex-wrap: wrap; gap: 6px; margin: 6px 0 0; }

/* Несколько фото в материале (20.10.2026): счётчик на миниатюре */
.onb-thumb .mat-pics-n { position: absolute; left: 4px; top: 50px; background: rgba(0,0,0,.65); color: #fff; font-size: 11px; line-height: 1; padding: 3px 5px; border-radius: 6px; pointer-events: none; }
.lb-overlay { overflow: hidden; }
.lb-overlay img.lb-img { user-select: none; -webkit-user-select: none; }

/* Оригиналы рекламных фото (20.10.2026) — подраздел в «Рекламных материалах» */
.mat-orig { border: 1px solid var(--line, #e3e7ee); border-radius: 12px; padding: 6px 10px; margin: 8px 0; }
.mat-orig-body { margin-top: 6px; }
.mat-orig-body[hidden] { display: none; }
.mat-orig-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(104px, 1fr)); gap: 8px; margin-top: 8px; }
.mat-orig-cell { display: flex; flex-direction: column; gap: 4px; }
.mat-orig-cell img { width: 100%; aspect-ratio: 1; object-fit: cover; border-radius: 8px; background: #eef1f5; cursor: pointer; }
.mat-orig-cell .btn { font-size: 12px; padding: 4px 6px; }

/* Кнопка «Позвонить» рядом с «Карточкой контакта» (21.10.2026). */
.btn.person-call { padding: 7px 9px; margin-right: 6px; flex: none; color: var(--accent, #2f6bd8); }
.btn.person-call svg { width: 18px; height: 18px; }
/* Вид договора в карточке раздела «Договоры» (23.10.2026) */
.cc-kind { margin: 4px 0 6px; font-size: 12.5px; line-height: 1.35; }
.cc-kind b { display: block; font-size: 12.5px; letter-spacing: .02em; }
.cc-kind span { display: block; color: var(--muted); font-size: 12px; }

/* «Модули кабинета» плиткой (27.10.2026): название, цена и переключатель в
   карточке; разделы подсвечены через один, как у списка таблиц плиткой. */
.mod-top { justify-content: space-between; }
.mod-tiles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 8px; margin-top: 2px; }
.mod-tile {
  display: flex; flex-direction: column; gap: 4px; min-width: 0; position: relative;
  padding: 8px 10px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface);
}
/* Размеры по объекту: строки часть/ширина/длина/высота/площадь + шильдики частей. */
.oe-sizes-block { display: block; }
.size-row { border: 1px solid var(--line); border-radius: var(--radius-sm); padding: 10px; margin: 8px 0; background: var(--surface); }
.size-part { margin-bottom: 8px; }
.size-chips { display: flex; flex-wrap: wrap; gap: 5px; margin-top: 6px; }
.size-chip { font-size: 11.5px; padding: 3px 9px; border: 1px solid var(--line); border-radius: 999px;
  background: var(--surface); color: var(--muted); cursor: pointer; }
.size-chip:hover { border-color: var(--brand); color: var(--brand); }
.size-dims { display: grid; grid-template-columns: repeat(4, 1fr); gap: 6px; }
@media (max-width: 420px) { .size-dims { grid-template-columns: repeat(2, 1fr); } }
.size-dims .sz-area input { font-weight: 700; background: color-mix(in srgb, var(--brand) 6%, var(--surface)); }
.size-del { margin-top: 8px; }
/* Знак «?» в правом нижнем углу плитки — открывает окно с описанием модуля. */
.mod-help { position: absolute; right: 6px; bottom: 6px; width: 20px; height: 20px; border-radius: 50%;
  border: 1px solid var(--line); background: var(--surface); color: var(--muted);
  font-size: 12px; font-weight: 700; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center; padding: 0; }
.mod-help:hover { color: var(--brand); border-color: var(--brand); }
.mod-tile.on { border-color: color-mix(in srgb, var(--ok) 45%, var(--line)); }
.mod-tile-top { display: flex; align-items: center; justify-content: space-between; gap: 6px; }
.mod-tile-ic { color: var(--brand); display: inline-flex; }
.mod-tile-name { font-size: 13px; font-weight: 600; line-height: 1.2;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.mod-tile-sub { font-size: 11px; color: var(--muted); line-height: 1.2; }
.mod-tile .btn.sm { align-self: flex-start; }
.mod-tile.mod-off .mod-tile-name { color: var(--muted); }
.mod-tile.mod-off .mod-tile-ic { opacity: .45; }
@media (min-width: 620px) { .mod-tiles { grid-template-columns: repeat(3, 1fr); } }
@media (min-width: 900px) { body.desk .mod-tiles { grid-template-columns: repeat(5, 1fr); } }
.mod-group:has(.mod-tiles) { padding: 6px 10px 10px; border-radius: 12px; margin-bottom: 6px; }
.mod-group:has(.mod-tiles):nth-of-type(even) { background: color-mix(in srgb, var(--muted) 9%, var(--surface)); }
/* Неизвестный этаж в шапке объекта — кнопка «указать» (29.10.2026). */
.pill.pill-empty { color: var(--muted); border-style: dashed; cursor: pointer; font-family: inherit; }
/* Кнопки под договором собственника переносятся (30.10.2026, скрин заказчика):
   три кнопки в строку были шире телефона и растягивали всю страницу объекта —
   вместе с ней вылезало за экран и окно «Поделиться». */
.cc-actions { flex-wrap: wrap; }

/* ЛКС · вкладка «Приёмка» (30.10.2026): пункт чек-листа сворачивается. */
.acc-own > summary { cursor: pointer; list-style: none; display: flex; gap: 8px; align-items: center; justify-content: space-between; }
.acc-own > summary::-webkit-details-marker { display: none; }
.acc-own[open] > summary { margin-bottom: 8px; }

/* Файлы ленты событий ЛКС (30.10.2026): снимок сверху, ниже — описание задачи
   или отчёта, которому файл принадлежит; листают свайпом по всем задачам ленты. */
.lb-overlay.lb-has-desc { flex-direction: column; justify-content: flex-start; padding: calc(12px + var(--safe-top)) 0 calc(12px + var(--safe-bottom)); }
.lb-has-desc .lb-img { max-height: 56vh; margin-top: 28px; flex: none; }
.lb-has-desc .lb-counter { top: calc(8px + var(--safe-top)); bottom: auto; }
.lb-has-desc .lb-nav { top: calc(28px + 28vh); }
.lb-desc { width: min(560px, 92vw); margin-top: 12px; color: #fff; background: rgba(255,255,255,.08); border-radius: 12px; padding: 10px 14px; overflow-y: auto; flex: 1 1 auto; min-height: 0; font-size: 14px; line-height: 1.4; }
.lb-desc-head { font-weight: 700; font-size: 15px; margin-bottom: 4px; }
.lb-desc-text { white-space: pre-wrap; }
.lb-desc-sub { opacity: .7; font-size: 12px; margin-top: 6px; }
/* Галерея по задачам (30.10.2026): файлы одной задачи — свайп влево-вправо,
   другие задачи — вверх-вниз. Кнопки ˄ ˅ для мыши — в правом верхнем углу. */
.lb-gal .lb-nav.up, .lb-gal .lb-nav.down,
.lb-has-desc .lb-nav.up, .lb-has-desc .lb-nav.down { left: auto; right: 10px; transform: none; margin-top: 0; width: 36px; height: 36px; font-size: 20px; }
.lb-gal .lb-nav.up, .lb-has-desc .lb-nav.up { top: calc(8px + var(--safe-top)); right: 52px; }
.lb-gal .lb-nav.down, .lb-has-desc .lb-nav.down { top: calc(8px + var(--safe-top)); }
/* Крестик всегда в правом верхнем углу (30.10.2026, @AS_OPr11): окно прокручивается
   само, и прижатый абсолютом крестик уезжал вверх вместе с содержимым — в длинной
   карточке лида его не было видно. Теперь он «прилипает» к верху окна. В блочном
   окне держится справа обтеканием, в колоночном (карточка лида) — align-self;
   отрицательный нижний отступ — чтобы не сдвигал заголовок. */
.modal > .modal-x {
  position: sticky; top: 0; float: right; align-self: flex-end; flex: none;
  margin: -8px -6px -34px 8px;
  box-shadow: 0 2px 8px rgba(0,0,0,.12);
}
/* «Поделиться → ЭЛИДОМ»: разделы кнопками вместо выпадающего списка (30.10.2026). */
.sh-sec-chips { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 4px; }
.sh-sec-chips .fchip { text-align: left; font-weight: 500; white-space: normal; }
/* Фото с приёмки (ЧКП) в «Сервисе»: счётчики, квитанции, ключи (30.10.2026).
   Нажатие на снимок — на весь экран, галочка — отметить для разбора ИИ. */
.chkp-box { margin-top: 10px; }
.chkp-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(96px, 1fr)); gap: 8px; margin: 8px 0; }
.chkp-item { border: 1px solid var(--line); border-radius: 10px; padding: 4px; background: var(--surface); }
.chkp-item.on { border-color: var(--brand); box-shadow: 0 0 0 2px var(--brand) inset; }
.chkp-item .meter-pic { display: block; width: 100%; height: 84px; border-radius: 7px; margin: 0; }
.chkp-check { display: flex; gap: 4px; align-items: flex-start; margin-top: 4px; font-size: 12px; line-height: 1.25; cursor: pointer; }
.chkp-check input { flex: none; margin: 1px 0 0; }
.chkp-cap { color: var(--muted); overflow-wrap: anywhere; }
.an-shot[data-view] { cursor: zoom-in; }
/* Поле выбора со своим выпадающим списком (31.10.2026, @AS_OPr11): вместо
   системных подсказок над клавиатурой — список под полем, листается вверх-вниз. */
.combo-dd .fld-input { padding-right: 64px; }
.combo-dd .combo-clear { right: 36px; }
.combo-tg {
  position: absolute; top: 50%; right: 6px; transform: translateY(-50%);
  width: 28px; height: 28px; border: 0; border-radius: 8px; cursor: pointer; padding: 0;
  background: transparent; color: var(--muted); font-size: 18px; line-height: 1;
  display: grid; place-items: center;
}
.combo-tg:hover { background: var(--surface-2); color: var(--text); }
.combo-list {
  position: absolute; left: 0; right: 0; top: calc(100% + 4px); z-index: 70;
  max-height: min(50vh, 340px); overflow-y: auto; overscroll-behavior: contain; -webkit-overflow-scrolling: touch;
  background: var(--surface); border: 1px solid var(--line); border-radius: 12px;
  box-shadow: 0 10px 28px rgba(0,0,0,.18); padding: 4px 0;
}
.combo-list[hidden] { display: none; }
.combo-opt {
  display: block; width: 100%; text-align: left; border: 0; background: none; cursor: pointer;
  font: inherit; font-size: 14px; color: var(--text); padding: 10px 12px; line-height: 1.3;
}
.combo-opt + .combo-opt { border-top: 1px solid var(--line); }
.combo-opt:hover, .combo-opt:active { background: var(--surface-2); }
.combo-opt.on { color: var(--brand); font-weight: 600; }
.combo-none { padding: 10px 12px; font-size: 13px; color: var(--muted); }

/* «Материалы» в ЛКС и ЛКА (31.10.2026, id=986): разделы как в ЛКУ, свёрнуты;
   внутри — плитка миниатюр фото и карточки роликов. */
.smat-head { display: flex; justify-content: space-between; gap: 8px; align-items: baseline; font-weight: 700; margin: 4px 2px 10px; }
.smat-head span { font-weight: 400; color: var(--muted); font-size: 13px; }
.smat-sec { margin-bottom: 10px; }
.smat-sec > summary { display: flex; gap: 8px; align-items: baseline; cursor: pointer; list-style: none; }
.smat-sec > summary::-webkit-details-marker { display: none; }
.smat-sec > summary::before { content: '›'; display: inline-block; transition: transform .15s; color: var(--muted); font-weight: 700; }
.smat-sec[open] > summary::before { transform: rotate(90deg); }
.smat-sec-title { flex: 1; font-weight: 700; }
.smat-sec-n { color: var(--muted); font-size: 12.5px; white-space: nowrap; }
.smat-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(140px, 1fr)); gap: 10px; margin-top: 10px; }
.smat-item { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.smat-item .meter-pic { width: 100%; height: 110px; margin: 0; border-radius: 10px; }
.smat-vid { position: relative; width: 100%; height: 110px; padding: 0; border: 0; border-radius: 10px; overflow: hidden; background: var(--surface-2, #eef1f5); display: flex; align-items: center; justify-content: center; color: var(--brand); cursor: pointer; }
.smat-vid img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .15s; }
.smat-vid img.on { opacity: 1; }
.smat-vplay { position: relative; display: flex; align-items: center; justify-content: center; width: 40px; height: 40px; border-radius: 50%; background: rgba(255,255,255,.85); }
.smat-vid img.on + .smat-vplay { background: rgba(0,0,0,.55); color: #fff; }
.smat-vid .ic { width: 28px; height: 28px; }
.smat-cap { font-size: 12.5px; line-height: 1.3; display: flex; flex-direction: column; gap: 2px; overflow-wrap: anywhere; }
.smat-cap span { color: var(--muted); }
.stat.wide { grid-column: 1 / -1; }
/* Карточка собственника: снимки документов в разделе «Документы» (31.10.2026). */
#od-box .onb-thumb .meter-pic { width: 96px; height: 72px; margin: 0; border-radius: 8px; }
#od-box .onb-thumb small { font-size: 11px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
#od-box button.onb-thumb-pdf { cursor: pointer; }
.fld-check[hidden] { display: none; }
/* Карточка объекта: сумма и кнопка «Из договора С/Ар» в одну строку. */
.oe-from-row { display: flex; gap: 8px; align-items: stretch; }
.oe-from-row .fld-input { flex: 1 1 auto; min-width: 0; }
.oe-from-row .btn { flex: 0 0 auto; white-space: nowrap; }

/* Связь карточки роли (С, Ар, Подр, Сотр) с базой контактов — первой строкой (31.10.2026) */
.cb-link { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; padding: 10px 12px; margin: 0 0 10px;
  border: 1px solid var(--line, #e3e6ea); border-radius: 12px; background: var(--bg-soft, #f6f8fa); }
.cb-link.on { border-color: rgba(46, 160, 67, .35); }
.cb-link.off { border-style: dashed; }
.cb-link > svg { flex: 0 0 auto; width: 20px; height: 20px; opacity: .7; }
.cb-link-main { flex: 1 1 200px; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.cb-link-main .row-sub { overflow-wrap: anywhere; }
.cb-link-act { display: flex; gap: 6px; flex-wrap: wrap; }

/* Шапка собственника на вкладке «Договоры» (31.10.2026): аватар, ФИО,
   обращение, д.р. и налоговый статус, ниже — звонок и две карточки. */
.owner-head-top { display: flex; gap: 12px; align-items: flex-start; }
.owner-head-main { flex: 1; min-width: 0; display: grid; gap: 2px; }
.owner-head .card-actions { margin-top: 10px; display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.owner-head .chip { padding: 1px 8px; font-size: 12px; }
.tenant-heads { display: grid; gap: 10px; }
/* Карточка роли (С, Ар, Подр, Сотр): при прокрутке шапкой остаётся только блок
   связи с базой контактов (31.10.2026). Поля прокручиваются вместе с окном, а не
   в своей рамке; справа место под липкий крестик. */
.modal.card-pin-cb .fields-box { max-height: none; overflow: visible; }
.modal.card-pin-cb > #cd-cb { position: sticky; top: -18px; z-index: 3; display: flow-root;
  background: var(--surface); padding: 8px 46px 0 0; margin-top: -8px; }
.modal.card-pin-cb > #cd-cb:empty { display: none; }
.modal.card-pin-cb > .modal-x { z-index: 4; }
/* Долг собственника по квитанции (31.10.2026, id=1036): строка погашения и пометка под строкой периода */
.rec-debt-note { font-size: 13px; margin: 4px 0 6px; }
.rec-debt-row.open { background: color-mix(in srgb, var(--danger) 8%, transparent); border-radius: 10px; }
#ard-monthly-box[hidden] { display: none; }

/* ЛКС: минусовые начисления в балансе (01.11.2026, id=1083) */
.minus-hist { margin: 10px 0; }
.minus-hist > summary { cursor: pointer; list-style: revert; }
.minus-period { font-size: 13px; font-weight: 700; margin: 10px 0 4px; color: var(--muted); }
.minus-now { font-size: 11px; font-weight: 600; padding: 2px 8px; border-radius: 999px; background: var(--surface); border: 1px solid var(--line); color: var(--text, inherit); }
.minus-hist .kv-row b.neg, .settle .kv-row b.neg { color: var(--danger); white-space: nowrap; }
.balance-total-debt.minus b { color: #fff; }

/* ЛКС: наличие минусовых начислений на плитке «Баланс» (01.11.2026, id=1086) */
.stat-alert { margin-top: 6px; padding: 4px 8px; border-radius: 8px; font-size: 12px; font-weight: 600; line-height: 1.3;
  color: var(--danger); background: color-mix(in srgb, var(--danger) 10%, transparent); overflow-wrap: anywhere; }

/* Чек собственника к выплате (01.11.2026, id=1099): миниатюра в строке вывода
   ЛКС и в окне «Чеки» ЛКУ. */
.wd-chek { display: flex; align-items: center; gap: 6px; margin-top: 4px; }
.wd-chek .meter-pic { display: inline-block; width: 56px; height: 42px; margin: 0; }
.wd-chek-link { color: var(--brand); text-decoration: underline; cursor: pointer; }
.chek-row { display: flex; align-items: center; gap: 10px; padding: 8px 0; border-top: 1px solid var(--line); }
.chek-row:first-child { border-top: 0; }
.chek-row .meter-pic { width: 64px; height: 48px; margin: 0; }
.chek-row .row-main { flex: 1; min-width: 0; }
.chek-row .chek-acts { display: flex; gap: 6px; flex-wrap: wrap; }

/* ── ЧаВО жителя (01.11.2026) ──────────────────────────────────────────────
   Вопросы — аккордеоном на <details>: разворачивается без скриптов, работает
   в Mini App и с клавиатуры. Видео — с сохранением пропорции 16:9. */
.faq-wrap .section-title { margin-top: 18px; }
.faq-video { margin: 12px 0 4px; }
.faq-video-box { position: relative; width: 100%; aspect-ratio: 16 / 9; border-radius: var(--radius-sm); overflow: hidden; background: #000; }
.faq-video-box iframe { position: absolute; inset: 0; width: 100%; height: 100%; border: 0; }
.faq-list { display: flex; flex-direction: column; gap: 8px; }
.faq-item { border: 1px solid var(--line); border-radius: var(--radius-sm); background: var(--surface); overflow: hidden; }
.faq-item[open] { border-color: color-mix(in srgb, var(--brand) 35%, var(--line)); }
.faq-q { cursor: pointer; padding: 12px 36px 12px 14px; font-weight: 600; font-size: 14.5px; position: relative; list-style: none; }
.faq-q::-webkit-details-marker { display: none; }
.faq-q::after { content: '+'; position: absolute; right: 14px; top: 50%; transform: translateY(-50%); font-size: 18px; color: var(--muted); }
.faq-item[open] .faq-q::after { content: '–'; }
.faq-q:focus-visible { outline: 2px solid var(--brand); outline-offset: -2px; }
.faq-a { padding: 0 14px 12px; font-size: 14px; line-height: 1.5; }
.faq-a p { margin: 0 0 8px; }
.faq-a .row-sub { margin-top: 6px; }

/* «Кто поедет» — карточки сотрудников по отделам (01.11.2026, id=1104) */
.who-pick { display: flex; flex-direction: column; gap: 6px; margin-top: 6px; max-height: 52vh; overflow-y: auto; padding: 2px; }
.who-group { font-size: 12px; font-weight: 700; color: var(--muted); text-transform: uppercase; letter-spacing: .03em; margin: 8px 2px 0; }
.who-card { position: relative; display: flex; align-items: center; gap: 10px; padding: 9px 12px; border: 1px solid var(--line, #e3e6ee); border-radius: 12px; background: var(--card, #fff); cursor: pointer; }
.who-card input { position: absolute; opacity: 0; pointer-events: none; width: 0; height: 0; }
.who-card .who-ava.avatar.sm { width: 36px; height: 36px; font-size: 13px; }
.who-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 3px; }
.who-name { font-weight: 600; line-height: 1.25; overflow-wrap: anywhere; }
.who-sub { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; font-size: 13px; }
.who-phone { color: var(--muted); white-space: nowrap; }
.chip.who-dept { margin: 0; font-size: 11px; padding: 1px 8px; background: var(--brand); }
.chip.who-dept.extra { background: transparent; color: var(--brand); border: 1px solid var(--brand); }
.chip.who-dept.none { background: var(--warn); }
.who-mark { flex: none; width: 20px; height: 20px; border-radius: 50%; border: 2px solid var(--line, #c9cfdb); }
.who-card:has(input:checked) { border-color: var(--brand); box-shadow: 0 0 0 1px var(--brand) inset; }
.who-card:has(input:checked) .who-mark { border-color: var(--brand); background: radial-gradient(circle, var(--brand) 45%, transparent 50%); }
.who-card:has(input:focus-visible) { outline: 2px solid var(--brand); outline-offset: 2px; }
/* Меню «Ещё» (01.11.2026, id=1111): группы по смыслу и вид плиткой в 3 столбца. */
.more-top { justify-content: space-between; margin-top: 10px; }
.more-group { margin-bottom: 6px; }
.more-group .section-title { margin: 12px 4px 6px; }
.more-group .list.menu { margin-top: 0; }
.more-tiles { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 8px; }
.more-tile {
  display: flex; flex-direction: column; align-items: center; justify-content: flex-start; gap: 6px;
  min-width: 0; padding: 10px 6px; border: 1px solid var(--line); border-radius: 12px;
  background: var(--surface); color: var(--text); text-decoration: none; text-align: center;
}
.more-tile:active { background: color-mix(in srgb, var(--brand) 8%, var(--surface)); }
.more-tile-ic { color: var(--brand); display: inline-flex; width: 36px; height: 36px; align-items: center;
  justify-content: center; border-radius: 10px; background: color-mix(in srgb, var(--brand) 9%, var(--surface)); }
.more-tile-name { font-size: 12px; font-weight: 600; line-height: 1.2; overflow-wrap: anywhere;
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.more-group.tiles { padding: 2px 8px 10px; border-radius: 12px; }
.more-group.tiles:nth-of-type(even) { background: color-mix(in srgb, var(--muted) 9%, var(--surface)); }

/* ── Кабинет агента (ЛКМА, 01.11.2026) ─────────────────────────────────────
   Главная — плитки, как в режиме агента у управляющего: число крупно, под ним
   название раздела и подпись. Вторая плитка выделена: база квартир — то, с чем
   агент работает каждый день. */
.ag-tiles { display: grid; grid-template-columns: repeat(2, 1fr); gap: 10px; margin-bottom: 12px; }
.ag-tile { display: flex; flex-direction: column; gap: 2px; padding: 12px 14px; border-radius: var(--radius-sm);
  background: var(--surface); border: 1px solid var(--line);
  color: var(--text); text-decoration: none; transition: border-color .12s, box-shadow .12s; }
/* Плитки кабинета агента: непрозрачные (opacity из набора «режима агента»
   управляющего не должен сюда протекать — тот же класс .ag-tile), при наведении —
   подсветка контуром (01.11.2026, просьба заказчика). */
.ag-tiles-cab .ag-tile { opacity: 1; background: var(--surface); border: 1px solid var(--line); color: var(--text); }
.ag-tiles-cab .ag-tile.blue { background: var(--brand); border-color: var(--brand); color: #fff; }
.ag-tiles-cab .ag-tile:hover { opacity: 1; border-color: var(--brand); box-shadow: inset 0 0 0 1px var(--brand); }
.ag-tiles-cab .ag-tile.blue:hover { opacity: 1; border-color: #fff; box-shadow: inset 0 0 0 2px color-mix(in srgb, #fff 55%, transparent); }
.ag-tile-val { font-size: 22px; font-weight: 700; line-height: 1.1; }
.ag-tile-name { font-size: 13.5px; font-weight: 600; }
.ag-tile-sub { font-size: 12px; opacity: .75; }
.ag-ad { display: flex; align-items: center; gap: 10px; }
.ag-ad-pic { width: 86px; height: 64px; object-fit: cover; border-radius: var(--radius-sm); flex: none; background: var(--line); }
.ag-ad-pic.empty { display: block; }
.ag-ad-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
/* ЛКМА «Все квартиры»: выдача списком или плиткой, шапка с картой (id=1118). */
.ag-mk-head { margin: 6px 0; gap: 8px; flex-wrap: wrap; }
.ag-mk-head .btn.active { border-color: var(--brand); color: var(--brand); }
#ag-mk-mapbox { margin-bottom: 8px; }
.ag-ads.rows { display: flex; flex-direction: column; gap: 8px; }
.ag-ads.tiles { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 8px; }
.ag-ads.tiles .ag-ad { flex-direction: column; align-items: stretch; padding: 0 0 10px; overflow: hidden; position: relative; }
.ag-ads.tiles .ag-ad-pic { width: 100%; height: 150px; border-radius: var(--radius) var(--radius) 0 0; }
.ag-ads.tiles .ag-ad-main { padding: 0 10px; }
.ag-ads.tiles .ag-ad > .chip { position: absolute; top: 8px; left: 8px; }
@media (max-width: 420px) { .ag-ads.tiles { grid-template-columns: repeat(2, 1fr); } .ag-ads.tiles .ag-ad-pic { height: 110px; } }
@media (max-width: 360px) { .ag-tiles { grid-template-columns: 1fr; } }
/* Запись разговора в кабинете агента: плеер во всю ширину карточки. */
.ag-rec { width: 100%; margin-top: 8px; }

/* Обучение МА: предложение на главной + раздел «Обучение» (02.11.2026). */
.learn-offer { position: relative; margin: 10px 0; padding: 14px; border: 1px solid var(--brand);
  border-radius: 12px; background: color-mix(in srgb, var(--brand) 7%, transparent); }
.learn-offer-x { position: absolute; top: 6px; right: 8px; border: none; background: none; font-size: 20px;
  line-height: 1; color: var(--muted); cursor: pointer; padding: 2px 6px; }
.learn-offer-h { font-size: 15px; display: flex; align-items: center; gap: 6px; }
.learn-offer-h svg { width: 18px; height: 18px; }
.learn-offer-sub { font-size: 13px; color: var(--muted); margin: 6px 0 10px; }
.learn-offer .btn.block { width: 100%; }
.learn-bar { display: block; height: 6px; border-radius: 4px; background: var(--line); margin-top: 6px; overflow: hidden; }
.learn-bar > span { display: block; height: 100%; background: var(--brand); }
.learn-prog { font-size: 13px; color: var(--muted); margin: 8px 0 12px; }
.learn-steps { display: flex; flex-direction: column; gap: 8px; }
.learn-step { display: flex; align-items: center; gap: 10px; width: 100%; text-align: left; cursor: pointer;
  padding: 10px 12px; border: 1px solid var(--line); border-radius: 10px; background: var(--surface); }
.learn-step.done { border-color: var(--ok); background: color-mix(in srgb, var(--ok) 7%, transparent); }
.learn-step-ck { flex: 0 0 22px; width: 22px; height: 22px; border-radius: 50%; border: 1px solid var(--line);
  display: inline-flex; align-items: center; justify-content: center; color: #fff; font-size: 13px; }
.learn-step.done .learn-step-ck { background: var(--ok); border-color: var(--ok); }
.learn-step-main { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.learn-step-t { font-size: 14px; font-weight: 600; }
.learn-step-s { font-size: 12.5px; color: var(--muted); }
.learn-step svg { flex: 0 0 auto; color: var(--muted); }
.learn-body { font-size: 14px; line-height: 1.5; white-space: normal; margin: 4px 0 10px; }

/* Панель списка «фильтр · порядок · поиск» во всех разделах (UI.listBar, id=1117). */
.lb-bar .mkq-menu { left: 0; right: auto; }
.lb-found { margin: -2px 0 8px; }
.lb-found .link-btn { display: inline; padding: 0; font-size: inherit; }

/* Запасной просмотр фото карточки объявления (js/market-card.js, id=1121) —
   в кабинетах, где нет своего лайтбокса (ЛКМА). */
.mc-lb { flex-direction: column; gap: 10px; }
.mc-lb img { max-width: 96vw; max-height: 82vh; object-fit: contain; }
.mc-lb .modal-x { position: absolute; top: 12px; right: 12px; }
.mc-lb-bar { display: flex; align-items: center; gap: 12px; color: #fff; font-size: 14px; }

/* Агенты (ЛКУ): поиск, запись телефонной книги, раскрывающаяся статистика
   (02.11.2026). У карточки и строки свой display — [hidden] задаём явно. */
.ag-search { margin: 8px 0; }
.ag-card[hidden], .list .row[hidden] { display: none; }
.ag-row-btns { display: flex; flex-direction: column; gap: 6px; align-items: flex-end; }
.ag-book { color: var(--muted); }
.ag-stats { margin-top: 10px; padding-top: 10px; border-top: 1px solid var(--line); }
.ag-stats[hidden] { display: none; }
.ag-stats-grid { display: flex; flex-direction: column; gap: 6px; }
.ag-stat { display: flex; gap: 8px; align-items: baseline; font-size: 13px; }
.ag-stat-k { flex: 0 0 96px; color: var(--muted); font-size: 11px; font-weight: 600;
  text-transform: uppercase; letter-spacing: .02em; }
.ag-stat-v { flex: 1; }
.ag-stats-note { margin-top: 8px; }
/* Метка статуса в «Размещении по площадкам» — кнопка смены статуса (02.11.2026). */
button.am-tag { border: 0; cursor: pointer; font-family: inherit; line-height: 1.5; }
button.am-tag:active { filter: brightness(.9); }
/* «+ ссылка» в ячейке «Размещения по площадкам» — вписать объявление, сделанное вручную (02.11.2026). */
.am-addlink { display: block; margin: 4px auto 0; border: 0; background: none; cursor: pointer; padding: 2px 6px;
  font: inherit; font-size: 11.5px; font-weight: 600; color: var(--brand); border-radius: 8px; }
.am-addlink:active { background: var(--surface-2); }
/* Откуда отметка в ячейке «Размещения по площадкам» (02.11.2026). */
.am-src { display: inline-block; margin: 2px 0; padding: 0 6px; border-radius: 999px; font-size: 10.5px; font-weight: 600; line-height: 1.6; }
.am-src.sys { background: color-mix(in srgb, var(--ok) 16%, transparent); color: var(--ok); }
.am-src.hand { background: color-mix(in srgb, var(--brand) 14%, transparent); color: var(--brand); }
.am-src.base { background: var(--surface-2); color: var(--muted); }
/* Поле со справочником в анкете заявки (02.11.2026): под списком — ввод своего
   значения, он появляется только при выборе «своё значение…». */
.fld .rq-own { margin-top: 6px; }
.fld .rq-own[hidden] { display: none; }

/* ── Заявки: вид плиткой, календарь и карта (02.11.2026) ───────────────────
   Плитка — две колонки на телефоне и три на компьютере: так охватывается
   глазом больше заявок, а списком удобнее читать подряд. */
.rq-tiles { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
@media (min-width: 900px) { .rq-tiles { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.rq-tiles .req-card { margin: 0; }
.rq-tiles .req-card .settle-title { font-size: 14px; }
.rq-tiles .req-card .row-sub { font-size: 12px; }
/* Раскрывающиеся блоки над списком: календарь и карта. */
.rq-fold { display: flex; align-items: center; gap: 8px; width: 100%; padding: 10px 12px; margin-bottom: 8px;
  background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius-sm);
  font: inherit; font-weight: 600; color: var(--text); cursor: pointer; text-align: left; }
.rq-fold.open { border-color: color-mix(in srgb, var(--brand) 35%, var(--line)); }
.rq-fold > span:first-of-type { flex: 1; }
.rq-fold-x { color: var(--muted); font-size: 18px; }
.rq-fold-body { border: 1px solid var(--line); border-top: 0; border-radius: 0 0 var(--radius-sm) var(--radius-sm);
  padding: 10px 12px; margin: -8px 0 10px; background: var(--surface); }
.rq-cal-top { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 8px; }
.rq-cal-top .row-sub { flex-basis: 100%; }
.rq-cal-dow, .rq-cal-grid { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.rq-cal-dow span { font-size: 11px; color: var(--muted); text-align: center; }
.rq-cal-day { min-height: 74px; border: 1px solid var(--line); border-radius: 6px; padding: 3px 4px; background: var(--bg); }
.rq-cal-day.empty { border: 0; background: none; }
.rq-cal-day.today { border-color: var(--brand); }
.rq-cal-day.over { background: color-mix(in srgb, var(--brand) 12%, var(--surface)); border-color: var(--brand); }
.rq-cal-n { font-size: 11px; color: var(--muted); }
.rq-cal-item { display: block; font-size: 11px; line-height: 1.25; padding: 2px 4px; margin-top: 2px; cursor: grab;
  background: color-mix(in srgb, var(--brand) 12%, var(--surface)); border-radius: 4px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Тема задачи и адрес объекта — двумя строками (04.11.2026): адрес приглушён и
   обрезается многоточием, тема остаётся в одну строку. */
.rq-cal-item .rq-cal-t { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rq-cal-addr { display: block; font-size: 10px; line-height: 1.2; color: var(--muted);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.rq-cal-item.hot { background: color-mix(in srgb, var(--danger) 14%, var(--surface)); }
.rq-cal-item.drag { opacity: .5; }
/* Отдельная подзадача (05.11.2026, id=1206): серая карточка со значком — в
   календаре задач и в календаре кабинета. */
.rq-cal-item.sub, .cal-ev.cal-sub, .cal-row.cal-sub, .cal-row-m.cal-sub { background: color-mix(in srgb, var(--muted) 20%, var(--surface)); }
.cal-ev.cal-sub, .cal-row.cal-sub, .cal-row-m.cal-sub { border-radius: 4px; }
.rq-sub-ic { display: inline-flex; flex: none; vertical-align: -2px; margin-right: 3px; color: var(--muted); }
.rq-sub-ic svg { width: 12px; height: 12px; }
.sub-task.sep { background: color-mix(in srgb, var(--muted) 10%, var(--surface)); }
.rq-cal-more { font-size: 10.5px; color: var(--muted); margin-top: 2px; }
.rq-hours { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.rq-hour { font-size: 12px; padding: 4px 8px; border: 1px dashed var(--line); border-radius: 6px; color: var(--muted); }
.rq-hour.over { border-style: solid; border-color: var(--brand); color: var(--text);
  background: color-mix(in srgb, var(--brand) 12%, var(--surface)); }
.rq-nodate { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 10px; }
.rq-nodate .rq-cal-item { display: inline-block; }
/* Результаты фильтра «Без срока» — отдельной строкой во всю ширину, чтобы
   поле поиска можно было обновлять, не трогая (04.11.2026). */
.rq-nd-body { width: 100%; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.rq-map { height: 320px; border-radius: var(--radius-sm); overflow: hidden; }
@media (max-width: 520px) { .rq-cal-day { min-height: 58px; } .rq-map { height: 240px; } }
/* Календарь задач: неделя и день (02.11.2026). */
.rq-cal-week { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); gap: 4px; }
.rq-cal-day.week { min-height: 110px; }
@media (max-width: 760px) { .rq-cal-week { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.rq-cal-dayview { display: flex; flex-direction: column; gap: 4px; }
.rq-hour-row { display: flex; gap: 8px; align-items: flex-start; border-top: 1px solid var(--line); padding-top: 4px; }
.rq-hour-row.over { background: color-mix(in srgb, var(--brand) 10%, transparent); }
.rq-hour-l { flex: 0 0 72px; font-size: 12px; color: var(--muted); }
.rq-hour-b { flex: 1; min-width: 0; display: flex; flex-wrap: wrap; gap: 4px; min-height: 22px; }
.rq-hour-b .rq-cal-item { display: inline-block; }
.tk-cal-per { flex: 0 0 auto; }
.rq-cal-more { cursor: pointer; }
/* Заявка, работа по которой ушла в задачу: показываем состав, но не даём
   править — кнопки и поля внутри блока работы выключены (02.11.2026). */
.rq-ro { opacity: .92; }
.rq-ro .btn, .rq-ro button:not([data-rq-tab]):not([data-rq-hint]), .rq-ro input, .rq-ro select, .rq-ro textarea, .rq-ro label.doc-up { pointer-events: none; }
.rq-ro .btn, .rq-ro label.doc-up { opacity: .45; }
.rq-ro input[type="checkbox"] { opacity: .5; }
/* Значок «молоток и отвёртка» в строке заявки — перенос в задачу (03.11.2026). */
.rq-towork { display: inline-flex; align-items: center; justify-content: center; width: 30px; height: 30px;
  border: 1px solid var(--line); border-radius: 8px; background: var(--surface); color: var(--muted); cursor: pointer; }
.rq-towork:hover { color: var(--brand); border-color: color-mix(in srgb, var(--brand) 40%, var(--line)); }
/* Статус встречи / приёмки в чек-листе (03.11.2026). */
.chip.plan-st { font-size: 11px; vertical-align: middle; }
.chip.plan-st.set { background: color-mix(in srgb, var(--brand) 14%, transparent); color: var(--brand); }
.chip.plan-st.done { background: color-mix(in srgb, var(--ok) 16%, transparent); color: var(--ok); }
.chip.plan-st.cancelled { background: var(--surface-2); color: var(--muted); }
.accept-plan.closed .accept-plan-main b { color: var(--muted); }
/* «Без срока» в календаре задач: фильтр по объекту и радиус (03.11.2026). */
.tk-nd-flt { display: flex; gap: 6px; align-items: flex-end; width: 100%; margin-bottom: 6px; }
.tk-nd-flt .fld { flex: 1; min-width: 0; margin: 0; }
.tk-nd-rbtn { flex: none; height: 40px; display: inline-flex; align-items: center; gap: 4px; }
.tk-nd-rbtn.on { border-color: var(--brand); color: var(--brand); }
.tk-nd-radius { display: flex; flex-direction: column; gap: 2px; width: 100%; margin-bottom: 6px; }
.tk-nd-radius input[type=range] { width: 100%; accent-color: var(--brand); }
/* Вид «День» календаря задач: высота карточки — длительность, ручка внизу (03.11.2026). */
.rq-cal-dayview .rq-hour-row { height: 48px; box-sizing: border-box; overflow: visible; }
.rq-cal-dayview .rq-hour-b { align-items: flex-start; flex-wrap: nowrap; overflow: visible; }
.rq-day-item { position: relative; z-index: 2; display: flex !important; flex-direction: column; justify-content: space-between;
  min-width: 120px; max-width: 100%; box-sizing: border-box; padding: 3px 6px 10px; overflow: hidden; }
.rq-day-txt { white-space: normal; overflow: hidden; }
.rq-day-dur { font-size: 10px; color: var(--muted); }
.rq-day-grip { position: absolute; left: 0; right: 0; bottom: 0; height: 12px; cursor: ns-resize; touch-action: none;
  background: linear-gradient(transparent 4px, color-mix(in srgb, var(--brand) 35%, transparent) 4px, color-mix(in srgb, var(--brand) 35%, transparent) 6px, transparent 6px); }
.rq-day-item.resizing { outline: 2px solid var(--brand); z-index: 5; }
/* Вид «День»: 00–09 свёрнуты кнопкой сверху, конец суток — 24:00 (03.11.2026). */
.rq-early-tg { border: 1px dashed var(--line); background: var(--surface-2); color: var(--muted); border-radius: 10px;
  padding: 6px 10px; font: inherit; font-size: 12px; font-weight: 600; cursor: pointer; text-align: left; }
.rq-hour-end { border-top: 1px solid var(--line); padding-top: 4px; display: flex; }
/* Условный объект компании первой карточкой в «Объектах» (03.11.2026) */
.card.card-company { border-left: 3px solid var(--accent, #2f6feb); }
/* Логотип компании на месте обложки: занимает свободную высоту карточки,
   по центру, вписан целиком (03.11.2026). */
.card-company .card-logo-wrap { flex: 1 1 auto; display: grid; place-items: center; padding: 10px 12px; min-height: 120px; }
.card-company .card-logo { max-width: 72%; max-height: 150px; width: auto; height: auto; object-fit: contain; opacity: .92; }
/* Дата в виде «День» календаря задач — кнопка выбора (04.11.2026). */
.tk-date-pick { position: relative; display: inline-block; cursor: pointer; border-radius: 8px; padding: 4px 6px; }
.tk-date-pick:active { background: var(--surface-2); }
.tk-date-pick input[type=date] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; border: 0; padding: 0; }
/* Меню задачи в календаре: длительное нажатие или правая кнопка мыши (04.11.2026). */
.rq-cal-item { -webkit-touch-callout: none; -webkit-user-select: none; user-select: none; }
.tk-ctx { position: fixed; z-index: 900; min-width: 210px; max-width: calc(100vw - 16px); background: var(--surface); border: 1px solid var(--line);
  border-radius: 12px; box-shadow: 0 10px 30px rgba(0,0,0,.25); padding: 4px 0; }
.tk-ctx-title { padding: 6px 12px; font-size: 12px; color: var(--muted); border-bottom: 1px solid var(--line); margin-bottom: 2px; }
.tk-ctx-item { position: relative; display: block; width: 100%; text-align: left; border: 0; background: none; cursor: pointer; font: inherit; font-size: 14px; padding: 10px 12px; color: var(--text); box-sizing: border-box; }
.tk-ctx-item.danger-text { color: var(--danger, #d9432f); }
.tk-ctx-item:hover, .tk-ctx-item:active { background: var(--surface-2); }
.tk-ctx-item input[type=date] { position: absolute; inset: 0; width: 100%; height: 100%; opacity: 0; cursor: pointer; border: 0; padding: 0; }
/* Миниатюры в окнах правки открываются на весь экран (04.11.2026). */
.onb-thumb img[data-doc-thumb] { cursor: zoom-in; }

/* Техника на объекте в форме заявки (04.11.2026, id=1166). */
.rq-tech { margin-top: 8px; }
.rq-tech[hidden] { display: none; }
.rq-tech-row { display: flex; align-items: center; gap: 10px; padding: 6px 0; cursor: pointer; }
.rq-tech-row img, .rq-tech-nopic { width: 44px; height: 44px; flex: none; border-radius: 8px; object-fit: cover; background: rgba(127, 127, 127, .15); }
.rq-tech-txt { display: flex; flex-direction: column; min-width: 0; }
.rq-tech-txt small { opacity: .7; }
