:root {
  /* Палитра: мягкий голубой фон, слегка тонированные поверхности.
     Все чипы, бейджи, кнопки берут оттенки из этой же палитры,
     чтобы интерфейс был спокойный и единый. */
  --bg: #eaf2fb;            /* основной фон страницы — нежно-голубой */
  --bg-soft: #dde8f4;       /* чуть темнее — выделения строк/секций */
  --surface: #f7fbff;       /* карточки, модалки, табличные обёртки */
  --surface-alt: #eef4fa;   /* th-фон таблиц, чередование строк */
  --border: #c8d6e6;        /* холодный сине-серый бордер */
  --border-soft: #d8e2ee;
  --fg: #0f172a;            /* slate-900 — почти чёрный, по запросу 2026-05-11 */
  --muted: #475569;         /* slate-600 — тёмнее, чем slate-500 */
  /* Менее яркий синий для primary-кнопок: blue-400 base, blue-500 hover.
     Раньше был blue-500 base / blue-600 hover — слишком насыщенно при
     длительной работе. По запросу заказчика 2026-05-08 смягчили. */
  --primary: #60a5fa;       /* blue-400 */
  --primary-hover: #3b82f6; /* blue-500 */
  --primary-soft: rgba(96, 165, 250, 0.14);
  --btn-bg: #dbe8f5;        /* кнопка по умолчанию — голубой тон фона */
  --btn-bg-hover: #c6d6e6;
  --danger: #dc2626;
  --danger-bg: #fee2e2;
  --danger-fg: #b91c1c;
  --danger-border: #fecaca;
  --ok: #059669;
  --ok-bg: #dcfce7;
  --ok-fg: #14532d;
  --ok-border: #bbf7d0;
  --warn-bg: #fff7ed;
  --warn-fg: #b45309;
  --warn-border: #fed7aa;
  --swatch-fallback: #94a3b8; /* slate-400, нейтральный плейсхолдер для пустого color */
  --shadow: 0 1px 2px rgba(30, 64, 128, 0.04), 0 1px 3px rgba(30, 64, 128, 0.06);
  /* Фон полей ввода. Отдельный токен (а не --surface), потому что в
     светлых темах инпуты должны быть белее поверхностей, а в тёмной
     («Антрацит») — темнее. Раньше фон был захардкожен #fff в ~14 местах,
     из-за чего тёмная тема давала «белое поле с почти белым текстом». */
  --input-bg: #fff;
  /* Цвет текста на заливке --primary (кнопки .btn--primary, .topbar__quick).
     Белый на blue-400 давал контраст 2.5:1 и выцветал на TN-матрицах —
     теперь тёмно-синий на мягком фоне (по образцу активной кнопки
     Схема/Спутник). Переопределяется темами: в «Гранате» primary тёмный,
     там текст остаётся белым. */
  --primary-fg: #0f2a52;
  /* Фокус-ореол вокруг полей ввода — в цвет primary ТЕКУЩЕЙ темы.
     Раньше был захардкожен rgba(37,99,235,.15): в малахите/охре/гранате
     рамка была цвета темы, а ореол — всегда синий. */
  --focus-ring: color-mix(in srgb, var(--primary) 18%, transparent);
  /* Бейдж «СА» у пунктов меню, доступных только суперадмину, — нейтральная
     пилюля вместо прежнего оранжевого текста (читался как предупреждение). */
  --sa-badge-bg: #e2e8f0;   /* slate-200 */
  --sa-badge-fg: #475569;   /* slate-600 */
  /* Шкала высот кнопок: md — стандартная, sm — тулбары и плотные ряды,
     xs — кнопки в ячейках таблиц и списках. Значения совпадают с тем,
     что раньше задавалось разрозненными контекстными селекторами. */
  --btn-h-md: 36px;
  --btn-h-sm: 32px;
  --btn-h-xs: 24px;
  /* Типографическая шкала. Одна точка правки, если понадобится «сделать
     шрифт крупнее». Экзотические размеры (9/10/15/17/18/24/32px) остаются
     литералами — это точечные декоративные случаи. */
  --fs-xs: 11px;
  --fs-sm: 12px;
  --fs-base: 13px;
  --fs-md: 14px;
  --fs-lg: 16px;
  --fs-h1: 22px;
  /* ── Шкала z-index — единая карта слоёв приложения ──
       40    sticky-шапка страницы (под топбаром)
       100   выпадающие меню топбара (внутри stacking-контекста топбара)
       1100  sticky-тулбар карты (выше leaflet-панелей 200–1000)
       1200  топбар (перекрывает map-toolbar и его дропдауны)
       1500  дропдауны карты («+ Участок», «Слои», «Инструменты»)
       1600  выпадашка поиска ФИО в тулбаре карты
       1750  тосты и уведомления карты
       1800  полоса вкладок документов (fixed-подвал)
       1850  окно результатов поиска ФИО
       2000  модалки
       9999  лайтбокс предпросмотра файлов
       50000 командная палитра (Ctrl+K)
       99999 оверлей self-update (поверх всего)
     Новые слои добавляйте сюда, а не магическим числом на месте. */
  --z-sticky-head: 40;
  --z-menu: 100;
  --z-map-toolbar: 1100;
  --z-topbar: 1200;
  --z-dropdown: 1500;
  --z-search: 1600;
  --z-toast: 1750;
  --z-doc-tabs: 1800;
  --z-fio: 1850;
  --z-modal: 2000;
  --z-lightbox: 9999;
  --z-palette: 50000;
  --z-overlay: 99999;
}

/* ──────────────────────────────────────────────────────────────────────
   Темы интерфейса. На <body> навешивается класс `theme-<имя>`
   (значение из settings.theme, см. MeHandler / SettingsService).
   Имена — по драгоценным камням / материалам. Канонические коды
   совпадают с CSS-классами (sapphire/anthracite/malachite/ochre/garnet).

   «Сапфир» — палитра по умолчанию — живёт в :root выше, отдельного
   класса не имеет: пустой class на <body> = sapphire. Остальные
   четыре переопределяют CSS-переменные ниже.
   ────────────────────────────────────────────────────────────────────── */

/* Антрацит — для работы при низкой освещённости / больших мониторов.
   Базовые тона — slate (как был fg в светлой теме), но инверсия:
   fg/bg меняются ролями. Акцент primary оставляем синим — он остаётся
   ярким и читаемым на тёмном фоне. */
body.theme-anthracite {
  --bg: #0f172a;             /* slate-900 — общий фон */
  --bg-soft: #1e293b;        /* slate-800 — выделения строк */
  --surface: #1e293b;        /* slate-800 — карточки, модалки */
  --surface-alt: #273548;    /* th-фон, чередование строк */
  --border: #334155;         /* slate-700 */
  --border-soft: #2a3a52;
  --fg: #e2e8f0;             /* slate-200 — основной текст */
  --muted: #94a3b8;          /* slate-400 — подсказки */
  --primary: #60a5fa;        /* остался blue-400 — хорошо читается */
  --primary-hover: #93c5fd;  /* blue-300 на hover'е поярче */
  --primary-soft: rgba(96, 165, 250, 0.22);
  --btn-bg: #334155;         /* кнопка по умолчанию — slate-700 */
  --btn-bg-hover: #475569;
  --danger: #ef4444;
  --danger-bg: #450a0a;
  --danger-fg: #fca5a5;
  --danger-border: #7f1d1d;
  --ok: #22c55e;
  --ok-bg: #052e16;
  --ok-fg: #86efac;
  --ok-border: #14532d;
  --warn-bg: #422006;
  --warn-fg: #fbbf24;
  --warn-border: #78350f;
  --swatch-fallback: #475569;
  --shadow: 0 1px 2px rgba(0, 0, 0, 0.3), 0 1px 3px rgba(0, 0, 0, 0.4);
  /* Поля ввода темнее поверхностей (slate-900) — читаются как «углубление»
     на карточках/модалках (--surface slate-800), рамка --border видна. */
  --input-bg: #0f172a;
  /* --primary-fg наследуется из :root (#0f2a52): primary тот же blue-400. */
  /* Бейдж «СА» — те же slate-тона, но инвертированные под тёмный фон. */
  --sa-badge-bg: #334155;   /* slate-700 */
  --sa-badge-fg: #cbd5e1;   /* slate-300 */
}

/* Малахит — светлая, как сапфир, но в зелёном спектре. */
body.theme-malachite {
  --bg: #e8f3e8;             /* мягкий салатовый фон */
  --bg-soft: #dceadc;
  --surface: #f4faf3;
  --surface-alt: #ecf5ec;
  --border: #b8d4b8;
  --border-soft: #cfe0cf;
  --fg: #1f3320;             /* зелёно-серый, не чисто чёрный */
  --muted: #5b6b5b;
  --primary: #4ade80;        /* green-400 */
  --primary-hover: #22c55e;  /* green-500 */
  --primary-soft: rgba(74, 222, 128, 0.16);
  --btn-bg: #d9e8d9;
  --btn-bg-hover: #c5d8c5;
  --primary-fg: #052e16;     /* тёмно-зелёный текст на светлом green-400 */
  --shadow: 0 1px 2px rgba(20, 60, 30, 0.05), 0 1px 3px rgba(20, 60, 30, 0.07);
}

/* Охра — светлая в тёплом песочно-янтарном спектре. Акцент — amber-500,
   контрастно к молочно-бежевому фону, при этом не «детский апельсин». */
body.theme-ochre {
  --bg: #fbf2e2;             /* пергаментно-бежевый */
  --bg-soft: #f3e3bf;
  --surface: #fefbf3;
  --surface-alt: #f6ecd1;
  --border: #d9bf8e;
  --border-soft: #e6d3a8;
  --fg: #3a2c10;             /* тёмно-янтарный, тёплый коричневый */
  --muted: #7d5e2c;
  --primary: #f59e0b;        /* amber-500 */
  --primary-hover: #d97706;  /* amber-600 */
  --primary-soft: rgba(245, 158, 11, 0.18);
  --btn-bg: #efe1c0;
  --btn-bg-hover: #e4d2a4;
  --primary-fg: #451a03;     /* тёмно-коричневый текст на светлом amber-500 */
  --shadow: 0 1px 2px rgba(120, 80, 20, 0.05), 0 1px 3px rgba(120, 80, 20, 0.07);
}

/* Гранат — светлая в винно-багровом спектре. Primary — rose-800, чтобы
   не сливался с --danger (red-600); кнопка «Удалить» остаётся узнаваемо
   красной, а основной акцент — приглушённый бордо. */
body.theme-garnet {
  --bg: #fbeae6;             /* розово-кремовый */
  --bg-soft: #f3d4cb;
  --surface: #fdf4f2;
  --surface-alt: #f7e2dc;
  --border: #d4a59a;
  --border-soft: #e2b6a9;
  --fg: #4a1a17;             /* тёмно-бордовый, ближе к чёрному */
  --muted: #7d3838;
  --primary: #9f1239;        /* rose-800 — винный, узнаваемо «гранатовый» */
  --primary-hover: #831843;  /* rose-900 */
  --primary-soft: rgba(159, 18, 57, 0.16);
  --btn-bg: #f0cdc4;
  --btn-bg-hover: #e2a99c;
  --primary-fg: #fff;        /* primary здесь ТЁМНЫЙ (rose-800) — белый читается */
  --shadow: 0 1px 2px rgba(120, 20, 30, 0.05), 0 1px 3px rgba(120, 20, 30, 0.07);
}

* { box-sizing: border-box; }

html, body {
  margin: 0;
  padding: 0;
  height: 100%;
}

body {
  font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
  font-size: var(--fs-md);
  line-height: 1.5;
  color: var(--fg);
  background: var(--bg);
}

a { color: var(--primary); text-decoration: none; }
a:hover { text-decoration: underline; }

code {
  font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, monospace;
  font-size: 0.92em;
  background: rgba(0,0,0,0.05);
  padding: 1px 6px;
  border-radius: 4px;
}

.muted { color: var(--muted); }

/* ============ Подсказки и интро в формах ============
   Унифицированные стили текста-помощника, чтобы все формы выглядели
   одинаково. Раньше в разных модалках было `font-size:12px`, `13px`,
   `14px` и три разных серых hex-кода — пользователь жаловался на разнобой.
   - .modal-intro — параграф «что делает диалог» в шапке формы.
   - .field-hint — мелкая подсказка под конкретным полем. */
/*
  С v0.69.3 подсказки и интро в формах увеличены на 1-2 px — операторы
  жаловались, что мелкий серый текст возле полей и чекбоксов трудно
  читать. Старые значения: .modal-intro 13px, .field-hint 12px.
*/
.modal-intro {
  font-size: var(--fs-md);
  color: var(--muted);
  margin: -4px 0 12px;
  line-height: 1.45;
}
.field-hint {
  font-size: var(--fs-base);
  color: var(--muted);
  margin: 4px 0 8px;
  line-height: 1.45;
}
/*
  Глобальный bump: любой <p class="muted"> и <p> внутри
  .placeholder без явно прописанного font-size получает 13 px вместо
  браузерного дефолта (12-13 в зависимости от контекста). Так подсказки
  возле чекбоксов перестают выглядеть «петитом».

  Inline style="font-size:..." всегда побеждает это правило, поэтому
  места, где намеренно мелкий шрифт нужен (нумерация в шапке таблицы,
  meta-строки в палитре), не сломаются.
*/
p.muted { font-size: var(--fs-base); line-height: 1.45; }
.placeholder p.muted, .modal__body p.muted, .doc-form p.muted { font-size: var(--fs-base); }
.placeholder .muted { line-height: 1.45; }
/* Текст вокруг inline-чекбоксов и radio. */
label > input[type="checkbox"] + *,
label > input[type="radio"] + * { font-size: var(--fs-md); }
/* Сам label с inline-чекбоксом/радио — крупнее на 1px относительно
   browser-defaults; line-height чуть свободнее для двустрочных
   подписей. */
.doc-form label:has(> input[type="checkbox"]),
.doc-form label:has(> input[type="radio"]) {
  font-size: var(--fs-md);
  line-height: 1.55;
  display: inline-flex;
  align-items: baseline;
  gap: 4px;
}
/* Если за интро/хинтом сразу идёт поле, лишний margin-top не нужен —
   между текстом и полем уже есть margin-bottom от текста. */
.modal-intro + .field, .field-hint + .field,
.modal-intro + .field-grid, .field-hint + .field-grid,
.modal-intro + .form-grid,  .field-hint + .form-grid { margin-top: 0; }

/* ============ Алёрты (success / warning / danger) ============
   Раньше status-сообщения в модалках задавались inline-style'ями
   с разными hex-цветами для одного и того же по смыслу состояния.
   Теперь — три класса поверх .alert; цвета едины и берутся
   из переменных :root. */
.alert {
  padding: 8px 12px;
  border: 1px solid;
  border-radius: 6px;
  font-size: var(--fs-base);
}
.alert--danger { background: var(--danger-bg); color: var(--danger-fg); border-color: var(--danger-border); }
.alert--ok     { background: var(--ok-bg);     color: var(--ok-fg);     border-color: var(--ok-border); }
.alert--warn   { background: var(--warn-bg);   color: var(--warn-fg);   border-color: var(--warn-border); }

/* ============ Кнопки ============
   Default-кнопка тонирована тем же голубым, что и фон страницы — это
   объединяет «тулбары + контент + бордеры» в одну спокойную палитру.
   Primary — насыщенный синий той же гаммы, для главных CTA. */
.btn {
  /* inline-flex выравнивает <a class="btn"> и <button class="btn"> по
     одной baseline и одинаковой высоте (line-height по высоте flex-box).
     Раньше был inline-block — у <a> и <button> разные нативные
     метрики (line-height, baseline), и в строке action'ов кнопка
     «Открыть» выглядела выше «Изменить»/«Удалить».
     С v0.69.3 добавлен min-height: 36px и box-sizing: border-box —
     это гарантирует одну высоту у соседних .btn даже если у них
     слегка разные padding'и или содержимое (text vs icon vs label).
     Размер 36 px подобран так, чтобы стандартная кнопка
     `padding:8px 14px + line-height:1.2 + 14 px шрифта` точно
     умещалась без рывка. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--border);
  background: var(--btn-bg);
  color: var(--fg);
  padding: 8px 14px;
  border-radius: 6px;
  font-size: var(--fs-md);
  font-family: inherit;
  cursor: pointer;
  text-align: center;
  text-decoration: none;
  line-height: 1.2;
  min-height: var(--btn-h-md);
  box-sizing: border-box;
  vertical-align: middle;
  white-space: nowrap; /* текст кнопки не переносится — высота не «прыгает» в тесном ряду */
  transition: background .1s ease, border-color .1s ease;
}
.btn:hover { background: var(--btn-bg-hover); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
/* Видимый фокус при клавиатурной навигации — рамка в цвет primary темы.
   Ореол :focus у полей ввода живёт отдельно (--focus-ring). */
.btn:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}

.btn--primary {
  background: var(--primary);
  border-color: var(--primary);
  /* Тёмный текст на мягком primary-фоне (см. --primary-fg в :root):
     белый на blue-400 давал контраст 2.5:1 при норме 4.5:1. */
  color: var(--primary-fg);
}
.btn--primary:hover { background: var(--primary-hover); border-color: var(--primary-hover); }

.btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--fg);
}
.btn--ghost:hover { background: var(--primary-soft); }

/* Размерные модификаторы — высоты из шкалы --btn-h-*. Раньше те же
   размеры задавались контекстными селекторами (тулбар карты, .btn--small,
   кнопки в таблицах) — новым местам используйте эти классы. */
.btn--sm {
  min-height: var(--btn-h-sm);
  padding: 4px 10px;
  font-size: var(--fs-base);
}
.btn--xs {
  min-height: var(--btn-h-xs);
  padding: 2px 8px;
  font-size: var(--fs-sm);
}

/* ============ Приложение (после логина) ============ */
.app { display: flex; flex-direction: column; min-height: 100vh; }

.topbar {
  display: flex;
  align-items: center;
  gap: 24px;
  padding: 0 24px;
  height: 56px;
  min-height: 56px;
  flex-shrink: 0;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  box-sizing: border-box;
  /* Топбар sticky'ится сверху, а доком-полоса (.doc-tabs) — под ним
     (top: 56px). Иначе на длинных страницах (карточка участка с большой
     таблицей захоронений) полоса открытых вкладок уезжала вместе со
     скроллом и казалось, что она пропала.
     Z-index 1200: топбар обязан перекрывать любые другие sticky-блоки —
     включая map-toolbar (1100), у которого внутри живёт дропдаун
     «+ Добавить участок» с z-index 1500. Без этого свои дропдауны
     топбара (Отчёты / Администрирование, z-index 100 относительно
     контекста топбара) проваливались под map-toolbar. Иерархия слоёв:
     модалки 2000 > топбар 1200 > map-toolbar 1100 > всё остальное
     (полная карта слоёв — у токенов --z-* в :root). */
  position: sticky;
  top: 0;
  z-index: var(--z-topbar);
}

.topbar__brand {
  font-weight: 700;
  font-size: var(--fs-lg);
  color: var(--primary);
}

.topbar__version {
  margin-left: 8px;
  font-weight: 400;
  font-size: var(--fs-sm);
  color: var(--muted);
}

/* Кнопка «Быстрые команды» в топбаре — открывает Командную палитру.
   Стиль такой же, как у «Сохранить» внизу формы (.btn--primary):
   фон --primary, текст --primary-fg (тёмный на светлом primary; белый
   на blue-400 давал контраст 2.5:1). На узких экранах подсказка-клавиша
   скрывается. */
.topbar__quick {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin: 0 18px 0 22px;
  padding: 7px 14px;
  border: 1px solid var(--primary);
  border-radius: 6px;
  background: var(--primary);
  color: var(--primary-fg);
  font-size: var(--fs-md);
  font-weight: 500;
  font-family: inherit;
  cursor: pointer;
  transition: background .1s ease, border-color .1s ease;
  white-space: nowrap;
}
.topbar__quick:hover {
  background: var(--primary-hover);
  border-color: var(--primary-hover);
}
.topbar__quick:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: 2px;
}
.topbar__quick-label {
  font-weight: 500;
}
.topbar__quick-kbd {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 1px 6px;
  border-radius: 4px;
  /* Плашка клавиши — полупрозрачная смесь из цвета текста кнопки, чтобы
     работать и с тёмным (сапфир), и с белым (гранат) --primary-fg. */
  background: color-mix(in srgb, var(--primary-fg) 14%, transparent);
  font-size: var(--fs-xs);
  font-weight: 500;
  color: inherit;
}
.topbar__quick-kbd kbd {
  background: transparent;
  border: none;
  padding: 0;
  font: inherit;
  color: inherit;
}
@media (max-width: 900px) {
  .topbar__quick-kbd { display: none; }
  .topbar__quick { margin: 0 10px 0 14px; padding: 6px 10px; }
}

.topbar__nav {
  display: flex;
  gap: 6px;
  flex: 1;
  align-items: center;
}

.topbar__nav a {
  padding: 6px 10px;
  border-radius: 6px;
  color: var(--fg);
  font-weight: 500;
}
.topbar__nav a:hover {
  background: var(--btn-bg);
  text-decoration: none;
}
.topbar__nav a[aria-current="page"] {
  /* Подсветка активной страницы — только фоном; цвет надписи
     остаётся обычным (--fg), как у соседних пунктов. Раньше был
     дополнительно var(--primary) — на ярких темах это смотрелось
     «вырвавшимся» из общего ряда, как будто пункт «горит». */
  background: var(--primary-soft);
  color: var(--fg);
}

/* Выпадающие группы в топбаре (Отчёты, Администрирование).
   Стилизуем кнопку максимально идентично .topbar__nav a,
   чтобы группы визуально не выпадали из общего ряда. */
.topbar__group { position: relative; display: inline-flex; align-items: center; }
.topbar__group-btn {
  padding: 6px 10px;
  border-radius: 6px;
  color: var(--fg);
  font-weight: 500;
  font-size: inherit;
  font-family: inherit;
  line-height: 1.5;
  background: transparent;
  border: none;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.topbar__group:hover > .topbar__group-btn,
.topbar__group--open > .topbar__group-btn {
  background: var(--btn-bg);
}
.topbar__group-menu {
  display: none;
  position: absolute;
  top: 100%;
  left: 0;
  min-width: 220px;
  background: var(--bg, #fff);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 4px 12px rgba(0,0,0,0.1);
  padding: 4px;
  z-index: var(--z-menu);
  flex-direction: column;
}
.topbar__group:hover > .topbar__group-menu,
.topbar__group--open > .topbar__group-menu {
  display: flex;
}
.topbar__group-menu a {
  padding: 6px 10px;
  border-radius: 4px;
  color: var(--fg);
  white-space: nowrap;
}
.topbar__group-menu a:hover {
  background: var(--btn-bg);
  text-decoration: none;
}
.topbar__group-menu a[aria-current="page"] {
  background: var(--primary-soft);
  color: var(--primary);
}
/* Пункты, доступные только суперадмину, — помечены нейтральным бейджем
   «СА» (пилюля через ::after), чтобы оператор-СА видел разницу между
   «общими» и «привилегированными» функциями. Раньше подсвечивались
   оранжевым текстом — читалось как «предупреждение», треть пунктов
   «Сервиса»/«Участков» выглядела тревожно. Сам текст пункта — обычного
   цвета; ховер/активность — общие правила меню выше. Для admin'а такие
   пункты вообще скрыты (data-min-role фильтром в JS), так что бейдж
   видит только сам СА. Цвета — токены --sa-badge-* (:root + тёмная тема). */
.topbar__group-menu a[data-min-role="superadmin"]::after {
  content: "СА";
  display: inline-block;
  margin-left: 8px;
  padding: 1px 6px;
  border-radius: 999px;
  background: var(--sa-badge-bg);
  color: var(--sa-badge-fg);
  font-size: 10px;
  font-weight: 700;
  letter-spacing: 0.05em;
  line-height: 1.4;
  vertical-align: 1px;
}
/* Подсветка кнопки группы, когда активен любой её пункт. Тоже
   только фоном — цвет надписи остаётся --fg, как у неактивных
   групп. См. соседний комментарий у .topbar__nav a[aria-current]. */
.topbar__group--active > .topbar__group-btn {
  background: var(--primary-soft);
  color: var(--fg);
}

/* Разделитель внутри выпадающего меню — визуально группирует пункты.
   Используется в «Сервис ▾» перед «⚠ Полная очистка базы» и в
   «Администрирование ▾» между «учётками» и «системой», чтобы глаз
   сразу видел два разных подсмысла. */
.topbar__group-menu-sep {
  height: 1px;
  margin: 4px 6px;
  background: var(--border);
}

/* Подзаголовок раздела внутри выпадающего меню — мелкий приглушённый
   лейбл над группой связанных пунктов (напр. «Объединение», «Доступ»,
   «Инфраструктура»). Помогает быстро найти нужный пункт в длинном меню.
   Скрывается из JS (hideEmptyMenuHeaders), если под ним не осталось
   видимых пунктов для текущей роли — поэтому нужен явный [hidden]-сброс
   (класс задаёт display, иначе перебил бы UA-правило [hidden]). */
.topbar__group-menu-header {
  padding: 7px 10px 2px;
  font-size: var(--fs-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  pointer-events: none;
  user-select: none;
}
.topbar__group-menu-header[hidden] { display: none; }

/* Опасный пункт меню — красный шрифт + предупреждающий ховер.
   Применяется к «⚠ Полная очистка базы», чтобы оператор сразу видел,
   что это деструктивная операция (и не кликнул по инерции, листая
   длинный список). Совместим с бейджем «СА» (тот красит только ::after). */
.topbar__group-menu-danger,
.topbar__group-menu a.topbar__group-menu-danger {
  color: var(--danger, #b91c1c);
  font-weight: 600;
}
.topbar__group-menu-danger:hover,
.topbar__group-menu a.topbar__group-menu-danger:hover {
  background: var(--danger-bg); /* токен темы: red-100 в светлых, тёмный в антраците */
  color: var(--danger, #b91c1c);
}

/* Иконочная группа в верхнем меню — для «?» (Справка / О программе).
   Кнопка круглая, по размеру буквы, без gap, чтобы не претендовать на
   место полноценного пункта меню. */
.topbar__group--icon > .topbar__group-btn {
  width: 30px;
  height: 30px;
  padding: 0;
  justify-content: center;
  border-radius: 50%;
  font-size: var(--fs-lg);
  font-weight: 600;
}
/* Меню значка раскрывается справа (а не от левого края), чтобы не
   выехать за границу окна — значок стоит в правой части шапки. */
.topbar__group--icon > .topbar__group-menu {
  left: auto;
  right: 0;
}

.topbar__user {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--muted);
  font-size: var(--fs-base);
}

/* Плашка «доступна новая версия» в шапке. Появляется после того,
   как суперадмин нажал «Проверить сейчас» в настройках сервера
   обновлений. Кликабельна — ведёт в /admin/updates. См. docs/05-self-update-design.md. */
.update-banner {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 12px;
  background: #fef3c7;     /* мягкий жёлтый — не тревожный, но заметный */
  color: #78350f;
  font-size: var(--fs-sm);
  font-weight: 600;
  text-decoration: none;
  border: 1px solid #fcd34d;
  white-space: nowrap;
}
.update-banner:hover { background: #fde68a; text-decoration: none; }
/* Атрибут hidden vs display:inline-flex — без явного override плашка
   показывается даже когда js поставил hidden=true. */
.update-banner[hidden] { display: none; }

/* Overlay при self-update: затемнённый фон + центральный «спиннер +
   сообщение». Появляется на время «сервер качает новый exe и
   перезапускается»; снимается, когда страница успешно перезагрузилась. */
.update-overlay {
  position: fixed; inset: 0;
  background: rgba(15, 23, 42, 0.78);
  display: flex; align-items: center; justify-content: center;
  z-index: var(--z-overlay);
}
.update-overlay[hidden] { display: none; }
.update-overlay__box {
  background: var(--surface); /* токен темы вместо #fff — работает и в «Антраците» */
  border-radius: 8px;
  padding: 32px 40px;
  text-align: center;
  max-width: 460px;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
}
.update-overlay__spinner {
  width: 40px; height: 40px;
  border: 4px solid #e5e7eb;
  border-top-color: var(--primary);
  border-radius: 50%;
  margin: 0 auto 18px;
  animation: spin 0.9s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }
.update-overlay__msg { font-size: 15px; font-weight: 500; margin-bottom: 8px; }
.update-overlay__hint { font-size: var(--fs-sm); }

.content {
  flex: 1;
  /* Горизонтальный padding 40px — на узких окнах (≤1400px max-width не
     активен) контент не «упирается в бока» с 24px-узким зазором, а
     имеет заметные поля. На широких окнах max-width центрирует блок,
     дополнительные 40px внутри визуально не мешают, но добавляют
     дыхания между текстом и краем фона. */
  padding: 24px 40px;
  max-width: 1400px;
  width: 100%;
  margin: 0 auto;
}
.content--full {
  /* режим «карта на всю ширину» — убираем max-width и padding. */
  max-width: none;
  padding: 0;
}

.placeholder { color: var(--muted); }
.placeholder h1 { color: var(--fg); margin-top: 0; font-size: 24px; }
.placeholder h2 { color: var(--fg); margin-top: 32px; font-size: 18px; }

/* --- Section page ---
   Заголовок + кнопки действий (Сохранить / Удалить / Назад / индикатор
   автосейва) приклеены к верху страницы, чтобы оператор всегда видел
   действия даже на длинных формах (карточка участка, запись книги).
   top: 56px — это высота топбара. Полоса doc-tabs теперь живёт в
   подвале, конкуренции за верхнюю «полку» нет. */
.page__header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 20px;
  gap: 12px;
  padding: 8px 0 6px;
}
/* page__header--sticky оставляет шапку «прилепленной» под топбаром.
   Используется только на длинных формах (карточка записи с табами,
   карточка участка с большой таблицей захоронений), где оператор
   часто скроллит и важно иметь название/кнопки под рукой. Списки
   справочников НЕ помечаются sticky — оператор предпочитает, чтобы
   шапка уезжала вместе с топбаром при скролле длинного списка. */
.page__header--sticky {
  position: sticky;
  top: 56px;
  background: var(--bg);
  z-index: var(--z-sticky-head);
}
/* Legacy: .page__header--static больше ничего не делает (sticky убран
   из дефолта). Оставлен для обратной совместимости с местами, где он
   уже выставлен в HTML. */
.page__header--static { }
.page__header h1 {
  margin: 0;
  font-size: var(--fs-h1);
}
.page__header .muted {
  font-size: var(--fs-base);
}
/* Мелкая «eyebrow»-подпись над h1 — для уточнения типа документа
   (например «Запись инвентаризации» над ФИО). */
.page__eyebrow {
  font-size: var(--fs-xs);
  color: var(--muted);
  margin-bottom: 2px;
  font-weight: 600;
}

.toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  margin-bottom: 16px;
}
.toolbar .search {
  flex: 1;
  max-width: 320px;
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: var(--fs-md);
  background: var(--surface);
}

/* --- Table --- */
.table-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
}
/* Если в .table-wrap вместо таблицы лежит «пустое состояние» (текст
   «Записей нет», «Журнал появится после первой выгрузки» и т.п.) —
   таблица не задаёт padding'и, текст прилипает к рамке. Добавляем
   собственный отступ для прямых дочерних элементов-заглушек. */
.table-wrap > p,
.table-wrap > .empty-state { padding: 14px 16px; margin: 0; }

/* ============ Универсальное «пустое состояние» ============
   Используется в местах, где список пуст и нечего показать —
   таблицы, реестры, истории, журналы. Класс задаёт центрированный
   muted-текст с приличным отступом, чтобы не смотрелось как ошибка
   рендеринга. */
.empty-state {
  color: var(--muted);
  font-size: var(--fs-base);
  text-align: center;
  padding: 24px 16px;
}
.empty-state__title { font-weight: 600; color: var(--fg); margin-bottom: 4px; }

table.table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-md);
}
table.table th,
table.table td {
  text-align: left;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
table.table th {
  background: var(--surface-alt);
  color: var(--muted);
  font-weight: 600;
  font-size: var(--fs-sm);
}
table.table tr:last-child td { border-bottom: none; }
table.table .row-actions {
  text-align: right;
  white-space: nowrap;
}

/* Группировка строк в табличных справочниках с заголовками-разделителями
   (используется на /burial-types для блоков «Семейные», «Правовой
   статус», «Прочие», «Импортированные»). Заголовок — узкая полоска
   с приглушённым фоном; «Импортированные» дополнительно выделяются
   жёлтой левой полоской, чтобы отличить пользовательские данные от
   системного seed'а. */
.table--grouped .bt-group-row td {
  background: var(--surface-alt);
  padding: 8px 12px;
  font-size: var(--fs-sm);
  border-top: 2px solid var(--border);
  border-bottom: 1px solid var(--border);
}
.table--grouped .bt-group-row:first-child td { border-top: none; }
.table--grouped .bt-group-row--imported td {
  border-left: 4px solid #f59e0b;
  background: #fef3c7;
}
.bt-group-title {
  font-weight: 700;
  color: var(--fg);
  text-transform: uppercase;
  letter-spacing: 0.04em;
}
.bt-group-count {
  margin-left: 8px;
  font-size: var(--fs-xs);
  font-weight: 400;
}
table.table .row-actions button {
  padding: 4px 10px;
  font-size: var(--fs-sm);
  margin-left: 4px;
}
table.table .empty-row td {
  text-align: center;
  color: var(--muted);
  padding: 24px;
}

/* --- Color swatch --- */
.swatch {
  display: inline-block;
  width: 14px;
  height: 14px;
  border-radius: 3px;
  border: 1px solid var(--border);
  vertical-align: middle;
  margin-right: 6px;
  background: var(--swatch-fallback); /* пустой color у burial_type → нейтральный slate */
}
/* Маленький круглый swatch — для плотных списков и индикаторов в заголовках. */
.swatch--dot   { width: 10px; height: 10px; border-radius: 50%; }
.swatch--mini  { width: 8px;  height: 8px;  border-radius: 50%; margin-right: 4px; }

/* --- Modal ---
   Двухсекционный layout: «шапка» (заголовок + действия) приклеена сверху,
   «тело» формы скроллится. На длинных формах (новая запись книги, форма
   участка) кнопки «Сохранить / Отмена» остаются всегда видимыми, не
   нужно проматывать форму до низа. */
.modal-backdrop {
  position: fixed;
  inset: 0;
  background: rgba(17, 24, 39, 0.5);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 40px 16px;
  /* Должен быть выше любых Leaflet-контролов (у них z-index ~1000) и
     popup'ов (~700). Иначе на странице карты модалка скрывается за картой. */
  z-index: var(--z-modal);
  /* overflow:hidden — скролл живёт внутри .modal__body, чтобы шапка
     с кнопками действительно «приклеилась». */
  overflow: hidden;
  box-sizing: border-box;
}
.modal {
  background: var(--surface);
  width: 100%;
  max-width: 520px;
  border-radius: 12px;
  box-shadow: 0 20px 40px rgba(0,0,0,0.2);
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 80px);
  overflow: hidden; /* чтобы скруглённые углы не съедались body */
}
.modal__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 22px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
  flex-shrink: 0;
}
.modal__head h2 { margin: 0; font-size: 18px; }
.modal__body {
  padding: 16px 22px 20px;
  overflow-y: auto;
  flex: 1 1 auto;
}
.modal__actions {
  display: flex;
  justify-content: flex-end;
  gap: 8px;
  flex-shrink: 0;
}
.modal__error {
  margin-top: 12px;
  padding: 8px 12px;
  /* danger-токены темы вместо захардкоженного red-100 + red-600 —
     плашка читаема и в тёмной теме. */
  background: var(--danger-bg);
  color: var(--danger-fg);
  border-radius: 6px;
  font-size: var(--fs-base);
}
/* --- Progress bar ---
   Используется на странице резервного копирования БД: рядом с
   «⤓ Скачать архив БД» / «⤒ Загрузить архив БД» появляется полоска
   с реальным процентом (для download — через response.body.getReader(),
   для upload — через XHR.upload.onprogress).
   .progress__bar--indeterminate — бегущая «зебра» когда сервер не
   отдал Content-Length и точный процент неизвестен. */
.progress {
  width: 100%;
  max-width: 480px;
  height: 22px;
  background: #f3f4f6;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  position: relative;
}
.progress__bar {
  height: 100%;
  background: var(--primary, #2563eb);
  width: 0%;
  transition: width 200ms ease-out;
}
.progress__bar--indeterminate {
  background-image: linear-gradient(
    45deg,
    rgba(255, 255, 255, 0.25) 25%,
    transparent 25%,
    transparent 50%,
    rgba(255, 255, 255, 0.25) 50%,
    rgba(255, 255, 255, 0.25) 75%,
    transparent 75%,
    transparent
  );
  background-size: 24px 24px;
  animation: progress-stripes 800ms linear infinite;
}
@keyframes progress-stripes {
  from { background-position: 0 0; }
  to   { background-position: 24px 0; }
}
.progress__text {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-sm);
  color: #1f2937;
  pointer-events: none;
  text-shadow: 0 0 4px rgba(255, 255, 255, 0.6);
}
/* Блок одноразового показа сгенерированного пароля. user-select:all
   делает выделение по одному клику — легче скопировать. */
.password-display {
  padding: 12px;
  background: #f3f4f6;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: ui-monospace, "SFMono-Regular", Consolas, "Liberation Mono", monospace;
  font-size: 15px;
  word-break: break-all;
  user-select: all;
  margin-top: 8px;
}

/* --- Forms ---
   Базовые стили полей ввода одинаковые на всех страницах.
   Класс .form-input — для одиночных инпутов без обёртки .field
   (например, быстрый поиск в тулбарах). */
.field {
  display: flex;
  flex-direction: column;
  gap: 4px;
  margin-bottom: 12px;
}
.field > span {
  font-size: var(--fs-sm);
  color: var(--muted);
}
.field input[type="text"],
.field input[type="number"],
.field input[type="date"],
.field input[type="time"],
.field input[type="datetime-local"],
.field input[type="search"],
.field input[type="email"],
.field input[type="tel"],
.field input[type="url"],
.field input[type="password"],
.field select,
.field textarea,
.form-input {
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: var(--fs-md);
  background: var(--input-bg);
  color: var(--fg);
  font-family: inherit;
  line-height: 1.3;
  min-height: var(--btn-h-md); /* поля и кнопки одной высоты в общем ряду */
  box-sizing: border-box;
}
.field input:focus,
.field select:focus,
.field textarea:focus,
.form-input:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.field input:disabled,
.field select:disabled,
.field textarea:disabled,
.form-input:disabled {
  background: var(--surface-alt); /* токен вместо #f3f4f6 — работает в тёмной теме */
  color: var(--muted);
  cursor: not-allowed;
}
.field textarea { min-height: 70px; resize: vertical; }
.field.row {
  flex-direction: row;
  align-items: center;
  gap: 10px;
}
.field.row input[type="color"] {
  width: 40px;
  height: 32px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: 6px;
  cursor: pointer;
}
.field-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
}
.field-grid .field { margin-bottom: 0; }
/* Тройной grid — для строк «Кладбище / Квартал / Ряд» и
   «Длина / Ширина / Площадь» в форме участка. */
.field-grid--3 { grid-template-columns: repeat(3, 1fr); }

/* Строка фильтров над таблицей справочников (например /plots:
   селектор кладбища + селектор квартала). align-items: end —
   подписи и сами поля выравниваются по нижнему краю в одну линию,
   независимо от длины подписи. !important нужен потому что
   renderCemeteryFilter ставит inline-style margin-bottom для
   обратной совместимости со страницами без .filter-row. */
.filter-row {
  display: flex;
  gap: 16px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 12px;
}
.filter-row .field,
.filter-row label.field.row { margin-bottom: 0 !important; }
.filter-row .field.row > span { font-size: var(--fs-md); color: var(--fg); }
.filter-row > * { flex-shrink: 0; }

/* Кликабельные заголовки таблиц со стрелками сортировки. */
.table th.sortable:hover { background: var(--surface-alt); }
.table th.sortable--active { color: var(--primary); }
.table .sort-arrow { font-size: var(--fs-xs); }
.table .sort-arrow--idle { opacity: 0.35; }

/* Иконка компаса для кнопок «Показать на карте». Цвет берётся из
   --primary через mask-image — кнопка перекрашивается синхронно с
   темой. Раньше использовался эмодзи 📍 (всегда чёрный, мелкий и
   разный шрифт под Win/macOS) — на скриншоте выглядел инородно. */
.icon-compass {
  display: inline-block;
  width: 16px;
  height: 16px;
  vertical-align: -3px;
  margin-right: 2px;
  background-color: var(--primary);
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1.5-13.5L7 14.5l8-3.5 3.5-8-8 3.5z'/%3E%3C/svg%3E") no-repeat center / contain;
          mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm-1.5-13.5L7 14.5l8-3.5 3.5-8-8 3.5z'/%3E%3C/svg%3E") no-repeat center / contain;
}

/* --- Catalog hub (карточки) --- */
.catalog-cards {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: 12px;
  margin-top: 8px;
}
.catalog-card {
  display: block;
  padding: 16px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: var(--shadow);
  text-decoration: none;
  color: var(--fg);
  transition: transform .08s ease, border-color .08s ease;
}
.catalog-card:hover {
  transform: translateY(-1px);
  border-color: var(--primary);
  text-decoration: none;
}
.catalog-card__title {
  font-weight: 600;
  font-size: 15px;
  margin-bottom: 4px;
}
.catalog-card__hint {
  font-size: var(--fs-sm);
  color: var(--muted);
}

/* Группы справочников — визуальное разделение по смысловой категории.
   Заголовок группы — приглушённый, цветовая полоса слева у каждой
   карточки даёт понять «это одна семья». */
.catalog-group {
  margin-top: 18px;
}
.catalog-group:first-of-type {
  margin-top: 8px;
}
.catalog-group__title {
  font-size: var(--fs-sm);
  text-transform: uppercase;
  letter-spacing: 0.6px;
  color: var(--muted);
  font-weight: 600;
  margin: 0 0 8px;
}
.catalog-card--objects { border-left: 4px solid #ef4444; }   /* red-500 */
.catalog-card--burials { border-left: 4px solid #3b82f6; }   /* blue-500 */
.catalog-card--parties { border-left: 4px solid #10b981; }   /* emerald-500 */
.catalog-card--admin   { border-left: 4px solid #94a3b8; }   /* slate-400 */

/* --- Карта --- */
.map-page {
  display: flex;
  flex-direction: column;
  height: calc(100vh - 56px); /* topbar = 56px */
  /* padding родителя уже снят классом content--full, свой margin не нужен. */
}
.map-page__toolbar {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 10px 16px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  flex-shrink: 0;
  flex-wrap: wrap;
  /* Тулбар карты приклеен к верху страницы, прямо под топбаром.
     Полоса doc-tabs на странице карты сдвигается ниже тулбара через
     переменную --doc-tabs-top, которую выставляет renderMapPage по
     фактической высоте тулбара.
     Z-index 1100: выше всех leaflet-слоёв (panes 200–700) и контролов
     (zoom/attribution на 800–1000), чтобы дропдаун «+ Добавить участок»
     не проваливался под карту — position:sticky+z-index создаёт
     собственный stacking context, и дропдаун внутри него (z-index 1500)
     теперь корректно перекрывает leaflet. */
  position: sticky;
  top: 56px;
  z-index: var(--z-map-toolbar);
}
.map-page__toolbar .search { max-width: 320px; }
.map-page__toolbar .muted { font-size: var(--fs-sm); }

/* Единая высота и шрифт всех кнопок, селектов и поисковых полей в
   тулбаре карты. Без этого «Кладбище: [Пермь]» (.field select 36px /
   14px) был выше и крупнее, чем остальные кнопки и поле поиска
   (~30px / 13px), а между собой кнопки и инпут поиска тоже немного
   расходились. Фиксируем всё на 32px / 13px (значения — из общих шкал
   --btn-h-* и --fs-*, см. :root). */
.map-page__toolbar {
  --toolbar-control-h: var(--btn-h-sm);
  --toolbar-control-fz: var(--fs-base);
}
.map-page__toolbar .field.row > span {
  font-size: var(--toolbar-control-fz);
  color: var(--fg);
}
.map-page__toolbar .field input,
.map-page__toolbar .field select,
.map-page__toolbar .map-search input[type="search"],
.map-page__toolbar .map-tools .btn,
.map-page__toolbar .btn {
  height: var(--toolbar-control-h);
  min-height: var(--toolbar-control-h);
  font-size: var(--toolbar-control-fz);
  line-height: 1.2;
  padding: 0 10px;
  box-sizing: border-box;
}
.map-page__toolbar .map-tools__group {
  height: var(--toolbar-control-h);
  padding: 0 4px;
  box-sizing: border-box;
}
.map-page__toolbar .map-tools__group .btn {
  height: calc(var(--toolbar-control-h) - 4px);
  min-height: calc(var(--toolbar-control-h) - 4px);
}

/* Блок «Схема / Спутник» прижимается к правому краю тулбара (а тулбар
   растянут на всю ширину окна — значит к правому краю экрана). Делается
   flex-логикой: .map-tools растягивается на оставшееся место, basemap-
   группа получает order:99 (становится последней в визуальном порядке)
   и margin-left:auto (выталкивается вправо). Остальные кнопки нормал-
   режима (Править/Сдвиг/Поворот, ⚙ Инфраструктура) остаются слева
   рядом с «+ Добавить участок». Разделители в нормал-режиме после
   этой перестановки оказываются между несвязанными группами и теряют
   смысл — прячем. Для infra-режима поведение не меняется. */
.map-page__toolbar .map-tools[data-mode-view="normal"] {
  flex: 1 1 auto;
}
.map-page__toolbar .map-tools[data-mode-view="normal"] .map-tools__measure {
  order: 97;
  margin-left: auto;
}
.map-page__toolbar .map-tools[data-mode-view="normal"] .map-tools__layers {
  order: 98;
}
.map-page__toolbar .map-tools[data-mode-view="normal"] .map-tools__basemap {
  order: 99;
}
.map-page__toolbar .map-tools[data-mode-view="normal"] .map-tools__sep {
  display: none;
}
/* Меню «Слои ▾» и «Инструменты ▾» прижаты к правому краю кнопки
   (а не к левому, как у plot/infra-dropdown), чтобы не вылезали
   за правый край экрана. */
#layers-menu, #measure-menu {
  left: auto;
  right: 0;
  min-width: 220px;
}
.map-layers__item {
  cursor: pointer;
  user-select: none;
}
.map-layers__item input[type="checkbox"] {
  margin: 0;
  cursor: pointer;
}

/* Tooltip итога замера (Линейка / Планимер). По умолчанию Leaflet-tooltip
   полупрозрачный с белым фоном — поверх спутника плохо читается. Ставим
   явно тёмный фон + белый шрифт с тенью. */
.leaflet-tooltip.measure-tooltip {
  background: rgba(17, 24, 39, 0.92);
  color: #fff;
  border: none;
  border-radius: 4px;
  padding: 4px 8px;
  font-weight: 600;
  font-size: var(--fs-base);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}
.leaflet-tooltip.measure-tooltip::before { display: none; }

/* --- Собственный рендер карты (map-osiris.js, реестровая сборка) ---
   Правила-эквиваленты для .osiris-* классов рендера. В ПОЛНОЙ сборке эти
   классы в DOM не появляются (там Leaflet), поэтому блок инертен и поведение
   полной сборки не меняется. Держим рядом с leaflet-правилами, чтобы при
   правке одного не забыть второе. */
.osiris-map { background: inherit; }
.osiris-map__canvas { display: block; }
.osiris-tooltip.measure-tooltip {
  background: rgba(17, 24, 39, 0.92);
  color: #fff;
  border: none;
  border-radius: 4px;
  padding: 4px 8px;
  font-weight: 600;
  font-size: var(--fs-base);
  box-shadow: 0 1px 4px rgba(0, 0, 0, 0.3);
}
/* Пейн инфра-маркеров: по умолчанию скрыт, показывается на глубоком зуме и
   при редактировании — как .leaflet-osirisInfraMarker-pane ниже. */
.osiris-pane-osirisInfraMarker { display: none; }
.osiris-deep-zoom .osiris-pane-osirisInfraMarker,
.osiris-editing .osiris-pane-osirisInfraMarker { display: block; }
/* Курсоры инструментов «Сдвиг»/«Поворот» — эквивалент .leaflet-grab/-interactive. */
.osiris-cursor-move .osiris-map__canvas { cursor: move !important; }
.osiris-cursor-rotate .osiris-map__canvas { cursor: crosshair !important; }

/* Подпись кладбища в режиме «Все кладбища» — кликабельная.
   Лежит как divIcon-маркер, поэтому по дефолту имеет фиксированные
   размеры от leaflet — сбрасываем, чтобы натянулось по контенту. */
.cem-label-marker {
  background: transparent !important;
  border: none !important;
  width: auto !important;
  height: auto !important;
  pointer-events: auto;
}
.cem-label-marker .cem-label {
  display: inline-block;
  padding: 4px 10px;
  background: rgba(255, 255, 255, 0.92);
  color: #1e3a8a;
  font-weight: 600;
  font-size: var(--fs-base);
  border: 1px solid #1e40af;
  border-radius: 4px;
  white-space: nowrap;
  cursor: pointer;
  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.15);
  transform: translate(-50%, -50%);
  transition: background-color 120ms ease, color 120ms ease;
}
.cem-label-marker .cem-label:hover {
  background: #1e40af;
  color: white;
}

.map-tools {
  display: flex;
  gap: 6px;
  flex-wrap: wrap;
  align-items: center;
}
/* .map-tools — flex-контейнер, поэтому атрибут [hidden] (display:none)
   должен перекрывать display:flex. */
.map-tools[hidden] { display: none; }
.map-tools .btn { padding: 6px 10px; font-size: var(--fs-base); }


/* Группа кнопок «Править / Сдвиг / Поворот» — визуально объединена в
   единый блок с лёгкой подложкой и тонкой границей, чтобы было видно,
   что эти три кнопки связаны (работают с выделенным участком). */
.map-tools__group {
  display: flex;
  gap: 4px;
  align-items: center;
  padding: 2px 4px;
  background: var(--btn-bg);
  border: 1px solid var(--border);
  border-radius: 6px;
}
/* Внутри группы делаем «бесшовные» кнопки (transparent) — НО только для
   обычных, не primary. Если случайно положить primary внутрь группы,
   правило background:transparent лишило бы её акцентной заливки
   (а текст у primary — контрастный к заливке --primary-fg, не к фону). */
.map-tools__group .btn:not(.btn--primary) {
  border: none;
  background: transparent;
}
.map-tools__group .btn:not(.btn--primary):hover:not(:disabled) {
  background: var(--btn-bg-hover);
}

/* Разделитель перед «Инфраструктура» — чтобы кнопка визуально
   отделялась от группы инструментов работы с участком. */
.map-tools__sep {
  width: 1px;
  align-self: stretch;
  background: var(--border);
  margin: 0 8px;
}

/* Переключатель подложки (Схема / Спутник). Активная кнопка
   подсвечивается, но БЕЗ ярко-синей заливки + белого текста
   (тяжело читается над спутниковыми тайлами и не нужен такой
   акцент): мягкая голубая подложка, тёмный текст полужирным. */
.map-tools__basemap .btn.btn--primary {
  background: var(--btn-bg-hover);
  border-color: var(--primary);
  color: var(--fg);
  font-weight: 700;
  box-shadow: inset 0 -2px 0 var(--primary);
}
.map-tools__basemap .btn.btn--primary:hover {
  background: #b6c8de;
  border-color: var(--primary);
  color: var(--fg);
}

/* --- Dropdown «+ Инфраструктура» (меню типов с иконками) --- */
.map-dropdown {
  position: relative;
  display: inline-block;
}
.map-dropdown__menu {
  position: absolute;
  top: 100%;
  left: 0;
  margin-top: 4px;
  min-width: 260px;
  max-height: 420px;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.12);
  padding: 6px 0;
  z-index: var(--z-dropdown); /* ниже модалок, но выше карты и её контролов */
  font-size: var(--fs-base);
}
/* Выбор маркера и меню «Слои» — без вертикальной прокрутки: показываем
   сразу все пункты (по запросу пользователя 2026-05-21). У остальных
   выпадашек ограничение высоты остаётся (например, длинный список видов
   захоронений в подменю «+ Участок»). */
#infra-menu,
#layers-menu {
  max-height: none;
  overflow-y: visible;
}
.map-dropdown__group {
  padding: 6px 12px 2px;
  font-size: var(--fs-xs);
  color: var(--muted);
  font-weight: 600;
}
.map-dropdown__item {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 12px;
  color: var(--fg);
  text-decoration: none;
}
.map-dropdown__item:hover { background: var(--bg-soft); text-decoration: none; }
.map-dropdown__item img { width: 18px; height: 18px; }
/* Контейнер под карту и боковую панель справа (информация об участке). */
.map-layout {
  display: flex;
  flex: 1;
  min-height: 0;
}
#map {
  flex: 1;
  min-height: 0;
  background: #e5e7eb;
}

/* Плашки-подсказки при рисовании на карте.
   Контейнер абсолютно спозиционирован внутри #map (Leaflet ставит
   контейнеру position:relative), прижат к верхней кромке карты по
   горизонтальному центру. Карта начинается сразу под тулбаром, поэтому
   top:10px — это и есть «10px ниже тулбара». Несколько плашек идут
   стопкой сверху вниз. pointer-events:none — плашки не перехватывают
   клики по карте во время рисования. */
/* Контейнер уведомлений карты: подсказки рисования + тосты («Сохранено»,
   «Изменено N объектов» и т.п.) — все в ЛЕВОМ ВЕРХНЕМ углу карты, стопкой
   сверху вниз (по запросу пользователя 2026-05-21). Сюда же toast()
   складывает свои плашки, пока открыта страница карты. pointer-events
   контейнера — none; .toast--prominent (с кнопкой Undo) сам включает клики. */
.map-notify {
  position: absolute;
  top: 10px;
  left: 10px;
  z-index: var(--z-toast); /* тот же слой, что глобальные тосты */
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
  pointer-events: none;
  max-width: min(440px, calc(100% - 20px));
}
/* Плашка-подсказка рисования — в стиле тоста (.toast). Через 5с JS вешает
   .is-fading, и она плавно гаснет (тосты при этом не трогаем). */
.map-draw-hint {
  background: var(--surface);
  color: var(--fg);
  border: 1px solid var(--border);
  font-size: var(--fs-md);
  font-weight: 500;
  line-height: 1.4;
  padding: 12px 22px;
  border-radius: 10px;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
  text-align: left;
  max-width: 100%;
  transition: opacity 0.4s ease;
}
.map-draw-hint.is-fading { opacity: 0; }

.map-layout__side {
  width: 360px;
  flex-shrink: 0;
  background: var(--surface);
  border-left: 1px solid var(--border);
  overflow-y: auto;
  font-size: var(--fs-base);
}
/* Свёрнутое состояние правой панели — остаётся узкая полоска с кнопкой-
   шевроном (.map-side-toggle); выделение участка при этом НЕ сбрасывается.
   Классы под JS-фазу (сворачивание добавят позже). */
.map-layout__side.is-collapsed {
  width: 28px;
  min-width: 28px;
  overflow: hidden;
}
/* Узкая вертикальная кнопка-шеврон между картой и панелью (на всю высоту
   ряда .map-layout): сворачивает/разворачивает панель, выделение участка
   НЕ сбрасывается (в отличие от «×» внутри панели). */
.map-side-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  min-width: 16px;
  align-self: stretch;
  padding: 0;
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-top: none;
  border-bottom: none;
  color: var(--muted);
  font-size: var(--fs-sm);
  cursor: pointer;
}
.map-side-toggle:hover { background: var(--btn-bg); color: var(--fg); }
/* Свёрнутая панель прячется целиком — полоска-шеврон остаётся. */
.map-layout__side.is-collapsed { display: none; }
.map-side__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-alt);
  position: sticky;
  top: 0;
  z-index: 1;
}
.map-side__head h3 { margin: 0; font-size: 15px; }
.map-side__head-actions {
  display: flex;
  gap: 4px;
  align-items: center;
}
.map-side__section {
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
.map-side__section:last-of-type { border-bottom: none; }
/* Строка реквизитов участка: «Квартал · Ряд · Участок» и
   «Габариты · Площадь» стоят в одну строку. На узкой панели последние
   элементы переносятся, а не вылезают за край. */
.map-side__params-row {
  display: flex;
  flex-wrap: wrap;
  gap: 4px 16px;
}
.map-side__label {
  font-size: var(--fs-xs);
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 6px;
}
/* Главная CTA «+ Добавить захоронение» сразу под шапкой — наиболее частое
   действие оператора на этом экране. */
.map-side__actions {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: 10px 12px;
  border-bottom: 1px solid var(--border);
}
/* Опасные действия (Удалить участок) — отдельным блоком в самом низу,
   на всю ширину колонки боковой панели, в той же геометрии, что главная
   CTA «+ Добавить захоронение». Цвет — приглушённый красный
   (.btn--danger-solid), чтобы кнопка читалась как «зеркальная»
   деструктивная CTA. */
.map-side__danger {
  padding: 10px 12px 14px;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Список «людей на участке» в боковой панели карты: клик выделяет,
   двойной клик — открывает карточку. */
.map-side__people {
  display: flex;
  flex-direction: column;
  gap: 2px;
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
}
.map-side__person {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 8px;
  align-items: center;
  padding: 6px 8px;
  cursor: pointer;
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-base);
  background: var(--surface); /* токен вместо #fff — тёмная тема */
  user-select: none;
}
.map-side__person:last-child { border-bottom: none; }
.map-side__person:hover { background: var(--bg-soft); }
.map-side__person.is-selected { background: var(--primary-soft); }
.map-side__person:focus { outline: 2px solid var(--primary); outline-offset: -2px; }
.map-side__person-fio { font-weight: 500; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.map-side__person-dates { font-size: var(--fs-xs); white-space: nowrap; }

/* Поиск ФИО в тулбаре карты: относительный контейнер + выпадашка под инпутом. */
.map-search {
  position: relative;
  flex: 1;
  max-width: 340px;
  min-width: 220px;
}
.map-search input[type="search"] {
  width: 100%;
  padding: 6px 10px;
  font-size: var(--fs-base);
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--input-bg);
  color: var(--fg);
}
.map-search__results {
  position: absolute;
  left: 0;
  /* Окно шире инпута, чтобы спокойно помещалось «Фамилия Имя Отчество»
     с локацией и датами. Минимум — ширина инпута, максимум — 480px. */
  min-width: 100%;
  width: 480px;
  max-width: 90vw;
  top: calc(100% + 4px);
  max-height: 70vh;
  overflow-y: auto;
  background: var(--surface); /* токен вместо #fff — тёмная тема */
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 8px 28px rgba(0, 0, 0, 0.18);
  z-index: var(--z-search);
  /* Лёгкая анимация появления — глаз понимает «окно открылось». */
  animation: map-search-open 120ms ease-out;
}
@keyframes map-search-open {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: translateY(0); }
}
.map-search__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 8px 12px;
  background: var(--surface);
  border-bottom: 1px solid var(--border);
  font-size: var(--fs-sm);
  font-weight: 600;
  color: var(--muted);
  border-radius: 8px 8px 0 0;
  position: sticky;
  top: 0;
  z-index: 1;
}
.map-search__close {
  background: transparent;
  border: none;
  color: var(--muted);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
  border-radius: 4px;
}
.map-search__close:hover { background: var(--btn-bg-hover); color: var(--fg); }
.map-search__row {
  padding: 8px 12px;
  cursor: pointer;
  border-bottom: 1px solid #f1f5f9;
}
.map-search__row:last-child { border-bottom: none; }
.map-search__row:hover { background: var(--primary-soft); }
/* Строка, выбранная стрелками с клавиатуры (fioResultsMove в app.js). */
.map-search__row.is-selected { background: var(--primary-soft); outline: 2px solid var(--primary); outline-offset: -2px; }
.map-search__row--noplot { opacity: 0.65; cursor: not-allowed; }
.map-search__row--noplot:hover { background: transparent; }
.map-search__fio { font-weight: 500; font-size: var(--fs-md); color: var(--fg); }
.map-search__meta { font-size: var(--fs-sm); color: var(--muted); margin-top: 2px; }
.map-search__empty { padding: 16px; color: var(--muted); font-size: var(--fs-base); text-align: center; }

/* Модалка результатов поиска ФИО (открывается по Enter из поля поиска
   на карте). Использует общий .modal-backdrop / .modal / .modal--wide,
   только содержимое — список без формы. */
.fio-modal__list {
  max-height: 60vh;
  overflow-y: auto;
}
.fio-modal__list .map-search__row {
  padding: 10px 22px;
}

/* Единое окно результатов поиска ФИО на карте (живое — обновляется по
   мере ввода). Объединяет прежние дропдаун + модалку: теперь одна выдача
   (по просьбе пользователя 2026-05-26). Без затемняющего backdrop, чтобы
   поле поиска в тулбаре оставалось доступным и можно было продолжать
   печатать; контейнер pointer-events:none, кликабельна только панель. */
.fio-results {
  position: fixed;
  top: 112px;            /* под топбаром (56) и тулбаром карты (~52) */
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-fio); /* выше тулбара и тостов, ниже модалок — см. карту --z-* */
  width: min(900px, 94vw);
  pointer-events: none;
}
.fio-results__panel {
  pointer-events: auto;
  display: flex;
  flex-direction: column;
  max-height: calc(100vh - 140px);
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 10px;
  box-shadow: 0 12px 36px rgba(0, 0, 0, 0.22);
  overflow: hidden;
  animation: map-search-open 120ms ease-out;
}
.fio-results__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 12px 16px;
  border-bottom: 1px solid var(--border);
  background: var(--surface);
}
.fio-results__head h2 { margin: 0; font-size: var(--fs-lg); }
.fio-results__count { color: var(--muted); font-size: var(--fs-base); white-space: nowrap; }
.fio-results__list { overflow-y: auto; }

/* Маркер активного режима «Инфраструктура» — небольшая текстовая метка
   слева в тулбаре. Стилистически в той же сине-голубой палитре, что и
   остальной интерфейс (ранее был оранжевым и выпадал из общего тона). */
.map-mode-tag {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: var(--fs-sm);
  font-weight: 600;
  letter-spacing: 0.01em;
  background: var(--primary-soft);
  color: var(--primary-hover);
  border: 1px solid color-mix(in srgb, var(--primary) 35%, transparent);
  white-space: nowrap;
}
.map-mode-tag::before {
  content: "";
  display: inline-block;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--primary);
  /* Лёгкая пульсация — глазу легко поймать «режим включён», но не назойливо. */
  animation: map-mode-pulse 1.6s ease-in-out infinite;
}
@keyframes map-mode-pulse {
  0%,   100% { opacity: 1;   transform: scale(1);   }
  50%        { opacity: 0.4; transform: scale(0.7); }
}

/* Тулбар инфра-режима. Ранее имел отдельный оранжевый фон — теперь
   общий стиль с тонкой синей подсветкой слева, чтобы оператор
   глазом понимал, что «режим работы изменён», но без диссонанса
   с остальной синей палитрой. */
.map-tools--infra {
  padding: 2px 8px 2px 10px;
  border-radius: 6px;
  background: linear-gradient(
    to right,
    var(--primary-soft) 0,
    var(--primary-soft) 3px,
    transparent 3px
  );
}

#map .leaflet-popup-content {
  font-size: var(--fs-base);
  line-height: 1.4;
}
/* ── Несгорающий бейдж активного режима рисования ──
   Пилюля у верхней кромки карты по центру («Рисование: участок ·
   Enter — завершить»). В отличие от .map-draw-hint не гаснет, пока
   режим включён. Рисуется JS'ом (фаза позже). */
.draw-status-badge {
  position: absolute;
  top: 8px;
  left: 50%;
  transform: translateX(-50%);
  z-index: var(--z-map-toolbar);
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 6px 14px;
  border-radius: 999px;
  background: var(--surface);
  color: var(--fg);
  border: 1px solid var(--border);
  box-shadow: 0 4px 16px rgba(0, 0, 0, 0.18);
  font-size: var(--fs-base);
  font-weight: 600;
  white-space: nowrap;
  pointer-events: none; /* не перехватывает клики по карте во время рисования */
}
.map-offline-banner {
  padding: 6px 12px;
  background: #fef3c7;
  color: #92400e;
  font-size: var(--fs-sm);
  border-bottom: 1px solid var(--border);
}
/* POI-маркер на карте (L.divIcon), чтобы управлять центрированием и рамкой */
.poi-marker {
  background: #fff;
  border: 2px solid #2563eb;
  border-radius: 50%;
  width: 28px;
  height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  box-shadow: 0 1px 2px rgba(0,0,0,0.15);
}
.poi-marker img { width: 20px; height: 20px; }

/* Маркер инфры, отмеченный на удаление в режиме «🗑 Удалять».
   Красная рамка + полупрозрачный заливочный круг + лёгкое
   красное «свечение» вокруг — оператору видно, что он отметил. */
.poi-marker--marked-deletion {
  border-color: var(--danger) !important;
  background: rgba(220, 38, 38, 0.15) !important;
  box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.35) !important;
}

/* Курсоры карты в режимах сдвига / поворота выделенного участка
   (кнопки «↔ Сдвиг» и «↻ Поворот»). Меняем cursor у leaflet-контейнера
   и его внутренних слоёв, иначе leaflet перекрывает курсором по умолчанию. */
.osiris-cursor-move,
.osiris-cursor-move .leaflet-grab,
.osiris-cursor-move .leaflet-interactive {
  cursor: move !important;
}
.osiris-cursor-rotate,
.osiris-cursor-rotate .leaflet-grab,
.osiris-cursor-rotate .leaflet-interactive {
  cursor: crosshair !important;
}

/* --- Spinner (для openWaitModal и т.п.) --- */
.spinner {
  width: 32px;
  height: 32px;
  border: 3px solid var(--border);
  border-top-color: var(--primary);
  border-radius: 50%;
  animation: spinner-rot 0.8s linear infinite;
}
@keyframes spinner-rot { to { transform: rotate(360deg); } }

/* --- Toast (v0.73.0) ---
   Все тосты по центру экрана, в стиле текущей темы оформления.
   До v0.73 уведомления висели в правом нижнем углу на чёрном фоне —
   оператор их часто пропускал, особенно в полноэкранном режиме карты.
   Теперь: центр верха страницы (под топбаром), фон/цвета из CSS-переменных
   темы. Несколько тостов выстраиваются один под другим вертикально
   с зазором 8px через flex-контейнер `#toast-stack`. */
#toast-stack {
  position: fixed;
  /* Снизу по центру: верхний край стека ~на 3/4 высоты окна, горизонтально по
     центру; тосты растут вниз (запрос оператора 2026-06-04). Единое место для
     всех тостов программы. */
  top: 75%;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  /* Z-index 1750 (по запросу пользователя 2026-05-19): выше топбара
     (1200), map-toolbar (1100), Leaflet pane'ов (~600), map-dropdown
     (1500), но НИЖЕ модалок (2000) — чтобы при показе модалки тост не
     закрывал её содержимое. */
  z-index: var(--z-toast);
  pointer-events: none;  /* контейнер не ловит клики; сами тосты — по необходимости */
  max-width: min(640px, 90vw);
}
.toast {
  position: relative;   /* в стеке — обычный flex-item */
  padding: 12px 22px;
  border-radius: 10px;
  /* Светлый стиль в духе топбара (по запросу пользователя 2026-05-19):
     фон --surface, текст --fg, граница --border. Это автоматически
     работает для каждой темы — переменные определены в .theme-light /
     .theme-dark / .theme-malachite / .theme-sand / .theme-cherry.
     !important — чтобы перекрыть возможные конфликты при унаследованных
     style. */
  background-color: var(--surface) !important;
  background-image: none !important;
  color: var(--fg) !important;
  border: 1px solid var(--border) !important;
  font-size: var(--fs-md);
  font-weight: 500;
  line-height: 1.4;
  max-width: 100%;
  text-align: center;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.18);
  opacity: 1 !important;
  transform: translateY(0);
  pointer-events: none;
}
/* Класс .show нужен для обратной совместимости (был использован для
   анимации появления). Сейчас тосты непрозрачные с момента вставки в
   DOM, .show просто не меняет вид. */
.toast.show {
  opacity: 1;
}
.toast.toast--error {
  background: var(--danger, #b91c1c);
  border-color: var(--danger, #b91c1c);
  color: #fff;
}
/* Prominent (с кнопкой Undo) использует тот же светлый стиль темы,
   но крупнее (см. .toast--prominent правила ниже). */

/* toast--near-cursor — устаревший вариант (v0.73 → центр). Опция
   остаётся в JS для обратной совместимости, но CSS-класс больше
   ничего особого не добавляет: тост всё равно показывается в центре
   по умолчанию. Удалить класс из API можно отдельным рефактором. */
.toast--near-cursor {
  /* no overrides — same as default */
}

/* Тост-уведомление с кнопкой действия (Undo) — КРУПНЕЕ обычного и в
   стеке #toast-stack (см. .toast). Кнопка «Отменить» подсвечена primary —
   оператор должен сразу её заметить.
   v0.73.0: фон в стиле темы (--surface), не выпадает визуально. */
.toast--prominent {
  padding: 14px 18px 14px 22px;
  border-radius: 12px;
  font-size: 17px;
  font-weight: 600;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18), 0 2px 6px rgba(0, 0, 0, 0.10);
  display: inline-flex;
  align-items: center;
  gap: 14px;
  pointer-events: auto;     /* prominent с кнопкой — нужны клики */
}
.toast--prominent.show {
  transform: translateY(0);
}
.toast--prominent .toast__text {
  letter-spacing: 0.2px;
}
/* Кнопка «Отменить» — крупная, красная (danger-цвет темы), легко заметить
   (запрос оператора 2026-06-04: кнопка отмены должна быть в красноватом цвете). */
.toast--prominent .toast__action {
  background: var(--danger, #b91c1c);
  border: none;
  color: #fff;
  padding: 8px 16px;
  border-radius: 8px;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  box-shadow: 0 1px 2px rgba(0, 0, 0, 0.18);
}
.toast--prominent .toast__action:hover {
  background: #9b1818;
}
.toast--prominent .toast__action:focus-visible {
  outline: 2px solid var(--danger, #b91c1c);
  outline-offset: 2px;
}

/* Тост с действием в обычном (не prominent) виде — оставляем мелкий
   inline-стиль для редких случаев, когда явно не нужно центрирование. */
/* ВАЖНО: только для НЕ-prominent тостов. У .toast--prominent кнопка
   оформляется правилом выше (синий фон, тёмный текст). Раньше селектор
   был просто «.toast .toast__action» — та же специфичность, что и у
   prominent-правила, но идёт ПОЗЖЕ, поэтому перебивал его: кнопка
   «Отменить» получала белый текст на светлом фоне (--surface с v0.73.0)
   и была невидимой (жалоба оператора 2026-05-27). :not(...) снимает
   наложение, prominent-кнопка снова контрастная. */
.toast:not(.toast--prominent) .toast__action {
  margin-left: 12px;
  background: var(--danger, #b91c1c);
  border: none;
  color: #fff;
  padding: 4px 10px;
  border-radius: 6px;
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
}
.toast:not(.toast--prominent) .toast__action:hover { background: #9b1818; }

/* ============ Command palette (Ctrl+K) ============ */
/* z-index должен быть выше Leaflet-контролов (.leaflet-control = 1000),
   sticky-тулбара журнала (1100), топбара ОСИРИС (1200), open-add dropdown
   (1500), модалок (2000) и update-overlay (99999) — иначе при открытии
   на странице карты палитра окажется ПОД маркер-/control-панелями
   Leaflet. Ставим заведомо больше всех, кроме update-overlay (он редкий
   и должен оставаться поверх палитры).
   Цвета — все через CSS-переменные текущей темы (sapphire / anthracite
   / malachite / ochre / garnet), чтобы палитра не выбивалась из
   общего стиля программы. */
.cmd-palette {
  position: fixed;
  inset: 0;
  z-index: var(--z-palette);
  display: flex;
  align-items: flex-start;
  justify-content: center;
  padding-top: 12vh;
}
.cmd-palette__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(0, 0, 0, 0.4);
  backdrop-filter: blur(2px);
}
.cmd-palette__panel {
  position: relative;
  /* Ширина увеличена в v0.69-dev: на узком списке (680 px) каждая
     команда занимала две строки (title + hint), вертикальной
     прокрутки было слишком много. Теперь панель ~960 px, item —
     одна строка с двухколоночной раскладкой (title слева, hint
     справа), команд на экран помещается заметно больше. */
  width: min(960px, 96vw);
  max-height: 75vh;
  background: var(--surface);
  color: var(--fg);
  border-radius: 12px;
  box-shadow: var(--shadow), 0 24px 64px rgba(0, 0, 0, 0.32);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  border: 1px solid var(--border);
}
.cmd-palette__input {
  width: 100%;
  border: none;
  outline: none;
  background: transparent;
  color: var(--fg);
  font-size: var(--fs-lg);
  padding: 14px 18px;
  border-bottom: 1px solid var(--border);
}
.cmd-palette__input::placeholder { color: var(--muted); }
.cmd-palette__list {
  overflow-y: auto;
  flex: 1;
  background: var(--surface);
}
/*
  С v0.69-dev — элементы палитры в две колонки: название слева,
  описание справа. Цель — уместить больше команд по высоте, чтобы
  оператор мог увидеть весь список без вертикальной прокрутки.
  На узких экранах (<= 640px) возвращаемся к вертикальной раскладке,
  иначе подсказка не помещается рядом с длинным названием.
*/
.cmd-palette__item {
  padding: 10px 18px;
  cursor: pointer;
  border-bottom: 1px solid var(--border-soft, var(--border));
  display: flex;
  align-items: baseline;
  gap: 16px;
}
.cmd-palette__item:last-child { border-bottom: none; }
.cmd-palette__item:hover { background: var(--surface-alt); }
.cmd-palette__item--active {
  background: var(--primary-soft);
  border-left: 3px solid var(--primary);
  padding-left: 15px;       /* компенсируем 3 px бордера */
}
.cmd-palette__item-title {
  font-size: var(--fs-md);
  font-weight: 500;
  color: var(--fg);
  flex: 0 0 300px;
  min-width: 0;
  word-break: break-word;
}
.cmd-palette__item-hint {
  font-size: var(--fs-sm);
  color: var(--muted);
  flex: 1 1 auto;
  min-width: 0;
  word-break: break-word;
}
@media (max-width: 640px) {
  .cmd-palette__item { flex-direction: column; align-items: stretch; gap: 2px; }
  .cmd-palette__item-title { flex: 0 0 auto; }
}
.cmd-palette__empty {
  padding: 24px;
  color: var(--muted);
  text-align: center;
  font-size: var(--fs-base);
}
.cmd-palette__footer {
  border-top: 1px solid var(--border);
  padding: 8px 18px;
  display: flex;
  gap: 18px;
  color: var(--muted);
  font-size: var(--fs-sm);
  background: var(--bg-soft);
}
.cmd-palette__footer kbd {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 4px;
  padding: 1px 5px;
  font-size: var(--fs-xs);
  color: var(--fg);
}

/* ============ Страница логина ============ */
.auth {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  background: linear-gradient(180deg, var(--bg) 0%, var(--bg-soft) 100%);
}

.auth__box {
  width: 100%;
  max-width: 380px;
  padding: 32px 28px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 12px;
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.08);
}

.auth__brand {
  margin: 0 0 4px;
  font-size: var(--fs-h1);
  color: var(--primary);
  text-align: center;
}
.auth__hint {
  margin: 0 0 24px;
  color: var(--muted);
  text-align: center;
  font-size: var(--fs-base);
}

.auth__form { display: flex; flex-direction: column; gap: 14px; }
.auth__form label {
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: var(--fs-base);
  color: var(--muted);
}
.auth__form input {
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: var(--fs-md);
  background: var(--input-bg);
  color: var(--fg);
}
.auth__form input:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
}

.auth__error {
  padding: 8px 12px;
  /* danger-токены темы — как у .modal__error. */
  background: var(--danger-bg);
  color: var(--danger-fg);
  border-radius: 6px;
  font-size: var(--fs-base);
}

.auth__footnote {
  margin-top: 20px;
  font-size: var(--fs-sm);
  text-align: center;
}

/* ============================================================================
   Фаза 3: фото-сетка для карточек участка и захоронения
   ============================================================================ */
.photo-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(180px, 1fr));
  gap: 12px;
  margin: 12px 0 24px;
}
.photo-grid__item {
  display: flex;
  flex-direction: column;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  text-decoration: none;
  color: inherit;
  box-shadow: var(--shadow);
}
.photo-grid__item:hover { text-decoration: none; }
.photo-grid__item img {
  width: 100%;
  height: 160px;
  object-fit: cover;
  display: block;
  background: #e5e7eb;
}
.photo-grid__missing {
  height: 160px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--muted);
  font-size: var(--fs-sm);
  background: var(--surface-alt);
  border-bottom: 1px solid var(--border);
}
.photo-grid__caption {
  padding: 6px 8px;
  font-size: var(--fs-xs);
  color: var(--muted);
  word-break: break-all;
}

/* ============================================================================
   Фаза 4: вкладки и сетка полей для карточки книги захоронений
   ============================================================================ */
.tabs { background: var(--surface); border: 1px solid var(--border); border-radius: 6px; padding: 0; box-shadow: var(--shadow); }
.tabs__nav {
  display: flex;
  flex-wrap: wrap;
  gap: 2px;
  border-bottom: 1px solid var(--border);
  padding: 6px 6px 0;
  background: var(--surface-alt);
  border-radius: 6px 6px 0 0;
}
.tabs__btn {
  background: transparent;
  border: none;
  padding: 8px 14px;
  cursor: pointer;
  font-size: var(--fs-base);
  border-radius: 6px 6px 0 0;
  color: var(--fg);
  border-bottom: 2px solid transparent;
  margin-bottom: -1px;
}
.tabs__btn:hover { background: var(--btn-bg); }
.tabs__btn.is-active {
  background: var(--surface);
  border: 1px solid var(--border);
  border-bottom-color: var(--surface);
  font-weight: 500;
}
.tabs__pane { display: none; padding: 16px; }
.tabs__pane.is-active { display: block; }

.fields-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 6px 24px;
  font-size: var(--fs-base);
}
.fields-grid > div { padding: 2px 0; }
.fields-grid b { color: var(--muted); font-weight: 500; }

.form-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 8px 16px;
}
.form-grid .field { margin: 0; }
/* Модификаторы для редких случаев. По умолчанию form-grid — 2 колонки;
   используйте --cols-1 для одиночной колонки, --cols-4 для плотных
   карточек участка. Раньше эти случаи задавались inline через
   style="grid-template-columns:..." — переезжаем на класс. */
.form-grid--cols-1 { grid-template-columns: 1fr; }
.form-grid--cols-4 { grid-template-columns: repeat(4, minmax(0, 1fr)); }

.resp-card {
  background: var(--surface-alt);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 10px 14px;
  margin-bottom: 8px;
  font-size: var(--fs-base);
  line-height: 1.5;
  /* Поля выкладываем горизонтально в один flex-wrap, чтобы карточка
     не растягивалась в высоту: короткие поля стоят в строку, длинные
     (паспорт, адрес) переходят на отдельную строку через --wide. */
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 4px 18px;
}
.resp-card__field { white-space: nowrap; }
.resp-card__field--wide {
  /* Длинное поле занимает всю ширину карточки (или хотя бы свою
     значительную часть) и может переноситься внутри. */
  flex: 1 1 100%;
  white-space: normal;
}
.resp-card__actions {
  /* Кнопки прижимаются к правому краю карточки, на отдельной «строке»
     через 100%-флекс — иначе короткие поля давят на них слева. */
  flex: 1 1 100%;
  display: flex;
  justify-content: flex-end;
  gap: 6px;
  margin-top: 4px;
}
/* Список «История ответственных» — карточки в ряд (auto-fit grid).
   Минимум 360px на колонку — узкая колонка делает поля паспорта
   нечитаемыми; на широком экране ставится 2-3-4 в ряд. */
.resp-history {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(360px, 1fr));
  gap: 10px;
  margin-bottom: 12px;
}
.resp-history .resp-card { margin-bottom: 0; }

/* Кликабельная таблица — каждая строка действует как кнопка. Используется
   в диалоге «Переместить на другой участок» (выбор участка кликом) и
   может пригодиться в других диалогах табличного выбора. */
table.table--clickable tbody tr { cursor: pointer; }
table.table--clickable tbody tr:hover { background: var(--surface-alt); }
/* Подсветка строки, к которой запись уже привязана (текущая) — оператор
   видит, какой участок выбран сейчас, и не пытается перенести на тот же. */
table.table tbody tr.row--current { background: rgba(99, 102, 241, 0.10); }
table.table--clickable tbody tr.row--current:hover { background: rgba(99, 102, 241, 0.18); }

/* Для большой формы редактирования записи книги — широкий модал + секции */
.modal--wide { max-width: 860px; max-height: 85vh; overflow-y: auto; }

/* ---- Окно «Разобрать»: попарное сравнение реквизитов при объединении ---- */
/* Панель над таблицей: тумблер «Только отличия» + счётчики. */
.mp-toolbar { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; margin: 4px 0 8px; flex-wrap: wrap; }
.mp-toggle { display: inline-flex; align-items: center; gap: 6px; cursor: pointer;
  font-size: var(--fs-base); user-select: none; }
.mp-counts { font-size: var(--fs-sm); }
/* Узкая колонка-подпись поля. */
.mp-table td.mp-label { white-space: nowrap; color: #475569; font-weight: 600;
  width: 1%; vertical-align: top; }
/* Заголовок раздела (Умерший / Захоронение / …). */
.mp-table tr.mp-section td { background: #f1f5f9; font-weight: 700; color: #334155;
  font-size: var(--fs-sm); text-transform: uppercase; letter-spacing: .03em;
  padding-top: 10px; }
/* Совпадающее значение — спокойный фон, показано один раз по центру. */
.mp-table tr.mp-same td.mp-same-val { color: #64748b; text-align: center; }
/* Различающееся поле — мягкая подсветка, чтобы сразу бросалось в глаза. */
.mp-table tr.mp-collision > td { background: rgba(245, 158, 11, 0.10); }
.mp-table label.mp-pick { display: block; cursor: pointer; }
.mp-table label.mp-pick input { margin-right: 6px; }
/* Режим «Только отличия»: прячем совпадающие строки и заголовки разделов. */
.mp-table.only-diffs tr.mp-same,
.mp-table.only-diffs tr.mp-section { display: none; }
/* Примечание про разные участки (раздельный выбор номера/геометрии). */
.mp-note { border-left: 3px solid #6366f1; background: rgba(99, 102, 241, 0.06);
  padding: 6px 10px; border-radius: 4px; margin: 6px 0; }

/* Форма создания/редактирования участка — компактная раскладка
   3-колонок (Кладбище/Квартал/Ряд, Длина/Ширина/Площадь) и плотный
   гутер между полями: чтобы вся форма влезала на экран без вертикальной
   прокрутки тела модалки. На очень коротких экранах (height < 720px)
   модалка всё равно скроллится — это безопасный fallback. */
.modal--plot { max-width: 760px; }
.modal--plot .modal__body { padding-top: 12px; padding-bottom: 12px; }
.modal--plot .modal__body .field { margin-bottom: 8px; }
.modal--plot .modal__body .form-section { margin: 10px 0 6px; }
.modal--plot .modal__body textarea { min-height: 60px; }
/* Строки «Кладбище/Квартал/Ряд» и «Вид/Номер», «Длина/Ширина/Площадь»:
   колонки обязаны ужиматься под ширину модалки. Без minmax(0,1fr) +
   min-width:0 длинное имя кладбища в <select> распирает grid, и строка
   вылезает за правый край окна (жалоба оператора 2026-05-27). */
.modal--plot .field-grid--3 { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.modal--plot .field-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.modal--plot .field-grid .field { min-width: 0; }
.modal--plot .field-grid .field select,
.modal--plot .field-grid .field input { min-width: 0; max-width: 100%; }

/* --- Форма «Редактировать кладбище» ---
   Двухколоночный layout: слева — все текстовые поля компактно, справа —
   мини-карта с кнопками рисования полигона + таблица точек. Цель —
   уложить форму на один экран без вертикальной прокрутки на типичном
   мониторе (≥ 768px высота).
   На узких экранах (< 900px по ширине) — fallback на одну колонку. */
/* v0.73.0: модалка кладбища расширена до ~80% экрана и переведена на
   3-колоночный layout (реквизиты | карта | таблица точек). Раньше
   была 1100px и 2 колонки — карта была мелкой, таблица точек уезжала
   под карту. По запросу пользователя 2026-05-19. */
.modal--cemetery {
  width: 80vw;
  max-width: 1600px;
  max-height: 92vh;
  overflow-y: auto;
}
.modal--cemetery .modal__body { padding-top: 12px; padding-bottom: 12px; }
.modal--cemetery .modal__body .field { margin-bottom: 8px; }
.modal--cemetery .modal__body textarea { min-height: 48px; }
.cemetery-form-grid {
  display: grid;
  /* Колонок может быть три (реквизиты | карта | точки) или две — в реестровом
     профиле мини-карта вырезана (feature:cemetery-mini-map). auto-fit по
     фактическому числу колонок избавляет от пустой третьей полосы. */
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  gap: 16px;
}
.cemetery-form-grid__col {
  display: flex;
  flex-direction: column;
  min-width: 0;
}
@media (max-width: 1100px) {
  /* Узкие экраны: 2 колонки (реквизиты + карта/таблица сверху-вниз). */
  .cemetery-form-grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1.05fr); }
}
@media (max-width: 700px) {
  .cemetery-form-grid { grid-template-columns: 1fr; }
}

/* Маркеры точек периметра на мини-карте кладбища: divIcon с
   нумерацией (1, 2, 3, …). Пользователь видит, какую точку
   удалит, если кликнет по ней. На главной карте /map тех же
   маркеров не используем — только в форме редактирования. */
.cem-vertex-marker {
  /* Сам контейнер делаем «прозрачным»: маркер — это белый кружок
     с цифрой по центру, без фона у leaflet-divicon-div. */
  background: transparent !important;
  border: none !important;
}
.cem-vertex-pin {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  background: #ea580c;
  color: #fff;
  font: 700 11px/1 system-ui, sans-serif;
  border: 2px solid #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25);
  cursor: pointer;
  /* Центрирование — через iconAnchor в JS (iconSize: 22, iconAnchor: 11,11).
     Раньше тут стоял transform: translate(-50%, -50%) — визуально работало,
     но DOM-bbox оставался в исходной позиции (leftTop=latLng), и click-hit-test
     по видимому пину иногда попадал в соседний маркер. На замыкании
     треугольника это удаляло не ту точку. */
}
.cem-vertex-pin:hover {
  background: #c2410c;
}

/* Аналогичный пин для OsirisDrawTool на главной карте (рисование
   кварталов, рядов, участков, областей, инфра-полигонов и линий).
   Поведение единое: drag — перемещение, клик — удалить, клик по
   первой точке (для polygon) — замкнуть и завершить. */
.osiris-draw-pin {
  background: transparent !important;
  border: none !important;
}
.osiris-draw-pin__dot {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 22px;
  height: 22px;
  border-radius: 50%;
  /* Цвет вершины задаётся per-layer через CSS-переменную --pin-color
     (см. OsirisEditTool.pinColorFor): кружок повторяет цвет своего
     полигона, чтобы было видно, к какому объекту относится узел. */
  background: var(--pin-color, #2563eb);
  color: #fff;
  font: 700 11px/1 system-ui, sans-serif;
  border: 2px solid #fff;
  box-shadow: 0 0 0 1px rgba(0, 0, 0, 0.25);
  cursor: grab;
  /* Центрирование — через iconAnchor в JS, не CSS-transform. */
}
.osiris-draw-pin__dot:hover {
  filter: brightness(0.85);
}
.osiris-draw-pin__dot:active {
  cursor: grabbing;
}
/* Полноэкранная модалка с картой — для диалога рисования участка
   («Нарисовать на карте» из формы создания плота). Карта внутри
   занимает почти всю высоту, тулбар закреплён сверху, кнопки «ОК /
   Отмена» — справа в шапке. */
.modal--map { max-width: 95vw; width: 95vw; max-height: 95vh; height: 95vh; }
.modal--map .modal__body {
  padding: 0;
  display: flex; flex-direction: column;
  flex: 1 1 auto; min-height: 0; overflow: hidden;
}
/* Внутри .modal__body есть `<form>` (обёртка openModal), которая ломает
   flex-chain: form по умолчанию display:block. Растягиваем её тоже как
   flex-column на всю высоту. */
.modal--map .modal__body > form {
  display: flex; flex-direction: column;
  flex: 1 1 auto; min-height: 0; height: 100%;
}
.plot-draw-toolbar {
  display: flex; flex-wrap: wrap; gap: 8px;
  padding: 10px 14px; border-bottom: 1px solid var(--border);
  background: var(--surface-alt); align-items: center;
  flex-shrink: 0;
}
.plot-draw-toolbar .field { margin: 0; }
.plot-draw-toolbar .field span { display: block; font-size: var(--fs-xs); color: var(--muted); margin-bottom: 2px; } /* был несуществующий --text-muted */
.plot-draw-toolbar .field select {
  padding: 4px 8px; border: 1px solid var(--border); border-radius: 4px;
  background: var(--surface); font-size: var(--fs-base); min-width: 160px;
}
.plot-draw-toolbar__sep { width: 1px; height: 28px; background: var(--border); margin: 0 4px; }
#plot-draw-map { flex: 1 1 auto; min-height: 300px; width: 100%; }
.form-section {
  font-size: var(--fs-base);
  font-weight: 600;
  color: var(--muted);
  margin: 18px 0 8px;
  padding-bottom: 4px;
  border-bottom: 1px solid var(--border);
}
.form-section:first-of-type { margin-top: 4px; }

/* ============================================================================
   Общие паттерны страниц: page__actions, filter-panel — используются и в
   журнале книги захоронений, и в других списках. Меняя здесь — меняем везде.
   ============================================================================ */

/* Кнопочная группа в заголовке страницы (справа от h1). */
.page__actions {
  display: inline-flex;
  gap: 8px;
  align-items: center;
}

.visually-hidden {
  position: absolute !important;
  width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0,0,0,0); white-space: nowrap; border: 0;
}

/* Бейдж активных фильтров внутри кнопки-тогглера. */
.filters-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  margin-left: 6px;
  border-radius: 999px;
  background: var(--primary);
  color: #fff;
  font-size: var(--fs-xs);
  font-weight: 600;
}
.filters-chevron { margin-left: 4px; color: var(--muted); font-size: var(--fs-xs); }

/* Общая сворачиваемая панель фильтров. Скрывается HTML-атрибутом hidden,
   что надёжнее любых grid-trick'ов (браузер не рендерит вовсе). */
.filter-panel {
  margin-bottom: 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px 16px;
  display: flex;
  flex-direction: column;
  gap: 12px;
}
.filter-panel[hidden] { display: none; }

/* Верхний ряд панели: большие важные поля (кладбище, поиск). */
.filter-panel__row {
  display: flex;
  gap: 12px;
  align-items: flex-end;
  flex-wrap: wrap;
}
.filter-panel__row .field { margin: 0; flex: 1; min-width: 180px; }

/* Подписи групп внутри панели. */
.filter-panel .journal-filters {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 16px;
  padding: 4px 0 0;
}
.filter-panel .journal-filters__group {
  display: flex;
  flex-direction: column;
  gap: 6px;
}
.filter-panel .journal-filters__group-title {
  font-size: var(--fs-xs);
  color: var(--muted);
  font-weight: 600;
  margin-bottom: 2px;
  border-bottom: 1px dashed var(--border);
  padding-bottom: 3px;
}

/*
  С v0.69.5 — новая горизонтальная вёрстка фильтров реестра.
  .journal-filters--rows переопределяет grid из старой вёрстки на
  вертикальный flex: каждая строка занимает всю ширину панели, поля
  внутри строки идут слева-направо. Заголовок строки слева,
  фиксированной ширины, чтобы инпуты выровнялись по вертикали.

  Чипы источника (.chip-group) — компактные radio-кнопки в одну
  линию. Активный чип получает primary-фон, как кнопка .btn--primary.
*/
.filter-panel .journal-filters--rows {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.journal-filters__row {
  display: flex;
  align-items: center;
  gap: 12px;
  flex-wrap: wrap;
}
.journal-filters__row-label {
  flex: 0 0 72px;
  font-size: var(--fs-base);
  color: var(--muted);
  font-weight: 600;
}
/* Поля фильтра: подпись ПЕРЕД полем (инлайн), как у блока дат. Три ячейки
   в ряду равны (flex 1 1 0) → ряды Локация/ФИО/Даты выровнены по колонкам. */
.journal-filters__row .field {
  flex: 1 1 0;
  min-width: 0;
  margin: 0;
  flex-direction: row;
  align-items: center;
  flex-wrap: wrap;
  gap: 6px;
}
.journal-filters__row .field > span {
  flex: 0 0 auto;
  font-weight: 600;
  white-space: nowrap;
}
.journal-filters__row .field > select,
.journal-filters__row .field > input {
  flex: 1 1 80px;
  min-width: 0;
}
/* Подсказка под селектором квартала (если кладбище не выбрано) — на всю
   ширину ячейки, под полем, чтобы не ломать инлайн-строку. */
.journal-filters__row .field > p {
  flex: 1 1 100%;
  margin: 2px 0 0;
}
.journal-filters__cell--xs { flex: 0 0 180px !important; min-width: 0 !important; }
.journal-filters__cell--sm { flex: 1 1 200px !important; }
.journal-filters__cell--md { flex: 1 1 240px !important; }

/* Три диапазона дат (рождение/смерть/захоронение) в одну строку —
   компактный фильтр реестра (v0.82.7). Каждый диапазон: подпись + «от–до». */
.journal-filters__row--dates { align-items: center; }
.journal-filters__daterange {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  flex: 1 1 0;
  min-width: 0;
}
.journal-filters__daterange-cap {
  font-size: var(--fs-sm);
  color: var(--muted);
  font-weight: 600;
  white-space: nowrap;
}
.journal-filters__daterange input[type="date"] {
  flex: 1 1 90px;
  min-width: 0;
  /* Стиль как у остальных полей приложения (.field input), иначе нативный
     date-инпут выглядит чужеродно (другой шрифт/рамка). */
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-family: inherit;
  font-size: var(--fs-base);
  line-height: 1.3;
  min-height: 34px;
  background: var(--input-bg);
  color: var(--fg);
  box-sizing: border-box;
}
.journal-filters__daterange input[type="date"]:focus {
  outline: none;
  border-color: var(--primary);
  box-shadow: 0 0 0 3px var(--focus-ring);
}
.journal-filters__dash { color: var(--muted); }

/* Источник: чип-группа поверх обычной строки фильтра. */
.journal-filters__row--source { align-items: center; }
.chip-group {
  display: inline-flex;
  flex-wrap: wrap;
  gap: 6px;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  padding: 6px 14px;
  border: 1px solid var(--border);
  border-radius: 999px;
  background: var(--btn-bg);
  cursor: pointer;
  font-size: var(--fs-base);
  user-select: none;
  transition: background .1s ease, border-color .1s ease, color .1s ease;
}
.chip:hover { background: var(--btn-bg-hover); }
.chip input[type="radio"],
.chip input[type="checkbox"] {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px; overflow: hidden;
  clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}
.chip:has(input:checked) {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
  font-weight: 500;
}

/* На узких экранах label-строки сворачиваются в самостоятельные
   строки, чтобы инпуты не давились. */
@media (max-width: 720px) {
  .journal-filters__row { flex-direction: column; align-items: stretch; }
  .journal-filters__row-label { flex: 0 0 auto; padding-bottom: 0; }
  .journal-filters__cell--xs,
  .journal-filters__cell--sm,
  .journal-filters__cell--md { flex: 1 1 auto !important; }
}
.filter-panel .field { margin: 0; }
.filter-panel .field > span { font-size: var(--fs-sm); color: var(--muted); }
/* В панели фильтров используем те же базовые стили .field, только чуть
   плотнее шрифт. Критично ИСКЛЮЧИТЬ чекбоксы/радио/color/file — иначе
   min-height/width превращает их в гигантские прямоугольники. */
.filter-panel .field input:not([type="checkbox"]):not([type="radio"]):not([type="color"]):not([type="file"]),
.filter-panel .field select,
.filter-panel .field textarea {
  font-size: var(--fs-base);
  min-height: 32px;
  padding: 6px 8px;
  width: 100%;
}
.filter-panel__footer {
  display: flex;
  justify-content: flex-end;
  padding-top: 6px;
  border-top: 1px solid var(--border);
}

/* Селектор кладбища — базовое оформление одинаковое на всех страницах. */
.cemetery-picker-inline {
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: 4px;
  font-size: var(--fs-base);
  background: var(--input-bg);
  width: 100%;
  font-family: inherit;
  color: var(--fg);
  min-height: 32px;
  box-sizing: border-box;
}

/* Книга захоронений: страница из двух частей.
   Верх (заголовок, поиск, фильтры) — в обычном ограниченном контейнере,
   чтобы длинные ряды полей не растягивались на весь экран.
   Нижний блок (таблица + боковая панель) — на всю ширину окна браузера. */
.burials-page { display: flex; flex-direction: column; }
.burials-page__top {
  max-width: 1400px;
  width: 100%;
  margin: 0 auto;
  /* Горизонтальный padding 40px — синхронно с .content (см. выше),
     чтобы реестр на узких окнах не упирался в бока. */
  padding: 24px 40px 0;
  box-sizing: border-box;
}

/* Тулбар журнала: всегда виден между page__header и панелью фильтров.
   Содержит селект кладбища и быстрый поиск — одни из самых частых действий. */
.journal-toolbar {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 12px;
  align-items: flex-end;
}
.journal-toolbar .field { min-width: 200px; }

/* Двухколоночная раскладка: таблица слева на всю оставшуюся ширину,
   боковая панель справа фиксированной ширины (360px). Заполняет всю
   ширину окна браузера (страница в режиме content--full). */
.journal-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 360px;
  gap: 12px;
  /* Горизонтальный padding 80px — реестр не должен прижиматься к краю
     экрана (по просьбе пользователя; раньше было 16px → 40px → 80px). */
  padding: 12px 80px 24px;
  align-items: start;
  width: 100%;
  box-sizing: border-box;
}
.journal-layout__main { min-width: 0; }
/* Горизонтальная прокрутка таблицы реестра, когда включено много колонок
   и они не помещаются по ширине (v0.82.2, ТЗ оператора). Раньше .table-wrap
   клипал overflow:hidden — правые колонки просто обрезались. Скроллим
   только реестр; остальные таблицы не трогаем.
   С 2026-07 — ещё и ВЕРТИКАЛЬНЫЙ скролл внутри обёртки: overflow-x:auto
   делал её scroll-контейнером, из-за чего position:sticky у thead липнул
   к обёртке, а не к окну — шапка «не работала». Теперь шапка липнет к
   верхней кромке самой обёртки. 220px ≈ топбар (56) + заголовок и тулбар
   реестра над таблицей; цифру можно уточнить по фактической вёрстке. */
.journal-layout .table-wrap {
  overflow: auto;
  max-height: calc(100vh - 220px);
}
.journal-layout__side {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 10px 12px;
  position: sticky;
  top: 12px;
  max-height: calc(100vh - 80px);
  overflow-y: auto;
  box-sizing: border-box;
}
/* На узких экранах панель уезжает вниз под таблицу, чтобы таблица
   не сжималась до нечитаемого состояния. */
@media (max-width: 1100px) {
  .journal-layout {
    grid-template-columns: minmax(0, 1fr);
  }
  .journal-layout__side { position: static; max-height: none; }
}

/* Плоская таблица журнала: одна запись = одна строка, колонки несут по одному
   самодостаточному значению. Sticky-header чтобы шапка не терялась при прокрутке. */
.journal-table {
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--fs-base);
}
.journal-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface-alt);
  text-transform: none;
  letter-spacing: 0;
  font-size: var(--fs-xs);
  padding: 8px 10px;
  white-space: nowrap;
}
.journal-table tbody td {
  padding: 8px 10px;
  /* Многострочные ячейки (v0.82.2, ТЗ оператора): при большом числе
     включённых колонок содержимое переносится на 2–3 строки, а не
     обрезается многоточием — длинные значения (ФИО, имя файла фото,
     «кто+когда») можно прочитать целиком. */
  white-space: normal;
  overflow-wrap: anywhere;
  vertical-align: top;
  max-width: 280px;
  line-height: 1.35;
}
.journal-table .col-source { width: 70px; }
.journal-table .col-fio { min-width: 140px; max-width: 240px; }
.journal-table .col-fio .fio-link { color: var(--fg); font-weight: 500; cursor: pointer; }
.journal-table .col-fio .fio-link:hover { color: var(--primary); text-decoration: underline; }
.journal-table .col-num-xs { width: 36px; text-align: center; }
.journal-table .col-date { width: 110px; text-align: right; font-variant-numeric: tabular-nums; }
.journal-table .col-cemetery { max-width: 150px; }
.journal-table .col-loc { width: 72px; }
/* Квартал (сектор): почти всегда короткое число — узкая колонка;
   заголовок «Квартал / (сектор)» в две строки (см. thFor), выравнивание
   по левому краю, как у остальных заголовков. */
.journal-table .col-sector { width: 56px; }
.journal-table th.col-sector { line-height: 1.15; }
.journal-table .col-type { color: var(--muted); max-width: 140px; }
.journal-table .col-rec { width: 88px; font-variant-numeric: tabular-nums; }
.journal-table th.col-rec,
.journal-table th.col-loc { line-height: 1.15; }
.journal-table .col-actions { width: 40px; text-align: right; }

/* Контентные ссылки (номер участка, ФИО на участке, «Выбранная запись» на
   карте, ссылки в подзаголовке карточки) — жирным цветом текста, а не
   светлым цветом темы (плохо читается на белом). Цвет темы — при наведении.
   Кнопки-ссылки (.btn) не трогаем. */
.journal-table .col-loc a:not(.btn),
.page-subhead a:not(.btn),
#map-side-selected a:not(.btn),
a.link-strong {
  color: var(--fg);
  font-weight: 600;
  text-decoration: none;
}
.journal-table .col-loc a:not(.btn):hover,
.page-subhead a:not(.btn):hover,
#map-side-selected a:not(.btn):hover,
a.link-strong:hover {
  color: var(--primary);
  text-decoration: underline;
}
/* Опциональные колонки реестра (v0.82.2). */
.journal-table .col-audit {
  width: 150px;
  color: var(--muted);
  font-size: var(--fs-sm);
  /* Не рвать длинное имя по буквам (иначе «Суперадминистрато|р» — одна
     буква на отдельной строке). Слово остаётся целым; если оно шире
     колонки — колонка сама чуть расширится, но без «сиротской» буквы. */
  overflow-wrap: normal;
  word-break: keep-all;
}
.journal-table .col-audit__time { display: block; font-size: var(--fs-xs); opacity: .75; white-space: nowrap; }
.journal-table .col-coords { width: 124px; color: var(--muted); font-variant-numeric: tabular-nums; }
.journal-table .col-photo { max-width: 160px; }
.journal-table .col-photo a { color: var(--fg); font-weight: 600; text-decoration: none; }
.journal-table .col-photo a:hover { color: var(--primary); text-decoration: underline; }

/*
  С v0.69.4 — массовое объединение в «Поиск и объединение записей».
  Чекбоксы в первой колонке + плавающая панель «Выбрано N» над
  таблицей. Цветовая гамма та же, что у .placeholder — оператор
  видит, что это «инструмент», а не отдельная страница.
*/
.dup-bulkbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  flex-wrap: wrap;
  padding: 10px 14px;
  background: var(--primary-soft);
  border: 1px solid var(--primary);
  border-radius: 6px;
  margin-bottom: 10px;
}
.dup-bulkbar__actions {
  display: flex;
  gap: 8px;
  flex-wrap: wrap;
}
.col-checkbox { width: 32px; text-align: center; }
.col-checkbox input[type="checkbox"] { vertical-align: middle; }
/* Сортировка: клик по th переключает asc/desc, индикатор справа от текста.
   Активная колонка получает is-asc / is-desc, остальные показывают
   нейтральный «двойной треугольник», намекая, что по ним тоже можно
   отсортировать. */
.journal-table .col-sort {
  cursor: pointer;
  user-select: none;
}
.journal-table .col-sort:hover { background: var(--bg-soft); }
/* Видимый фокус при клавиатурной навигации по заголовкам сортировки —
   по образцу .jrow:focus ниже. */
.journal-table .col-sort:focus-visible {
  outline: 2px solid var(--primary);
  outline-offset: -2px;
}
.journal-table .col-sort .col-sort__ind {
  display: inline-block;
  width: 0;
  height: 0;
  margin-left: 6px;
  vertical-align: middle;
  border-left: 4px solid transparent;
  border-right: 4px solid transparent;
  /* По умолчанию — серый «двойной треугольник» через двойной border */
  border-bottom: 4px solid #cbd5e1;
  border-top: 4px solid #cbd5e1;
  position: relative;
  top: -1px;
}
.journal-table .col-sort.is-asc .col-sort__ind {
  border-bottom: 5px solid var(--primary);
  border-top: none;
}
.journal-table .col-sort.is-desc .col-sort__ind {
  border-top: 5px solid var(--primary);
  border-bottom: none;
}
.jrow { cursor: pointer; }
.jrow:nth-child(even) { background: var(--surface-alt); }
.jrow:hover { background: var(--bg-soft); }
.jrow.is-selected { background: var(--primary-soft); }
.jrow.is-selected:hover { background: rgba(59, 130, 246, 0.18); }
.jrow:focus { outline: 2px solid var(--primary); outline-offset: -2px; }
/* Множественный выбор чекбоксами — лёгкая подсветка отмеченной строки.
   Не конфликтует с .is-selected (одиночное выделение синим): отмеченные
   строки видны мягким золотистым тоном, а активная одиночная — синим. */
.jrow--checked { background: rgba(250, 204, 21, 0.12) !important; }
.jrow--checked:hover { background: rgba(250, 204, 21, 0.20) !important; }
.col-select { width: 32px; text-align: center; padding: 0 4px; }
.col-select input[type="checkbox"] { cursor: pointer; }

.btn--icon {
  padding: 4px 8px;
  font-size: var(--fs-md);
  line-height: 1;
  background: transparent;
  border-color: transparent;
  color: var(--muted);
  text-decoration: none;
  /* .btn задаёт min-height: 36px; для иконки в модалках (× «Закрыть»)
     это слишком много — она должна помещаться в заголовок 32-36 px
     высотой. Но и меньше 28px нельзя: кликабельная зона должна
     оставаться попадаемой мышью/пальцем (доступность). */
  min-width: 28px;
  min-height: 28px;
}
.btn--icon:hover { text-decoration: none; }

/* Все «удалить» — пастельно-красные. Не яркий красный (как primary
   у destructive-кнопки), а мягкий розоватый с тёмно-красным текстом —
   оператор видит «опасно», но не пугается, и кнопка не доминирует
   над основным CTA на странице. Любое подтверждение — отдельным confirm-диалогом. */
/* Единый стиль для всех кнопок «Удалить» в интерфейсе — заполненная
   розово-красная (#e3256b) с белым текстом. По насыщенности это
   зеркальная CTA по отношению к синей .btn--primary. Так оператору
   проще «считывать» кнопку: один цвет — везде значит «удалить». */
/* Менее яркий красный (по запросу 2026-05-08). Раньше был ярко-малиновый
   #e3256b — слишком кричащий. Сохраняем функциональную «знаковость» —
   это всё ещё единственная красная CTA в интерфейсе, но мягче для глаз.
   С 2026-07 фон — из danger-токена темы (--danger, разбавленный белым до
   уровня прежнего red-400), а текст ТЁМНО-красный вместо белого: белый
   на red-400 давал контраст 2.8:1 при норме 4.5:1. */
.btn--danger {
  background: color-mix(in srgb, var(--danger) 55%, #fff);
  border: 1px solid color-mix(in srgb, var(--danger) 55%, #fff);
  color: #450a0a;
}
.btn--danger:hover {
  /* Ступень темнее — больше доля --danger в смеси. */
  background: color-mix(in srgb, var(--danger) 70%, #fff);
  border-color: color-mix(in srgb, var(--danger) 70%, #fff);
  color: #450a0a;
}
/* Ghost-вариант — текстовая кнопка «Удалить» в шапке карточки записи
   книги. Тон тот же, но без подложки и рамки. */
.btn--danger.btn--ghost {
  background: transparent;
  border-color: transparent;
  color: var(--danger);
}
.btn--danger.btn--ghost:hover {
  background: color-mix(in srgb, var(--danger) 10%, transparent);
  color: var(--danger-fg);
}
.btn--icon:hover { background: var(--btn-bg); color: var(--fg); }

/* Бейдж источника записи в журнале. */
.src-badge {
  display: inline-block;
  padding: 2px 7px;
  border-radius: 10px;
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: 0.02em;
  white-space: nowrap;
}
.src-badge--book {
  background: rgba(37, 99, 235, 0.12);
  color: var(--primary);
}
.src-badge--inventory {
  background: rgba(5, 150, 105, 0.12);
  color: var(--ok);
}
/* Bookmark+inventory: запись 1С-импорта с merge-парой Книга↔Регистрация.
   Градиент синий→зелёный, чтобы визуально выделялась как «обе ветки сразу». */
.src-badge--book-inv {
  background: linear-gradient(90deg, rgba(37, 99, 235, 0.18), rgba(5, 150, 105, 0.18));
  color: #1e3a8a;
  border: 1px solid rgba(37, 99, 235, 0.25);
}
.jrow--inventory { background-color: rgba(5, 150, 105, 0.03); }
.jrow--inventory:nth-child(even) { background-color: rgba(5, 150, 105, 0.055); }

.journal-side__head { font-size: var(--fs-sm); color: var(--muted); margin-bottom: 4px; }
.journal-photos {
  display: flex;
  flex-wrap: wrap;
  gap: 4px;
  margin-bottom: 4px;
}
.journal-photos a {
  width: 54px;
  height: 54px;
  overflow: hidden;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: #e5e7eb;
  display: inline-block;
}
.journal-photos img { width: 100%; height: 100%; object-fit: cover; display: block; }
.journal-photo-missing {
  width: 54px; height: 54px;
  display: flex; align-items: center; justify-content: center;
  font-size: 18px; color: var(--muted); background: var(--surface-alt);
}
/* Снимок есть в базе, но файла нет — архив инвентаризации переносят
   отдельно и заливают частями. Место занимаем, но не кричим. */
.file-preview__missing {
  min-width: 260px; min-height: 160px;
  display: flex; align-items: center; justify-content: center;
  padding: 24px;
  color: var(--muted); font-size: var(--fs-sm);
  background: var(--surface-alt); border-radius: 6px;
}
.journal-photo-doc {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  background: #f3f4f6;
  color: #6b7280;
  font-weight: 700; font-size: var(--fs-xs); letter-spacing: 0.5px;
}
.journal-side__actions {
  display: flex; flex-direction: column; gap: 6px; margin-top: 12px;
}

/* ============================================================================
   Полоса вкладок открытых документов — fixed-подвал внизу окна.
   Видна только если открыт ≥1 документ (burial/plot/grave/inventory).
   body.has-doc-tabs выставляется в renderDocTabs, и страница даёт
   снизу запас высоты, чтобы её последние строки не закрывала полоса.
   ============================================================================ */
.doc-tabs {
  display: flex;
  gap: 2px;
  padding: 4px 16px;
  background: var(--surface);
  border-top: 1px solid var(--border);
  overflow-x: auto;
  scrollbar-width: thin;
  /* Полоса вкладок — fixed-подвал, всегда видна внизу окна, поверх
     любого контента. Контент компенсирует высоту через
     body.has-doc-tabs { padding-bottom: 44px } (см. ниже), чтобы
     последние строки страницы не уходили под полосу. */
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  /* Выше карты, её Leaflet-контролов (~1000) и тостов, но ниже модалок
     (2000): иначе выпадающее ВВЕРХ меню группы (.doc-group__menu)
     проваливается под полигоны карты (их pane ~450 «протекает» в корневой
     stacking-контекст, т.к. контейнер Leaflet своего контекста не создаёт). */
  z-index: var(--z-doc-tabs);
  flex-shrink: 0;
  box-shadow: 0 -2px 6px rgba(0,0,0,0.06);
}
/* display:flex перекрывает дефолтный display:none от атрибута hidden,
   поэтому явно возвращаем его, когда документов нет ни одного. */
.doc-tabs[hidden] { display: none; }

/* Класс на body выставляет JS (renderDocTabs) при наличии открытых
   документов. Контент компенсирует высоту полосы, чтобы её не
   закрывал нижний край. На странице карты — отдельно ограничиваем
   высоту .map-page (она height-bound).
   Высота полосы: 4px+4px (padding) + ~34px (вкладка с padding 6+6 +
   line-height для font-size 13px + border 1+1) ≈ 42–44px. Берём 56px
   с щедрым запасом — мало того что чуть просторнее визуально, ещё и
   браузеры по-разному считают line-height/font-metrics, и без запаса
   на «Управление ролями» с полной прокруткой последняя строка
   проваливалась под полосу.
   Дублируем отступ ещё и на .content — body { height: 100% } сам по
   себе с `padding-bottom` ведёт себя ненадёжно (в зависимости от
   overflow владельца), а .content всегда принимает паддинг. */
body.has-doc-tabs { padding-bottom: 56px; }
body.has-doc-tabs .content { padding-bottom: calc(24px + 56px); }
body.has-doc-tabs .map-page { height: calc(100vh - 56px - 56px); }
.doc-tab {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px 6px 12px;
  max-width: 240px;
  /* Голубой тон в той же гамме, что обычная кнопка («Добавить участок» и т.п.) —
     полоса вкладок хорошо видна на белом фоне страницы. */
  background: var(--btn-bg);
  border: 1px solid var(--border);
  border-top: none;
  border-radius: 0 0 6px 6px;
  color: var(--fg);
  text-decoration: none;
  font-size: var(--fs-base);
  white-space: nowrap;
}
.doc-tab:hover { background: var(--btn-bg-hover); text-decoration: none; }
.doc-tab.is-active {
  background: var(--surface);
  color: var(--fg);
  font-weight: 500;
  /* Подчёркиваем активную вкладку снизу (тень снизу-внутрь), потому
     что полоса теперь приклеена к нижнему краю окна. */
  box-shadow: 0 1px 0 var(--primary) inset;
  position: relative;
  z-index: 1;
}
.doc-tab__title {
  max-width: 190px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.doc-tab__close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  /* Хитбокс ≥24px (доступность: раньше крестик был 18×18 и промахивался
     мышью). Визуально глиф прежний, а отрицательный вертикальный margin
     компенсирует рост бокса, чтобы высота вкладки не изменилась. */
  min-width: 24px;
  min-height: 24px;
  margin: -3px 0;
  background: transparent;
  border: none;
  border-radius: 3px;
  color: var(--muted);
  font-size: var(--fs-lg);
  line-height: 1;
  cursor: pointer;
  padding: 0;
}
.doc-tab__close:hover { background: rgba(0,0,0,0.1); color: var(--fg); }
/* «Карта» (home) — без кнопок (неудаляемая). Пользовательские вкладки
   могут быть закреплены (pin): у них остаётся ✕, но «Закрыть все» их не
   трогает. Признак «закреплена» — яркая иконка 📌 (см. .doc-tab__pin). */
.doc-tab.doc-tab--pinned { opacity: 0.97; }

/* Кнопка закрепления вкладки (📌): тусклая/обесцвеченная, когда не
   закреплена; яркая — когда закреплена. */
.doc-tab__pin {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 16px;
  height: 18px;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: 3px;
  font-size: var(--fs-xs);
  line-height: 1;
  cursor: pointer;
  opacity: 0.3;
  filter: grayscale(1);
}
.doc-tab__pin:hover { opacity: 0.7; }
.doc-tab__pin.is-pinned { opacity: 1; filter: none; }

/* ---- Группы вкладок (Захоронения / Участки / Сервис / Администрирование) ----
   Кнопка группы со счётчиком + выпадающее ВВЕРХ меню со списком открытых
   вкладок (полоса приклеена к низу окна, поэтому меню раскрывается вверх). */
.doc-group { position: relative; display: inline-flex; flex-shrink: 0; }
.doc-group__btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 6px 10px 6px 12px;
  background: var(--btn-bg);
  border: 1px solid var(--border);
  border-top: none;
  border-radius: 0 0 6px 6px;
  color: var(--fg);
  font-family: inherit;
  font-size: var(--fs-base);
  white-space: nowrap;
  cursor: pointer;
}
.doc-group__btn:hover { background: var(--btn-bg-hover); }
.doc-group.is-active .doc-group__btn {
  background: var(--surface);
  font-weight: 500;
  box-shadow: 0 1px 0 var(--primary) inset;
}
.doc-group__count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 17px;
  height: 16px;
  padding: 0 4px;
  border-radius: 8px;
  background: var(--primary);
  color: #fff;
  font-size: var(--fs-xs);
  line-height: 1;
}
.doc-group__caret { font-size: 9px; color: var(--muted); }
.doc-group__menu {
  /* position: fixed (а не absolute): у полосы .doc-tabs overflow-x: auto,
     который форсит overflow-y: auto и ОБРЕЗАЕТ выпадающее вверх меню. fixed
     не обрезается overflow-предком и позиционируется от вьюпорта — координаты
     (left/bottom от кнопки группы) ставит JS при открытии. */
  position: fixed;
  min-width: 230px;
  max-width: 380px;
  max-height: 60vh;
  overflow-y: auto;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  box-shadow: 0 4px 18px rgba(0,0,0,0.20);
  padding: 4px;
  display: none;
  z-index: 60;
}
.doc-group.is-open .doc-group__menu { display: block; }
.doc-group__item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 6px 8px;
  border-radius: 6px;
  color: var(--fg);
  text-decoration: none;
  font-size: var(--fs-base);
}
.doc-group__item:hover { background: var(--btn-bg-hover); text-decoration: none; }
.doc-group__item.is-active { background: var(--btn-bg); font-weight: 500; }
.doc-group__item-title { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* «Закрыть все» — приклеена к правому краю полосы (sticky), видна даже
   при горизонтальной прокрутке множества вкладок. */
.doc-tabs__close-all {
  position: sticky;
  right: 4px;
  margin-left: auto;
  align-self: center;
  flex-shrink: 0;
  padding: 4px 10px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--muted);
  font-size: var(--fs-sm);
  white-space: nowrap;
  cursor: pointer;
  box-shadow: -6px 0 6px -4px rgba(0, 0, 0, 0.15);
}
.doc-tabs__close-all:hover { background: var(--btn-bg-hover); color: var(--fg); }

/* ============================================================================
   Карточка записи книги захоронений: подшапка с ключевыми мета-полями,
   inline-форма редактирования, индикатор сохранения.
   ============================================================================ */
.page-subhead {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 20px;
  padding: 10px 14px;
  margin-bottom: 14px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  font-size: var(--fs-base);
  color: var(--fg);
}
.page-subhead b { color: var(--muted); font-weight: 500; margin-right: 4px; }

.burial-form { display: block; }
.burial-form .fields-grid,
.burial-form .form-grid { margin-top: 4px; }

/* Общая форма редактирования — используется и для карточки записи книги,
   и для карточки участка. Одинаковая верстка полей, секций, save-status. */
.doc-form { display: block; }
.doc-form .fields-grid,
.doc-form .form-grid { margin-top: 4px; }

/* Кнопка-иконка для мелких операций (настройки колонок, «открыть во вкладке») —
   без лишнего фона; при hover — лёгкая подсветка. */
.btn-settings-columns { white-space: nowrap; }

/* Блок «Связь с книгой» на карточке /grave/:id */
.link-panel {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 12px 16px;
  margin: 16px 0;
}
.link-candidate {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  cursor: pointer;
  margin: 0;
}
.link-candidate:last-child { border-bottom: none; }
.link-candidate:hover { background: var(--surface-alt); }
.link-candidate input[type="radio"] { flex-shrink: 0; }

.save-status {
  font-size: var(--fs-sm);
  color: var(--muted);
  min-width: 90px;
  text-align: right;
  /* Плавная смена цвета вместо резкого «мигания» при автосейве
     (muted → синий «Сохраняем…» → зелёный «Сохранено»). */
  transition: color .2s ease;
}
.save-status.is-saving { color: var(--primary); }
.save-status.is-saved  { color: var(--ok); }
.save-status.is-dirty  { color: var(--muted); }
.save-status.is-error  { color: var(--danger); }

/* Матрица ролей × ресурсов × действий (страница /roles, суперадмин). */
.roles-matrix td, .roles-matrix th { vertical-align: middle; text-align: center; }
.roles-matrix td:first-child, .roles-matrix th[rowspan] { text-align: left; }
.roles-matrix .role-col { border-left: 1px solid var(--border); }
.roles-matrix .cell { display: inline-flex; flex-direction: column; align-items: center; gap: 2px; }
.roles-matrix .cell input { margin: 0; }
.roles-matrix .role-col__head {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 4px 0;
}
.roles-matrix .role-col__del-btn {
  margin-top: 4px;
  font-size: var(--fs-xs);
  padding: 3px 8px;
  align-self: center;
}
/* Раньше здесь была глобальная заливка .btn.btn--danger ярко-красным,
   которая перебивала мягкий розовый стиль выше. Удалена по запросу
   оператора — кнопка «Удалить» теперь повсюду в спокойной розовой
   гамме, а не в насыщенно-красной. */

/* Табличная форма координат для форм квартала и участка (ТЗ
   Дмитров-2026, п. 3.2.1 / 3.2.2). Две колонки ввода lat/lng, кнопка
   «+ Добавить точку», красный крестик в конце строки. */
/* Свёрнутый блок координат полигона (details/summary): шапка с числом точек,
   внутри — таблица построчно (одна точка = строка) + «Добавить точку». */
.coord-details {
  margin-top: 4px;
  border: 1px solid var(--border, #e5e7eb);
  border-radius: 8px;
  background: var(--surface, #fff);
}
.coord-summary {
  cursor: pointer;
  padding: 8px 12px;
  font-size: var(--fs-base);
  font-weight: 500;
  color: var(--fg);
  user-select: none;
  list-style: none;
  display: flex;
  align-items: center;
  gap: 6px;
}
.coord-summary::-webkit-details-marker { display: none; }
.coord-summary::before {
  content: "▸";
  color: var(--muted, #6b7280);
  transition: transform .12s ease;
}
.coord-details[open] .coord-summary::before { transform: rotate(90deg); }
.coord-summary__count { font-weight: 400; }
.coord-details > .coord-scroll { overflow-x: auto; margin: 4px 12px 0; }
.coord-details > p { margin-left: 12px; margin-right: 12px; }
.coord-details > .coord-add { margin: 8px 12px 12px; }
.coord-table {
  width: auto;
  border-collapse: collapse;
}
.coord-table th,
.coord-table td {
  border: 1px solid var(--border, #e5e7eb);
  padding: 4px 6px;
  vertical-align: middle;
}
.coord-table th {
  background: var(--surface-alt);
  font-weight: 500;
  font-size: var(--fs-base);
  text-align: left;
  color: var(--muted, #6b7280);
}
/* Таблица-список: строка = точка (№ / Широта / Долгота / ✕). */
.coord-table--list { width: auto; }
.coord-table--list .coord-th-n { width: 40px; text-align: center; }
.coord-table--list .coord-th-del { width: 30px; }
.coord-table--list .coord-n { text-align: center; font-variant-numeric: tabular-nums; color: var(--muted, #6b7280); }
.coord-table--list .coord-del { display: block; margin: 0 auto; }
.coord-table input[type="number"] {
  /* Ширина под полную координату с запасом: напр. «56,29072743778»
     (14 символов) или отрицательная долгота. 16ch — чтобы все цифры
     помещались без обрезки. Спиннеры скрыты (см. ниже) — не нужны для
     координат и съедали бы ширину. */
  width: 16ch;
  box-sizing: content-box;
  border: none;
  padding: 4px 6px;
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-md);
  background: transparent;
}
/* Прячем стрелки-спиннеры у числовых полей координат. */
.coord-table input[type="number"]::-webkit-outer-spin-button,
.coord-table input[type="number"]::-webkit-inner-spin-button { -webkit-appearance: none; margin: 0; }
.coord-table input[type="number"] { -moz-appearance: textfield; appearance: textfield; }
.coord-table input[type="number"]:focus {
  outline: 2px solid var(--primary, #2563eb);
  outline-offset: -2px;
}
.coord-table .coord-del {
  border: none;
  background: transparent;
  cursor: pointer;
  padding: 0 2px;
  font-size: var(--fs-sm);
  line-height: 1;
  color: var(--danger, #b91c1c);
}
.coord-table .coord-del:hover { color: #7f1010; }

/* ============================================================================
 * Вкладка «Фото / Сканы» в карточке записи книги: галерея + сканы (PDF/img)
 * ============================================================================ */
.file-upload {
  display: flex; align-items: center; gap: 10px;
  margin: 4px 0 8px;
}
.file-upload__hint { font-size: var(--fs-base); }
.file-upload .btn { cursor: pointer; }

/*
  .file-picker — стилизованная альтернатива нативному <input type="file">
  внутри форм (импорт JSON, XLSX и т.п.). Сам input спрятан через `hidden`,
  кликается через <label class="btn">; имя выбранного файла рисуется
  отдельным span'ом справа. До v0.69.3 в этих местах вылезала нативная
  «древневиндовая» кнопка «Browse…», которая ломала визуал всей формы.
*/
.file-picker {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-top: 4px;
  flex-wrap: wrap;
}
.file-picker .btn { cursor: pointer; }
.file-picker__name {
  font-size: var(--fs-base);
  word-break: break-all;
}

/* ── «Обратиться в техподдержку» (с v0.74) ────────────────────────── */
.support-toolbar {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: wrap;
  margin: 8px 0 10px;
}
.support-toolbar__label { font-size: var(--fs-base); color: var(--muted); font-weight: 500; }
.support-tool.is-active {
  background: var(--primary);
  border-color: var(--primary);
  color: #fff;
}
.support-toolbar__color {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  font-size: var(--fs-base);
  color: var(--muted);
  cursor: pointer;
}
.support-toolbar__color input[type="color"] {
  width: 28px; height: 24px; padding: 0; border: 1px solid var(--border);
  border-radius: 4px; cursor: pointer; background: none;
}
.support-modal {
  max-width: min(1180px, 96vw);
  width: 100%;
}
.support-canvas-wrap {
  border: 1px solid var(--border);
  border-radius: 6px;
  overflow: hidden;
  background: #fff;
  box-shadow: var(--shadow, 0 1px 3px rgba(0,0,0,.1));
  width: 100%;
  /* max-width задаётся inline = натуральная ширина скрина, чтобы не
     растягивать картинку выше 100% (иначе размылась бы). */
}
/* Канвас масштабируется по ширине контейнера; внутреннее разрешение
   (атрибуты width/height) сохраняется, поэтому отрисовка чёткая, а
   координаты мыши переводятся через getBoundingClientRect. */
#support-canvas {
  display: block;
  cursor: crosshair;
  width: 100%;
  height: auto;
  touch-action: none;
}

.file-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(140px, 1fr));
  gap: 10px;
  margin-top: 4px;
}

.file-card {
  display: flex;
  flex-direction: column;
  gap: 4px;
  padding: 6px;
  border: 1px solid var(--border);
  border-radius: 4px;
  background: var(--surface); /* токен вместо #fff — тёмная тема */
}
.file-card__thumb {
  display: block;
  width: 100%;
  height: 100px;
  border-radius: 3px;
  overflow: hidden;
  background: #e5e7eb;
}
.file-card__thumb img {
  width: 100%; height: 100%; object-fit: cover; display: block;
}
/* Снимок числится за записью, а файла ещё нет: архив инвентаризации
   переносят отдельно от базы и заливают частями. Оператору важно понять,
   что это временно, поэтому пишем словами, а не значком. */
.file-card__missing {
  width: 100%; height: 100%;
  display: flex; align-items: center; justify-content: center;
  padding: 6px; box-sizing: border-box;
  text-align: center; line-height: 1.25;
  font-size: var(--fs-xs, 11px); color: var(--muted);
  background: var(--surface-alt);
}
.file-card__thumb--doc {
  display: flex; align-items: center; justify-content: center;
  background: #f3f4f6;
  color: var(--muted);
  font-weight: 600;
  letter-spacing: 0.5px;
}
.file-card__mime { font-size: var(--fs-base); }
.file-card__meta {
  display: flex; flex-direction: column; gap: 2px;
  min-width: 0;
}
.file-card__name {
  font-size: var(--fs-base);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.file-card__size { font-size: var(--fs-xs); }
.btn--small {
  padding: 2px 8px;
  font-size: var(--fs-sm);
  /* .btn задаёт min-height: 36px для нормальных кнопок; .btn--small
     намеренно компактнее (используется в плотных списках, в
     таблицах), переопределяем. Значение — из общей шкалы --btn-h-*;
     класс — исторический синоним нового .btn--xs. */
  min-height: var(--btn-h-xs);
}

/* ============================================================================
 * Модалка «Колонки таблицы» — список с drag-n-drop для смены порядка.
 * Каждая строка: ≡ (handle для перетаскивания) + чекбокс (видимость) + label.
 * При перетаскивании строка получает .col-row--dragging (полупрозрачная),
 * строка под курсором — .col-row--drop-target (синяя полоска сверху или снизу
 * в зависимости от data-drop-before).
 * ============================================================================ */
.col-list {
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.col-row {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 6px 8px;
  border: 1px solid transparent;
  border-radius: 4px;
  background: var(--surface);
  cursor: default;
  user-select: none;
}
.col-row:hover { background: var(--bg-soft); }
.col-row__handle {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  font-size: var(--fs-lg);
  color: var(--muted);
  cursor: grab;
}
.col-row[draggable="true"]:active .col-row__handle { cursor: grabbing; }
.col-row__label { flex: 1; }
/* Кнопки ↑/↓ — альтернатива drag&drop (тачпад/клавиатура). Появляются
   заметнее при наведении/фокусе на строку, но кликабельны всегда. */
.col-row__move { display: inline-flex; gap: 2px; flex-shrink: 0; }
.col-row__move .btn--icon { min-width: 26px; min-height: 26px; padding: 2px 6px; line-height: 1; }
/* «? Как это работает» — компактная ссылка на статью справки в шапке сложных
   страниц (helpLink в app.js). Мелкая, приглушённая, не спорит с h1. */
.help-inline-link {
  font-size: var(--fs-sm);
  font-weight: 400;
  color: var(--primary);
  text-decoration: none;
  vertical-align: middle;
  margin-left: 8px;
  white-space: nowrap;
}
.help-inline-link:hover { text-decoration: underline; }
.col-row--dragging {
  opacity: 0.45;
  background: var(--primary-soft);
  border-color: var(--primary);
}
/* Полоска-индикатор перед/после строки-цели, в зависимости от того, ближе
   к верхней или нижней половине строки находится курсор (data-drop-before). */
.col-row--drop-target[data-drop-before="1"] { box-shadow: 0 -2px 0 var(--primary); }
.col-row--drop-target[data-drop-before="0"] { box-shadow: 0 2px 0 var(--primary); }

/* ============================================================================
 * Лайтбокс предпросмотра файла (фото / PDF) на вкладке «Фото / Сканы».
 * Картинка вписывается в контейнер; PDF рендерится в <iframe> на всю
 * высоту окна. Закрытие: клик по фону, кнопка ×, Esc.
 * ============================================================================ */
.file-preview-backdrop {
  position: fixed; inset: 0;
  background: rgba(15, 23, 42, 0.78);
  display: flex; align-items: center; justify-content: center;
  z-index: var(--z-lightbox);
  padding: 24px;
}
.file-preview {
  background: #fff;
  border-radius: 6px;
  display: flex; flex-direction: column;
  width: min(95vw, 1100px);
  max-height: 92vh;
  overflow: hidden;
  box-shadow: 0 20px 60px rgba(0, 0, 0, 0.4);
}
.file-preview__head {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border);
  background: var(--surface-alt);
}
.file-preview__title {
  flex: 1;
  font-weight: 600;
  font-size: var(--fs-base);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis;
}
.file-preview__actions {
  display: flex; gap: 4px; align-items: center;
}
/* Кнопки в шапке лайтбокса визуально выровнены под стиль топбара —
   прозрачный фон, лёгкая голубая подсветка на hover, без рамки.
   Так шапка модалки и шапка приложения смотрятся одной семьёй
   (запрос пользователя 2026-05-05). */
.file-preview__actions .btn,
.file-preview__actions .btn--small {
  background: transparent;
  border: none;
  color: var(--fg);
  font-weight: 500;
  font-size: var(--fs-base);
  padding: 4px 10px;
  border-radius: 6px;
  line-height: 1.5;
  box-shadow: none;
}
.file-preview__actions .btn:hover,
.file-preview__actions .btn--small:hover {
  background: var(--btn-bg);
  text-decoration: none;
}
.file-preview__actions .btn[aria-label="Закрыть"] {
  font-size: 18px;
  padding: 0 8px;
  line-height: 1;
}
.file-preview__body {
  flex: 1;
  display: flex; align-items: center; justify-content: center;
  background: #1f2937;
  min-height: 200px;
  overflow: hidden; /* zoom/pan живёт внутри viewport */
}
/* Viewport картинки — клиппинг + позиционирование .file-preview__img,
   у которой transform-origin (0,0) полностью описывает положение через
   translate+scale (см. _wireImageZoomPan). */
.file-preview__viewport {
  position: relative;
  width: 100%;
  height: 86vh;
  overflow: hidden;
  cursor: grab;
  user-select: none;
}
.file-preview__viewport:active { cursor: grabbing; }
.file-preview__img {
  position: absolute;
  top: 0; left: 0;
  transform-origin: 0 0;
  background: #fff;
  /* JS выставит transform; пока не загрузилось — спрячем по умолчанию,
     fit() в onload вычислит правильное положение. */
  will-change: transform;
  user-select: none;
  -webkit-user-drag: none;
  /* Сглаживание при дробных масштабах. */
  image-rendering: auto;
}
.file-preview__frame {
  width: 100%;
  height: 86vh;
  border: 0;
  background: #fff;
}
.file-preview__nopreview {
  padding: 32px;
  display: flex; flex-direction: column; align-items: center; gap: 8px;
  color: #fff;
}
.file-preview__nopreview-icon {
  font-size: 32px;
  font-weight: 700;
  letter-spacing: 1px;
  background: #374151;
  color: #f3f4f6;
  padding: 16px 24px;
  border-radius: 6px;
}

/* На близком зуме (≥17, уровень улицы) плашка названия кладбища
   только мешает: оператор уже работает внутри кладбища с конкретными
   участками, а плашка перекрывает их собой. Класс выставляется на
   контейнере карты по событию zoomend. То же — для outlier-плашек
   кладбищ (если у кладбища есть «оторвавшиеся» кластера плотов и для
   них нарисована дополнительная плашка). */
.osiris-deep-zoom .cem-label-marker {
  display: none;
}

/* Маркеры инфраструктуры (вода, парковка, туалет — POI-иконки) ведут себя
   зеркально плашке названия: на обзорном зуме (<17) их нет — там важнее
   название кладбища, а россыпь иконок только мешает; при z≥17, когда плашка
   названия уже исчезла, маркеры появляются. По умолчанию pane скрыт, класс
   osiris-deep-zoom (z≥17, выставляется в updateLabelsVisibility) его
   показывает. Полигональные зоны инфраструктуры — в другом pane, не затронуты. */
.leaflet-osirisInfraMarker-pane {
  display: none;
}
.osiris-deep-zoom .leaflet-osirisInfraMarker-pane {
  display: block;
}
/* В режиме правки структуры POI-маркеры видны на любом зуме — иначе на
   обзорном зуме они скрыты и их нельзя перетащить. */
.osiris-editing .leaflet-osirisInfraMarker-pane {
  display: block;
}

/* [feature:import1c] */
/* Индетерминантный прогресс-бар (для стадий, где сервер не сообщает
   реальный процент: ctool1cd → JSON → импорт). Используется в
   /import-1cd (единственный потребитель — paintImport1CDStatus), поэтому
   вырезается вместе со страницей импорта 1С. Идея — классический striped-animated паттерн как у
   Bootstrap: прозрачная диагональная полосатая текстура поверх
   сплошной заливки, текстура едет влево с постоянной скоростью.
   Так пользователь видит «работа идёт», но индикатор не прыгает
   взад-вперёд (что воспринимается как глюк).

   `!important` нужен, потому что у самого DIV'а inline-shorthand
   `background:#0369a1` обнуляет background-image — без important наша
   текстура «пропадает», бар становится сплошной заливкой. */
.progress-indeterminate {
  background-image: linear-gradient(
    45deg,
    rgba(255, 255, 255, 0.25) 25%,
    transparent 25%,
    transparent 50%,
    rgba(255, 255, 255, 0.25) 50%,
    rgba(255, 255, 255, 0.25) 75%,
    transparent 75%,
    transparent
  ) !important;
  background-size: 24px 24px !important;
  animation: progress-stripe-flow 1s linear infinite;
}
@keyframes progress-stripe-flow {
  from { background-position: 24px 0; }
  to   { background-position: 0 0; }
}
/* [/feature:import1c] */

/* =====================================================================
   v0.54 — UI spacing patches: предотвращаем слипание элементов в
   inline-style flex-контейнерах, добавляем breathing room в шапках
   карточек, формах и модалках. Не ломает существующих стилей —
   только декорирует там, где padding/gap были забыты.
   ===================================================================== */

/* Ряд кнопок в шапке карточки документа (Реестр захоронений / запись /
   участок). Раньше «← К списку», «📄 Свидетельство», «Удалить» сидели
   слишком близко. */
.page__actions {
  display: flex;
  gap: 10px;
  align-items: center;
  flex-wrap: wrap;
  /* Центрируем блок кнопок по вертикали относительно h1. .page__header
     выравнивает детей по baseline; когда в .page__actions появляется/
     исчезает индикатор «✓ Сохранено» (автосейв карточки захоронения),
     baseline блока смещается и кнопки «прыгают» вверх-вниз. align-self:
     center убирает зависимость от baseline — блок больше не дёргается
     (жалоба оператора 2026-05-27). */
  align-self: center;
}

/* Кнопки в строке внутри плашек (Резервное копирование, Сервер
   обновлений и т.п.) — между button и подсказкой `<span class="muted">`
   должен быть явный отступ. */
.placeholder .row > * + * { margin-left: 0; }
.placeholder .row { gap: 10px !important; }

/* Контейнеры fieldset с двумя date-input'ами (рождения / смерти /
   захоронения) на странице отчёта. Подпись «с» / «по» прилипала
   к input'у — теперь между span и input есть gap. */
fieldset.field > legend { margin-bottom: 4px; }
fieldset.field > div > label > span { margin-right: 6px; }

/* Список чекбоксов колонок отчёта — каждое значение в своей строке
   с лёгким padding'ом, чтобы клик попадал на label целиком. */
#rep-cols label,
#rep-cols .checkbox-row {
  padding: 4px 6px;
  border-radius: 4px;
  transition: background 0.1s ease;
}
#rep-cols label:hover { background: #f3f4f6; }

/* Фильтры журнала захоронений: радиокнопки источника записи
   (Все / Только книга / Только инвентаризация) — должны быть в
   столбик с зазором, а не слипаться вертикально. */
.journal-filters__group { display: flex; flex-direction: column; gap: 6px; }
.journal-filters__group .field { margin-bottom: 0 !important; }
.journal-filters__group .field.row { padding: 2px 0; }

/* Справка: в TOC увеличиваем padding и зазор между пунктами; в
   article — больше воздуха перед h2 и h3. */
.help-page__toc a { padding: 8px 10px !important; line-height: 1.35 !important; }
.help-page__toc a + a { margin-top: 2px; }
.help-page__article h2 { margin-bottom: 14px !important; }
.help-page__article ul li,
.help-page__article ol li { margin-bottom: 8px !important; }
.help-page__article h2 + ul,
.help-page__article h2 + ol,
.help-page__article h3 + ul,
.help-page__article h3 + ol { margin-top: 8px; }

/* Модалки: первый элемент в body не должен прилипать к границе
   заголовка. */
.modal__body > *:first-child { margin-top: 0; }
.modal__body .field:last-child { margin-bottom: 0; }
.modal__body fieldset + fieldset,
.modal__body section + section { margin-top: 14px; }

/* Доплата по плашкам страниц-разделов админки: между двумя section
   подряд (без явного margin-top на второй) добавляем зазор. */
.placeholder + .placeholder { margin-top: 18px; }
section.placeholder h2:first-child { margin-top: 0; }
section.placeholder p:first-of-type { margin-top: 0; }

/* «Реестр захоронений (XLSX)» — компактные расстояния, чтобы вся
   форма (10+ фильтров + ~12 колонок) помещалась на экран без
   прокрутки на типичном ноутбуке 1080p. Снимаем дефолтные
   .field { margin-bottom: 12px; gap: 4px }, ужимаем поля ввода и
   fieldset'ы. Изолировано классом .report-form, остальные формы
   проекта это не затрагивает. */
.report-form .field { margin-bottom: 4px; gap: 2px; }
.report-form .field > span { font-size: var(--fs-xs); }
.report-form .field input,
.report-form .field select { padding: 4px 8px; min-height: 28px; font-size: var(--fs-base); }
.report-form fieldset.field { padding: 4px 12px 6px !important; margin-top: 6px !important; }
.report-form fieldset.field legend { font-size: var(--fs-xs); }
.report-form fieldset.field input[type="date"] { padding: 2px 6px; min-height: 24px; }
.report-form h3 { margin: 0 0 4px !important; }
.report-form #rep-cols { gap: 2px !important; font-size: var(--fs-base) !important; }
.report-form #rep-cols label { padding: 1px 0; }

/* ---- Настраиваемая форма (Сервис → Настраиваемая форма, v0.85) ---- */
/* Поля в три ровные колонки (без «лесенок»), компактные межстрочные отступы. */
.cf-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 6px 16px;
  align-items: start;
}
.cf-grid .field { margin: 0; }
/* Многострочные поля (примечания/адрес) — на всю ширину строки. */
.cf-grid .cf-wide { grid-column: 1 / -1; }
@media (max-width: 1000px) { .cf-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px)  { .cf-grid { grid-template-columns: 1fr; } }

/* Панели «Настраиваемой формы»: кнопки, селекты и поля — одной высотой,
   в одну линию (за основу высота кнопки). */
.cf-toolbar, .cf-modebar { align-items: center; }
.cf-toolbar .btn, .cf-modebar .btn,
.cf-toolbar label.btn, .cf-modebar label.btn,
.cf-toolbar .cf-ctl, .cf-modebar .cf-ctl {
  /* Исторические 38px: на 2px выше стандартной кнопки (--btn-h-md=36),
     чтобы селекты с нативной рамкой не резались. Привязано к шкале. */
  height: calc(var(--btn-h-md) + 2px);
  box-sizing: border-box;
  display: inline-flex;
  align-items: center;
  margin: 0;
}
.cf-ctl {
  padding: 0 10px;
  border: 1px solid #cbd5e1;
  border-radius: 6px;
  background: var(--surface, #fff);
  color: inherit;
  font: inherit;
}
.cf-tb-label { font-size: var(--fs-base); color: #475569; white-space: nowrap; }

/* =====================================================================
   2026-07: классы под ближайшие JS-фазы (аудит UI, разделы 2/4/7).
   CSS готов заранее, JS навешивает классы позже.
   ===================================================================== */

/* Обновление списка без стирания старого контента: таблица тускнеет и
   не ловит клики, пока не пришёл ответ (вместо мигания «Загрузка…»
   на каждый тик debounce — см. аудит, раздел 2). */
.is-refreshing {
  opacity: .5;
  pointer-events: none;
  cursor: progress;
}

/* Скелетон-строки на месте будущего списка — layout не «прыгает».
   Использование: <div class="skeleton-rows"><div></div>×N</div>. */
.skeleton-rows > div {
  height: 28px;
  border-radius: 6px;
  background: linear-gradient(90deg, var(--border) 25%, transparent 50%, var(--border) 75%);
  background-size: 200% 100%;
  animation: shimmer 1.2s infinite;
  margin-bottom: 8px;
}
@keyframes shimmer {
  to { background-position: -200% 0; }
}

/* ── Оверфлоу топбара «Ещё ▾» ──
   На широких экранах группа #nav-more скрыта; на узких (≤1280px —
   ноутбуки 1366×768 и масштаб Windows 125-150%) вместо групп
   «Импорт/экспорт», «Участки», «Сервис» показывается она (дубли их
   пунктов уже лежат в index.html внутри #nav-more).
   :not([hidden]) обязателен: роль-фильтр JS прячет группу атрибутом
   hidden, и CSS не должен его перебивать. */
#nav-more { display: none; }
@media (max-width: 1280px) {
  #nav-import, #nav-plots, #nav-service { display: none; }
  #nav-more:not([hidden]) { display: inline-flex; }
}

/* ── Мини-набор mask-иконок ──
   По образцу .icon-compass: форма — SVG-маска, цвет — currentColor,
   поэтому иконка перекрашивается вместе с текстом кнопки/ссылки и
   темой. Замена разнокалиберным глифам ⚠ ✓ ✕ (шрифтозависимы, всегда
   чёрные, разные под Win/macOS). Использование: <span class="ico
   ico--check"></span> рядом с текстом. */
.ico {
  display: inline-block;
  width: 14px;
  height: 14px;
  background: currentColor;
  -webkit-mask-size: contain;
          mask-size: contain;
  -webkit-mask-repeat: no-repeat;
          mask-repeat: no-repeat;
  -webkit-mask-position: center;
          mask-position: center;
  vertical-align: -2px;
}
/* Треугольник с восклицательным знаком. */
.ico--warn {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M12 2L22.5 20.5H1.5ZM11 9.5h2v5h-2zM11 16.5h2v2h-2z'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M12 2L22.5 20.5H1.5ZM11 9.5h2v5h-2zM11 16.5h2v2h-2z'/%3E%3C/svg%3E");
}
/* Галочка. */
.ico--check {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16.2 4.8 12l-1.4 1.4L9 19 21 7l-1.4-1.4z'/%3E%3C/svg%3E");
}
/* Крестик (закрыть / отменить). */
.ico--close {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.4 17.6 5 12 10.6 6.4 5 5 6.4 10.6 12 5 17.6 6.4 19 12 13.4 17.6 19 19 17.6 13.4 12z'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 6.4 17.6 5 12 10.6 6.4 5 5 6.4 10.6 12 5 17.6 6.4 19 12 13.4 17.6 19 19 17.6 13.4 12z'/%3E%3C/svg%3E");
}
/* Стрелка вниз в лоток (скачать). */
.ico--download {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 9h-4V3H9v6H5l7 7zM5 18v2h14v-2z'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M19 9h-4V3H9v6H5l7 7zM5 18v2h14v-2z'/%3E%3C/svg%3E");
}
/* Стрелка вверх из лотка (загрузить). */
.ico--upload {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16h6v-6h4l-7-7-7 7h4zM5 18v2h14v-2z'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath d='M9 16h6v-6h4l-7-7-7 7h4zM5 18v2h14v-2z'/%3E%3C/svg%3E");
}
/* Булавка-геоточка (показать на карте). */
.ico--pin {
  -webkit-mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 1 1 0-5 2.5 2.5 0 0 1 0 5z'/%3E%3C/svg%3E");
          mask-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpath fill-rule='evenodd' d='M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7zm0 9.5a2.5 2.5 0 1 1 0-5 2.5 2.5 0 0 1 0 5z'/%3E%3C/svg%3E");
}

/* ============ Печать (Ctrl+P) ============
   Базовые правила: прячем «хром» приложения (топбар, полосу вкладок
   документов, инструменты карты, боковую панель реестра, кнопки),
   таблицы раскрываем на полную высоту без внутренних скроллов, фон
   белый / текст чёрный — независимо от темы. До 2026-07 @media print
   не было вовсе: Ctrl+P печатал топбар и обрезанную таблицу.
   !important — чтобы гарантированно перебить inline-стили из JS. */
@media print {
  /* Свёрнутые разделы раскрываются JS-ом (beforeprint), но их внутренние
     скроллы надо распрямить, иначе на бумагу попадёт только первый экран
     таблицы координат. */
  .coord-scroll, .coord-details {
    overflow: visible !important;
    max-height: none !important;
  }
  .topbar,
  #doc-tabs,
  .doc-tabs,
  .map-tools,
  .journal-layout__side,
  .page__actions,
  .tabs__nav,
  .modal-backdrop,
  .save-status,
  .btn {
    display: none !important;
  }
  /* Карточка захоронения: по умолчанию печатается активная вкладка (базовое
     правило .tabs__pane{display:none} оставляет видимой лишь .is-active).
     Если оператор выбрал разделы в диалоге печати, тело получает класс
     printing-selected — тогда печатаются ИМЕННО отмеченные панели, а не та,
     что открыта на экране. */
  body.printing-selected .tabs__pane { display: none !important; }
  body.printing-selected .tabs__pane[data-print-on] { display: block !important; }

  /* Поля ввода на бумаге — это документ, а не форма. Рамки, заливку и
     стрелку выпадающего списка убираем, значение печатается как обычный
     текст (замечание 08.2026, скрин печатной формы «Умерший»). Флажки
     оставляем как есть — они и на бумаге читаются как флажки. */
  input, select, textarea {
    border: none !important;
    background: transparent !important;
    box-shadow: none !important;
    padding: 0 !important;
    color: #000 !important;
    font: inherit !important;
    appearance: none !important;
    -webkit-appearance: none !important;
    resize: none !important;
  }
  textarea { overflow: visible !important; height: auto !important; min-height: 0 !important; }
  input[type="checkbox"], input[type="radio"] {
    appearance: auto !important;
    -webkit-appearance: auto !important;
  }

  /* Плотнее по вертикали: карточка участка с координатами укладывалась на
     два листа, причём на втором оставалось одно поле. */
   { margin: 12mm; }
  body { font-size: 12px; }
  .form-grid, .fields-grid { gap: 4px 12px !important; }
  .field { margin-bottom: 4px !important; }
  h1 { font-size: 18px !important; margin: 0 0 6px !important; }
  h3 { font-size: 14px !important; margin: 8px 0 4px !important; }
  .page__header { margin-bottom: 6px !important; }
  .content--full, .content { max-width: none !important; }
  .table-wrap {
    overflow: visible !important;
    max-height: none !important;
  }
  body {
    background: #fff;
    color: #000;
  }
}


/* Координата вне диапазона WGS84 — подсветка поля и подпись под таблицей.
   Замечание пользователя 08.2026: форма принимала «324321» как широту и
   молча сохраняла мусор. */
.coord-input--bad {
  border-color: #dc2626 !important;
  background: #fef2f2;
}
.coord-error {
  margin: 6px 0 0;
  font-size: 12px;
  line-height: 1.4;
  color: #b91c1c;
}

/* Одноколоночный вариант сетки полей — для узких панелей (боковая панель
   карты). Двухколоночная сетка там переносила значение под подпись, и
   соседние поля оказывались на разных уровнях. */
.fields-grid--one {
  grid-template-columns: 1fr;
}

/* Постоянная подпись «Сохраняется автоматически» у шапки карточки участка.
   Ненавязчиво: мельче основного текста, приглушённая, не конкурирует со
   статусом «✓ Сохранено» рядом. */
.save-hint {
  font-size: 12px;
  align-self: center;
  white-space: nowrap;
}

/* Ошибка конкретного реквизита — у самого поля, а не общей плашкой.
   Раньше единственным сообщением при сохранении было «нет связи с
   сервером», то есть про что угодно, кроме реальной причины. */
.field-input--bad {
  border-color: #dc2626 !important;
  background: #fef2f2;
}
.field-error {
  margin: 4px 0 0;
  font-size: 12px;
  line-height: 1.35;
  color: #b91c1c;
}

/* ============ Печатный ДОКУМЕНТ (#print-doc) ============
   Собирается перед печатью из данных карточки (см. printAsDocument).
   На экране не показывается никогда — только на бумаге. Раньше печаталась
   сама форма, и на лист уходил её снимок с рамками полей. */
#print-doc { display: none; }

@media print {
  /* Когда печатаем документ — прячем приложение целиком и показываем только
     собранный узел. */
  body.printing-doc > *:not(#print-doc) { display: none !important; }
  body.printing-doc #print-doc { display: block !important; }

  #print-doc {
    color: #000;
    /* 9,5pt: с крупным снимком и всеми разделами лист плотный, а мельче
       9pt документ уже неудобно читать вслух у стойки. */
    font-size: 9.5pt;
    line-height: 1.18;
  }
  .print-doc__head {
    display: flex;
    gap: 12px;
    align-items: flex-start;
    justify-content: space-between;
    border-bottom: 1.5pt solid #000;
    padding-bottom: 4pt;
    margin-bottom: 6pt;
  }
  #print-doc h1 {
    font-size: 13.5pt !important;
    margin: 0 0 2pt !important;
  }
  .print-doc__sub { font-size: 9pt; color: #444; }
  .print-doc__meta {
    display: flex;
    flex-wrap: wrap;
    gap: 2pt 10pt;
    font-size: 8.5pt;
    max-width: 60%;
    justify-content: flex-end;
    text-align: right;
  }
  /* Верхний ряд: первый раздел слева, снимок справа. Ниже — остальные
     разделы в две колонки (.print-doc__rest). Такая раскладка, а не
     обтекание: таблица не заходит под float (она открывает свой контекст
     форматирования), поэтому при float под снимком оставалась пустая
     полоса в пол-листа и карточка уезжала на второй лист. */
  .print-doc__top {
    display: flex;
    gap: 6mm;
    align-items: flex-start;
    margin-bottom: 6pt;
  }
  .print-doc__top-main { flex: 1; min-width: 0; }
  .print-doc__top-photo { flex: 0 0 auto; }
  /* Фото — КРУПНОЕ: просьба пользователя 08.2026 «минимум 1/8 листа, лучше
     треть». 85×105 мм — это ~8 900 мм² при печатной области A4 с полями
     12 мм (186×273 = 50 778 мм²), то есть примерно шестая часть листа:
     заметно больше требуемого минимума, но столько, чтобы карточка со
     всеми разделами оставалась на ОДНОМ листе.
     object-fit: cover — снимок ЗАПОЛНЯЕТ отведённое место. С contain
     горизонтальный кадр давал сверху и снизу серые поля, и от обещанной
     «шестой части листа» самой фотографии оставалась половина. */
  .print-doc__photo {
    display: block;
    width: 85mm;
    height: 105mm;
    object-fit: cover;
    object-position: center;
    background: #f4f4f4;
    border: 0.5pt solid #999;
  }
  /* Остальные разделы — в две колонки. Раздел не рвём между колонками:
     половина «Ответственного» в одной колонке, половина в другой читается
     как ошибка вёрстки. */
  .print-doc__rest { column-count: 2; column-gap: 8mm; }
  .print-doc__section { break-inside: avoid; margin-bottom: 4pt; }
  /* Разделы с таблицами — снизу, во всю ширину листа. */
  .print-doc__wide { clear: both; }
  #print-doc h2 {
    font-size: 11.5pt !important;
    margin: 0 0 2pt !important;
    padding-bottom: 1.5pt;
    border-bottom: 0.5pt solid #999;
  }
  /* Пары «реквизит: значение» — столбиком: сами разделы уже разложены в две
     колонки (.print-doc__rest), и вторая колонка ВНУТРИ раздела дала бы
     четыре колонки на листе — в них не помещается ни один адрес. */
  .print-doc__pairs {
    width: 100%;
    border-collapse: collapse;
  }
  .print-doc__pairs tbody { display: block; }
  .print-doc__pairs tr { display: block; break-inside: avoid; }
  .print-doc__pairs th {
    font-weight: normal;
    color: #333;
    text-align: left;
    padding: 0.2pt 4pt 0.2pt 0;
    white-space: nowrap;
  }
  .print-doc__pairs th::after { content: ":"; }
  .print-doc__pairs td { font-weight: 600; padding: 0.2pt 0; }
  .print-doc__pairs th, .print-doc__pairs td { display: inline; }
  /* Таблица внутри узкой колонки: table-layout fixed + перенос слов, иначе
     широкий журнал регистраций уезжал за край колонки и правые столбцы
     обрезались (на бумаге это выглядело как потерянные данные). */
  .print-doc__table {
    width: 100%;
    table-layout: fixed;
    border-collapse: collapse;
    font-size: 7.5pt;
    margin-top: 3pt;
  }
  .print-doc__table th, .print-doc__table td {
    border: 0.5pt solid #999;
    padding: 1pt 2pt;
    text-align: left;
    overflow-wrap: anywhere;
  }
  .print-doc__table th { background: #eee; font-weight: 600; }
}

@media print {
  /* Подзаголовок таблицы внутри раздела печатного документа
     (например «Координаты полигона» в карточке участка). */
  .print-doc__subhead {
    font-size: 9.5pt;
    margin: 4pt 0 2pt;
    font-weight: 600;
  }
}
