/* ИС ПФ ВНИРО */

/* =====================================================================
   01. Imports and fonts
   ===================================================================== */

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 400;
  font-display: swap;
  src: local("Inter Regular"), local("Inter-Regular");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 500;
  font-display: swap;
  src: local("Inter Medium"), local("Inter-Medium");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 600;
  font-display: swap;
  src: local("Inter SemiBold"), local("Inter-SemiBold");
}

@font-face {
  font-family: "Inter";
  font-style: normal;
  font-weight: 700;
  font-display: swap;
  src: local("Inter Bold"), local("Inter-Bold");
}

/* =====================================================================
   02. Variables and themes
   ===================================================================== */

:root {
  /* --- Base (Backgrounds) --- */
  --bg: #ffffff;
  --bg-soft: #f7f7f8;
  --bg-elev: #ffffff;
  --bg-hover: #f2f2f4;
  --bg-active: #ebebee;
  --surface: #ffffff;

  /* --- Typography (Colors) --- */
  --text: #18181b;
  --text-muted: #52525b;
  --text-dim: #71717a;
  --text-faint: #a1a1aa;

  /* --- Actions & Interactive --- */
  --accent: #1c8bed;
  --accent-fg: #ffffff;
  --accent-soft: rgba(28, 139, 237, .10);
  --water-map-color: #6ba5d7;
  --steel-azure: #064789ff;
  --rich-cerulean: #427aa1ff;
  --alice-blue: #ebf2faff;
  --molten-lava: #780000ff;
  --brick-red: #c1121fff;
  --papaya-whip: #fdf0d5ff;
  --deep-space-blue: #003049ff;
  --steel-blue: #669bbcff;
  --danger: #b91c1c;
  --danger-bg: #fef2f2;
  --warn: #b45309;
  --ok: #15803d;
  --tender: #f4e4a6;
  --focus-ring: 0 0 0 3px rgba(24, 24, 27, .12);

  /* --- Notifications (deal diagnostics) --- */
  --not-error: #dd6e42;
  --not-warning: #e8dab2;
  --not-message: #4f6d7a;

  /* --- Chart series (finance dynamics) --- */
  --terra: #dd6e42;

  /* --- Borders & Surfaces --- */
  --border: #e4e4e7;
  --border-strong: #d4d4d8;
  --radius: 8px;
  --radius-lg: 14px;
  --radius-search: 31px;
  --radius-full: 999px;
  --ring-3: 3px;

  /* --- Statuses (Field Surveys) --- */
  --st-demand: #c7522a;
  --st-planned: #e5c185;
  --st-surveyed: #fbf2c4;
  --st-processed: #74a892;
  --st-ready: #008585;

  /* --- Deal statuses (ВНИРО.Контракт) --- */
  --deal-neutral: var(--bg);
  --deal-neutral-bad: #e3e3df;
  --deal-attention: #f9f9f6;
  --deal-strong-attention: #f5f4eb;
  --deal-cool: #dff1e3;
  --deal-super-cool: #dbf0dc;

  /* --- Shadows & Effects --- */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .04), 0 1px 3px rgba(0, 0, 0, .05);
  --shadow-2: 0 4px 10px rgba(0, 0, 0, .06), 0 2px 4px rgba(0, 0, 0, .04);
  --shadow-3: 0 10px 30px rgba(0, 0, 0, .10), 0 4px 8px rgba(0, 0, 0, .05);
  --blur: 12px;

  /* --- Layout Metrics --- */
  --sz-header: 56px;
  --sz-max-width: 1440px;
  --sz-side-panel: 560px;
  --sz-sidebar-w: 240px;
  --sz-sidebar-max: 380px;
  --sz-modal-w: 800px;
  --sz-modal-sm: 400px;
  --sz-form-w: 360px;
  --sz-kv-label-w: 160px;
  --sz-filter-w: 200px;
  --sz-num-width: 200px;
  --sz-row-h: var(--sp-huge);
  --sz-col-name-w: var(--sz-sidebar-w);
  --sz-hero-h: calc(var(--sp-huge) * 3);
  --sz-list-max-h: calc(var(--sp-huge) * 6);
  --sz-list-sm-h: calc(var(--sp-huge) * 4);
  --sz-pdf-min-h: calc(var(--sp-huge) * 10);
  --sz-map-min-h: var(--sz-sidebar-w);
  --sz-map-max-h: var(--sz-pdf-min-h);
  --sz-stat-w: 112px;
  /* Высота компактной карточки = отступы сверху и снизу + строка суммы.
     Считаем из токенов, чтобы она не разъехалась при правке отступов. */
  --sz-deal-card-h: calc(var(--sp-xl) * 2 + var(--fs-lg) * 1.4);
  --sz-deal-card-w: 400px;
  --sz-msg-w: var(--sz-modal-sm);
  --sz-timeline-w: calc(var(--sp-huge) * 2);
  --sz-toggle-left: calc(var(--sp-huge) * 2);
  --ht-input: 34px;
  --sz-ui-action: 36px;
  --sz-ui-sm: 18px;
  --sz-fab: var(--sz-header);
  --sz-avatar: calc(var(--sp-huge) * 3);
  --sz-avatar-sm: var(--sz-stat-w);
  --sz-avatar-fallback: 72px;
  --sz-logo-splash: calc(var(--sp-huge) * 2);
  --sz-logo-sm: 120px;
  --sz-filter: var(--sz-ui-sm);
  --sz-icon-add: var(--sp-xl);
  --sz-icon-offset: -3px;
  /* Колонки шапки документа (финансовые документы, вертикальный таймлайн). */
  --sz-doc-col-marker: var(--sp-xl);
  --sz-doc-col-date: 96px;
  /* Ширина, доступная при горизонтальных полях `--sp-xl` с обеих сторон. */
  --sz-avail-w: calc(100vw - var(--sp-xl) - var(--sp-xl));
  /* Минимальная ширина ячейки сетки статистики (CRM). */
  --sz-stats-col-min: 185px;
  /* Повторяющиеся габариты (см. docs/css-hardcoded-sizes.md). */
  --sz-grid-cell: 200px;
  --sz-workbook-min-h: 480px;
  --sz-page-w: 960px;

  /* --- Spacing Scale --- */
  --sp-micro: 1px;
  --sp-tiny: 2px;
  --sp-xs: 4px;
  --sp-sm: 6px;
  --sp-base: 8px;
  --sp-md: 12px;
  --sp-lg: 16px;
  --sp-xl: 24px;
  --sp-huge: 48px;
  --sp-max: 80px;

  /* --- Typography Scale --- */
  --fs-micro: 9px;
  --fs-tiny: 10px;
  --fs-xs: 11px;
  --fs-sm: 12px;
  --fs-main: 13px;
  --fs-base: 14px;
  --fs-md: 16px;
  --fs-lg: 20px;
  --fs-xl: 22px;
  --fs-2xl: 26px;
  --fs-3xl: 28px;
}

[data-theme="dark"] {
  /* --- Base (Backgrounds) --- */
  --bg: #28284e;
  --bg-soft: #30305a;
  --bg-elev: #363666;
  --bg-hover: #3f3f73;
  --bg-active: #484882;
  --surface: #333360;

  /* --- Typography (Colors) --- */
  --text: #f4f4f5;
  --text-muted: #c4c4d8;
  --text-dim: #a5a5c4;
  --text-faint: #8585aa;

  /* --- Actions & Interactive --- */
  --accent: #1c8bed;
  --accent-fg: #ffffff;
  --accent-soft: rgba(28, 139, 237, .16);
  --water-map-color: #6ba5d7;
  --danger: #fca5a5;
  --danger-bg: #4a2f45;
  --warn: #fbbf24;
  --ok: #86efac;
  --focus-ring: 0 0 0 3px rgba(244, 244, 245, .18);

  /* --- Notifications (deal diagnostics) --- */
  --not-error: #dd6e42;
  --not-warning: #e8dab2;
  --not-message: #4f6d7a;

  /* --- Chart series (finance dynamics) --- */
  --terra: #dd6e42;

  /* --- Borders & Surfaces --- */
  --border: #565686;
  --border-strong: #6b6ba0;
  --radius: 8px;
  --radius-lg: 14px;
  --radius-full: 999px;

  /* --- Deal statuses (ВНИРО.Контракт) --- */
  --deal-neutral: var(--bg);
  --deal-neutral-bad: #45453f;
  --deal-attention: #34342f;
  --deal-strong-attention: #464334;
  --deal-cool: #30483a;
  --deal-super-cool: #28533a;

  /* --- Statuses (Field Surveys) --- */
  --shadow-1: 0 1px 2px rgba(0, 0, 0, .5), 0 1px 3px rgba(0, 0, 0, .45);
  --shadow-2: 0 6px 14px rgba(0, 0, 0, .55), 0 2px 6px rgba(0, 0, 0, .4);
  --shadow-3: 0 18px 40px rgba(0, 0, 0, .7);
}

/* =====================================================================
   03. Base selectors and app shell
   ===================================================================== */

/* ---------- Reset and document defaults ---------- */

* {
  box-sizing: border-box;
}

[hidden],
.is-hidden {
  display: none !important;
}

/* --- Вспомогательные утилиты. Inline-стили запрещены (см. readme п.13): --- */
/* --- всё оформление — только через CSS, с токенами --sp-* / --fs-* / --text-* --- */
.span-full {
  grid-column: 1 / -1;
}

.text-faint {
  color: var(--text-faint);
}

.text-muted {
  color: var(--text-muted);
}

.text-dim {
  color: var(--text-dim);
}

.text-warn {
  color: var(--warn);
}

.text-ok {
  color: var(--ok);
}

.text-center {
  text-align: center;
}

.text-right {
  text-align: right;
}

.nowrap {
  white-space: nowrap;
}

.msg-max {
  max-width: 380px;
  line-height: 1.5;
}

.chosen-chip {
  background: var(--bg-active);
  border-color: var(--border-strong);
  color: var(--text);
  cursor: default;
}

/* Отступы-утилиты по токенам 4px-сетки (вместо «магических» px в inline-стилях). */
.fs-sm {
  font-size: var(--fs-sm);
}

.fs-xs {
  font-size: var(--fs-xs);
}

.lh-16 {
  line-height: 1.6;
}

.flex-1 {
  flex: 1 1 auto;
}

/* Статус-строка конфиг-диалога (цвета — только через классы, не inline). */
.cfg-status {
  color: var(--text-dim);
}

.cfg-status.cfg-ok {
  color: var(--ok);
}

.cfg-status.cfg-err {
  color: var(--danger);
}

.mt-xs { margin-top: var(--sp-xs); }
.mt-sm { margin-top: var(--sp-sm); }
.mt-base { margin-top: var(--sp-base); }
.mt-md { margin-top: var(--sp-md); }
.mt-lg { margin-top: var(--sp-lg); }
.mt-xl { margin-top: var(--sp-xl); }
.mb-xs { margin-bottom: var(--sp-xs); }
.mb-sm { margin-bottom: var(--sp-sm); }
.mb-base { margin-bottom: var(--sp-base); }
.mb-md { margin-bottom: var(--sp-md); }
.mb-lg { margin-bottom: var(--sp-lg); }
.mb-xl { margin-bottom: var(--sp-xl); }

/* Широкие вспомогательные состояния для «мягких» элементов (запрещено display:none здесь). */
.is-disabled {
  opacity: 0.35;
  cursor: not-allowed;
}

html,
body {
  margin: 0;
  padding: 0;
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  font-family: "Inter", system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  color: var(--text);
  background: var(--bg);
  font-size: var(--fs-base);
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

a {
  color: inherit;
}

button,
input,
select,
textarea,
option,
optgroup {
  font-family: inherit;
  font-size: inherit;
  color: inherit;
}

button {
  cursor: pointer;
}

button:focus {
  outline: none;
  box-shadow: none;
}

/* ---------- Application frame ---------- */

main {
  flex: 1 1 0;
  min-height: 0;
  display: block;
}

section,
.module {
  background: var(--bg);
}

.module,
.side-panel .body,
.modal .body,
.editor-overlay {
  overflow-y: auto;
}

body.module-open {
  overflow-y: visible;
}

#app {
  height: 100%;
}

/* ---------- Icons ---------- */

.i {
  width: var(--sp-xl);
  height: var(--sp-xl);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  vertical-align: var(--sz-icon-offset);
  font-size: var(--sp-xl);
  line-height: 1;
  flex: 0 0 auto;
}

.i.i-sm {
  width: var(--sp-lg);
  height: var(--sp-lg);
  font-size: var(--sp-lg);
}

.i.i-lg {
  width: var(--sp-xl);
  height: var(--sp-xl);
  font-size: var(--sp-xl);
}

.i.i-xl {
  width: var(--sp-xl);
  height: var(--sp-xl);
  font-size: var(--sp-xl);
}

/* ---------- Global header ---------- */

header {
  flex: 0 0 auto;
  position: sticky;
  top: 0;
  z-index: 60;
  height: var(--sz-header);
  background: var(--bg);
  color: var(--text);
}

.brand-name {
  color: inherit;
}

.header-inner {
  display: flex;
  align-items: center;
  gap: var(--sp-lg);
  padding: 0 var(--sp-huge);
  height: 100%;
  max-width: var(--sz-max-width);
  margin: 0 auto;
}

header::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  border-bottom: var(--sp-micro) solid var(--border);
}

.header-inner h1 {
  margin: 0;
  font-size: var(--fs-base);
  font-weight: 600;
  letter-spacing: -0.005em;
  display: inline-flex;
  align-items: center;
}

.header-inner .brand {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-base);
  text-decoration: none;
  color: inherit;
}

.header-inner .brand-logo {
  width: var(--sp-xl);
  height: var(--sp-xl);
  object-fit: contain;
  filter: none;
}

.header-inner .stats {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-xs);
  margin-left: auto;
  flex-wrap: wrap;
  justify-content: flex-end;
  font-size: var(--fs-xs);
  color: var(--text-dim);
}

.header-inner h1 .brand-name {
  color: var(--text);
  font-weight: 700;
}

header .stats .i {
  opacity: .8;
}

/* ---------- Global theme control ---------- */

.theme-toggle {
  position: fixed;
  left: clamp(var(--sp-xl), 6vw, var(--sz-toggle-left));
  bottom: var(--sp-xl);
  z-index: 70;
  width: var(--sz-ui-action);
  height: var(--sz-ui-action);
  border-radius: 50%;
  background: transparent;
  border: var(--sp-micro) solid var(--border);
  color: var(--text-muted);
  margin: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.theme-toggle:hover {
  background: var(--bg-hover);
  color: var(--text);
}

/* =====================================================================
   04. Loading, error, and login screens
   ===================================================================== */

/* ---------- Splash screen ---------- */

.splash {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: calc(100vh - var(--sz-header));
  padding: var(--sp-huge) var(--sp-xl);
  text-align: center;
  color: var(--text-muted);
}

.splash-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 50vw;
  max-width: 100%;
  padding: var(--sp-huge);
  box-sizing: border-box;
}

.splash-logo {
  width: auto;
  height: auto;
  max-width: 78%;
  max-height: 60vh;
  object-fit: contain;
}

.splash h2 {
  margin: var(--sp-xl) 0 0;
  color: var(--text-muted);
  font-weight: 600;
  font-size: var(--fs-md);
}

/* ---------- Error screen ---------- */

.error-screen {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  min-height: calc(100vh - var(--sz-header));
  padding: var(--sp-huge) var(--sp-xl);
  text-align: center;
  color: var(--text-muted);
}

.error-screen h2 {
  margin: 0 0 var(--sp-base);
  color: var(--text);
  font-weight: 600;
  font-size: var(--fs-lg);
}

.error-screen p {
  margin: var(--sp-xs) 0;
  font-size: var(--fs-main);
  max-width: var(--sz-msg-w);
  line-height: 1.5;
}

.error-screen .error-icon {
  margin-bottom: var(--sp-lg);
}

.error-screen .error-icon-svg {
  color: var(--text-faint);
}

.error-screen #error-detail {
  margin-top: var(--sp-md);
  font-size: var(--fs-sm);
  color: var(--text-faint);
}

.error-screen .error-retry {
  margin-top: var(--sp-lg);
}

/* ---------- Login screen ---------- */

.login-screen {
  position: fixed;
  inset: 0;
  display: grid;
  grid-template-columns: 1fr 1fr;
  background: var(--bg);
  z-index: 1000;
}

.login-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-huge);
  background: #f5f5f5;
  border-right: var(--sp-micro) solid #e4e4e4;
}

.login-logo {
  width: auto;
  height: auto;
  max-width: 78%;
  max-height: 60vh;
  object-fit: contain;
}

.login-form {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-huge);
}

.login-form-inner {
  width: 100%;
  max-width: var(--sz-form-w);
  display: flex;
  flex-direction: column;
  gap: var(--sp-lg);
}

.login-heading {
  margin: 0 0 var(--sp-sm);
  font-size: var(--fs-xl);
  font-weight: 600;
  color: var(--text);
  letter-spacing: -0.005em;
}

.login-field {
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.login-error {
  background: var(--danger-bg);
  color: var(--danger);
  padding: var(--sp-base) var(--sp-md);
  border-radius: var(--radius);
  font-size: var(--fs-main);
  border: var(--sp-micro) solid color-mix(in srgb, var(--danger) 30%, transparent);
}

.login-btn {
  margin-top: var(--sp-xs);
  padding: var(--sp-md);
  border: 0;
  border-radius: var(--radius);
  background: var(--accent);
  color: var(--accent-fg);
  font-size: var(--fs-base);
  font-weight: 600;
  cursor: pointer;
}

.login-field input {
  padding: var(--sp-md) var(--sp-md);
  border: var(--sp-micro) solid var(--border-strong);
  border-radius: var(--radius);
  background: var(--bg);
  color: var(--text);
  font-size: var(--fs-base);
}

.login-btn:disabled {
  opacity: .55;
  cursor: default;
}

[data-theme="dark"] .login-brand {
  background: #ebebeb;
  border-right-color: #d8d8d8;
}

.login-field input:focus {
  outline: none;
  box-shadow: var(--shadow-2);
}

.login-btn:hover:not(:disabled) {
  opacity: .9;
}

/* =====================================================================
   05. Main menu and dashboard
   ===================================================================== */

/* ---------- Menu layout ---------- */

/* ---------- Two-pane dashboard shell (shared by the main menu and module dashboards) ---------- */

.dash-shell {
  display: grid;
  grid-template-columns: var(--sz-sidebar-max) 1fr;
  grid-template-rows: 100%;
  gap: var(--sz-header);
  padding: var(--sp-huge);
  max-width: var(--sz-max-width);
  margin: 0 auto;
  overflow: hidden;
}

#view-menu {
  height: 100%;
}

/* ---------- Dashboard theme controls ---------- */

.dash-theme .th-sys,
.dash-theme .th-light,
.dash-theme .th-dark {
  display: none;
}

.dash-theme .th-sys {
  display: block;
}

[data-theme-pref="light"] .dash-theme .th-light {
  display: block;
}

[data-theme-pref="dark"] .dash-theme .th-dark {
  display: block;
}

[data-theme-pref] .dash-theme .th-sys {
  display: none;
}

[data-theme-pref="system"] .dash-theme .th-sys {
  display: block;
}

/* ---------- Dashboard profile ---------- */

.dash-side {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  padding: 0;
  margin: 0;
  background: transparent;
  border: 0;
  box-sizing: border-box;
  overflow: visible;
  height: 100%;
}

.dash-avatar {
  position: relative;
  width: var(--sz-avatar);
  height: var(--sz-avatar);
  border-radius: 50%;
  background: var(--bg-soft);
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  overflow: hidden;
  margin: 0 0 var(--sp-xl) 0;
  box-shadow: 0 var(--sp-sm) var(--sp-xl) rgba(0, 0, 0, .10);
}

.dash-hello {
  font-size: var(--fs-sm);
  color: var(--text-dim);
  letter-spacing: .06em;
  text-transform: uppercase;
  margin-bottom: var(--sp-xs);
}

.dash-name {
  font-size: var(--fs-3xl);
  font-weight: 700;
  line-height: 1.1;
  color: var(--text);
  letter-spacing: -0.01em;
  margin-bottom: var(--sp-xs);
}

.dash-email {
  font-size: var(--fs-main);
  color: var(--text-muted);
  margin-bottom: var(--sp-md);
}

.dash-role {
  font-size: var(--fs-main);
  color: var(--text-muted);
  line-height: 1.5;
  margin-bottom: var(--sp-xl);
}

.dash-avatar .dash-avatar-fallback {
  width: var(--sz-avatar-fallback);
  height: var(--sz-avatar-fallback);
  stroke-width: 1.4;
  color: var(--text-dim);
}

.dash-avatar .dash-avatar-img {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  border-radius: 50%;
  display: block;
}

.dash-avatar .dash-avatar-img[hidden] {
  display: none;
}

/* ---------- Dashboard stats ---------- */

.dash-stats {
  display: flex;
  flex-direction: column;
  gap: var(--sp-xl);
  padding: 0;
  margin: auto 0;
}

.dash-tile {
  background: transparent;
  border: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: var(--sp-tiny);
}

.dash-stat-link {
  appearance: none;
  display: inline;
  padding: 0;
  border: 0;
  border-bottom: var(--sp-micro) dashed var(--border-strong);
  background: transparent;
  color: inherit;
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.dash-stat-link:hover,
.dash-stat-link:focus-visible {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.dash-tile-value {
  font-size: var(--fs-lg);
  font-weight: 600;
  color: var(--text);
  line-height: 1.1;
}

.dash-tile-sub {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  line-height: 1.4;
}

/* ---------- Dashboard actions ---------- */

.dash-actions {
  margin-top: auto;
  display: flex;
  flex-direction: column;
}

.dash-actions button {
  display: flex;
  align-items: center;
  gap: var(--sp-base);
  padding: var(--sp-base) var(--sp-xs);
  border: 0;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
  font: inherit;
  font-size: var(--fs-main);
  border-radius: var(--sp-sm);
}

.dash-actions button:hover {
  color: var(--text);
}

.dash-actions button:focus-visible {
  outline: none;
  box-shadow: none;
}

.dash-actions button .i {
  width: var(--sp-xl);
  height: var(--sp-xl);
  flex: 0 0 auto;
  font-size: var(--sp-xl);
}

/* ---------- Bento grid ---------- */

.bento-section {
  grid-column: 1 / -1;
  font-size: var(--fs-sm);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--text-muted);
  text-align: center;
  margin: var(--sp-md) 0 calc(var(--sp-xs) * -1);
  padding: 0;
}

/* Scrollable main column of the dashboard shell (bento grid in the menu,
   stacked sections in module dashboards). */
.dash-main {
  min-height: 0;
  height: 100%;
  display: flex;
  flex-direction: column;
  gap: var(--sp-lg);
  overflow-y: auto;
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.dash-main::-webkit-scrollbar {
  width: 0;
  height: 0;
  display: none;
}

/* Bento card grid (main menu only). */
.menu-bento {
  display: grid;
  gap: var(--sp-lg);
  grid-template-columns: repeat(auto-fit, minmax(var(--sz-sidebar-w), 1fr));
  align-content: start;
}

.bento-section:first-child {
  margin-top: 0;
}

/* ---------- Bento cards ---------- */

.bento-card {
  position: relative;
  background: var(--bg);
  border: var(--sp-micro) solid transparent;
  border-radius: var(--radius-lg);
  padding: var(--sp-xl) var(--sp-xl) var(--sp-lg);
  display: grid;
  grid-template-columns: 1fr;
  grid-template-rows: auto auto auto;
  grid-template-areas: "icon" "title" "sub";
  row-gap: var(--sp-sm);
  justify-items: start;
  align-content: start;
  cursor: pointer;
  text-align: left;
  font-family: inherit;
  color: var(--text);
  box-shadow: none;
  transition: background .12s ease, box-shadow .12s ease, transform .12s ease;
}

.bento-icon {
  grid-area: icon;
  width: auto;
  height: auto;
  background: transparent;
  border: 0;
  color: var(--text);
  display: inline-flex;
  align-items: center;
  justify-content: flex-start;
  margin: 0 0 var(--sp-xs) 0;
}

.bento-title {
  grid-area: title;
  font-size: var(--fs-md);
  font-weight: 600;
  color: var(--text);
  line-height: 1.25;
}

.bento-sub {
  grid-area: sub;
  font-size: var(--fs-xs);
  color: var(--text-dim);
  line-height: 1.4;
}

.bento-card[hidden] {
  display: none !important;
}

.bento-card:hover {
  background: var(--bg);
  box-shadow: var(--shadow-2);
}

.bento-card:active {
  transform: translateY(var(--sp-micro));
}

.bento-card:focus-visible {
  outline: none;
  box-shadow: var(--shadow-2);
}

.bento-card.bento-soon {
  cursor: not-allowed;
  opacity: .55;
  background: var(--bg);
}

.bento-card.bento-soon:hover {
  transform: none;
  background: var(--bg);
  box-shadow: none;
}

/* Progressive data states on bento tiles */
.bento-card.is-loading,
.bento-card.is-idle {
  cursor: pointer;
  opacity: 0.85;
}

.bento-card.is-loading .bento-icon .i,
.bento-card.is-idle .bento-icon .i {
  animation: bento-spin 0.9s linear infinite;
}

@keyframes bento-spin {
  to {
    transform: rotate(360deg);
  }
}

.bento-card.is-nodata {
  cursor: not-allowed;
  opacity: 0.78;
  background: var(--bg-soft, var(--bg));
  border-color: var(--border);
}

.bento-card.is-nodata .bento-icon {
  color: var(--text-faint, var(--text-dim));
}

.bento-card.is-nodata .bento-sub {
  color: var(--danger, #b91c1c);
  font-weight: 500;
}

.bento-card.is-nodata:hover {
  box-shadow: none;
  transform: none;
}

.bento-card.is-ready {
  cursor: pointer;
  opacity: 1;
  pointer-events: auto;
}

.bento-card.is-loading:hover,
.bento-card.is-idle:hover {
  box-shadow: none;
  transform: none;
}

/* ---------- Bento hero and quick actions ---------- */

.bento-add {
  position: absolute;
  top: var(--sp-sm);
  right: var(--sp-sm);
  width: var(--sz-ui-action);
  height: var(--sz-ui-action);
  border-radius: 50%;
  color: var(--text-muted);
  align-items: center;
  justify-content: center;
  cursor: pointer;
  line-height: 1;
  transition: transform .12s, opacity .15s;
  z-index: 2;
  display: none;
  opacity: 0;
}

.bento-card.bento-hero {
  grid-column: 1 / -1;
  min-height: var(--sz-hero-h);
  padding: var(--sp-xl) var(--sp-xl) var(--sp-xl);
  border-width: var(--sp-tiny);
  display: grid;
  grid-template-columns: minmax(0, 1.5fr) minmax(0, 1fr);
  grid-template-rows: auto 1fr;
  grid-template-areas: "icon sub" "title sub";
  column-gap: var(--sp-lg);
  row-gap: var(--sp-sm);
  align-items: end;
  box-shadow: var(--shadow-2);
}

.bento-add:hover {
  transform: scale(1.15);
  color: var(--text);
}

.bento-card.bento-hero .bento-icon {
  margin: 0;
  align-self: start;
}

.bento-card.bento-hero .bento-title {
  min-width: 0;
  overflow-wrap: anywhere;
  font-size: var(--fs-lg);
  align-self: end;
}

.bento-card.bento-hero .bento-sub {
  min-width: 0;
  overflow-wrap: anywhere;
  text-align: right;
  line-height: 1.5;
  font-size: var(--fs-sm);
  color: var(--text-dim);
  align-self: end;
  justify-self: end;
}

/* Quick-save for modules with unsaved changes. Hover-revealed like the
   quick-add "+"; both action buttons live in the card's top-right corner,
   opposite the major icon — the corner is always free there. */
.bento-save {
  position: absolute;
  top: var(--sp-sm);
  right: calc(var(--sp-sm) + var(--sz-ui-action));
  width: var(--sz-ui-action);
  height: var(--sz-ui-action);
  border-radius: 50%;
  color: var(--text-muted);
  align-items: center;
  justify-content: center;
  cursor: pointer;
  line-height: 1;
  transition: transform .12s, opacity .15s;
  z-index: 2;
  display: none;
  opacity: 0;
}
.bento-save:hover {
  transform: scale(1.15);
  color: var(--text);
}
.bento-card:hover .bento-save.visible {
  display: flex;
  opacity: 1;
}

/* Modules with unsaved changes get a red dot next to the major (top-left)
   icon, so the pending state is readable at a glance without tinting the
   whole card and breaking its solid-surface look. */
.bento-card.bento-dirty::after {
  content: '';
  position: absolute;
  top: var(--sp-sm);
  left: var(--sp-sm);
  width: 10px;
  height: 10px;
  border-radius: 50%;
  background: var(--accent);
  box-shadow: 0 0 0 2px var(--bg);
}

.bento-card:hover .bento-add.visible {
  display: flex;
  opacity: 1;
}

/* =====================================================================
   06. Module layouts and module tables
   ===================================================================== */

/* ---------- Module shell ---------- */

.module {
  padding: 0 var(--sp-huge) var(--sp-max);
  max-width: var(--sz-max-width);
  margin: 0 auto;
}

/* In list/table layouts the page is the scroll container. An overflowed
   module would trap its sticky header even though the module itself has no
   constrained scrolling height, so let the editor bar stick to the viewport. */
.module:not([data-view="map"]) {
  overflow-y: visible;
}

.editor-overlay {
  position: fixed;
  inset: 0;
  background: var(--bg);
  z-index: 90;
  overflow: auto;
  padding: 0 var(--sp-huge) var(--sp-max);
  max-width: var(--sz-max-width);
  margin: 0 auto;
}

body.module-open>header {
  display: none;
}

.editor-overlay.show {
  display: block !important;
}

/* ---------- Module header and editor toolbar ---------- */

.editor-bar {
  display: grid;
  grid-template-columns: 1fr auto 1fr;
  align-items: center;
  gap: var(--sp-lg);
  padding: 0;
  margin: var(--sp-lg) 0;
  position: sticky;
  top: 0;
  z-index: 50;
  height: var(--sz-header);
}

.editor-bar .mh-user,
.editor-bar .editor-title,
.editor-bar button {
  padding: var(--sp-md);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-2);
}

.module[data-view="map"] .editor-bar .mh-user,
.module[data-view="map"] .editor-bar .editor-title,
.module[data-view="map"] .editor-bar button {
  backdrop-filter: blur(var(--blur));
}

.module:not([data-view="map"]) .editor-bar {
  background: var(--bg);
}

.module:not([data-view="map"]) .editor-bar .mh-user,
.module:not([data-view="map"]) .editor-bar .editor-title,
.module:not([data-view="map"]) .editor-bar button {
  box-shadow: none;
}

.editor-title {
  margin: 0;
  font-size: var(--fs-base);
  font-weight: 600;
  letter-spacing: -0.005em;
  color: var(--text);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-base);
  justify-self: center;
  white-space: nowrap;
}

.editor-title-stack {
  display: inline-flex;
  flex-direction: column;
  gap: var(--sp-tiny);
  line-height: 1.15;
}

.editor-title-stack small {
  font-size: var(--fs-xs);
  font-weight: 400;
  color: var(--text-dim);
}

.actions {
  justify-self: end;
  display: flex;
  gap: var(--sp-xs);
  align-items: center;
}

/* ---------- Module header user block ---------- */

.mh-user {
  justify-self: start;
  display: inline-flex;
  align-items: center;
  gap: var(--sp-md);
  font-size: var(--fs-main);
  font-weight: 500;
  color: var(--text);
}

.mh-user .mh-user-avatar {
  width: var(--sp-xl);
  height: var(--sp-xl);
  border-radius: 50%;
  background: var(--bg-soft);
  overflow: hidden;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
}

.mh-user .mh-user-name {
  white-space: nowrap;
}

.mh-user .mh-user-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

.mh-user .mh-user-avatar .i {
  width: var(--sp-lg);
  height: var(--sp-lg);
  color: var(--text-dim);
  font-size: var(--sp-lg);
}

/* ---------- Hero search and filters ---------- */

.hero {
  padding: 0;
  margin: 12.5vh 0;
  display: flex;
  align-items: flex-start;
}

.search-card {
  width: 100%;
  background: var(--surface);
  border: var(--sp-micro) solid var(--border-strong);
  border-radius: var(--radius-search);
  overflow: hidden;
}

.hero-search {
  display: flex;
  align-items: center;
  gap: var(--sp-lg);
  background: transparent;
  border: 0;
  padding: var(--sp-md);
}

.hero-icon {
  color: var(--text-dim);
  display: inline-flex;
  width: var(--sz-ui-action);
  height: var(--sz-ui-action);
  align-items: center;
  justify-content: center;
}

.hero-search .hero-icon {
  display: none;
}

#module-coverage .hero-search .hero-icon,
#module-map .hero-search .hero-icon {
  display: none;
}

.hero-search input[type="search"]::-webkit-search-cancel-button {
  -webkit-appearance: none;
  appearance: none;
  display: none;
}

.hero-clear {
  width: var(--sz-ui-action);
  height: var(--sz-ui-action);
  border-radius: 50%;
  background: transparent;
  border: 0;
  color: var(--text-muted);
  display: none;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex: 0 0 auto;
}

.hero-search.has-value:hover .hero-clear,
.hero-search.has-value:focus-within .hero-clear {
  display: inline-flex;
}

.hero-clear:hover {
  background: var(--bg-hover);
  color: var(--text);
}

.hero-filter {
  width: var(--sz-ui-action);
  height: var(--sz-ui-action);
  border-radius: 50%;
  background: transparent;
  border: 0;
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  flex: 0 0 auto;
  transition: background .12s ease, color .12s ease;
}

.hero-search-submit {
  width: auto;
  min-width: var(--sz-stat-w);
  padding: 0 var(--sp-lg);
  border-radius: var(--radius-full);
  background: var(--accent);
  color: var(--accent-fg);
  font-size: var(--fs-sm);
  font-weight: 600;
}

.hero-filter.hero-search-submit:hover,
.hero-filter.hero-search-submit:focus-visible {
  background: color-mix(in srgb, var(--accent) 88%, black);
  color: var(--accent-fg);
}

.hero-filter.hero-search-submit:disabled {
  background: var(--bg-soft);
  color: var(--text-faint);
  cursor: wait;
}

.map-search-submit:disabled {
  background: var(--bg-soft);
  color: var(--text-faint);
  cursor: wait;
}

.map-search-status {
  display: none;
  padding: 0 var(--sp-xl) var(--sp-md);
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.map-search-status:not(:empty) {
  display: block;
}

.map-search-status.error {
  color: var(--danger);
}

.filters-wrap {
  background: transparent;
  border: 0;
  border-top: var(--sp-micro) solid var(--border);
  margin: 0;
}

.filters-check {
  flex-direction: row !important;
  align-items: center;
  gap: var(--sp-base) !important;
  cursor: pointer;
}

.filters .filter-field {
  display: flex;
  flex-direction: column;
  gap: var(--sp-xs);
  min-width: 0;
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.filter-multiselect {
  position: relative;
  width: 100%;
  max-width: 100%;
  min-width: 0;
}

#module-crm .search-card:has(.filter-multiselect[open]) {
  overflow: visible;
}

#module-crm .hero:has(.filter-multiselect[open]) {
  z-index: 140;
}

.filter-multiselect>summary {
  display: flex;
  align-items: center;
  width: 100%;
  max-width: 100%;
  justify-content: space-between;
  gap: var(--sp-base);
  height: var(--ht-input);
  box-sizing: border-box;
  padding: 0 var(--sp-md);
  border: var(--sp-micro) solid var(--border-strong);
  border-radius: var(--sp-sm);
  background: var(--bg);
  color: var(--text);
  font-size: var(--fs-main);
  list-style: none;
  cursor: pointer;
}

.filter-multiselect>summary::-webkit-details-marker {
  display: none;
}

.filter-multiselect>summary:focus-visible,
.filter-multiselect[open]>summary {
  outline: none;
  box-shadow: var(--shadow-2);
}

.filter-multiselect>summary .i {
  flex: 0 0 auto;
  color: var(--text-muted);
  transition: transform .15s ease;
}

.filter-multiselect[open]>summary .i {
  transform: rotate(180deg);
}

.filter-multiselect-value {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.filter-multiselect-options {
  position: absolute;
  top: calc(100% + var(--sp-xs));
  left: 0;
  z-index: 320;
  display: grid;
  grid-template-columns: 1fr;
  gap: 0;
  width: 100%;
  max-height: var(--sz-list-max-h);
  padding: 0;
  overflow: auto;
  box-sizing: border-box;
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--sp-sm);
  background: var(--surface);
  box-shadow: var(--shadow-2);
  font-size: var(--fs-main);
}

/* Modern browsers move the options into the top layer. The absolute rule
   above remains as a functional fallback where the Popover API is absent. */
.filter-multiselect-options[popover] {
  position: fixed;
  inset: auto;
  margin: 0;
  width: auto;
  z-index: 10000;
}

.filters .filter-multiselect-option {
  display: grid;
  grid-template-columns: auto auto minmax(0, 1fr);
  align-items: center;
  gap: var(--sp-base);
  min-width: 0;
  padding: var(--sp-sm) var(--sp-md);
  padding-left: calc(var(--sp-md) + var(--filter-depth, 0) * var(--sp-lg));
  border-bottom: var(--sp-micro) solid var(--border);
  color: var(--text);
  cursor: pointer;
}

.filters .filter-multiselect-option.is-plain {
  grid-template-columns: auto minmax(0, 1fr);
}

.filters .filter-multiselect-option:last-child {
  border-bottom: 0;
}

.filters .filter-multiselect-option:hover {
  background: var(--bg-hover);
}

.filter-multiselect-option>span:last-child {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.filter-multiselect-option input[type="checkbox"] {
  width: var(--sp-lg);
  height: var(--sp-lg);
  margin: 0;
  accent-color: var(--accent);
}

.filter-status-swatch {
  width: var(--sp-md);
  height: var(--sp-md);
  border: var(--sp-micro) solid var(--border-strong);
  border-radius: 50%;
  background: var(--filter-status-color, var(--deal-neutral));
}

.filters-footer {
  display: flex;
  justify-content: flex-end;
  padding-top: var(--sp-xs);
}

/* Панель группировки дел — всплывает из FAB, геометрия как у легенды карты. */
.deals-group-panel {
  position: fixed;
  right: var(--deals-group-right, calc(max(var(--sp-xl), env(safe-area-inset-right)) + var(--sp-xl) + var(--sp-xs)));
  bottom: var(--deals-group-bottom, calc(max(var(--sp-xl), env(safe-area-inset-bottom)) + var(--sp-xl) + var(--sp-xs)));
  width: min(280px, var(--sz-avail-w));
  z-index: 120;
  background: var(--surface);
  color: var(--text);
  font-size: var(--fs-sm);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  overflow: hidden;
  transform-origin: 100% 100%;
  transform: scale(.04);
  opacity: 0;
  pointer-events: none;
  transition: transform .26s cubic-bezier(.2, .85, .2, 1), opacity .18s ease;
  will-change: transform, opacity;
}

.deals-group-panel.is-open {
  transform: scale(1);
  opacity: 1;
  pointer-events: auto;
}

.deals-group-body {
  padding: var(--sp-xl);
}

.deals-group-title {
  font-size: var(--fs-sm);
  color: var(--text-muted);
  margin-bottom: var(--sp-base);
}

.fab.deals-group-fab,
.fab.deals-timeline-fab {
  background: var(--surface);
  color: var(--text);
  border: var(--sp-micro) solid var(--border-strong);
}

/* Пока календарь открыт, его кнопка подсвечена акцентом. */
.fab.deals-timeline-fab.is-active {
  background: var(--accent);
  color: var(--accent-fg);
  border-color: var(--accent);
}

.group-picker-list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-xs);
}

.group-picker-row {
  display: flex;
  align-items: center;
  gap: var(--sp-base);
}

.group-picker-row .filters-check {
  flex: 1 1 auto;
  color: var(--text);
}

.group-picker-moves {
  display: flex;
  align-items: center;
  gap: var(--sp-xs);
}

/* Стрелки порядка — как действия на плитках меню: без рамки и заливки. */
.group-move {
  padding: 0;
  border: 0;
  background: transparent;
  border-radius: 50%;
  color: var(--text-muted);
  display: flex;
  align-items: center;
  justify-content: center;
  line-height: 1;
  cursor: pointer;
  transition: transform .12s, color .15s, opacity .15s;
}

.group-move:hover:not([disabled]) {
  transform: scale(1.15);
  color: var(--text);
}

.group-move[disabled] {
  opacity: .3;
  cursor: default;
}

.reset-btn {
  background: transparent;
  border: var(--sp-micro) solid var(--border-strong);
  color: var(--text-muted);
  border-radius: var(--sp-sm);
  padding: var(--sp-sm) var(--sp-md);
  cursor: pointer;
  font-size: var(--fs-sm);
}

.len-range {
  display: flex;
  gap: var(--sp-xs);
  align-items: center;
}

.hero-search input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  outline: none;
  background: transparent;
  font-size: var(--fs-md);
  padding: var(--sp-xs) 0 var(--sp-xs) var(--sp-md);
  color: var(--text);
}

.filters label {
  display: flex;
  flex-direction: column;
  gap: var(--sp-xs);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.filters input:not([type=checkbox]):not([type=radio]),
.filters select {
  height: var(--ht-input);
  box-sizing: border-box;
  padding: 0 var(--sp-md);
  border: var(--sp-micro) solid var(--border-strong);
  border-radius: var(--sp-sm);
  font-size: var(--fs-main);
  background: var(--bg);
  color: var(--text);
  width: 100%;
}

.filters-wrap>summary {
  display: none;
}

.search-card:focus-within {
  box-shadow: var(--shadow-2);
}

.hero-filter:hover {
  background: var(--bg-hover);
  color: var(--text);
}

.hero-filter:focus-visible {
  outline: none;
  box-shadow: none;
}

.hero-filter.active {
  background: var(--accent);
  color: var(--accent-fg);
}

.filters-wrap.filters-hidden {
  display: none;
}

.reset-btn:hover {
  background: var(--bg-hover);
  color: var(--text);
}

.filters-wrap .filters {
  margin: 0;
  border: 0;
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(var(--sz-filter-w), 1fr));
  gap: var(--sp-md) var(--sp-lg);
  padding: var(--sp-xl) var(--sp-xl) var(--sp-xl);
}

.len-range .sep {
  color: var(--text-faint);
}

.hero>.search-card {
  width: 100%;
}

.hero-search input::placeholder {
  color: var(--text-faint);
}

.filters input:focus,
.filters select:focus {
  outline: none;
  box-shadow: var(--shadow-2);
}

/* ---------- Toolbars ---------- */

.toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-md);
  padding: var(--sp-xs) 0 var(--sp-md);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.toolbar .group-by {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-sm);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.toolbar .group-by select {
  padding: var(--sp-sm) var(--sp-base);
  border: var(--sp-micro) solid var(--border-strong);
  border-radius: var(--sp-sm);
  background: var(--bg);
  color: var(--text);
  font-size: var(--fs-sm);
  font-family: inherit;
}

.toolbar .group-by select:focus {
  outline: none;
  box-shadow: var(--shadow-2);
}

/* ---------- Main tables ---------- */

table {
  width: 100%;
  border-collapse: collapse;
  background: var(--surface);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--radius);
  overflow: hidden;
  font-size: var(--fs-main);
}

thead th {
  background: var(--bg-soft);
  text-align: left;
  padding: var(--sp-base) var(--sp-md);
  font-weight: 500;
  color: var(--text-muted);
  border-bottom: var(--sp-micro) solid var(--border);
  cursor: default;
  user-select: none;
  white-space: nowrap;
  font-size: var(--fs-sm);
  letter-spacing: .01em;
}

.main-table th {
  cursor: default;
}

.main-table th[data-sort] {
  cursor: pointer;
}

.main-table th.sort-disabled {
  cursor: default;
  color: #999;
}

.main-table th.sort-disabled .arrow {
  color: #999;
}

tbody td {
  padding: var(--sp-md) var(--sp-md);
  border-bottom: var(--sp-micro) solid var(--border);
  vertical-align: top;
  color: var(--text);
  line-height: 1.4;
}

.main-table td {
  vertical-align: baseline;
}

tbody tr {
  cursor: pointer;
  color: var(--text);
}

td.num {
  text-align: right !important;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
  color: var(--text);
}

td.curr,
th.curr {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

td.mono,
th.mono {
  font-variant-numeric: tabular-nums;
  font-feature-settings: "tnum" 1;
}

td.long {
  overflow-wrap: anywhere;
  word-break: normal;
  max-width: var(--long-cell-max, 35cqw);
}

td.long .long-cell-limit {
  display: block;
  max-width: var(--long-cell-max, 35cqw);
  overflow-wrap: anywhere;
  word-break: normal;
  white-space: normal;
}

.main-table {
  container-type: inline-size;
}

th.num {
  text-align: right;
}

th.col-id,
td.col-id {
  width: 4ch;
  min-width: 4ch;
  color: var(--text-faint);
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-sm);
}

th.col-name,
td.col-name {
  min-width: var(--sz-col-name-w);
  font-weight: 500;
}

td.actions {
  white-space: nowrap;
  display: table-cell;
}

td.actions button {
  /* height: var(--sz-ui-sm); */
  margin: calc(-0.5 * (var(--sz-ui-action) - var(--sz-ui-sm))) 0;
}

tbody tr:hover {
  background: var(--bg-hover);
  cursor: pointer;
}

tbody td:first-child {
  position: relative;
}

thead th .arrow {
  font-size: var(--fs-tiny);
  color: var(--text);
  margin-left: var(--sp-xs);
}

tbody tr:last-child td {
  border-bottom: 0;
}

tbody td:first-child::before {
  content: "";
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: var(--sp-xs);
  z-index: 10;
  background: transparent;
  pointer-events: none;
}

.main-table tr {
  min-height: var(--sz-row-h);
}

/* ---------- Grouped rows ---------- */

.group-toggle {
  display: flex;
  align-items: center;
  gap: var(--sp-md);
  width: 100%;
  padding: var(--sp-lg) var(--sp-lg);
  background: transparent;
  border: 0;
  color: var(--text);
  font: inherit;
  font-weight: 600;
  font-size: var(--fs-base);
  text-align: left;
  cursor: pointer;
  letter-spacing: -0.005em;
}

.group-chevron {
  width: var(--sp-xl);
  height: var(--sp-xl);
  stroke-width: 2;
  color: var(--text-muted);
  transition: transform .15s ease;
  flex: 0 0 auto;
}

.group-label {
  flex: 1 1 auto;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.group-count {
  font-weight: 500;
  color: var(--text-dim);
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
  background: var(--bg);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--radius-full);
  padding: var(--sp-micro) var(--sp-base);
}

/* «Активный» счётчик-бейдж (выбранная группа): заменял inline-стиль. */
.group-count.chosen-chip {
  background: var(--bg-active);
  border-color: var(--border-strong);
  color: var(--text);
  cursor: default;
}

tbody tr.group-row {
  border-bottom: var(--sp-micro) solid var(--border-strong);
  cursor: default;
}

tbody tr.group-row td {
  padding: 0;
  border-bottom: 0;
}

.group-toggle:hover {
  background: var(--bg-hover);
}

.group-toggle:focus-visible {
  outline: none;
  box-shadow: none;
}

tbody tr.group-row:hover {
  background: var(--bg-hover);
}

tbody tr.group-row+tr.group-row {
  border-top: 0;
}

.group-toggle[aria-expanded="false"] .group-chevron {
  transform: rotate(-90deg);
}

tbody tr.group-row td:last-child::after {
  display: none !important;
}

/* ---------- View tabs ---------- */

.view-tabs {
  display: flex;
  gap: var(--sp-tiny);
  background: var(--bg-active);
  padding: var(--sp-tiny);
  border-radius: var(--sp-base);
  box-shadow: var(--shadow-2);
  --level: 0;
}

.view-tabs,
.view-tabs[data-module] {
  position: fixed;
  left: 50%;
  bottom: calc(var(--sp-xl) + var(--level) * 44px);
  transform: translateX(-50%);
  z-index: 110;
}

.view-tabs.small {
  position: static;
  transform: none;
  box-shadow: none;
  background: transparent;
  justify-content: center;
  margin: var(--sp-md) auto;
}

.view-tabs[data-sub] {
  --level: 1;
}

/* Отдельные вкладки остаются на базовой высоте (эквивалент inline `--level:0`,
   убранного в рамках запрета inline-стилей). */
.view-tabs.crm-deals-mode,
.view-tabs[data-sub="commerce-docs"],
.view-tabs[data-sub="catalog-index"],
.view-tabs[data-sub="kpi-year"] {
  --level: 0;
}

.tab-btn {
  border: 0;
  background: transparent;
  padding: var(--sp-sm) var(--sp-lg);
  border-radius: var(--sp-sm);
  font-size: var(--fs-sm);
  color: var(--text-muted);
  cursor: pointer;
}

.tab-btn.active {
  background: var(--bg-elev);
  color: var(--text);
  box-shadow: var(--shadow-1);
}

[data-theme="dark"] .view-tabs {
  background: var(--bg-active);
}

/* ---------- Map view mode ---------- */

.module[data-view="map"] {
  background: transparent !important;
}

.module[data-view="map"] .empty-view,
.module[data-view="map"] .toolbar,
.module[data-view="map"] table,
.module[data-view="map"] .pager {
  display: none !important;
}

.module[data-view="map"] .search-card {
  pointer-events: auto;
  box-shadow: var(--shadow-3);
  background: var(--surface);
}

/* Карты модулей, где клик создаёт новую запись: курсор-крестик на пустом месте,
   маркеры записей остаются pointer. */
.map-new-record {
  cursor: crosshair;
}

.map-new-record .leaflet-interactive {
  cursor: pointer;
}

/* close button floats over the map in map mode: give it a surface like other header parts */
.module[data-view="map"] .actions .close-action {
  background: var(--bg);
  color: var(--text);
  border-radius: var(--radius-full);
  box-shadow: var(--shadow-2);
  padding: var(--sp-md);
  width: auto;
  height: auto;
}

.module[data-view="map"] .actions .close-action:hover {
  background: var(--bg-hover);
  color: var(--text);
}

/* Карта в режиме карты — самый нижний ярус интерфейса модуля.
   isolation: её панели Leaflet имеют zIndex до 700 (попапы, маркеры), и без
   собственного контекста наложения они рисовались бы поверх шапки, легенды и
   FAB. Порядок ярусов: карта 5 → шапка .editor-bar 50 → поиск .hero 100 →
   легенда .map-legend-panel 120 → FAB .fab-stack 130 → панели 3000+. */
/* Вне режима карты контейнер карты модуля не отображается вовсе. Одного
   position: static мало: у .leaflet-container нет своего position, поэтому
   панели Leaflet (position: absolute) получают содержащим блоком область
   просмотра, не обрезаются overflow:hidden контейнера и перекрывают модуль —
   переключатель «Список» выглядел так, будто карта не выключается. */
.module:not([data-view="map"]) .map-view-full {
  display: none !important;
}

.module[data-view="map"] .map-view-full {
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 5;
  isolation: isolate;
  display: block !important;
}

/* Leaflet zoom controls — geojson.io-like card, middle-left */
.leaflet-top.leaflet-left {
  top: 50%;
  bottom: auto;
  transform: translateY(-50%);
}

.leaflet-top.leaflet-left .leaflet-control-zoom {
  margin-top: 0;
  margin-left: var(--sp-lg);
}

.leaflet-control-zoom.leaflet-bar {
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-2);
  /* same as .fab */
  overflow: hidden;
  background: var(--surface);
}

.leaflet-control-zoom.leaflet-bar a {
  width: 34px;
  height: 34px;
  line-height: 34px;
  font-size: 18px;
  font-weight: 500;
  color: var(--text);
  background: var(--surface);
  border-bottom: var(--sp-micro) solid var(--border);
  text-indent: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.leaflet-control-zoom.leaflet-bar a:last-child {
  border-bottom: 0;
}

.leaflet-control-zoom.leaflet-bar a:hover {
  background: var(--bg-hover);
  color: var(--text);
}

.leaflet-control-zoom.leaflet-bar a:active {
  background: var(--bg-active);
}

.leaflet-control-zoom.leaflet-bar a.leaflet-disabled {
  color: var(--text-faint);
  background: var(--bg-soft);
  cursor: default;
}

.leaflet-control-zoom-in {
  border-top-left-radius: var(--radius);
  border-top-right-radius: var(--radius);
}

.leaflet-control-zoom-out {
  border-bottom-left-radius: var(--radius);
  border-bottom-right-radius: var(--radius);
}

[data-theme="dark"] .leaflet-control-zoom.leaflet-bar,
[data-theme="dark"] .leaflet-control-zoom.leaflet-bar a {
  background: var(--surface);
  color: var(--text);
  border-color: var(--border);
}

[data-theme="dark"] .leaflet-control-zoom.leaflet-bar a:hover {
  background: var(--bg-hover);
}

.module[data-view="map"] .hero {
  position: relative;
  z-index: 100;
  pointer-events: none;
}

.module[data-view="map"] .search-card .filters-wrap {
  background: var(--surface);
  border-bottom-left-radius: var(--sp-xl);
  border-bottom-right-radius: var(--sp-xl);
}

.map-empty {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-xl);
  color: var(--text-muted);
  background: var(--bg-soft);
  text-align: center;
}

.map-survey-marker-icon {
  background: transparent;
  border: 0;
}

.map-survey-marker {
  display: block;
  width: 14px;
  height: 14px;
  background: var(--marker-color);
  border: 2px solid #fff;
  box-shadow: var(--shadow-2);
}

.map-survey-marker.shape-round,
.legend-swatch.shape-round {
  border-radius: 50%;
}

.map-survey-marker.shape-square,
.legend-swatch.shape-square {
  border-radius: var(--sp-tiny);
}

.map-survey-marker.shape-diamond,
.legend-swatch.shape-diamond {
  border-radius: var(--sp-tiny);
  transform: rotate(45deg) scale(.9);
}

.map-interest-marker-icon {
  background: transparent;
  border: 0;
  pointer-events: none;
}

.map-interest-marker {
  --cross-color: var(--poi-color, var(--accent));
  position: relative;
  display: block;
  width: 72px;
  height: 72px;
}

.map-interest-arm {
  position: absolute;
  display: block;
  background: var(--cross-color);
  border: 0;
  border-radius: var(--sp-tiny);
}

.map-interest-arm.arm-top,
.map-interest-arm.arm-bottom {
  left: 50%;
  width: 2px;
  height: 26px;
  transform: translateX(-50%);
}

.map-interest-arm.arm-top {
  top: 3px;
}

.map-interest-arm.arm-bottom {
  bottom: 3px;
}

.map-interest-arm.arm-left,
.map-interest-arm.arm-right {
  top: 50%;
  width: 26px;
  height: 2px;
  transform: translateY(-50%);
}

.map-interest-arm.arm-left {
  left: 3px;
}

.map-interest-arm.arm-right {
  right: 3px;
}

.map-fab-stack {
  position: fixed;
  right: max(var(--sp-xl), env(safe-area-inset-right));
  bottom: max(var(--sp-xl), env(safe-area-inset-bottom));
  z-index: 130;
}

.module:not([data-view="map"]) .map-layers-fab,
.module:not([data-view="map"]) .map-fit-fab {
  display: none;
}

.module[data-view="map"] .fab-stack {
  z-index: 130;
}

/* Легенда карты — в левом нижнем углу, с теми же отступами от края экрана,
   что и стек FAB в правом нижнем (зеркально). */
.map-legend-panel {
  position: fixed;
  left: max(var(--sp-xl), env(safe-area-inset-left));
  bottom: max(var(--sp-xl), env(safe-area-inset-bottom));
  width: min(360px, var(--sz-avail-w));
  height: auto;
  z-index: 120;
  backdrop-filter: blur(var(--blur));
  color: var(--text);
  font-size: var(--fs-sm);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  overflow: hidden;
  display: flex;
  flex-direction: column;
  transform-origin: 0 100%;
  transform: scale(.04);
  opacity: 0;
  pointer-events: none;
  transition: transform .26s cubic-bezier(.2, .85, .2, 1), opacity .18s ease;
  will-change: transform, opacity;
}

.map-legend-panel.is-open {
  transform: scale(1);
  opacity: 1;
  pointer-events: auto;
}

.map-legend-body {
  flex: 1 1 auto;
  min-height: 0;
  overflow: auto;
  padding: var(--sp-lg);
}

.legend-tree,
.legend-tree ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

.legend-tree>.legend-node,
.legend-branch>ul>.legend-node {
  position: relative;
  margin: var(--sp-sm) 0;
}

/* Подводки дерева. Ствол раньше рисовался одной линией на весь список с
   отступом от низа, а хвост ниже последнего ответвления закрашивался полосой
   цвета фона — с полупрозрачной легендой (blur) эта полоса стала видна. Теперь
   ствол собран из сегментов по числу строк: у каждой строки свой кусок от
   верхнего отступа до нижнего (отступы соседних строк смыкаются), а у
   последней строки ветки он обрывается ровно на середине строки — там же, где
   её ответвление. Заодно ответвление всегда по центру строки, даже если строка
   выше штатной высоты. */
.legend-branch>ul {
  --legend-line-x: calc(var(--sp-md) + var(--sp-base));
  position: relative;
  display: flow-root;
  margin: 0;
  padding: 0 0 0 calc(var(--legend-line-x) + var(--sp-lg));
  border-left: 0;
}

.legend-branch>ul>.legend-node>.legend-layer {
  position: relative;
}

.legend-branch>ul>.legend-node>.legend-layer::before {
  content: "";
  position: absolute;
  left: calc(0px - var(--sp-lg));
  top: calc(0px - var(--sp-sm));
  bottom: calc(0px - var(--sp-sm));
  border-left: var(--sp-micro) solid var(--border);
  z-index: 0;
}

.legend-branch>ul>.legend-node:last-child>.legend-layer::before {
  bottom: 50%;
}

.legend-branch>ul>.legend-node>.legend-layer::after {
  content: "";
  position: absolute;
  left: calc(0px - var(--sp-lg));
  top: 50%;
  width: var(--sp-lg);
  border-top: var(--sp-micro) solid var(--border);
  z-index: 2;
}

/* Строка легенды — flex, а не grid с фиксированными колонками: шеврон и свотч
   есть не у каждой строки (у строки модуля и у строк вне дерева свотча нет), и
   в сетке из четырёх колонок подпись попадала в узкую колонку свотча — текст
   почти не было видно. Здесь каждый элемент занимает своё, подпись забирает
   остаток ширины. Зазор плотнее sp-md: в панели шириной 360 px место нужнее
   подписи, иначе вложенные строки не помещаются. */
.legend-layer {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  min-height: var(--sz-ui-action);
  padding: var(--sp-sm) var(--sp-md);
  border-radius: var(--sp-sm);
  cursor: default;
}

.legend-layer>.legend-chevron {
  flex: 0 0 var(--sp-lg);
}

.legend-layer>.legend-layer-text {
  flex: 1 1 auto;
}

.legend-layer>.legend-count,
.legend-layer>.legend-switch-wrap {
  flex: 0 0 auto;
}

.legend-layer.is-parent {
  cursor: pointer;
  font-weight: 600;
}

.legend-chevron {
  width: var(--sp-lg);
  height: var(--sp-lg);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--text-dim);
  transition: transform .15s ease;
  pointer-events: none;
}

.legend-chevron-empty {
  visibility: hidden;
}

.legend-branch[aria-expanded="false"]>.legend-layer .legend-chevron {
  transform: rotate(-90deg);
}

.legend-layer:hover {
  background: var(--bg-hover);
}

.legend-switch-wrap {
  position: relative;
  display: inline-flex;
  align-items: center;
  cursor: pointer;
}

.legend-layer input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.legend-switch {
  position: relative;
  width: 34px;
  height: 20px;
  border-radius: var(--radius-full);
  background: var(--bg-active);
  border: var(--sp-micro) solid var(--border-strong);
  transition: background .15s ease, border-color .15s ease;
}

.legend-switch::after {
  content: "";
  position: absolute;
  width: 16px;
  height: 16px;
  top: 1px;
  left: 1px;
  border-radius: 50%;
  background: var(--surface);
  box-shadow: var(--shadow-1);
  transition: transform .15s ease;
}

.legend-layer input:checked+.legend-switch {
  background: var(--accent);
  border-color: var(--accent);
}

.legend-layer input:checked+.legend-switch::after {
  transform: translateX(14px);
}

.legend-layer input:indeterminate+.legend-switch {
  background: color-mix(in srgb, var(--accent) 42%, var(--bg-active));
  border-color: color-mix(in srgb, var(--accent) 65%, var(--border-strong));
}

.legend-layer input:indeterminate+.legend-switch::after {
  transform: translateX(7px);
}

.legend-layer input:focus-visible+.legend-switch {
  box-shadow: var(--shadow-2);
}

.legend-layer .legend-swatch {
  display: inline-block;
}

.legend-swatch {
  width: var(--sp-lg);
  height: var(--sp-base);
  border-radius: var(--radius-full);
  border: none;
  flex: 0 0 auto;
}

.legend-swatch-water {
  border-radius: var(--radius-full);
  background: var(--water-map-color);
}

.legend-swatch-survey {
  background: var(--accent);
}

.legend-swatch.shape-diamond {
  transform-origin: center;
}

/* Строка легенды — строго в одну строку: перенос делает строки разными по
   высоте, и подводки дерева (они отсчитываются от стандартной высоты строки)
   разъезжаются.
   Длинное название сокращается многоточием, полностью оно в title строки. */
.legend-layer-text {
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: 500;
}

.legend-count {
  color: var(--text-dim);
  font-size: var(--fs-sm);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.legend-empty {
  color: var(--text-faint);
  font-size: var(--fs-sm);
  padding: var(--sp-sm) var(--sp-md);
}

.legend-layer.depth-2 {
  font-size: var(--fs-sm);
}

/* ---------- Workbook layout (workbooks module type) ---------- */

.workbook-layout {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 6fr);
  gap: var(--sp-lg);
  align-items: start;
  margin-top: var(--sp-lg);
}

.workbook-index {
  display: flex;
  flex-direction: column;
  gap: var(--sp-md);
  background: var(--surface);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--sp-md);
  min-height: var(--sz-workbook-min-h);
}

.workbook-index-toolbar {
  display: flex;
  align-items: center;
  gap: var(--sp-md);
  justify-content: space-between;
}

.workbook-search {
  flex: 1 1 auto;
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-xs) var(--sp-sm);
  background: var(--bg-soft);
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
}

.workbook-search .hero-icon {
  display: inline-flex;
  width: auto;
  height: auto;
  color: var(--text-dim);
}

.workbook-search input[type="search"] {
  border: 0;
  background: transparent;
  width: 100%;
  font-size: var(--fs-main);
  color: var(--text);
  outline: none;
}

.workbook-count {
  font-size: var(--fs-sm);
  color: var(--text-dim);
  white-space: nowrap;
}

.workbook-table-wrap {
  overflow-x: auto;
  border-radius: var(--radius);
  border: var(--sp-micro) solid var(--border);
}

.workbook-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-main);
}

.workbook-table th {
  background: var(--bg-soft);
  color: var(--text-muted);
  font-weight: 600;
  font-size: var(--fs-sm);
  padding: var(--sp-sm) var(--sp-md);
  text-align: left;
  border-bottom: var(--sp-micro) solid var(--border);
  white-space: nowrap;
  user-select: none;
}

.workbook-table th[data-sort] {
  cursor: pointer;
}

.workbook-table td {
  padding: var(--sp-sm) var(--sp-md);
  border-bottom: var(--sp-micro) solid var(--border);
  vertical-align: baseline;
}

.workbook-table tbody tr {
  cursor: pointer;
  transition: background .12s ease;
}

.workbook-table tbody tr:hover {
  background: var(--bg-hover);
}

.workbook-table tbody tr.is-selected {
  background: var(--accent-soft);
  font-weight: 500;
}

.workbook-detail {
  background: var(--surface);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--sp-xl);
  min-height: var(--sz-workbook-min-h);
  display: flex;
  flex-direction: column;
}

.workbook-detail .empty {
  flex: 1 1 auto;
  min-height: 360px;
}

.workbook-detail-header {
  margin-bottom: var(--sp-lg);
  padding-bottom: var(--sp-md);
  border-bottom: var(--sp-micro) solid var(--border);
  display: flex;
  flex-direction: column;
  gap: var(--sp-base);
}

.workbook-detail-title-row {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-md);
}

.workbook-detail-title {
  font-size: var(--fs-xl);
  font-weight: 600;
  color: var(--text);
  margin: 0;
  line-height: 1.25;
}

.workbook-detail-actions {
  display: flex;
  align-items: center;
  gap: var(--sp-xs);
  flex: 0 0 auto;
}

.workbook-detail-meta {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-md);
  font-size: var(--fs-sm);
  color: var(--text-dim);
}

.workbook-detail-meta-item {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-xs);
}

.workbook-detail-body {
  display: flex;
  flex-direction: column;
  gap: var(--sp-md);
}

.workbook-detail-body .wb-title {
  font-size: var(--fs-base);
  font-weight: 600;
  color: var(--text);
}

.workbook-detail-body .wb-loc {
  font-size: var(--fs-sm);
  color: var(--text-dim);
}

.workbook-detail-body .wb-desc {
  font-size: var(--fs-main);
  line-height: 1.5;
  color: var(--text);
}

.workbook-detail-body .wb-unit {
  font-weight: 400;
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

.workbook-detail-body .wb-unit-sm {
  font-weight: 400;
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.workbook-detail-body .wb-raw-toggle {
  font-size: var(--fs-xs);
  padding: var(--sp-xs) var(--sp-sm);
}

.workbook-detail-body .wb-id {
  color: var(--text-muted);
  font-size: var(--fs-sm);
  margin-left: var(--sp-sm);
}

.workbook-detail-section {
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
}

.workbook-detail-section h4 {
  margin: 0;
  font-size: var(--fs-base);
  font-weight: 600;
  color: var(--text);
}

.workbook-params-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--sz-grid-cell), 1fr));
  gap: var(--sp-md);
}

.workbook-param-card {
  background: var(--bg-soft);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-sm) var(--sp-md);
  display: flex;
  flex-direction: column;
  gap: var(--sp-tiny);
}

.workbook-param-name {
  font-size: var(--fs-xs);
  color: var(--text-dim);
}

.workbook-param-val {
  font-size: var(--fs-md);
  font-weight: 600;
  color: var(--text);
}

.workbook-results-grid {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(var(--sz-grid-cell), 1fr));
  gap: var(--sp-md);
}

.workbook-result-card {
  background: var(--accent-soft);
  border: var(--sp-micro) solid rgba(28, 139, 237, .2);
  border-radius: var(--radius);
  padding: var(--sp-md);
  display: flex;
  flex-direction: column;
  gap: var(--sp-tiny);
}

.workbook-result-name {
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

.workbook-result-val {
  font-size: var(--fs-lg);
  font-weight: 700;
  color: var(--text);
}

.workbook-raw-xml {
  background: var(--bg-soft);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--radius);
  padding: var(--sp-md);
  font-family: monospace;
  font-size: var(--fs-xs);
  color: var(--text);
  overflow-x: auto;
  white-space: pre-wrap;
  word-break: break-all;
  max-height: 400px;
}

/* =====================================================================
   07. Common reusable elements
   ===================================================================== */

/* ---------- Buttons ---------- */

.actions button {
  width: var(--sz-ui-action);
  height: var(--sz-ui-action);
  border-radius: var(--sp-sm);
  border: 0;
  background: transparent;
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background .12s ease, color .12s ease;
}

.actions button .i {
  width: var(--sz-ui-sm);
  height: var(--sz-ui-sm);
  font-size: var(--sz-ui-sm);
}

.actions button:hover {
  background: var(--bg-hover);
  color: var(--text);
}

.btn {
  padding: var(--sp-base) var(--sp-lg);
  font-size: var(--fs-main);
  font-weight: 500;
  width: auto !important;
}

.btn.primary {
  background: var(--accent) !important;
  color: var(--accent-fg) !important;
}

.btn.danger {
  background: var(--danger);
  color: #fff;
}

.iconbtn {
  width: var(--sz-ui-action);
  height: var(--sz-ui-action);
  border-radius: var(--sp-sm);
  border: 0;
  background: transparent;
  color: var(--text-muted);
  font-size: var(--fs-md);
  line-height: 1;
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  position: relative;
  transition: background .12s ease, color .12s ease;
}

.btn:disabled {
  opacity: .5;
  cursor: default;
}

.btn.secondary {
  background: var(--surface);
  color: var(--text);
}

.btn.secondary:not(.subtable-toggle) {
  border: var(--sp-micro) solid var(--border-strong);
}

.iconbtn:active {
  background: var(--bg-active);
}

.iconbtn:disabled {
  opacity: .35;
  cursor: default;
}

.iconbtn:focus-visible {
  outline: none;
  box-shadow: none;
}

.iconbtn.primary {
  color: var(--ok);
}

.iconbtn.danger {
  color: var(--danger);
}

.btn.danger.secondary {
  background: var(--surface);
  color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 40%, transparent);
}

.btn:hover:not(:disabled) {
  opacity: .9;
}

.iconbtn:hover:not(:disabled) {
  background: var(--bg-hover);
  color: var(--text);
}

.btn.secondary:hover:not(:disabled) {
  background: var(--bg-hover);
}

.btn.danger.secondary:hover:not(:disabled) {
  background: var(--danger-bg);
}

/* Small icon-only button (table rows, sub-forms) */
.mini-icon-btn {
  width: 24px;
  height: 24px;
}

/* --- Tip (help) button --- */

.tip-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--sp-xl);
  height: var(--sp-xl);
  border-radius: 50%;
  border: var(--sp-micro) solid var(--border-strong);
  background: var(--bg-soft);
  color: var(--text-muted);
  font-size: var(--fs-sm);
  font-weight: 700;
  cursor: pointer;
  margin-left: var(--sp-sm);
  vertical-align: middle;
}

.tip-btn:hover {
  background: var(--bg);
  color: var(--text);
}

/* ---------- Floating actions ---------- */

.fab-stack {
  position: fixed;
  right: max(var(--sp-xl), env(safe-area-inset-right));
  bottom: max(var(--sp-xl), env(safe-area-inset-bottom));
  display: flex;
  flex-direction: column;
  gap: var(--sp-md);
  z-index: 50;
}

.fab {
  position: relative;
  width: var(--sz-fab);
  height: var(--sz-fab);
  border-radius: 50%;
  background: var(--accent);
  color: var(--accent-fg);
  border: 0;
  font-size: var(--fs-lg);
  line-height: 1;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  box-shadow: var(--shadow-2);
  transition: opacity .12s ease, transform .12s ease;
}

.fab.fab-revert {
  background: var(--surface);
  color: var(--text);
  border: var(--sp-micro) solid var(--border-strong);
}

/* «ВНИРО.Контракт Данные» — вторичное действие: акцент в стеке оставлен
   планированию (в модуле «Финансовые показатели» это профильное действие),
   иначе два акцентных круга спорят друг с другом. */
.fab.vniro-contract-fab {
  background: var(--surface);
  color: var(--text);
  border: var(--sp-micro) solid var(--border-strong);
}

.fab:disabled {
  opacity: 1;
  cursor: default;
  pointer-events: none;
  background: var(--bg-soft);
  color: var(--text-faint);
  border: var(--sp-micro) solid var(--border);
  box-shadow: none;
}

.fab .dirty-dot {
  position: absolute;
  top: var(--sp-xs);
  right: var(--sp-xs);
  margin: 0;
  box-shadow: 0 0 0 var(--sp-tiny) var(--bg);
}

.fab:disabled .dirty-dot {
  display: none !important;
}

.fab:hover {
  opacity: .92;
}

.fab:active {
  transform: translateY(var(--sp-micro));
}

.fab:focus-visible {
  outline: none;
  box-shadow: none;
}

/* Map FABs (legend / fit) are secondary surface buttons in every module —
   это состояние «выключено». Состояние «включено» описано ниже и должно идти
   после этого блока: селекторы здесь специфичнее (.fab + класс), поэтому
   акцент, объявленный раньше, ими перебивался и кнопка не менялась. */
.fab.map-layers-fab,
.fab.map-fit-fab,
#module-coverage .fab.map-layers-fab,
#module-coverage .fab.map-fit-fab,
#module-map .fab.map-layers-fab,
#module-map .fab.map-fit-fab {
  background: var(--surface);
  color: var(--text);
  border: var(--sp-micro) solid var(--border-strong);
}

/* Кнопка легенды двух состояний: включена — акцентная, как основное действие.
   Легенда открыта по умолчанию, поэтому при входе в режим карты кнопка сразу
   акцентная. Селекторы повторяют форму блока выше (и его ID-варианты), чтобы
   перебить его по специфичности и порядку. */
.fab.map-layers-fab.is-active,
#module-coverage .fab.map-layers-fab.is-active,
#module-map .fab.map-layers-fab.is-active {
  background: var(--accent);
  color: var(--accent-fg);
  border-color: var(--accent);
}

/* ---------- Modals ---------- */

.confirm-modal {
  max-width: var(--sz-modal-sm);
  border-radius: var(--radius-lg);
}

.confirm-modal .confirm-body {
  padding: var(--sp-xl);
  text-align: center;
}

.confirm-modal .confirm-msg {
  margin: 0 0 var(--sp-lg);
  font-size: var(--fs-base);
  line-height: 1.5;
}

.confirm-modal .confirm-actions {
  display: flex;
  gap: var(--sp-base);
  justify-content: center;
}

.modal-bg {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, .45);
  display: none;
  align-items: center;
  justify-content: center;
  z-index: 10000;
  padding: var(--sp-xl);
}

.modal {
  background: var(--surface);
  color: var(--text);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--radius-lg);
  max-width: var(--sz-modal-w);
  width: 100%;
  max-height: 90vh;
  overflow: auto;
  box-shadow: var(--shadow-3);
}

.modal header {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--surface);
  color: var(--text);
  padding: var(--sp-lg) var(--sp-xl);
  border-bottom: var(--sp-micro) solid var(--border);
  display: flex;
  justify-content: space-between;
  align-items: center;
  border-radius: var(--radius-lg) var(--radius-lg) 0 0;
  max-width: none;
  margin: 0;
  height: auto;
}

.modal header h2 {
  margin: 0;
  font-size: var(--fs-md);
  font-weight: 600;
}

.modal-bg.side-mode {
  background: transparent;
  pointer-events: none;
  justify-content: flex-end;
  align-items: stretch;
  padding: 0;
  z-index: 10000;
}

.modal-bg.show {
  display: flex;
}

.modal .iconbtn {
  color: var(--text-muted);
  background: transparent;
}

.modal .body {
  padding: var(--sp-lg) var(--sp-xl) var(--sp-xl);
}

.modal .close {
  width: var(--sz-ui-action);
  height: var(--sz-ui-action);
  border-radius: var(--sp-sm);
  border: 0;
  background: transparent;
  color: var(--text-muted);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background .12s ease, color .12s ease;
}

.modal .actions {
  display: flex;
  gap: var(--sp-base);
  padding: var(--sp-md) var(--sp-xl);
  border-top: var(--sp-micro) solid var(--border);
  background: var(--bg-soft);
  border-radius: 0 0 var(--radius-lg) var(--radius-lg);
}

.modal header::after {
  content: none;
}

.modal-bg.side-mode.with-side {
  padding-right: 0;
}

.modal .close:focus-visible {
  outline: none;
  box-shadow: none;
}

.modal-bg.side-mode .modal {
  pointer-events: auto;
  max-width: var(--sz-side-panel);
  width: var(--sz-side-panel);
  max-height: 100vh;
  height: 100vh;
  border-radius: 0;
  box-shadow: var(--shadow-3);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform .25s ease;
  border-left: var(--sp-micro) solid var(--border);
}

.modal .close:hover {
  background: var(--bg-hover);
  color: var(--text);
}

.modal .actions .spacer {
  flex: 1;
}

.modal-bg.side-mode .modal header {
  border-radius: 0;
  justify-content: space-between;
}

.modal-bg.side-mode.show .modal {
  transform: translateX(0);
}

.modal-bg.side-mode .modal .body {
  flex: 1 1 auto;
  overflow: auto;
}

.modal-bg.side-mode .modal .actions {
  border-radius: 0;
}

/* ---------- Side panels ---------- */

.side-panel {
  position: fixed;
  top: 0;
  right: 0;
  height: 100%;
  width: var(--sz-side-panel);
  max-width: 90vw;
  background: var(--surface);
  color: var(--text);
  border-left: var(--sp-micro) solid var(--border);
  box-shadow: var(--shadow-3);
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform .25s ease, width .25s ease, max-width .25s ease, top .25s ease, right .25s ease, height .25s ease, border-radius .25s ease;
  z-index: 3000;
}

/* Занавес за развёрнутой панелью: всё, что под ним, расплывается, чтобы запись
   читалась целиком. z-index ставит app.js — на единицу меньше развёрнутой
   панели, поэтому остальные панели стека тоже оказываются под размытием.
   Клик по занавесу возвращает панель к краю. */
.panel-curtain {
  position: fixed;
  inset: 0;
  z-index: 2999;
  background: color-mix(in srgb, var(--bg) 32%, transparent);
  backdrop-filter: blur(var(--blur));
  -webkit-backdrop-filter: blur(var(--blur));
  opacity: 0;
  transition: opacity .22s ease;
  pointer-events: none;
}

.panel-curtain.is-on {
  opacity: 1;
  pointer-events: auto;
}

.side-panel.is-expanded {
  --panel-exp-w: clamp(min(640px, 90vw), 50vw, 90vw);
  top: var(--sp-max);
  bottom: var(--sp-lg);
  right: calc((100vw - var(--panel-exp-w)) / 2);
  width: var(--panel-exp-w);
  max-width: 90vw;
  height: calc(100vh - var(--sp-max) - var(--sp-lg));
  max-height: calc(100vh - var(--sp-max) - var(--sp-lg));
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  overflow: hidden;
  transform: translateY(0);
  opacity: 1;
  transition: transform .28s ease, top .28s ease, opacity .28s ease, width .25s ease, right .25s ease;
}

.side-panel.is-expanded:not(.show) {
  transform: translateY(-100%) !important;
  opacity: 0;
}

.side-panel.is-expanded header {
  border-top-left-radius: var(--radius-lg);
  border-top-right-radius: var(--radius-lg);
}

.side-panel.is-expanded .sp-footer {
  border-bottom-left-radius: var(--radius-lg);
  border-bottom-right-radius: var(--radius-lg);
}

.sp-expand.active,
.side-panel.is-expanded .sp-expand {
  color: var(--accent);
}

.side-panel.is-depressed:not(.is-expanded) {
  top: calc(var(--depress-step, 1) * (var(--sz-header) + var(--sp-base))) !important;
  height: calc(100% - (var(--depress-step, 1) * (var(--sz-header) + var(--sp-base)))) !important;
}

.side-panel.behind {
  cursor: pointer;
}

.side-panel.behind.is-hovered header,
.side-panel.behind:hover header {
  filter: none;
  background: var(--surface);
}

.side-panel header {
  display: flex;
  padding: 0 calc(var(--sp-huge) * .5);
  align-items: center;
  justify-content: space-between;
  height: var(--sz-header);
  background: var(--surface);
  border-bottom: var(--sp-micro) solid var(--border);
  position: static;
  max-width: none;
  margin: 0;
}

.side-panel[hidden] {
  display: none !important;
}

.side-panel.show {
  transform: translateX(0);
}

.side-panel .actions {
  display: flex;
  gap: var(--sp-xs);
  flex: 0 0 auto;
  margin-left: auto;
}

.side-panel .placeholder {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-md);
  color: var(--text-muted);
  text-align: center;
  padding: var(--sp-xl);
  font-size: var(--fs-main);
}

.side-panel .body {
  flex: 1 1 auto;
  min-height: 0;
  position: relative;
  background: var(--bg);
  overflow: auto;
  padding: var(--sp-huge);
}

.side-panel .sp-footer {
  display: flex;
  width: 100%;
  gap: var(--sp-base);
  padding: var(--sp-md) var(--sp-xl);
  border-top: var(--sp-micro) solid var(--border);
  background: var(--bg-soft);
  flex: 0 0 auto;
}

.side-panel .sp-footer.is-visible {
  display: flex !important;
}

.side-panel .sp-footer .spacer {
  flex: 1;
}

.side-panel .sp-delete.is-visible {
  display: inline-flex !important;
}

.side-panel.behind header {
  filter: brightness(.96);
  transition: filter .15s ease, background .15s ease;
}

.side-panel header::after {
  content: none;
}

.side-panel header .title {
  flex: 1;
  min-width: 0;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  font-weight: 600;
  font-size: var(--fs-base);
}

.poi-title-dot {
  display: inline-block;
  width: var(--sp-md);
  height: var(--sp-md);
  border-radius: 50%;
  margin-right: var(--sp-base);
  vertical-align: middle;
}

.side-panel header .actions {
  display: flex;
  gap: var(--sp-xs);
}

.side-panel .body .kv {
  margin: 0 0 var(--sp-lg);
}

.side-panel .placeholder .icon {
  color: var(--text-faint);
}

.side-panel .placeholder .path {
  font-size: var(--fs-xs);
  background: var(--bg-soft);
  color: var(--text-muted);
  padding: var(--sp-sm) var(--sp-md);
  border-radius: var(--sp-sm);
  word-break: break-all;
  max-width: 100%;
}

.side-panel .body h3.sec {
  font-size: var(--fs-main);
  color: var(--text-muted);
  font-weight: 600;
  margin: var(--sp-huge) 0 var(--sp-md);
  padding-bottom: var(--sp-sm);
  border-bottom: var(--sp-micro) solid var(--border);
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
}

.side-panel .body .placeholder {
  position: static;
  min-height: 30vh;
}

.side-panel .body h3.sec:first-child {
  margin-top: 0;
}

/* Отдельные заголовки секций используют увеличенный отступ сверху (заменял
   inline `margin-top`). Специфичность выше базового правила `.side-panel .body h3.sec`. */
.side-panel .body h3.sec.mt-xl {
  margin-top: var(--sp-xl);
}

/* Подзаголовок внутри секции (используется и в админке прав, и в панели
   «Информация из ВНИРО.Контракт»). Без своего правила h4 берёт крупный
   браузерный размер — задаём его явно. */
.side-panel .body h4.sec {
  margin: var(--sp-lg) 0 var(--sp-xs);
  color: var(--text);
  font-size: var(--fs-main);
  font-weight: 600;
}
/* ---------- Forms ---------- */

.form-grid {
  gap: var(--sp-md) var(--sp-lg);
  display: flex;
  flex-direction: column;
}

.form-grid label,
.form-grid .form-field {
  display: flex;
  flex-direction: column;
  gap: var(--sp-xs);
  font-size: var(--fs-sm);
  color: var(--text-muted);
}

.form-grid code {
  font-size: var(--fs-sm);
  background: var(--bg-soft);
  padding: var(--sp-micro) var(--sp-sm);
  border-radius: var(--sp-xs);
}

.form-grid input,
.form-grid select {
  height: var(--ht-input);
  padding: 0 var(--sp-md);
  border: var(--sp-micro) solid var(--border-strong);
  border-radius: var(--sp-sm);
  background: var(--bg);
  color: var(--text);
  font-size: var(--fs-base);
  width: 100%;
}

/* Числовые поля: ограничиваем сам инпут, а не всю подпись. Значение — справа.
   Табличные цифры — чтобы разряды не «прыгали» при вводе. */
.num-input {
  max-width: var(--sz-num-width);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

/* Только у полей с провайдером: отступ под кнопку выбора. */
.num-picker .input-wrap input {
  padding-right: calc(var(--sp-md) + var(--ht-input));
}

.form-grid textarea {
  padding: var(--sp-base) var(--sp-md);
  border: var(--sp-micro) solid var(--border-strong);
  border-radius: var(--sp-sm);
  background: var(--bg);
  color: var(--text);
  font-size: var(--fs-base);
  width: 100%;
}

.form-grid input:disabled,
.form-grid select:disabled,
.form-grid textarea:disabled,
.lookup input:not([type="hidden"]):disabled {
  background: var(--bg-soft);
  color: var(--text-faint);
  border-color: var(--border);
  cursor: not-allowed;
  opacity: 1;
}

.form-grid input:disabled::placeholder,
.form-grid textarea:disabled::placeholder,
.lookup input:not([type="hidden"]):disabled::placeholder {
  color: var(--text-faint);
}

/* Неактивные (расчётные) поля — readonly: изменить нельзя, но значение
   можно выделить и скопировать. Отличаются только фоном: рамка, шрифт
   и цвет текста такие же, как у активных полей. */
.form-grid input.computed,
.lookup input.computed {
  background: var(--bg-soft);
}

.form-grid textarea.resize-vertical {
  resize: vertical;
}

.edit-file-block {
  margin-bottom: var(--sp-lg);
}

.req {
  color: var(--danger);
}

.side-panel .body .add-row {
  margin-top: var(--sp-base);
}

.btn-compact {
  font-size: var(--fs-xs);
}

.form-grid .hint,
.form-results .hint {
  font-size: var(--fs-xs);
  color: var(--text-dim);
}

/* Подпись результата расчёта: строка причины под парой «поле — значение». */
.form-results .hint:not([hidden]) {
  margin-top: var(--sp-sm);
}

.hint-danger,
.text-danger {
  color: var(--danger) !important;
}

/* Подзаголовок внутри секции панели («Ручной запуск» в разделе «Загрузка данных»). */
/* Строка «поле — значение» с точечной выноской: сестра .fin-crit, но без
   пройден/провален. Живёт внутри .fin-crit-group, который задаёт колонку. */
.fin-fact {
  display: flex;
  align-items: baseline;
  gap: var(--sp-md);
  font-size: var(--fs-sm);
}

/* В боковой панели блок крупнее, чем во всплывающей диагностике сделки:
   .fin-criteria задаёт --fs-tiny, иначе заголовок был бы мельче своих строк. */
.side-panel .body .fin-crit-group-title {
  font-size: var(--fs-sm);
}

.fin-fact-label {
  flex: 0 1 auto;
  min-width: 0;
  color: var(--text-dim);
  overflow-wrap: anywhere;
}

.fin-fact-leader {
  flex: 1 1 auto;
  align-self: center;
  min-width: var(--sp-lg);
  border-bottom: var(--sp-tiny) dotted var(--border-strong);
}

.fin-fact-value {
  flex: 0 0 auto;
  color: var(--text);
  text-align: right;
}

/* Ряд с одной кнопкой действия в теле панели. Базовый .actions прижимает
   содержимое вправо (justify-self / margin-left: auto) — это нужно строкам
   таблиц и sub-row, но не самостоятельному ряду под заголовком: он должен
   начинаться слева. Поэтому отдельный модификатор, а не переопределение
   .actions внутри .body (иначе поехали бы кнопки удаления в редакторе НИР). */
.actions.actions-row {
  justify-self: start;
  margin-left: 0;
}

/* Неуспешный результат: подсвечиваем только значение, подпись остаётся
   нейтральной — как в .fin-crit--fail. */
.fin-fact--fail .fin-fact-value {
  color: var(--danger);
}

/* Пояснение к непройденной проверке (причина отказа рядом с названием шага). */
.fin-crit-note {
  color: var(--text-muted);
}

/* Сумма плана с индикатором актуальности редакции. */
.plans-table .plan-amount {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: var(--sp-sm);
}

.plans-table tr.plan-superseded td {
  color: var(--text-dim);
}

.plan-indicator {
  flex: 0 0 auto;
  width: var(--sp-base);
  height: var(--sp-base);
  border-radius: 50%;
  background-color: var(--text-faint);
}

.plan-indicator[data-state="active"] {
  background-color: var(--ok);
}

.plan-indicator[data-state="superseded"] {
  background-color: var(--not-error);
}

.form-grid .err-msg {
  font-size: var(--fs-xs);
  color: var(--danger);
}

.form-grid label.full,
.form-grid div.full {
  grid-column: 1 / -1;
}

.form-instruction {
  color: var(--text-muted);
  font-size: var(--fs-sm);
  margin: var(--sp-lg) 0;
}

.form-section {
  display: flex;
  flex-direction: column;
}

.form-section + .form-section {
  margin-top: var(--sp-huge);
}

/* h3 секции с неактивными полями кликабелен: показывает/скрывает их. */
.form-section > h3.sec.has-inactive {
  display: flex;
  align-items: center;
  gap: var(--sp-xs);
  cursor: pointer;
  user-select: none;
}

/* Маркер — омега: bold, пока расчётные поля показаны (состояние по умолчанию),
   subtle — когда пользователь их скрыл. Прижат вправо; font-size: unset —
   иначе .i даёт иконке var(--sp-xl). */
.form-section > h3.sec.has-inactive .sec-toggle {
  margin-left: auto;
  font-size: unset;
  color: var(--text);
  font-weight: 700;
  transition: color .12s;
}

.form-section.hide-inactive > h3.sec.has-inactive .sec-toggle {
  color: var(--text-dim);
  font-weight: 400;
}

.form-results {
  margin-top: calc(var(--sp-xl) + var(--sp-sm));
  border-top: var(--sp-micro) solid var(--border);
  padding-top: var(--sp-lg);
}

.form-grid input:focus,
.form-grid select:focus,
.form-grid textarea:focus {
  outline: none;
  box-shadow: var(--shadow-2);
}

/* Кнопки в теле панели: без скругления; при переходе с клавиатуры —
   видимое кольцо фокуса (глобальное button:focus его гасит). */
.side-panel .body button:focus-visible {
  box-shadow: var(--focus-ring);
}

/* ---------- File drop ---------- */

.file-drop {
  border: var(--sp-micro) dashed var(--border);
  border-radius: var(--sp-sm);
  padding: var(--sp-md) var(--sp-lg);
  cursor: pointer;
  color: var(--text-dim);
  font-size: var(--fs-xs);
  line-height: 1.5;
  transition: border-color .15s, background .15s;
  position: relative;
  display: flex;
  align-items: center;
  gap: var(--sp-lg);
}

.file-drop:hover {
  border-color: var(--border-strong);
}

.file-drop.drag-over {
  border-color: var(--accent);
  background: var(--bg-soft);
}

.file-drop.has-file {
  border-style: solid;
}

.file-drop .fd-icon {
  color: var(--text-faint);
  flex: 0 0 auto;
}

.file-drop .fd-body {
  flex: 1 1 auto;
  min-width: 0;
}

.file-drop .fd-name {
  font-weight: 600;
  color: var(--text);
  font-size: var(--fs-sm);
}

.file-drop .fd-remove {
  flex: 0 0 auto;
  width: var(--sp-xl);
  height: var(--sp-xl);
  border-radius: 50%;
  border: 0;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  z-index: 2;
}

.file-drop .fd-remove[hidden] {
  display: none !important;
}

.file-drop input[type="file"] {
  position: absolute;
  inset: 0;
  opacity: 0;
  cursor: pointer;
  width: 100%;
  height: 100%;
}

.file-drop .fd-remove:hover {
  background: var(--bg-hover);
  color: var(--danger);
}

/* --- Photo picker (JPEG file-drop + optional description) --- */

.photo-row {
  padding: 0;
  border: 0;
  border-radius: 0;
}

.photo-picker {
  display: flex;
  flex-direction: column;
  width: 100%;
}

.photo-picker.expanded .file-drop {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
}

.photo-desc {
  display: none;
  height: var(--ht-input);
  padding: 0 var(--sp-md);
  border: var(--sp-micro) solid var(--border);
  border-top: 0;
  border-radius: 0 0 var(--sp-sm) var(--sp-sm);
  background: var(--bg);
  color: var(--text);
  font-size: var(--fs-base);
  width: 100%;
  box-sizing: border-box;
}

.photo-picker.expanded .photo-desc {
  display: block;
}

.photo-desc:focus {
  outline: none;
  box-shadow: var(--shadow-2);
}

/* ---------- Lookup, chips, and autocomplete ---------- */

.lookup {
  position: relative;
  min-width: 0;
  width: 100%;
}

.lookup input:not([type="hidden"]) {
  height: var(--ht-input);
  padding: 0 var(--sp-md);
  border: var(--sp-micro) solid var(--border-strong);
  border-radius: var(--sp-sm);
  background: var(--bg);
  color: var(--text);
  font-size: var(--fs-base);
  width: 100%;
  box-sizing: border-box;
}

.lookup input:not([type="hidden"]):focus {
  outline: none;
  box-shadow: var(--shadow-2);
}

.chips-pop {
  position: relative;
}

.chips {
  display: flex;
  flex-wrap: wrap;
  overflow: visible;
  gap: var(--sp-xs);
  padding: var(--sp-xs);
  border: var(--sp-micro) solid var(--border-strong);
  border-radius: var(--sp-sm);
  background: var(--bg);
  min-height: var(--ht-input);
  height: auto;
  align-items: center;
  width: 100%;
  min-width: 0;
  box-sizing: border-box;
}

.chips:focus-within {
  box-shadow: var(--shadow-2);
}

.chips::-webkit-scrollbar {
  display: none;
}

.chip {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-xs);
  background: var(--bg-soft);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--radius-full);
  padding: 0 var(--sp-base);
  height: calc(var(--sz-ui-action) - var(--sp-base));
  font-size: var(--fs-sm);
  color: var(--text);
  white-space: nowrap;
  flex: 0 0 auto;
}

.chip button {
  background: transparent;
  border: 0;
  cursor: pointer;
  color: var(--text-muted);
  padding: var(--sp-tiny) var(--sp-xs);
  border-radius: 50%;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.chip-principal {
  width: var(--sp-md);
  height: var(--sp-md);
  min-width: var(--sp-md);
  min-height: var(--sp-md);
  padding: 0 !important;
  border: var(--sp-micro) solid var(--text-faint) !important;
  background: transparent !important;
}

.chip-principal.active {
  border-color: var(--accent) !important;
  background: var(--accent) !important;
}

.chip-principal:hover {
  border-color: var(--text-muted) !important;
}

.chip-principal.active:hover {
  border-color: var(--accent) !important;
  background: var(--accent) !important;
}

.wp-preview {
  cursor: text;
  padding: 0 var(--sp-md);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--sp-sm);
  background: var(--bg);
  font-size: var(--fs-main);
  line-height: var(--ht-input);
  height: var(--ht-input);
  box-sizing: border-box;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  width: 100%;
  max-width: 100%;
}

.lookup .wp-preview {
  display: none;
}

.sub-row-surveys>.sub-row-main>.sub-row-water>.wp-preview {
  display: block;
  flex: 1 1 auto;
  cursor: pointer;
}

.lookup .results {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  background: var(--surface);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--sp-sm);
  box-shadow: var(--shadow-2);
  max-height: var(--sz-list-max-h);
  overflow: auto;
  z-index: 10;
  display: none;
}

/* Principal assignment uses the browser top layer so its options stay above
   sticky headers, floating controls, cards, tables, and side panels. Position
   and viewport-aware dimensions are supplied by bindStaffLookup(). */
.deal-principal-lookup .results[popover] {
  position: fixed;
  inset: auto;
  margin: 0;
  box-sizing: border-box;
  z-index: 10000;
}

.chips-pop .results {
  background: var(--surface);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--sp-sm);
  box-shadow: var(--shadow-2);
  max-height: var(--sz-list-sm-h);
  overflow: auto;
  display: none;
  margin-top: var(--sp-xs);
}

.chips .add {
  flex: 1 1 var(--sz-stat-w);
  min-width: var(--sz-stat-w);
  border: 0;
  outline: none;
  background: transparent;
  font-size: var(--fs-main);
  padding: 0 var(--sp-sm);
  color: var(--text);
  height: calc(var(--sz-ui-action) - var(--sp-base));
}

.chips .add:focus,
.chips .chip button:focus {
  outline: none;
  box-shadow: none;
}

.lookup.picked input {
  display: none;
}

.chip button:hover {
  background: var(--bg-active);
  color: var(--text);
}

.wp-preview:hover {
  border-color: var(--border-strong);
}

.wp-preview:focus {
  outline: none;
  box-shadow: var(--shadow-2);
}

.lookup.picked .wp-preview {
  display: block;
}

.lookup.open .results,
.lookup .results.open,
.chips-pop.open .results {
  display: block;
}

.lookup .results .row,
.lookup .results .item,
.chips-pop .results .item {
  padding: var(--sp-sm) var(--sp-md);
  cursor: pointer;
  font-size: var(--fs-main);
  border-bottom: var(--sp-micro) solid var(--border);
}

.lookup .results .empty,
.chips-pop .results .empty {
  padding: var(--sp-md);
  color: var(--text-muted);
  font-size: var(--fs-main);
}

.lookup .results .item small,
.chips-pop .results .item small {
  color: var(--text-muted);
}

.lookup .results .item-title {
  font-weight: 600;
}

.lookup .results .item .sub {
  font-size: var(--fs-xs);
  color: var(--text-dim);
}

.substitute-note {
  color: var(--warn);
  margin-left: var(--sp-base);
}

.lookup .results .row:last-child,
.lookup .results .item:last-child,
.chips-pop .results .item:last-child {
  border-bottom: 0;
}

.lookup .results .row:hover,
.lookup .results .row.active,
.lookup .results .item:hover,
.lookup .results .item.active,
.chips-pop .results .item:hover,
.chips-pop .results .item.active {
  background: var(--bg-hover);
}

.lookup .results .row .sub {
  font-size: var(--fs-xs);
  color: var(--text-dim);
}

/* ---------- Number Picker ---------- */

.num-picker {
  position: relative;
  display: flex;
  flex-direction: column;
}

.num-picker .input-wrap {
  position: relative;
  display: flex;
  align-items: center;
  max-width: var(--sz-num-width);
}

/* Отступ задаёт .num-input — он одинаков у поля с провайдером и у обычного,
   поэтому цифры стоят на одной линии, а до кнопки остаётся промежуток. */

.num-picker .toggle-pick {
  position: absolute;
  right: var(--sp-micro);
  top: var(--sp-micro);
  bottom: var(--sp-micro);
  width: var(--ht-input);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--text-dim);
  border-radius: 0 var(--radius) var(--radius) 0;
  transition: background .12s, color .12s;
  background: transparent;
  border: 0;
  padding: 0;
}

.num-picker .toggle-pick:hover {
  color: var(--text);
  background: var(--bg-soft);
}

.num-picker.open .toggle-pick {
  color: var(--ok);
  background: var(--bg-soft);
}

.num-picker-values {
  position: absolute;
  left: 0;
  top: 100%;
  z-index: 10;
  display: grid;
  grid-template-columns: repeat(5, minmax(0, 1fr));
  gap: var(--sp-xs);
  padding: var(--sp-sm);
  background: var(--surface);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--sp-sm);
  box-shadow: var(--shadow-2);
}

.num-picker-values button {
  height: var(--ht-input);
  padding: 0 var(--sp-sm);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--sp-sm);
  background: var(--bg);
  color: var(--text);
  font-size: var(--fs-main);
  cursor: pointer;
}

.num-picker-values button:hover {
  background: var(--bg-soft);
  border-color: var(--border-strong);
}

/* ---------- Geo Picker ---------- */

.geo-picker {
  position: relative;
  display: flex;
  flex-direction: column;
}

.geo-picker .input-wrap {
  position: relative;
  display: flex;
  align-items: center;
}

.geo-picker input {
  padding-right: var(--ht-input) !important;
}

.geo-picker .toggle-map {
  position: absolute;
  right: var(--sp-micro);
  top: var(--sp-micro);
  bottom: var(--sp-micro);
  width: var(--ht-input);
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  color: var(--text-dim);
  border-radius: 0 var(--radius) var(--radius) 0;
  transition: background .12s, color .12s;
  background: transparent;
  border: 0;
  padding: 0;
}

.geo-picker .toggle-map:not(:disabled):hover {
  background: var(--bg-hover);
  color: var(--text);
}

.geo-picker .toggle-map:disabled {
  opacity: .3;
  cursor: default;
}

.geo-picker .water-map-wrap {
  margin-top: 0;
  border-top: 0;
  border-top-left-radius: 0;
  border-top-right-radius: 0;
  display: none;
}

.geo-picker.expanded .water-map-wrap {
  display: block;
}

.geo-picker.expanded {
  box-shadow: var(--shadow-3);
  border-radius: var(--radius);
  z-index: 10;
}

.geo-picker.expanded input {
  border-bottom-left-radius: 0;
  border-bottom-right-radius: 0;
  border-bottom: var(--sp-micro) dashed var(--border);
}

/* ---------- Custom Choice Picker ---------- */

.custom-picker {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: var(--sp-md);
  margin-top: var(--sp-xs);
}

.custom-picker .picker-option {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-md);
  padding: var(--sp-md) var(--sp-lg);
  background: var(--bg-soft);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--radius);
  cursor: pointer;
  transition: background .15s ease, border-color .15s ease, box-shadow .15s ease;
  user-select: none;
}

.custom-picker .picker-option:hover {
  background: var(--bg-hover);
  border-color: var(--border-strong);
}

.custom-picker .picker-option.active {
  background: var(--accent-soft);
  border-color: var(--accent);
  box-shadow: 0 0 0 var(--sp-micro) var(--accent);
}

.custom-picker .picker-radio {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  border: 2px solid var(--border-strong);
  background: var(--surface);
  flex: 0 0 auto;
  margin-top: 2px;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: border-color .15s ease, background-color .15s ease;
}

.custom-picker .picker-option.active .picker-radio {
  border-color: var(--accent);
  background: var(--accent);
  box-shadow: inset 0 0 0 var(--ring-3) var(--surface);
}

.custom-picker .picker-checkbox {
  width: 24px;
  height: 16px;
  border-radius: 999px;
  border: 2px solid var(--border-strong);
  background: var(--surface);
  flex: 0 0 auto;
  margin-top: 2px;
  position: relative;
  transition: border-color .15s ease, background-color .15s ease;
}

.custom-picker .picker-checkbox::after {
  content: "";
  position: absolute;
  width: 8px;
  height: 8px;
  border-radius: 50%;
  background: var(--border-strong);
  top: 50%;
  left: 2px;
  transform: translateY(-50%);
  transition: left .15s ease, background-color .15s ease;
}

.custom-picker .picker-option.active .picker-checkbox {
  border-color: var(--accent);
  background: var(--accent);
}

.custom-picker .picker-option.active .picker-checkbox::after {
  background: var(--accent-fg);
  left: 10px;
}

.custom-picker .picker-content {
  display: flex;
  flex-direction: column;
  gap: var(--sp-tiny);
}

.custom-picker .picker-title {
  font-weight: 600;
  font-size: var(--fs-main);
  color: var(--text);
}

.custom-picker .picker-details {
  font-size: var(--fs-sm);
  color: var(--text-dim);
  line-height: 1.35;
}

.geo-picker.expanded .toggle-map {
  color: var(--ok);
  background: var(--bg-soft);
}

/* ---------- Status picker ---------- */

.status-dot {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-sm);
  font-size: var(--fs-main);
}

.sd-circle {
  display: inline-block;
  width: var(--sp-md);
  height: var(--sp-md);
  border-radius: 50%;
  flex: 0 0 auto;
}

/* ---------- survey-indicator ---------- */
.survey-indicator {
  width: var(--sp-md);
  height: var(--sp-md);
  border-radius: 50%;
  display: inline-block;
  flex: 0 0 auto;
  background-color: var(--text-faint);
  border: var(--sp-micro) solid rgba(0, 0, 0, 0.05);
  cursor: pointer;
}

.survey-indicator[status="demand"] {
  background-color: var(--st-demand);
}

.survey-indicator[status="planned"] {
  background-color: var(--st-planned);
}

.survey-indicator[status="surveyed"] {
  background-color: var(--st-surveyed);
}

.survey-indicator[status="processed"] {
  background-color: var(--st-processed);
}

.survey-indicator[status="ready"] {
  background-color: var(--st-ready);
}

.study-cell {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: var(--sp-xs) var(--sp-md);
}

.study-item {
  display: inline-flex;
  align-items: baseline;
  gap: var(--sp-xs);
  white-space: nowrap;
  color: var(--text-muted);
  font-size: var(--fs-sm);
}

.study-item b {
  color: var(--text);
  font-weight: 600;
}

.study-label {
  color: var(--text-dim);
}

.study-cat {
  align-items: center;
}

.status-picker {
  position: relative;
}

.sp-trigger {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  padding: 0 var(--sp-md);
  height: var(--ht-input);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--sp-sm);
  background: var(--bg);
  cursor: pointer;
  width: 100%;
  font: inherit;
  color: var(--text);
  text-align: left;
}

.sp-dropdown {
  display: none;
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  margin-top: var(--sp-tiny);
  background: var(--surface);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--sp-sm);
  box-shadow: var(--shadow-2);
  z-index: 10;
  overflow: hidden;
}

.sp-option {
  display: flex;
  align-items: center;
  gap: var(--sp-base);
  padding: var(--sp-base) var(--sp-md);
  cursor: pointer;
  font-size: var(--fs-main);
}

.sp-trigger:hover {
  border-color: var(--border-strong);
}

.sp-option:hover {
  background: var(--bg-hover);
}

.status-picker.open .sp-dropdown {
  display: block;
}

/* ---------- Generic content blocks ---------- */

.sp-section {
  color: var(--text-muted);
}

.empty {
  color: var(--text-faint);
  font-size: var(--fs-main);
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 2.8em;
  text-align: center;
}

.empty-view {
  display: flex;
  align-items: center;
  justify-content: center;
  text-align: center;
  min-height: clamp(240px, 45vh, 600px);
  padding: var(--sp-xl) var(--sp-base);
  color: var(--text-faint);
  font-size: var(--fs-md);
  font-weight: 500;
  user-select: none;
}

.timeline {
  display: flex;
  flex-direction: column;
  gap: var(--sp-sm);
  padding-left: var(--sp-sm);
  border-left: var(--sp-micro) solid var(--border);
  margin-left: var(--sp-xs);
}

.timeline-item {
  display: flex;
  gap: var(--sp-base);
  padding: var(--sp-sm) 0 var(--sp-sm) var(--sp-md);
  font-size: var(--fs-sm);
}

.kv {
  display: flex;
  flex-direction: column;
  gap: var(--sp-md);
  font-size: var(--fs-main);
}

.kv-pair {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-lg);
}

.kv-pair>.k {
  flex: 0 0 var(--sz-kv-label-w);
}

.kv-pair>.v {
  flex: 1 1 auto;
  min-width: 0;
}

/* Inverted kv — long labels, short values (fishcap view form).
   Label takes available space and wraps, value is compact and right-aligned.
   Use: <div class="kv kv--inverted"> */
.kv.kv--inverted .kv-pair>.k {
  flex: 1 1 auto;
  color: var(--text-muted);
}

.kv.kv--inverted .kv-pair>.v {
  flex: 0 0 var(--sz-kv-label-w);
  min-width: 0;
  text-align: right;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.sub-table {
  width: 100%;
  border-collapse: collapse;
  font-size: var(--fs-main);
  background: var(--surface);
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--sp-sm);
  overflow: hidden;
}

.sub-table th,
.sub-table td {
  padding: var(--sp-sm) var(--sp-md);
  border-bottom: var(--sp-micro) solid var(--border);
  text-align: left;
  vertical-align: top;
}

.sub-table th {
  background: var(--bg-soft);
  color: var(--text-muted);
  font-weight: 500;
  font-size: var(--fs-sm);
}

/* Long read-only subtables share one full-width secondary disclosure button. */
.subtable-toggle {
  width: 100% !important;
  height: var(--sz-ui-action);
  padding: 0;
  border: 0;
}

/* Биологические параметры вселяемого вида — таблица в редакторе и в панели
   просмотра. Тот же равномерный раскрой колонок и перенос заголовков
   использует таблица результатов расчёта (.fc-result-table). */
.biology-table,
.fc-result-table {
  table-layout: fixed;
}

/* Подписи колонок длинные — разрешаем перенос вместо переполнения
   (глобальное thead th задаёт white-space: nowrap). */
.biology-table th,
.fc-result-table th {
  white-space: normal;
  overflow-wrap: break-word;
}

/* --- Reusable card utilities --- */

/* Отступ сверху на величину var(--sp-lg) для блока-обёртки контента,
   следующего за заголовком/переключателем. Переиспользуется в любом модуле:
   вешается на саму обёртку, её содержимое своих верхних отступов не несёт. */
.top-lg-margined {
  margin-top: var(--sp-lg);
}

.shadow-expanded {
  margin: calc(-1.5 * var(--sp-xl));
  padding: calc(1.5 * var(--sp-xl));
}

.shadowed-card {
  padding: var(--sp-lg);
  border: 0;
  border-radius: var(--sp-md);
  background: var(--bg);
  box-shadow: var(--shadow-2);
}

.stat-card-label {
  font-size: var(--fs-sm);
}

.stat-card-value {
  margin-top: var(--sp-lg);
  font-size: var(--fs-xl);
  font-weight: 700;
  text-align: right;
}

/* --- Невидимый placeholder панели действий (hidden actions placeholder) --- */

.ghost-actions {
  visibility: hidden;
  pointer-events: none;
}

/* ---------- Spreadsheet ---------- */

/* Таблица-спредшит: инпут в ячейке без собственного оформления и занимает её
   целиком; Enter — переход на следующую строку в той же колонке
   (setupSpreadsheet в app.js). */
.spreadsheet {
  font-variant-numeric: tabular-nums;
}

.spreadsheet th,
.spreadsheet td {
  border-right: var(--sp-micro) solid var(--border);
  vertical-align: middle;
}

.spreadsheet th:last-child,
.spreadsheet td:last-child {
  border-right: 0;
}

/* Отступ живёт в инпуте, а не в ячейке: тогда инпут занимает ячейку целиком.
   Нулевой отступ — только ячейкам с инпутом (редактируемая таблица); ячейки
   просмотра с текстом сохраняют обычный отступ .sub-table.
   У первой колонки инпута нет, поэтому отступ возвращаем ей отдельно. */
.spreadsheet td:has(input) {
  padding: 0;
}

.spreadsheet td:first-child {
  padding: var(--sp-sm) var(--sp-md);
}

.spreadsheet td input {
  display: block;
  width: 100%;
  max-width: none;
  height: auto;
  padding: var(--sp-sm) var(--sp-md);
  border: 0;
  border-radius: 0;
  background: transparent;
}

/* У инпута в ячейке нет оформления ни в покое, ни в фокусе —
   перебиваем тень и контур, которые даёт .form-grid. */
.spreadsheet td input:focus {
  box-shadow: none;
  outline: none;
}

.kv .k {
  color: var(--text-muted);
}

.kv .v {
  color: var(--text);
}

.timeline-item .dt {
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
  min-width: var(--sz-timeline-w);
}

.timeline-item .drop {
  color: var(--warn);
  font-size: var(--fs-xs);
  margin-left: var(--sp-xs);
}

.sub-table tr:hover {
  background: var(--bg-hover);
}

.sub-table tr:last-child td {
  border-bottom: 0;
}

/* ---------- Pagination and toasts ---------- */

.pager {
  display: flex;
  gap: var(--sp-sm);
  align-items: center;
  justify-content: center;
  margin: var(--sp-lg) 0 0;
}

.pager button {
  background: transparent;
  border: 0;
  color: var(--text-muted);
  padding: var(--sp-sm) var(--sp-md);
  font-size: var(--fs-main);
  font-weight: 500;
  cursor: pointer;
  transition: all .15s ease;
}

.pager button.active {
  color: var(--text);
  font-weight: 700;
}

.pager button .pager-ellipsis,
.pager .pager-ellipsis {
  padding: 0 var(--sp-xs);
}

.pager button:disabled {
  opacity: .3;
  cursor: default;
}

.pager button:hover:not(:disabled) {
  color: var(--text);
  text-decoration: underline;
}

button.lines-toggle {
  width: 100% !important;
  background: var(--surface);
  color: var(--text-faint);
  border: none;
}

button.lines-toggle:hover {
  background: var(--bg-active);
}

#toast {
  position: fixed;
  left: 50%;
  bottom: var(--sp-xl);
  transform: translateX(-50%);
  background: var(--surface);
  border-radius: var(--sp-base);
  box-shadow: var(--shadow-3);
  z-index: 1100;
  opacity: 0;
  pointer-events: none;
  transition: opacity .2s;
  max-width: min(560px, calc(100vw - 2 * var(--sp-lg)));
}

#toast.show {
  opacity: 1;
  pointer-events: auto;
}

/* Кликабельный тост выглядит как обычный; отличие — метка «Больше…» в конце. */
#toast .toast-head {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  padding: var(--sp-md) var(--sp-lg);
  line-height: var(--sz-ui-sm);
}

#toast .toast-spin {
  flex: 0 0 auto;
  width: var(--sp-lg);
  height: var(--sp-lg);
  font-size: var(--sp-lg);
  color: var(--text-muted);
  animation: bento-spin 0.9s linear infinite;
}

#toast .toast-msg {
  flex: 1 1 auto;
  min-width: 0;
  overflow-wrap: anywhere;
}

#toast .toast-more {
  flex: 0 0 auto;
  color: var(--text-muted);
  font-size: var(--fs-sm);
  font-weight: 500;
  white-space: nowrap;
  cursor: pointer;
}

#toast .toast-more:hover {
  text-decoration: underline;
}

#toast .toast-close {
  display: none;
  flex: 0 0 auto;
  width: var(--sz-ui-sm);
  height: var(--sz-ui-sm);
  padding: 0;
  border: 0;
  background: transparent;
  color: var(--text-muted);
  cursor: pointer;
  align-items: center;
  justify-content: center;
  line-height: 1;
}

#toast .toast-close:hover {
  background: transparent;
  color: var(--text);
}

#toast .toast-close:focus,
#toast .toast-close:focus-visible {
  outline: none;
  box-shadow: none;
}

#toast.open .toast-close {
  display: inline-flex;
}

#toast.open .toast-more {
  display: none;
}

#toast .toast-detail {
  display: none;
  padding: var(--sp-sm) var(--sp-lg) var(--sp-md);
  border-top: var(--sp-micro) solid var(--border);
  font-size: var(--fs-xs);
  color: var(--text-muted);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 40vh;
  overflow: auto;
}

#toast.open .toast-detail {
  display: block;
}

/* =====================================================================
   08. Feature-specific elements
   ===================================================================== */

/* ---------- Row states and flags ---------- */

.coll {
  color: var(--warn);
  font-size: var(--fs-sm);
  display: inline-flex;
  align-items: center;
  gap: var(--sp-tiny);
}

.coll-none {
  color: var(--text-faint);
  font-size: var(--fs-sm);
}

.dirty-dot {
  display: inline-block;
  width: var(--sp-base);
  height: var(--sp-base);
  border-radius: 50%;
  background: var(--warn);
  margin-right: var(--sp-xs);
}

.row-flag {
  display: inline-block;
  font-size: var(--fs-tiny);
  font-weight: 600;
  padding: var(--sp-micro) var(--sp-sm);
  border-radius: var(--sp-xs);
  margin-right: var(--sp-sm);
  background: var(--bg-soft);
  color: var(--text-muted);
  border: var(--sp-micro) solid var(--border);
}

.main-table td.col-id {
  position: relative;
  overflow: visible;
}

.main-table td.col-id .row-flag {
  position: absolute;
  top: var(--sp-xs);
  left: calc(100% - var(--sp-sm));
  transform: translateY(-50%);
  z-index: 25;
  margin: 0;
  line-height: 1.15;
  white-space: nowrap;
  pointer-events: none;
  box-shadow: var(--shadow-1);
}

tbody tr.is-indirect {
  color: var(--text-faint);
}

tbody tr.row-removed {
  opacity: .45;
}

.row-flag.new {
  color: var(--ok);
  border-color: color-mix(in srgb, var(--ok) 40%, transparent);
}

.row-flag.dirty {
  color: var(--warn);
  border-color: color-mix(in srgb, var(--warn) 40%, transparent);
}

.row-flag.removed {
  color: var(--danger);
  border-color: color-mix(in srgb, var(--danger) 40%, transparent);
}

.iconbtn .dirty-dot {
  position: absolute;
  top: var(--sp-sm);
  right: var(--sp-sm);
  width: var(--sp-base);
  height: var(--sp-base);
  border-radius: 50%;
  background: var(--warn);
  box-shadow: 0 0 0 var(--sp-tiny) var(--bg);
}

tbody tr.group-row.collapsed {
  border-bottom-width: var(--sp-micro);
}

tr.row-dirty td:first-child::before,
.main-table tr.row-dirty::before {
  background: var(--warn) !important;
}

tr.row-new td:first-child::before,
.main-table tr.row-new::before {
  background: var(--ok) !important;
}

tr.row-st-demand td:first-child::before,
.main-table tr.row-st-demand::before {
  background: var(--st-demand);
}

tr.row-st-planned td:first-child::before,
.main-table tr.row-st-planned::before {
  background: var(--st-planned);
}

tr.row-st-surveyed td:first-child::before,
.main-table tr.row-st-surveyed::before {
  background: var(--st-surveyed);
}

tr.row-st-processed td:first-child::before,
.main-table tr.row-st-processed::before {
  background: var(--st-processed);
}

tr.row-st-ready td:first-child::before,
.main-table tr.row-st-ready::before {
  background: var(--st-ready);
}

tr.coll-row td:first-child::before,
.main-table tr.coll-row::before {
  background: var(--warn);
}

tbody tr.row-removed td:not(:last-child) {
  text-decoration: line-through;
}

/* ---------- Survey status components ---------- */

.status-bar {
  display: inline-flex;
  flex-direction: column;
  gap: var(--sp-tiny);
  align-items: flex-start;
  min-width: var(--sz-stat-w);
}

.status-bar .sb-track {
  display: flex;
  gap: var(--sp-tiny);
  width: 100%;
  min-width: var(--sz-stat-w);
}

.status-bar .sb-label {
  font-size: var(--fs-xs);
  color: var(--text-dim);
  white-space: nowrap;
}

.status-bar .seg {
  flex: 1 1 0;
  height: var(--sp-xs);
  border-radius: var(--sp-tiny);
  background: var(--bg-active);
}

.status-bar .seg-off {
  background: var(--bg-active);
}

.status-bar .seg-demand.seg-on {
  background: var(--st-demand);
}

.status-bar .seg-planned.seg-on {
  background: var(--st-planned);
}

.status-bar .seg-surveyed.seg-on {
  background: var(--st-surveyed);
}

.status-bar .seg-processed.seg-on {
  background: var(--st-processed);
}

.status-bar .seg-ready.seg-on {
  background: var(--st-ready);
}

/* ---------- Pills and badges ---------- */

.surv {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-xs);
  padding: var(--sp-micro) var(--sp-base);
  border-radius: var(--sp-md);
  font-size: var(--fs-xs);
  font-weight: 500;
  background: var(--bg-soft);
  color: var(--text-muted);
  border: var(--sp-micro) solid var(--border);
  white-space: nowrap;
}

.surv-none {
  color: var(--text-faint);
  font-size: var(--fs-xs);
  font-style: italic;
}

.pill {
  padding: var(--sp-micro) var(--sp-sm);
  border-radius: var(--sp-md);
  font-size: var(--fs-xs);
  font-weight: 500;
  background: var(--bg-soft);
  color: var(--text-muted);
  border: var(--sp-micro) solid var(--border);
}

/* Deal view: textual explanation under the status pill */
.deal-status-note {
  margin-top: var(--sp-md);
  color: var(--text-muted);
  font-size: var(--fs-tiny);
}

/* Deal view: principal sits in the main kv block as a regular value.
   Timeline docs reuse the same lookup after .finance-doc-details.
   Lookup overlays the text — no extra padding/border so the input
   stays exactly where the value is, including when the panel expands. */
.kv .v.deal-principal,
.finance-doc-principal {
  position: relative;
}

.finance-doc-principal {
  font-size: var(--fs-xs);
  line-height: 1.45;
  min-width: 0;
}

.kv .deal-principal-lookup.lookup,
.finance-doc-principal .deal-principal-lookup.lookup {
  width: 100%;
  min-width: 0;
}

.kv .deal-principal-lookup .wp-preview,
.kv .deal-principal-lookup input,
.finance-doc-principal .deal-principal-lookup .wp-preview,
.finance-doc-principal .deal-principal-lookup input {
  display: block;
  width: 100%;
  height: auto;
  min-height: 0;
  margin: 0;
  padding: 0;
  border: 0;
  border-radius: 0;
  background: transparent;
  box-shadow: none;
  font: inherit;
  font-size: inherit;
  line-height: inherit;
  color: inherit;
  text-align: left;
}

.kv .deal-principal-lookup .wp-preview,
.finance-doc-principal .deal-principal-lookup .wp-preview {
  cursor: pointer;
  white-space: normal;
  overflow: visible;
  text-overflow: unset;
}

.kv .deal-principal-lookup.picked input,
.finance-doc-principal .deal-principal-lookup.picked input {
  display: none;
}

.kv .deal-principal-lookup:not(.picked) .wp-preview,
.finance-doc-principal .deal-principal-lookup:not(.picked) .wp-preview {
  display: none;
}

.kv .deal-principal-lookup .wp-preview.is-empty,
.kv .deal-principal-empty,
.kv .deal-principal-lookup input::placeholder,
.finance-doc-principal .deal-principal-lookup .wp-preview.is-empty,
.finance-doc-principal .deal-principal-lookup input::placeholder {
  color: var(--text-faint);
}

.kv .deal-principal-lookup.is-inherited .wp-preview,
.finance-doc-principal .deal-principal-lookup.is-inherited .wp-preview,
.finance-doc-principal .deal-principal-name.is-inherited {
  color: var(--text-muted);
}

.kv .deal-principal-lookup input:focus,
.kv .deal-principal-lookup input:focus-visible,
.kv .deal-principal-lookup .wp-preview:focus,
.kv .deal-principal-lookup .wp-preview:focus-visible,
.finance-doc-principal .deal-principal-lookup input:focus,
.finance-doc-principal .deal-principal-lookup input:focus-visible,
.finance-doc-principal .deal-principal-lookup .wp-preview:focus,
.finance-doc-principal .deal-principal-lookup .wp-preview:focus-visible {
  outline: none;
  box-shadow: none;
}

.kv .deal-principal-lookup .results,
.finance-doc-principal .deal-principal-lookup .results {
  left: 0;
  right: auto;
  width: max-content;
  min-width: 12em;
  max-width: min(22em, 100%);
  z-index: 40;
}

.kv .deal-principal-lookup.open .results,
.finance-doc-principal .deal-principal-lookup.open .results {
  display: block;
}

.pill.cat-0,
.pill.cat-1,
.pill.cat-2 {
  width: auto;
  height: auto;
  padding: 0;
  border: none;
  border-radius: 0;
  background: transparent;
  display: inline;
  line-height: inherit;
  vertical-align: baseline;
}

.pill.cat-0 {
  color: var(--steel-azure);
}

.pill.cat-1 {
  color: var(--rich-cerulean);
}

.pill.cat-2 {
  color: var(--steel-azure);
}

.pill.cat-0 .i,
.pill.cat-1 .i,
.pill.cat-2 .i {
  margin: -.5em 0;
}

.pill.cat-virtual {
  opacity: .82;
}

.sub-table.survey-sub-table .last-col {
  width: 50%;
}

/* --- Keyword pill --- */

.kw-pill {
  display: inline-block;
  padding: var(--sp-tiny) var(--sp-base);
  border-radius: var(--sp-md);
  font-size: var(--fs-sm);
  background: var(--bg-soft);
  color: var(--text-muted);
  border: var(--sp-micro) solid var(--border);
  margin: var(--sp-tiny) var(--sp-tiny) var(--sp-tiny) 0;
}

/* ---------- Water objects and maps ---------- */

.wf-chain {
  margin: 0;
  border-left: var(--sp-micro) solid var(--border);
}

.wf-step {
  display: flex;
  align-items: center;
  padding: var(--sp-sm) var(--sp-base);
  cursor: pointer;
  border-radius: 0 var(--sp-sm) var(--sp-sm) 0;
  transition: background .12s;
}

/* Expand tributaries: a full-width row, not a secondary button card. */
.wf-toggle {
  display: flex;
  width: 100% !important;
  justify-content: center;
  border: 0 !important;
  background: transparent !important;
  padding: var(--sp-xs) var(--sp-base);
  border-radius: 0 var(--sp-sm) var(--sp-sm) 0;
  box-shadow: none;
}

.wf-toggle:hover:not(:disabled) {
  background: var(--bg-hover) !important;
}

.wf-info {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  flex-wrap: wrap;
  min-width: 0;
}

.wf-bank {
  font-size: var(--fs-xl);
  color: var(--text-muted);
  flex: 0 0 auto;
  line-height: 1;
}

.wf-bank-up {
  color: var(--text-dim);
}

.wf-name {
  font-size: var(--fs-main);
  font-weight: 600;
  color: var(--text);
  white-space: nowrap;
}

.wf-km {
  font-size: var(--fs-xs);
  color: var(--text-dim);
  white-space: nowrap;
}

.auto-desc,
.kv .v.auto-desc {
  color: var(--text-faint);
}

.geo-dot {
  display: inline-block;
  width: var(--sp-base);
  height: var(--sp-base);
  border-radius: 50%;
  background: var(--accent);
  margin-right: var(--sp-sm);
  vertical-align: middle;
}

.water-link,
.item-link {
  color: var(--text);
  text-decoration: none;
  border-bottom: var(--sp-micro) dashed var(--border-strong);
}

.water-map-wrap {
  position: relative;
  border-radius: var(--sp-base);
  overflow: hidden;
  border: var(--sp-micro) solid var(--border);
}

/* Компактная мини-карта в строках «к/в» (кв-строки), 300px по ширине. */
.water-map-wrap.mini {
  width: 100%;
  aspect-ratio: 1;
  max-width: 300px;
}

.wf-step:hover {
  background: var(--bg-hover);
}

.water-link:hover,
.item-link:hover {
  color: var(--accent);
  border-bottom-color: var(--accent);
}

.water-map-wrap .wm-map {
  width: 100%;
  aspect-ratio: 1;
  min-height: var(--sz-map-min-h);
  max-height: var(--sz-map-max-h);
}

/* ---------- Survey/category editors ---------- */

.survey-editor-list,
.ed-r-waters-list {
  display: flex;
  flex-direction: column;
  gap: var(--sp-lg);
}

.research-water-row {
  display: flex;
  flex-direction: column;
  gap: var(--sp-base);
}

.sub-row {
  margin-bottom: var(--sp-sm);
}

.sub-row-main {
  display: flex;
  align-items: flex-start;
  gap: var(--sp-base);
}

.sub-row-water {
  flex: 1 1 auto;
  min-width: 0;
}

.sub-row-del {
  flex: 0 0 auto;
}

.sub-row-surveys {
  margin-left: var(--sp-md);
  padding-left: var(--sp-md);
  border-left: 2px solid var(--bg-hover);
  display: flex;
  flex-direction: column;
  gap: var(--sp-base);
}

.cat-bar {
  display: flex;
  flex: 0 0 auto;
  height: var(--ht-input);
  border-radius: var(--sp-sm);
  overflow: hidden;
  border: var(--sp-micro) solid var(--border);
}

.cat-stage {
  border: 0;
  background: var(--bg-soft);
  color: var(--text-muted);
  padding: var(--sp-xs) var(--sp-md);
  font-size: var(--fs-sm);
  font-weight: 600;
  cursor: pointer;
  transition: background .15s, color .15s;
  line-height: 1.4;
}

.cat-bar button,
.perm-bar button {
  border-radius: 0 !important;
}

.sub-row-water input {
  width: 100%;
  box-sizing: border-box;
}

.cat-stage .i {
  width: 1em;
  height: 1em;
  font-size: 1em;
  line-height: 1;
  vertical-align: -0.125em;
}

.cat-stage:hover {
  background: var(--bg-hover);
}

.cat-stage+.cat-stage {
  border-left: var(--sp-micro) solid var(--border);
}

.cat-stage.active.cat-0 {
  background: var(--steel-azure);
  color: #fff;
}

.cat-stage.active.cat-1 {
  background: var(--rich-cerulean);
  color: #fff;
}

.cat-stage.active.cat-2 {
  background: var(--alice-blue);
  color: var(--steel-azure);
}

/* ---------- Admin permissions ---------- */

.perm-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-md);
  margin-bottom: var(--sp-sm);
}

.perm-label {
  font-size: var(--fs-main);
  color: var(--text);
  flex: 1 1 auto;
}

.perm-bar {
  display: flex;
  flex: 0 0 auto;
  border-radius: var(--sp-sm);
  overflow: hidden;
  border: var(--sp-micro) solid var(--border);
}

.perm-stage {
  border: 0;
  background: var(--bg-soft);
  color: var(--text-muted);
  padding: var(--sp-sm) var(--sp-md);
  min-width: var(--sz-ui-action);
  font-size: var(--fs-main);
  cursor: pointer;
  transition: background .15s, color .15s;
  line-height: 1.4;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

.perm-stage:hover {
  background: var(--bg-hover);
}

.perm-stage+.perm-stage {
  border-left: var(--sp-micro) solid var(--border);
}

.perm-stage.active.perm-none {
  background: var(--bg-hover);
  color: var(--text-muted);
}

.perm-stage.active.perm-read {
  background: var(--text-muted);
  color: var(--bg);
}

.perm-stage.active.perm-write {
  background: var(--text);
  color: var(--bg);
}

/* ---------- Document and PDF views ---------- */

.sp-pdf-wrap {
  width: 100%;
  height: 100%;
  min-height: var(--sz-pdf-min-h);
  margin: 0;
}

.sp-pdf {
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
  background: var(--bg);
}

.sp-doc-header {
  padding: var(--sp-md) var(--sp-lg) var(--sp-xs);
  border-bottom: var(--sp-micro) solid var(--border);
  margin: 0;
  background: var(--bg-soft);
}

.sp-doc {}

.ed-path-preview .sp-doc {
  font-size: var(--fs-sm);
  padding: var(--sp-lg);
  background: var(--bg);
}

.sp-doc table {
  border-radius: 0;
}

.ed-path-preview .sp-doc table {
  font-size: var(--fs-xs);
  padding: var(--sp-md);
}

.ed-path-preview {
  margin: var(--sp-lg) 0;
  border: var(--sp-micro) solid var(--border);
  border-radius: var(--radius);
  background: var(--bg-soft);
  height: auto;
  min-height: 100px;
  max-height: 80vh;
  overflow: auto;
  resize: vertical;
}

.sp-doc-header p {
  margin: var(--sp-xs) 0;
  font-size: var(--fs-main);
}

.ed-path-preview:empty {
  display: none;
}

.side-panel .pdf-close {
  position: absolute;
  top: var(--sp-md);
  right: var(--sp-md);
  z-index: 5;
  width: var(--sz-ui-action);
  height: var(--sz-ui-action);
  border-radius: 50%;
  background: rgba(0, 0, 0, .55);
  color: #fff;
  border: 0;
  cursor: pointer;
  font-size: var(--fs-xl);
  line-height: 1;
  display: none;
}

.side-panel.pdf-mode .body {
  background: #525659;
  padding: 0;
}

.side-panel.pdf-mode .sp-pdf-wrap {
  height: 100%;
}

.side-panel.pdf-mode .body.sp-pdf-mobile-body {
  overflow-x: hidden;
  overflow-y: auto;
  overscroll-behavior: contain;
  -webkit-overflow-scrolling: touch;
  touch-action: pan-y pinch-zoom;
}

.side-panel.pdf-mode .sp-pdf-pages {
  width: 100%;
  height: auto;
  min-height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-lg);
  padding: var(--sp-md);
  background: #525659;
}

.sp-pdf-mobile-status {
  min-height: 50vh;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--sp-xs);
  color: #fff;
  text-align: center;
}

.sp-pdf-mobile-status a,
.sp-pdf-mobile-info a {
  color: #fff;
  font-weight: 600;
  text-decoration: underline;
  text-underline-offset: 2px;
}

.sp-pdf-mobile-info {
  position: sticky;
  top: 0;
  z-index: 4;
  width: min(100%, var(--sz-page-w));
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-md);
  padding: var(--sp-sm) var(--sp-md);
  border-radius: var(--radius);
  background: rgba(30, 32, 34, .88);
  color: #fff;
  box-shadow: var(--shadow-1);
}

.sp-pdf-page {
  position: relative;
  flex: 0 0 auto;
  width: min(100%, var(--sz-page-w));
  aspect-ratio: 210 / 297;
  overflow: hidden;
  background: #f4f4f4;
  box-shadow: var(--shadow-2);
  contain: layout paint;
}

.sp-pdf-page-canvas {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  display: block;
  background: #fff;
}

.sp-pdf-page-number {
  position: absolute;
  top: var(--sp-xs);
  left: var(--sp-xs);
  z-index: 2;
  padding: var(--sp-tiny) var(--sp-xs);
  border-radius: var(--radius-sm);
  background: rgba(20, 22, 24, .72);
  color: #fff;
  font-size: var(--fs-xs);
  line-height: 1.4;
  pointer-events: none;
}

.sp-pdf-page.is-rendering::after,
.sp-pdf-page.has-error::after {
  content: "Загрузка…";
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  color: #555;
  font-size: var(--fs-main);
}

.sp-pdf-page.has-error::after {
  content: "Не удалось отобразить страницу";
  padding: var(--sp-xl);
  text-align: center;
  color: var(--danger);
}

.side-panel .pdf-close:hover {
  background: rgba(0, 0, 0, .75);
}

/* =====================================================================
   09. Media queries
   ===================================================================== */

/* =====================================================================
   09. Media queries
   ===================================================================== */

@media (max-width: 1000px) {

  :root {
    --sz-header: 48px;
    --sz-avatar: calc(var(--sp-huge) * 2.3);
    --sz-avatar-fallback: 48px;

    --fs-tiny: 8px;
    --fs-xs: 10px;
    --fs-sm: 10px;
    --fs-base: 13px;
    --fs-md: 14px;
    --fs-lg: 16px;
    --fs-2xl: 22px;
    --fs-3xl: 22px;
  }

  html,
  body {
    overflow: visible;
    height: auto;
    display: block;
  }

  /* An expanded panel owns the mobile viewport. Keep touch-scroll inside its
     body instead of chaining it to the module underneath the curtain. */
  html.panel-scroll-locked,
  html.panel-scroll-locked body {
    overflow: hidden;
    overscroll-behavior: none;
  }

  main {
    height: auto;
    overflow: visible;
  }

  #app {
    height: auto;
  }

  .dash-shell {
    display: flex;
    flex-direction: column;
    padding: var(--sp-huge);
    height: auto;
    min-height: 100%;
    overflow: visible;
    position: relative;
    inset: auto;
  }

  .dash-side {
    display: contents;
  }

  .dash-user {
    order: 1;
    display: flex;
    align-items: center;
    gap: var(--sp-xl);
    width: 100%;
  }

  .dash-info {
    display: flex;
    flex-direction: column;
    min-width: 0;
  }

  .dash-stats {
    order: 2;
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    margin: 0;
    width: 100%;
  }

  .dash-main {
    overflow: visible;
    height: auto;
  }

  .menu-bento {
    order: 3;
  }

  .dash-avatar {
    margin-left: 0;
    margin-bottom: 0;
  }

  .dash-email {
    margin-bottom: 0;
  }

  .dash-actions {
    order: 4;
    display: flex;
    flex-direction: row;
    justify-content: space-between;
    gap: var(--sp-base);
    margin-top: 0;
    border-top: var(--sp-micro) solid var(--border);
    padding-top: var(--sp-xl);
  }

  .dash-logout {
    margin-top: 0;
  }

  /* Tables (Card Mode) */
  .main-table thead {
    display: none;
  }

  .main-table,
  .main-table tbody,
  .main-table tr,
  .main-table td {
    /* display: block; */
    /* width: 100%; */
  }

  .main-table {
    border: 0 !important;
    background: transparent !important;
  }

  .main-table tr {
    position: relative;
    background: var(--surface);
    border: var(--sp-micro) solid var(--border);
    border-radius: var(--radius);
    margin-bottom: var(--sp-md);
    padding: var(--sp-md);
    box-shadow: var(--shadow-1);
    display: flex;
    flex-wrap: wrap;
    gap: var(--sp-base);
  }

  .main-table tr:has(.actions) {
    padding-right: calc(var(--sz-ui-action) + 3 * var(--sp-md));
    padding-left: var(--sp-xl);
  }

  .main-table tr::before {
    content: "";
    position: absolute;
    left: 0;
    top: 0;
    bottom: 0;
    width: var(--sp-xs);
    z-index: 10;
    background: transparent;
    pointer-events: none;
    border-top-left-radius: var(--radius);
    border-bottom-left-radius: var(--radius);
  }

  /* На планшете псевдоэлемент первой ячейки — это ПОДПИСЬ колонки
     (data-label), а не цветная полоса строки (полосу рисует tr::before).
     Десктопные правила цвета строки, напр. tr.row-dirty td:first-child::before
     { background: var(--warn) !important } (специфичность 0,2,3), иначе
     перебивали бы background этой подписи; поднимаем специфичность через tr
     и ставим !important, чтобы фон подписи оставался прозрачным. */
  .main-table tr td:first-child::before {
    content: attr(data-label);
    display: block;
    position: static;
    inset: auto;
    width: auto;
    height: auto;
    background: none !important;
    pointer-events: none;
    color: var(--text-dim);
    font-size: var(--fs-tiny);
    font-weight: 600;
    text-transform: uppercase;
    margin-bottom: var(--sp-xs);
  }

  .main-table td {
    padding: var(--sp-sm) 0 0;
    border: 0 !important;
    text-align: unset !important;
    min-width: 30%;
  }

  .main-table td::before {
    content: attr(data-label);
    display: block;
    color: var(--text-dim);
    font-size: var(--fs-tiny);
    font-weight: 600;
    text-transform: uppercase;
    margin-bottom: var(--sp-xs);
  }

  .main-table td.actions {
    position: absolute;
    top: 0;
    right: 0;
    bottom: 0;
    min-width: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: flex-end;
    background: var(--bg-soft);
    border-top: 0 !important;
    border-left: var(--sp-micro) solid var(--border) !important;
    padding: var(--sp-md);
    margin: 0;
  }

  td.actions button {
    margin: 0;
  }

  .main-table td.actions button {
    height: var(--sz-ui-action);
  }

  .main-table td.actions::before {
    content: none;
  }

  td.long {
    width: 100%;
  }

  td.long .long-cell-limit {
    max-width: none;
  }

  .workbook-layout {
    grid-template-columns: 1fr;
  }

  .side-panel.is-expanded {
    top: 0;
    bottom: 0;
    right: 0;
    width: 100%;
    max-width: 100%;
    height: 100%;
    height: 100dvh;
    max-height: 100%;
    max-height: 100dvh;
    border-radius: 0;
    border: 0;
  }

  /* Module headers: длинные заголовки переносятся на несколько строк,
     чтобы не вылезать за экран на планшетах и телефонах. */
  .editor-bar {
    grid-template-columns: auto minmax(0, 1fr) auto;
    height: auto;
    min-height: var(--sz-header);
  }

  .editor-title {
    white-space: normal;
    flex-wrap: wrap;
    justify-content: center;
    text-align: center;
    min-width: 0;
    overflow-wrap: anywhere;
  }
}

@media (max-width: 750px) {

  :root {
    /* --- Layout Metrics --- */
    --sz-logo-splash: 120px;

    /* --- Spacing Scale --- */
    --sp-huge: 24px;

    /* --- Typography Scale --- */
    --fs-base: 12px;
    --fs-md: 12px;
    --fs-lg: 16px;
    --fs-xl: 20px;
    --fs-2xl: 20px;
    --fs-3xl: 20px;
  }

  /* Header & Navigation */
  header .stats {
    display: none !important;
  }

  .mh-user .mh-user-name {
    display: none;
  }

  /* Login Screen */
  .login-screen {
    grid-template-columns: 1fr;
    grid-template-rows: .5fr 1fr;
  }

  .login-brand {
    border-right: 0;
    border-bottom: var(--sp-micro) solid var(--border);
  }

  .splash-brand {
    width: 100%;
  }

  .login-logo,
  .splash-logo {
    max-width: 75%;
    max-height: var(--sz-logo-splash);
  }

  .login-form {
    align-items: flex-start;
  }

  .login-form-inner {
    margin: 0 auto;
  }

  /* Dashboard & Menu */
  .dash-stats {
    flex-direction: column;
  }

  .menu-bento {
    grid-template-columns: 1fr;
  }

  .bento-card.bento-hero {
    min-height: 0;
    display: grid;
    grid-template-columns: 1fr;
    grid-template-rows: auto auto auto;
    grid-template-areas: "icon" "title" "sub";
    align-items: start;
    justify-content: stretch;
    row-gap: var(--sp-sm);
    padding: var(--sp-xl) var(--sp-xl) var(--sp-lg);
  }

  .bento-card.bento-hero .bento-title {
    font-size: var(--fs-md);
  }

  .bento-card.bento-hero .bento-sub {
    text-align: left;
    font-size: var(--fs-xs);
    line-height: 1.4;
    align-self: start;
    justify-self: start;
  }

  /* Toolbar */
  .toolbar {
    flex-direction: column;
    align-items: flex-start;
  }

  .toolbar .group-by,
  .toolbar .right {
    margin-left: 0;
    width: 100%;
  }

  .kv-pair {
    flex-direction: column;
    gap: var(--sp-xs);
  }

  .kv-pair>.k {
    flex: 0 0 auto;
  }

  .kv-pair>.v {
    width: 100%;
  }

  .kv.kv--inverted .kv-pair>.v {
    flex: 0 0 auto;
    width: 100%;
    text-align: left;
  }

  /* Forms & Panels */

  .editor-title .i {
    display: none;
  }
}

/* ---------- Report (print) — body.report, A4, no adaptive ---------- */
/* For printing purposes: body class 'report'. Inside it no max-width queries should be applied.
   It should always count as A4 (-margins) sheet. No adaptive layout, wider screen = wider margins,
   but content solid like A4 page. */
body.report {
  display: block;
  height: auto;
  overflow: visible;
  background: #fff;
  color: #000;
  /* A4 width 210mm, minus margins via padding, centered with auto margins */
  width: 210mm;
  max-width: calc(100% - 80px);
  margin: 40px auto;
  padding: 30mm;
  box-sizing: border-box;
  box-shadow: 0 2px 24px rgba(0,0,0,.12);
}

body.report .form-section {
  margin-top: var(--sp-xl);
}

body.report .kv,
body.report .kv.kv--inverted {
  gap: var(--sp-sm);
}

body.report .kv-pair {
  flex-direction: row !important;
  gap: var(--sp-lg) !important;
}

body.report .kv-pair>.k {
  flex: 1 1 auto !important;
  color: #555 !important;
}

body.report .kv-pair>.v {
  flex: 0 0 180px !important;
  width: 180px !important;
  text-align: right !important;
  color: #000 !important;
}

body.report table.main-table,
body.report table.sub-table {
  display: table !important;
  width: 100% !important;
  border: 1px solid #ccc !important;
  background: #fff !important;
}

body.report table.main-table thead,
body.report table.sub-table thead {
  display: table-header-group !important;
}

body.report table.main-table tr,
body.report table.sub-table tr {
  display: table-row !important;
  flex: none !important;
  width: auto !important;
  max-width: none !important;
  min-width: 0 !important;
  height: auto !important;
  padding: 0 !important;
  background: transparent !important;
  box-shadow: none !important;
  transform: none !important;
}

body.report table.main-table td,
body.report table.main-table th,
body.report table.sub-table td,
body.report table.sub-table th {
  display: table-cell !important;
  padding: 6px 10px !important;
  border: 1px solid #ccc !important;
  text-align: left !important;
  min-width: 0 !important;
}

body.report table.main-table td.num,
body.report table.sub-table td.num {
  text-align: right !important;
}

body.report .fab-stack,
body.report .view-tabs,
body.report header {
  display: none !important;
}

@media print {
  body.report {
    width: 210mm;
    max-width: none;
    margin: 0;
    padding: 30mm;
    box-shadow: none;
  }
  @page {
    size: A4;
    margin: 10mm;
  }
}

/* ---------- Dashboard settings control ---------- */

#dash-settings {
  /* Styled via .dash-actions button — keep selector for specificity */
}

#dash-settings .i {
  opacity: 0.9;
}

/* ---------- Settings — only radio groups are new, layout reuses existing form styles ---------- */
/* Radio/checkbox groups: vertical list. Each option on its own line left-aligned,
   radio/checkbox at far left (picker-radio / picker-checkbox flex:0 0 auto),
   title + comment (hint) stacked vertically (picker-content column, hint below picker-title),
   no gap between options. All options follow setting name (label>span)
   and instruction (.hint) — both reuse existing .form-grid / .hint styles. */
.settings-theme-picker,
.settings-panelmode-picker,
.settings-mapprovider-picker,
.settings-hillshade-picker {
  display: flex;
  flex-direction: column;
  gap: 0;
}

/* Settings themselves are more separated than the default form-grid gap. */
#panel-settings .form-grid {
  gap: var(--sp-xl);
}

/* Settings labels — normal color, not dimmed (override .form-grid label muted). */
#panel-settings .form-grid label,
#panel-settings .form-grid label > span,
#panel-settings .form-section h3.sec {
  color: var(--text);
}

/* All option text left-aligned. */
#panel-settings .settings-theme-picker .picker-option,
#panel-settings .settings-panelmode-picker .picker-option,
#panel-settings .settings-mapprovider-picker .picker-option,
#panel-settings .settings-hillshade-picker .picker-option {
  text-align: left;
  justify-content: flex-start;
}
#panel-settings .settings-theme-picker .picker-content,
#panel-settings .settings-panelmode-picker .picker-content,
#panel-settings .settings-mapprovider-picker .picker-content,
#panel-settings .settings-hillshade-picker .picker-content,
#panel-settings .settings-theme-picker .picker-title,
#panel-settings .settings-panelmode-picker .picker-title,
#panel-settings .settings-mapprovider-picker .picker-title,
#panel-settings .settings-hillshade-picker .picker-title,
#panel-settings .settings-theme-picker .hint,
#panel-settings .settings-panelmode-picker .hint,
#panel-settings .settings-mapprovider-picker .hint,
#panel-settings .settings-hillshade-picker .hint {
  text-align: left;
}

/* Options: no icon, no outline/fill in usual state — only hover font color and selected fill.
   Mirrors deal timeline (finance-doc-bar): hover changes title color to accent
   (and radio/checkbox border), selected fills background (and radio dot / checkbox tick). */
#panel-settings .settings-theme-picker .picker-option,
#panel-settings .settings-panelmode-picker .picker-option,
#panel-settings .settings-mapprovider-picker .picker-option,
#panel-settings .settings-hillshade-picker .picker-option {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}
#panel-settings .settings-theme-picker .picker-option:hover,
#panel-settings .settings-panelmode-picker .picker-option:hover,
#panel-settings .settings-mapprovider-picker .picker-option:hover,
#panel-settings .settings-hillshade-picker .picker-option:hover {
  background: transparent;
  border-color: transparent;
  box-shadow: none;
}
#panel-settings .settings-theme-picker .picker-option:hover .picker-title,
#panel-settings .settings-panelmode-picker .picker-option:hover .picker-title,
#panel-settings .settings-mapprovider-picker .picker-option:hover .picker-title,
#panel-settings .settings-hillshade-picker .picker-option:hover .picker-title {
  color: var(--accent);
}
#panel-settings .settings-theme-picker .picker-option:hover .picker-radio,
#panel-settings .settings-panelmode-picker .picker-option:hover .picker-radio,
#panel-settings .settings-mapprovider-picker .picker-option:hover .picker-radio,
#panel-settings .settings-hillshade-picker .picker-option:hover .picker-checkbox {
  border-color: var(--accent);
}
#panel-settings .settings-theme-picker .picker-option.active,
#panel-settings .settings-panelmode-picker .picker-option.active,
#panel-settings .settings-mapprovider-picker .picker-option.active,
#panel-settings .settings-hillshade-picker .picker-option.active {
  background: var(--accent-soft);
  border-color: transparent;
  box-shadow: none;
}

/* On narrow screens (phone) no mode change — always expanded */
@media (max-width: 750px) {
  #panel-settings .settings-panelmode-picker {
    display: none !important;
  }
  .side-panel .sp-expand {
    display: none !important;
  }
}

/* ---------- Fishcap: calculation-mode segmented toggle ---------- */
.calc-mode-toggle {
  margin: 0 0 var(--sp-huge);
  display: flex;
  flex-direction: column;
  align-items: center;
}

.calc-mode-toggle .form-instruction {
  max-width: 720px;
  margin: 0 0 var(--sp-lg);
}

.calc-mode-toggle .seg {
  display: inline-flex;
  gap: var(--sp-xs);
  padding: var(--sp-xs);
  background: var(--bg-soft);
  border-radius: var(--radius);
}

.calc-mode-toggle .seg-btn {
  border: 0;
  background: transparent;
  padding: var(--sp-sm) var(--sp-xl);
  border-radius: calc(var(--radius) - var(--sp-xs));
  font-size: var(--fs-main);
  color: var(--text-muted);
  cursor: pointer;
  transition: background .12s, color .12s, box-shadow .12s;
}

.calc-mode-toggle .seg-btn:hover {
  color: var(--text);
}

.calc-mode-toggle .seg-btn.active {
  background: var(--accent);
  color: var(--accent-fg);
  box-shadow: var(--shadow-1);
}

/* Модельный пикер: поле выбора + кнопка «+» (создать модель),
   как у number/geo-пикеров. */
#fc-popmodel-picker .lookup {
  width: 100%;
}
#fc-popmodel-picker .lookup .toggle-map {
  z-index: 2;
}

/* Результирующий график рыбоводного расчёта (стиль графиков КПЭ). */
.fc-result-plot {
  position: relative;
}

.fc-result-plot-svg {
  display: block;
  width: 100%;
  height: auto;
  cursor: crosshair;
  touch-action: pan-y;
}

.fc-plot-tick {
  font-size: var(--fs-tiny);
  fill: var(--text-muted);
}

.fc-plot-axis-title {
  font-size: var(--fs-xs);
  font-weight: 600;
}

.fc-plot-xnote {
  clear: both;
  text-align: center;
  font-size: var(--fs-xs);
  color: var(--text-muted);
  margin-top: var(--sp-xs);
}

.fc-plot-legend {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--sp-md);
  margin-top: var(--sp-xl);
  font-size: var(--fs-xs);
  color: var(--text-muted);
}

.fc-legend-item {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-sm);
  white-space: nowrap;
}

.fc-legend-line {
  flex: none;
  width: 28px;
  height: 8px;
  overflow: visible;
}

/* Тултип курсора результирующего графика. */

.fc-plot-tooltip {
  position: absolute;
  z-index: 5;
  pointer-events: none;
  min-width: 210px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--radius);
  box-shadow: var(--shadow-2, 0 4px 18px rgba(0,0,0,.18));
  padding: var(--sp-sm) var(--sp-md);
  font-size: var(--fs-xs);
}

.fc-plot-tip-title {
  font-weight: 700;
  margin-bottom: var(--sp-xs);
  color: var(--text);
}

.fc-plot-tip-row {
  display: flex;
  align-items: center;
  gap: var(--sp-sm);
  padding: 1px 0;
  color: var(--text-muted);
  white-space: nowrap;
}

.fc-plot-tip-row b {
  margin-left: auto;
  padding-left: var(--sp-md);
  color: var(--text);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}

.fc-plot-tip-dot {
  width: 10px;
  height: 3px;
  border-radius: 2px;
  background: var(--c, #ccc);
  flex: none;
}

/* Гистограммы возрастной структуры под курсором графика динамики:
   бины постоянной ширины, N — слева (терракота), B — справа (акцент). */
.fc-plot-hist {
  pointer-events: none;
}

/* Подпись возраста у конца выноски бина (0+, 1+, …). */
.fc-plot-hist-age {
  font-size: var(--fs-micro);
  font-weight: 600;
  fill: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.fc-plot-tick--num {
  fill: var(--terra, #dd6e42);
}

.fc-plot-tick--mass {
  fill: var(--accent);
}

/* Переключатель результатов в секции «Результаты»: верхний уровень — крупный
   переключатель основных состояний «Структура»/«Динамика» (как у выбора
   метода расчёта), под ним — мелкий под-переключатель вида внутри состояния. */
.fc-result-tabs {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--sp-sm);
  margin-top: var(--sp-xl);
}

.fc-result-main {
  display: inline-flex;
  gap: var(--sp-xs);
  padding: var(--sp-xs);
  background: var(--bg-soft);
  border-radius: var(--radius);
}

.fc-result-main .seg-btn {
  border: 0;
  background: transparent;
  padding: var(--sp-sm) var(--sp-xl);
  border-radius: calc(var(--radius) - var(--sp-xs));
  font-size: var(--fs-main);
  color: var(--text-muted);
  cursor: pointer;
  transition: background .12s, color .12s, box-shadow .12s;
}

.fc-result-main .seg-btn:hover {
  color: var(--text);
}

.fc-result-main .seg-btn.active {
  background: var(--accent);
  color: var(--accent-fg);
  box-shadow: var(--shadow-1);
}

/* Мелкий под-переключатель (порядок строк таблицы / вид динамики). */
.fc-result-switch {
  display: inline-flex;
  flex-wrap: wrap;
  gap: var(--sp-xs);
  padding: var(--sp-xs);
  background: var(--bg-soft);
  border-radius: var(--radius);
}

.fc-result-switch .seg-btn {
  border: 0;
  background: transparent;
  padding: var(--sp-xs) var(--sp-lg);
  border-radius: calc(var(--radius) - var(--sp-xs));
  font-size: var(--fs-sm);
  color: var(--text-muted);
  cursor: pointer;
  transition: background .12s, color .12s, box-shadow .12s;
}

.fc-result-switch .seg-btn:hover {
  color: var(--text);
}

.fc-result-switch .seg-btn.active {
  background: var(--accent);
  color: var(--accent-fg);
  box-shadow: var(--shadow-1);
}

/* Таблица результатов (те же числа, что на графике): конечная возрастная
   структура стада. Колонки равной ширины (table-layout: fixed, см. выше),
   подписи переносятся; числа тоже могут перенестись по разрядам, чтобы не
   вылезать за колонку на узкой панели. */
.fc-result-table-wrap {
  container-type: inline-size;
}

.fc-result-table {
  font-variant-numeric: tabular-nums;
}

/* Длинные подписи колонок — по умолчанию; на узкой панели (боковая панель
   не развёрнута) показываются короткие обозначения, а полная подпись
   открывается во всплывающей подсказке по наведению (атрибут title). */
.fc-result-table th .fc-th-short {
  display: none;
}

@container (max-width: 520px) {
  .fc-result-table th .fc-th-full {
    display: none;
  }
  .fc-result-table th .fc-th-short {
    display: inline;
    cursor: help;
    font-weight: 600;
  }
}

.fc-result-table td.num {
  text-align: right;
  white-space: normal;
  overflow-wrap: break-word;
  word-break: break-word;
}

.fc-result-table tr.fc-total-row td {
  border-top: 2px solid var(--border-strong);
  background: var(--bg-soft);
}

/* Единый блок для пользователей, отключивших анимацию: отключаем переходы
   у всех компонентов, где они заданы (вместо трёх отдельных @media-блоков). */
@media (prefers-reduced-motion: reduce) {
  .deals-group-panel {
    transition: none;
  }

  .map-legend-panel {
    transition: none;
  }

  .panel-curtain {
    transition: none;
  }
}
