/* ============================================================
   zagran — единая тема Spectrum (тёмный графит, изумрудный акцент,
   светофорная статусная палитра — DESIGN-SPEC §1, §A1).
   Подключается во все шаблоны: <link rel="stylesheet" href="/static/theme.css">
   Меняешь палитру ЗДЕСЬ — применяется на всех страницах.
   Мост легаси-имён (--surface, --accent, --green и т.д. ниже) — ПОСТОЯННЫЙ
   публичный API темы, а не временная затычка: старые классы держатся на нём.
   ============================================================ */

/* Самохост — без обращений к внешнему Google Fonts CDN (DESIGN-SPEC §2: панель админская,
   из РФ, внешний @import блокирует рендер CSS и зависит от доступности стороннего хоста).
   Файлы лежат в app/static/fonts/, лицензии — там же (Inter: SIL OFL 1.1, JetBrains Mono: SIL OFL 1.1). */
@font-face {
  font-family: 'Inter';
  src: url('/static/fonts/InterVariable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

@font-face {
  font-family: 'JetBrains Mono';
  src: url('/static/fonts/JetBrainsMono-Variable.woff2') format('woff2');
  font-weight: 100 800;
  font-style: normal;
  font-display: swap;
}

:root {
  /* поверхности */
  --bg: #0a0b0d;  --sf-sunken: #0d0e11;  --card: #111317;  --card-2: #16181d;
  --overlay: rgba(6,7,9,.72);  --hair: #1e2128;  --hair-strong: #2a2e37;

  /* текст — 4 уровня */
  --ink: #ffffff;  --ink-value: #e5e7eb;  --ink-label: #9ca3af;  --ink-muted: #6b7280;

  /* семантика */
  --emerald: #10b981;  --emerald-bright: #22c55e;  --emerald-up: #34d399;  --emerald-dim: #059669;
  --amber: #f59e0b;    --amber-bright: #fbbf24;
  --info: #3b82f6;     --info-bright: #60a5fa;
  --violet: #8b5cf6;   --violet-text: #a78bfa;
  --loss: #ef4444;     --loss-bright: #f87171;

  --emerald-soft: rgba(16,185,129,.12);  --amber-soft: rgba(245,158,11,.12);
  --info-soft:    rgba(59,130,246,.12);  --violet-soft: rgba(139,92,246,.12);
  --loss-soft:    rgba(239,68,68,.12);
  /* усиленный тинт под hover мягко-залитых элементов (DESIGN-SPEC §4.5: danger 0.15 → 0.25)
     и нейтральный тинт для «паузы» — серый не имеет семантического токена. */
  --loss-soft-2:  rgba(239,68,68,.22);   --grey-soft: rgba(156,163,175,.12);

  /* ── МОСТ: старые имена → новые значения. ПОСТОЯННЫЙ, это публичный API темы ── */
  /* ⚠️ ИМЯ-ЛОВУШКА: в DESIGN-SPEC `--surface` — это #0d0e11 («сайдбар, утопленные
     области»), здесь оно зовётся --sf-sunken. Мостовой --surface = --card (#111317).
     Пишешь по спеке — бери var(--sf-sunken), иначе получишь не тот цвет. */
  --surface: var(--card);        --surface2: var(--card-2);
  --border:  var(--hair-strong); --border-soft: var(--hair);
  --text: var(--ink-value);      --text-dim: var(--ink-label);
  --muted: var(--ink-label);     /* НЕ --ink-muted: вторичный текст поплывёт по контрасту */
  --accent: var(--emerald);      --accent-dim: var(--emerald-dim);  --accent-bg: var(--emerald-soft);
  --green: var(--emerald-up);    --red: var(--loss-bright);
  --yellow: var(--amber-bright); --purple: var(--violet-text);

  /* три токена используются, но НИГДЕ не были определены (спасали фолбэки):
     accounts.html:10 var(--ok), processing_presets.html:569 var(--line),
     tracker_postback.html:27 var(--font-mono) */
  --ok: var(--emerald-bright);  --line: var(--hair);  --font-mono: var(--mono);

  /* геометрия. ⚠️ --r-inp меняется 10px → 8px — ЗАПЛАНИРОВАННОЕ изменение геометрии */
  --r-pill: 999px;  --r-card: 16px;  --r-inp: 8px;  --r-sm: 8px;  --r-chip: 12px;

  /* ── ШКАЛА ПЛОТНОСТИ (DESIGN-SPEC §3.2, A4) ───────────────────────────────
     ЗДЕСЬ — просторная шкала (дашборды, настройки, карточки). Компактная живёт
     в `.dense` (см. блок примитивов ниже) и переопределяет ЭТИ ЖЕ имена, поэтому
     примитивы написаны один раз и работают в обеих плотностях. */
  --pad-card: 20px;    /* внутренний отступ карточки (.pad)              dense: 12px */
  --rhythm:   24px;    /* вертикальный ритм (.stack, .hr)                dense: 8px  */
  --row-h:    auto;    /* высота строки таблицы                          dense: 36px */
  --cell-y:   12px;    /* ячейка таблицы, вертикаль                      dense: 8px  */
  --cell-x:   16px;    /* ячейка таблицы, горизонталь                    dense: 12px */
  --fs-metric: 24px;   /* крупное значение (.metric)                     dense: 14px */
  --ichip-size: 36px;  /* иконо-чип (.ichip)                             dense: 28px */
  --btn-h:    40px;    /* высота кнопки                                  dense: 32px */
  --btn-px:   16px;    /* горизонтальный паддинг кнопки                  dense: 12px */
  --btn-fs:   13px;    /* кегль кнопки                                   dense: 12px */

  /* движение */
  --ease: cubic-bezier(.22, 1, .36, 1);   /* easeOutExpo */
  --d-fast: .15s;  --d-base: .25s;  --d-slow: .4s;
  --shadow-pop: 0 8px 24px -8px rgba(0,0,0,.55);

  /* цвета серий графиков (DESIGN-SPEC §1.3) — назначать по порядку 1→N, не по кругу */
  --series-1: #3b82f6;  --series-2: #d97706;  --series-3: #059669;  --series-4: #a855f7;
  --series-5: #dc2626;  --series-6: #0891b2;  --series-7: #db2777;  --series-8: #65a30d;

  /* статус-светофор (DESIGN-SPEC §1) */
  --status-good: #22c55e;  --status-warning: #f59e0b;
  --status-serious: #f97316;  --status-critical: #ef4444;

  --font: 'Inter', system-ui, -apple-system, sans-serif;
  --mono: 'JetBrains Mono', ui-monospace, SFMono-Regular, monospace;
}

* { box-sizing: border-box; margin: 0; padding: 0; }
body {
  background: var(--bg); color: var(--text);
  font-family: var(--font); font-size: 14px; min-height: 100vh;
  -webkit-font-smoothing: antialiased;
}

/* ---------- топбар ---------- */
.topbar {
  background: var(--bg); border-bottom: 1px solid var(--border-soft);
  padding: 0 28px; height: 60px; display: flex; align-items: center; gap: 14px;
  position: sticky; top: 0; z-index: 10;
}
/* Лого по центру колонки сайдбара (220px). Бокс во всю ширину колонки,
   сдвинут влево на левый паддинг топбара (28px), чтобы центр бокса совпал
   с центром колонки сайдбара (которая начинается от края экрана). */
.topbar .logo {
  font-size: 30px; font-weight: 800; letter-spacing: -0.5px;
  color: var(--text); text-decoration: none; flex: none;
  width: 220px; margin-left: -28px; text-align: center;
}
.topbar nav { display: flex; align-items: center; gap: 4px; }
/* Глобалки сдвинуты правее (не липнут к сайдбару); flex-spacer слева
   двигает весь блок навигации ближе к центру топбара. */
.topbar .nav-lead { flex: 1; }
.topbar nav a {
  padding: 8px 16px; border-radius: var(--r-pill); color: var(--muted);
  text-decoration: none; font-weight: 600; font-size: 13.5px; transition: all .15s;
}
.topbar nav a:hover { color: var(--text); background: var(--surface2); }
.topbar nav a.active { color: var(--bg); background: var(--accent); }

/* Разделитель глобальных и проектных разделов. */
.topbar .nav-sep {
  width: 1px; height: 24px; background: var(--border); flex: none; margin: 0 16px;
}

/* Проектная капсула: только тонкая обводка-контур (без заливки) — вкладки
   внутри ведут себя как обычные nav-вкладки (тот же hover/active).
   Селектор проекта внутри выделен синей заливкой — явно читается как дропдаун. */
.topbar .scope-group {
  display: flex; align-items: center; gap: 2px;
  padding: 4px 6px; border: 1px solid var(--border); border-radius: var(--r-pill);
}
.topbar .scope-group .proj-btn {
  margin-left: 0; padding: 6px 12px; font-size: 13.5px; font-weight: 600;
  background: var(--accent-bg); border: 1px solid var(--accent-dim);
}
.topbar .scope-group .proj-btn:hover { background: var(--accent-bg); border-color: var(--accent); }
.topbar .scope-group .proj-btn .proj-current { color: var(--accent); }
.topbar .nav-scoped { gap: 4px; margin-left: 4px; }
/* заглушка-вкладка в топбаре («скоро») — как в сайдбаре, но инлайн */
.topbar a.stub { opacity: .6; }
.topbar .nav-soon {
  margin-left: 6px; font-size: 9px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--muted); background: var(--surface2); padding: 2px 6px; border-radius: var(--r-pill);
  vertical-align: middle;
}
.topbar .spacer { flex: 1; }
.topbar .updated { color: var(--muted); font-size: 12px; }

/* ---------- раскладка: боковая колонка + контент ---------- */
.layout { display: grid; grid-template-columns: 220px 1fr; min-height: calc(100vh - 60px); }
.sidebar {
  border-right: 1px solid var(--border-soft); padding: 22px 14px;
  display: flex; flex-direction: column; gap: 4px;
}
.sidebar .sb-title {
  font-size: 11px; text-transform: uppercase; letter-spacing: .6px;
  color: var(--muted); font-weight: 700; padding: 4px 12px 10px;
}
.sidebar a {
  padding: 10px 14px; border-radius: var(--r-sm); color: var(--muted);
  text-decoration: none; font-weight: 600; font-size: 13.5px; transition: all .15s;
  display: flex; align-items: center; gap: 10px;
}
.sidebar a:hover { color: var(--text); background: var(--surface2); }
.sidebar a.active { color: var(--text); background: var(--accent-bg); }
.sidebar a .ico { width: 16px; text-align: center; opacity: .85; }
.content { padding: 28px 32px; min-width: 0; }

/* ---------- контейнер/заголовок ---------- */
.container { max-width: 1480px; margin: 0 auto; padding: 28px; }
.page-header { display: flex; align-items: center; gap: 12px; margin-bottom: 22px; }
.page-header h1 { font-size: 22px; font-weight: 700; letter-spacing: -0.4px; }
.page-header .count {
  background: var(--surface2); color: var(--muted);
  border-radius: var(--r-pill); padding: 3px 12px; font-size: 12px; font-weight: 600;
}
.page-header .actions { margin-left: auto; display: flex; gap: 8px; }

/* ---------- кнопки (pill) — DESIGN-SPEC §4.5 ----------
   Высота/паддинг/кегль читаются из шкалы плотности: в `.dense` кнопка сама
   становится 32/12/12 без отдельного класса. min-height (а не height) —
   чтобы кнопка с двухстрочной подписью не обрезалась.
   Именование: `.btn-primary` — ОСНОВНОЕ имя, `.btn-accent` — живой алиас
   (на него завязаны сотни мест, он остаётся рабочим навсегда).
   Вертикальный паддинг 6px оставлен НЕ для высоты (её держит min-height), а как
   воздух под перенос: на двух строках подпись иначе упрётся вплотную в кант. */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  min-height: var(--btn-h); padding: 6px var(--btn-px);
  border-radius: var(--r-pill); border: 1px solid var(--border);
  font-size: var(--btn-fs); font-weight: 600; cursor: pointer;
  background: var(--surface); color: var(--text); font-family: var(--font);
  transition: background-color var(--d-fast) var(--ease),
              border-color var(--d-fast) var(--ease),
              color var(--d-fast) var(--ease),
              transform var(--d-fast) var(--ease);
}
.btn:hover { background: var(--surface2); border-color: var(--muted); }
.btn:active { transform: scale(.96); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn:disabled:active { transform: none; }
.btn-primary, .btn-accent { background: var(--accent); color: var(--bg); border-color: var(--accent); }
.btn-primary:hover, .btn-accent:hover { background: var(--accent-dim); border-color: var(--accent-dim); }
.btn-danger { background: var(--loss-soft); color: var(--loss-bright); border-color: transparent; }
.btn-danger:hover { background: var(--loss-soft-2); border-color: transparent; }
.btn-ghost { background: transparent; border-color: transparent; color: var(--muted); }
.btn-ghost:hover { background: var(--surface2); color: var(--text); }
/* Третий член семейства: БЕЗ заливки, но С кантом. `.btn` = заливка + кант,
   `.btn-ghost` = ни того, ни другого, `.btn-outline` = только кант.
   До A8 жил тремя байт-в-байт копиями `.btn-ghost-outline` в channel_settings/docgen/mediagen
   на 15 сайтов вызова — копии разъехались бы тихо, в border-color. Ховер наследуется от
   `.btn:hover` (кант → --muted) и повторяет фон/цвет `.btn-ghost:hover`. */
.btn-outline { background: transparent; border-color: var(--border); color: var(--muted); }
.btn-outline:hover { background: var(--surface2); color: var(--text); }
/* размеры вне контекста плотности: 32 / 40 (дефолт) / 44 */
.btn-sm { min-height: 32px; padding: 6px 12px; font-size: 12px; }
.btn-lg { min-height: 44px; padding: 6px 20px; font-size: 14px; }

/* ---------- карточки/таблицы ---------- */
/* Тонкий внутренний блик сверху (DESIGN-SPEC §4.1) — отделяет карточку от фона
   лучше любой тени. Паддинг карточке НЕ даём: сотни существующих карточек держат
   таблицы во всю ширину и ставят паддинг инлайном. Отступ — отдельным `.pad`. */
.card {
  background: var(--surface); border: 1px solid var(--border-soft);
  border-radius: var(--r-card); overflow: hidden;
  box-shadow: inset 0 1px 0 rgba(255,255,255,.04);
}
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
thead th {
  padding: 12px 16px; text-align: left; font-size: 11px; font-weight: 700;
  color: var(--muted); text-transform: uppercase; letter-spacing: .6px;
  border-bottom: 1px solid var(--border-soft); white-space: nowrap;
}
tbody tr { border-bottom: 1px solid var(--border-soft); transition: background .12s; }
tbody tr:last-child { border-bottom: none; }
tbody tr:hover { background: var(--surface2); }
tbody td { padding: 13px 16px; vertical-align: middle; }

/* ---------- бейджи статусов ---------- */
.badge { display: inline-flex; align-items: center; gap: 5px; padding: 4px 10px; border-radius: var(--r-pill); font-size: 11px; font-weight: 700; }
.badge::before { content: ''; display: block; width: 6px; height: 6px; border-radius: 50%; }
/* Тинты — те же *-soft, что у .status-pill ниже: «живой/успех» обязан нести ОДИН
   зелёный, иначе бейдж и пилюля на одной странице светят разными зелёными. */
.badge-green  { background: var(--emerald-soft); color: var(--green); }
.badge-green::before  { background: var(--green); }
.badge-red    { background: var(--loss-soft); color: var(--red); }
.badge-red::before    { background: var(--red); }
.badge-grey   { background: var(--grey-soft); color: var(--muted); }
.badge-grey::before   { background: var(--muted); }
.badge-yellow { background: var(--amber-soft); color: var(--yellow); }
.badge-yellow::before { background: var(--yellow); }

/* ---------- инпуты ---------- */
/* Поле УТОПЛЕНО: фон --sf-sunken темнее карточки (--card), но светлее окна (--bg)
   — DESIGN-SPEC §4.6. Геометрию (padding 9/12) намеренно не трогаем: на ней держатся
   узкие поля внутри плотных таблиц в 45 шаблонах; компактный вариант — в `.dense`. */
.inp {
  background: var(--sf-sunken); border: 1px solid var(--border); border-radius: var(--r-inp);
  color: var(--text); padding: 9px 12px; font-family: var(--font); font-size: 13px; width: 100%;
  transition: border-color .15s;
}
/* outline:none снят (хвосты трека A): кольцо фокуса даёт глобальный `:focus-visible`
   ниже в этом файле (box-shadow). Здесь остаётся только смена канта. */
.inp:focus { border-color: var(--accent-dim); }
label { display: flex; flex-direction: column; gap: 5px; font-size: 12px; color: var(--muted); }

/* Селекты под тему: тёплый графит, мягкое скругление, кастомная каретка вместо
   системной стрелки. Применяется ко ВСЕМ <select> (Ресурсы/Посты/План и пр.).
   Узкие селекты в таблицах сами переопределяют padding/font-size — их не ломает. */
select {
  -webkit-appearance: none; -moz-appearance: none; appearance: none;
  background-color: var(--surface2);
  border: 1px solid var(--border); border-radius: var(--r-inp);
  color: var(--text); font-family: var(--font); font-size: 13px; font-weight: 600;
  padding: 8px 34px 8px 12px; cursor: pointer; transition: border-color .15s, background-color .15s;
  /* Каретка ▾ нарисована SVG в data-URI. Значение --muted тут зашито буквой
     (%239ca3af = --ink-label): внутрь data-URI var() не пролезает, браузер его
     не резолвит. Меняешь --ink-label — правь и здесь. */
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8'%3E%3Cpath fill='none' stroke='%239ca3af' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round' d='M1 1.5 6 6.5 11 1.5'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 12px center;
}
select:hover { border-color: var(--muted); background-color: var(--surface); }
/* outline:none снят (хвосты трека A, `:focus-visible` даёт кольцо): та же
   логика, что у .inp:focus выше. */
select:focus { border-color: var(--accent-dim); }
select.inp { cursor: pointer; }
select option { background: var(--surface); color: var(--text); }

/* ---------- утилиты ---------- */
.mono { font-family: var(--mono); font-size: 12.5px; letter-spacing: .2px; }
/* ⚠️ ЛОВУШКА КОНТРАСТА. `.muted` = var(--muted) = --ink-label = #9ca3af (≈7:1 на карточке).
   Его новый эквивалент — `.txt-label`, а НЕ `.txt-muted`: последний светит --ink-muted
   #6b7280 (3.9:1, ниже порога 4.5:1) и годится только для eyebrow/disabled/плейсхолдера. */
.muted { color: var(--muted); }
.empty-state { padding: 64px; text-align: center; color: var(--muted); }
.empty-state .icon { font-size: 36px; margin-bottom: 12px; }

/* ---------- модалка ---------- */
.modal-overlay {
  display: none; position: fixed; inset: 0; background: rgba(0,0,0,.55);
  backdrop-filter: blur(2px); z-index: 50; align-items: center; justify-content: center;
}
.modal-overlay.open { display: flex; }
.modal-card {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-card);
  width: 500px; max-width: 92vw; max-height: 90vh; overflow-y: auto; padding: 24px;
}

/* ---------- индикатор уровня прогрева ---------- */
.lvlbar { display: inline-flex; align-items: center; gap: 7px; }
.lvlbar .track { height: 5px; width: 60px; background: var(--border); border-radius: var(--r-pill); overflow: hidden; }
.lvlbar .fill { height: 100%; background: var(--accent); border-radius: var(--r-pill); }
.lvlbar .num { font-size: 11px; color: var(--muted); font-weight: 600; }

.action-pill { font-size: 11px; background: var(--surface2); padding: 3px 9px; border-radius: var(--r-sm); font-weight: 600; }

/* ---------- key-value (детали) ---------- */
.kv { display: flex; justify-content: space-between; gap: 12px; padding: 6px 0; border-bottom: 1px solid var(--border-soft); font-size: 12px; }
.kv:last-child { border-bottom: none; }
.kv .k { color: var(--muted); }
.kv .v { font-family: var(--mono); text-align: right; word-break: break-all; }

/* ---------- тосты (всплывающие оповещения) ---------- */
.toast-wrap {
  position: fixed; bottom: 24px; right: 24px; z-index: 100;
  display: flex; flex-direction: column; gap: 10px; pointer-events: none;
}
.toast {
  background: var(--surface2); border: 1px solid var(--border);
  border-left: 3px solid var(--accent); border-radius: var(--r-sm);
  padding: 12px 16px; font-size: 13px; font-weight: 600; color: var(--text);
  box-shadow: 0 8px 28px rgba(0,0,0,.35);
  animation: toast-in .2s ease; min-width: 200px;
}
.toast.ok    { border-left-color: var(--green); }
.toast.err   { border-left-color: var(--red); }
.toast.fade  { animation: toast-out .3s ease forwards; }
@keyframes toast-in  { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes toast-out { to { opacity: 0; transform: translateY(8px); } }

/* ---------- спиннер кнопки «Обновить» (общий для всех вкладок) ---------- */
.spin { display: inline-block; animation: spin .8s linear infinite; }
@keyframes spin { from { transform: rotate(0); } to { transform: rotate(360deg); } }

/* ---------- скроллбар (DESIGN-SPEC §A3) ---------- */
* { scrollbar-width: thin; scrollbar-color: var(--hair-strong) transparent; }
*::-webkit-scrollbar { width: 10px; height: 10px; }
*::-webkit-scrollbar-thumb {
  background: var(--hair-strong); border-radius: 999px;
  border: 3px solid transparent; background-clip: content-box;
}

/* ---------- фокус-кольцо (DESIGN-SPEC §A3) ---------- */
/* outline:none — с заменой (box-shadow), это не нарушение правила «никогда outline:none
   без замены», а его реализация. */
:focus-visible { outline: none; box-shadow: 0 0 0 2px rgba(16,185,129,.5); }

/* ---------- prefers-reduced-motion (DESIGN-SPEC §A3) ---------- */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: .001ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .001ms !important;
  }
}

/* ---------- дропдауны топбара (селектор проекта, юзер-меню) ---------- */
.dropdown { position: relative; }
.proj-btn, .user-btn {
  display: inline-flex; align-items: center; gap: 8px; cursor: pointer;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-pill);
  color: var(--text); font-family: var(--font); font-size: 13px; font-weight: 600;
  padding: 7px 14px; transition: all .15s;
}
.proj-btn:hover, .user-btn:hover { background: var(--surface2); border-color: var(--muted); }
.proj-btn { margin-left: 8px; }
.proj-btn .proj-label { color: var(--muted); font-weight: 600; }
.proj-btn .proj-current { color: var(--accent); }
.caret { font-size: 10px; color: var(--muted); }
.user-btn .user-avatar {
  width: 22px; height: 22px; border-radius: 50%; display: inline-flex;
  align-items: center; justify-content: center; background: var(--accent); color: var(--bg);
  font-size: 11px; font-weight: 800;
}
.dropdown-menu {
  display: none; position: absolute; top: calc(100% + 8px); left: 0; z-index: 40;
  min-width: 200px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-card); padding: 6px; box-shadow: 0 12px 32px rgba(0,0,0,.4);
}
.dropdown-menu-right { left: auto; right: 0; }
.dropdown.open .dropdown-menu { display: block; }
.dropdown-menu form { margin: 0; }
.dropdown-item {
  display: block; width: 100%; text-align: left; box-sizing: border-box;
  padding: 9px 12px; border-radius: var(--r-sm); border: none; cursor: pointer;
  background: transparent; color: var(--text-dim); font-family: var(--font);
  font-size: 13px; font-weight: 600; text-decoration: none; transition: all .12s;
}
.dropdown-item:hover { background: var(--surface2); color: var(--text); }
.dropdown-item.active { background: var(--accent-bg); color: var(--text); }
.dropdown-item.danger { color: var(--red); }
.dropdown-item.danger:hover { background: var(--loss-soft); }
.dropdown-empty { padding: 9px 12px; font-size: 12px; color: var(--muted); }

/* ---------- раскрывающиеся группы сайдбара (напр. Отзывы) ---------- */
.sidebar .sb-group { display: flex; flex-direction: column; }
.sidebar .sb-parent {
  display: flex; align-items: center; gap: 10px; cursor: pointer;
  padding: 10px 14px; border-radius: var(--r-sm); border: none; background: transparent;
  color: var(--muted); font-family: var(--font); font-weight: 600; font-size: 13.5px;
  transition: all .15s; text-align: left;
}
.sidebar .sb-parent:hover { color: var(--text); background: var(--surface2); }
.sidebar .sb-parent .ico { width: 16px; text-align: center; opacity: .85; }
.sidebar .sb-parent .sb-parent-title { flex: 1; }
.sidebar .sb-caret { font-size: 10px; transition: transform .15s; }
.sidebar .sb-group.open .sb-caret { transform: rotate(180deg); }
.sidebar .sb-children { display: none; flex-direction: column; gap: 2px; padding-left: 26px; }
.sidebar .sb-group.open .sb-children { display: flex; }
.sidebar .sb-children a { padding: 8px 12px; font-size: 13px; }

/* зелёный акцент пункта сайдбара (напр. «Клиенты с TG») */
.sidebar a.nav-green { color: var(--green); }
.sidebar a.nav-green .ico { opacity: 1; }
.sidebar a.nav-green:hover { background: var(--emerald-soft); color: var(--green); }
.sidebar a.nav-green.active { color: var(--green); background: var(--emerald-soft); }

/* заглушки разделов в сайдбаре («скоро») */
.sidebar a.stub { opacity: .6; }
.sidebar .sb-soon {
  margin-left: auto; font-size: 9px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--muted); background: var(--surface2); padding: 2px 7px; border-radius: var(--r-pill);
}

/* ===== flatpickr: тёмная тема попапа под переменные фермы (см. datetime.js) ===== */
.flatpickr-calendar {
  background: var(--surface); color: var(--text);
  border: 1px solid var(--border); border-radius: var(--r-sm);
  box-shadow: 0 8px 28px rgba(0,0,0,.45);
}
.flatpickr-calendar.arrowTop::before,
.flatpickr-calendar.arrowTop::after { border-bottom-color: var(--border); }
.flatpickr-calendar.arrowBottom::before,
.flatpickr-calendar.arrowBottom::after { border-top-color: var(--border); }
.flatpickr-months, .flatpickr-month,
.flatpickr-current-month, .flatpickr-weekdays { background: var(--surface); color: var(--text); }
.flatpickr-current-month input.cur-year,
.flatpickr-current-month .flatpickr-monthDropdown-months { color: var(--text); }
.flatpickr-weekday { color: var(--muted); background: var(--surface); }
.flatpickr-months .flatpickr-prev-month svg,
.flatpickr-months .flatpickr-next-month svg { fill: var(--muted); }
.flatpickr-months .flatpickr-prev-month:hover svg,
.flatpickr-months .flatpickr-next-month:hover svg { fill: var(--accent); }
.flatpickr-day {
  color: var(--text); border-radius: var(--r-sm);
  border-color: transparent;
}
.flatpickr-day:hover,
.flatpickr-day:focus { background: var(--surface2); border-color: var(--surface2); }
.flatpickr-day.today { border-color: var(--accent-dim); }
.flatpickr-day.selected,
.flatpickr-day.selected:hover {
  background: var(--accent); border-color: var(--accent); color: var(--bg);
}
.flatpickr-day.flatpickr-disabled,
.flatpickr-day.prevMonthDay,
.flatpickr-day.nextMonthDay { color: var(--muted); opacity: .5; }
/* тайм-пикер (колёсики ЧЧ:ММ) */
.flatpickr-time { background: var(--surface); }
.flatpickr-time input,
.flatpickr-time .flatpickr-time-separator,
.flatpickr-time .flatpickr-am-pm { color: var(--text); background: var(--surface); }
.flatpickr-time input:hover,
.flatpickr-time input:focus,
.flatpickr-time .flatpickr-am-pm:hover,
.flatpickr-time .numInputWrapper:hover { background: var(--surface2); }
.numInputWrapper span.arrowUp::after { border-bottom-color: var(--muted); }
.numInputWrapper span.arrowDown::after { border-top-color: var(--muted); }
.numInputWrapper span:hover { background: var(--surface2); }

/* ============================================================
   ОБРАБОТКА — переиспользуемые компоненты (тоггл, KPI, модуль-карточка).
   Вайб темы: тёплый графит, pill-скругления, точечный голубой акцент.
   Идея модуля: левый кант + иконка кодируют ЖИВОЕ состояние (вкл/выкл) —
   один взгляд по вкладке = что активно. См. spec 2026-07-21-processing.
   ============================================================ */

/* --- тоггл-свитч (pill, как остальная тема) --- */
.switch { position: relative; display: inline-flex; align-items: center;
  width: 42px; height: 24px; flex: 0 0 auto; }
.switch input { position: absolute; inset: 0; opacity: 0; width: 100%; height: 100%;
  margin: 0; cursor: pointer; }
.switch .slider { position: absolute; inset: 0; background: var(--surface2);
  border: 1px solid var(--border); border-radius: var(--r-pill);
  transition: background .16s ease, border-color .16s ease; }
.switch .slider::before { content: ""; position: absolute; width: 16px; height: 16px;
  left: 3px; top: 3px; background: var(--muted); border-radius: 50%;
  transition: transform .16s ease, background .16s ease; }
.switch input:checked + .slider { background: var(--accent-bg); border-color: var(--accent); }
.switch input:checked + .slider::before { transform: translateX(18px); background: var(--accent); }
.switch input:focus-visible + .slider { outline: 2px solid var(--accent); outline-offset: 2px; }
.switch input:disabled { cursor: not-allowed; }
.switch input:disabled + .slider { opacity: .45; }

/* --- KPI-плитка статистики --- */
.stat-tile { flex: 1; min-width: 130px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--r-card); padding: 14px 16px; }
.stat-tile .n { font-size: 24px; font-weight: 800; color: var(--text); line-height: 1.1;
  letter-spacing: -.01em; }
.stat-tile .l { color: var(--muted); font-size: 12px; margin-top: 4px; }
.stat-tile.warn .n { color: var(--yellow); }
.stat-tile.bad  .n { color: var(--red); }
.stat-tile.good .n { color: var(--green); }

/* --- карточка-модуль с тогглом на заголовке (настройки обработки) --- */
/* Левый кант = сигнатура состояния: зелёный когда вкл, гасится когда выкл. */
.module-card { background: var(--surface); border: 1px solid var(--border);
  border-left: 3px solid var(--border); border-radius: var(--r-card);
  margin-bottom: 16px; overflow: hidden; transition: border-left-color .16s ease, opacity .16s ease; }
.module-card.is-on  { border-left-color: var(--green); }
.module-card.is-off { border-left-color: var(--border); opacity: .78; }
.module-card.is-ref { border-left-color: var(--accent-dim); }  /* справочник (вертикали) */
.module-head { display: flex; align-items: center; gap: 10px; padding: 14px 16px; }
.module-head .ico { font-size: 17px; line-height: 1; filter: grayscale(.4); transition: filter .16s ease; }
.module-card.is-on .module-head .ico { filter: none; }
.module-head .ttl { font-weight: 700; font-size: 15px; color: var(--text); }
.module-head .sub { color: var(--muted); font-size: 12px; }
.module-head .spacer { flex: 1; }
.module-head .state { font-size: 11px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--muted); margin-right: 2px; }
.module-card.is-on .module-head .state { color: var(--green); }
.module-body { padding: 0 16px 16px; border-top: 1px solid var(--border-soft); padding-top: 14px; }
.module-note { color: var(--muted); font-size: 12px; line-height: 1.5; margin: 0 0 12px; }
.module-sub-block { border-top: 1px solid var(--border-soft); margin-top: 14px; padding-top: 14px; }
.module-sub-block > .sbt { font-size: 11px; text-transform: uppercase; letter-spacing: .5px;
  color: var(--muted); margin-bottom: 10px; }

/* флаг «ждёт применения» (снип n8n / SQL ещё не применён) */
.pending-flag { display: inline-flex; align-items: center; gap: 5px; font-size: 11px;
  color: var(--yellow); background: var(--amber-soft); padding: 3px 9px; border-radius: var(--r-pill); }

/* строка «подпись + тоггл справа» внутри тела модуля */
.toggle-row { display: flex; align-items: flex-start; gap: 12px; padding: 8px 0; }
.toggle-row .tr-txt { flex: 1; }
.toggle-row .tr-txt b { font-weight: 600; font-size: 13px; color: var(--text); }
.toggle-row .tr-txt span { display: block; color: var(--muted); font-size: 12px; margin-top: 2px; }

/* пункт сайдбара «служебное» (напр. Чаты Chatwoot) — отделён кантом сверху, приглушён */
.sidebar a.nav-advanced { opacity: .72; border-top: 1px solid var(--border-soft);
  margin-top: 6px; padding-top: 12px; }
.sidebar a.nav-advanced:hover, .sidebar a.nav-advanced.active { opacity: 1; }


/* ============================================================================
   ПРИМИТИВЫ SPECTRUM (A4) — слой, на который переводятся 45 шаблонов.
   ----------------------------------------------------------------------------
   ПРАВИЛО ИМЁН. Классы выше — живые, на них завязано 8000+ строк инлайн-JS,
   они не переименовываются и не удаляются. Там, где имя из DESIGN-SPEC уже занято
   локальным <style> шаблонов, примитив получает ДРУГОЕ имя (спека — не начальник
   работающему проду):
     .pill  занят (admin_orgs/admin_users/channel_commenting/mini_sites) → .status-pill
     .tbl   занят (table.tbl в 6 шаблонах)                              → .data-table
     .row   занят (.actor-card .row, .c-buttons .row, .dr-edit .row)    → .flex-row
     .col   занят (.ftbl .col)                                          → .flex-col
     .dot   занят (.tab .dot, .pd-chip .dot, .detail-grp .dot)          → .sdot
     .value занят (.stat-card .value в import/launch)                   → .metric
   `.btn-primary` вводится как основное имя, `.btn-accent` живёт вечным алиасом.
   `.num` оставлен как есть: он аддитивен (только tabular-nums) и ни одно
   существующее правило с ним не конфликтует по свойствам.
   ============================================================================ */

/* ---------- компактная шкала плотности (DESIGN-SPEC §3.2) ----------
   Вешается на КОНТЕЙНЕР (таблица, список лидов, лог) — все примитивы внутри
   сами перестраиваются, потому что читают одни и те же имена переменных. */
.dense {
  --pad-card: 12px;
  --rhythm:   8px;
  --row-h:    36px;
  --cell-y:   8px;
  --cell-x:   12px;
  --fs-metric: 14px;
  --ichip-size: 28px;
  --btn-h:    32px;
  --btn-px:   12px;
  --btn-fs:   12px;
}
/* .inp геометрию из переменных не читает (см. коммент у .inp) — сжимаем точечно */
.dense .inp { padding: 6px 10px; font-size: 12px; }

/* ---------- карточка: отступ и интерактив ---------- */
.pad   { padding: var(--pad-card); }
.pad-0 { padding: 0; }
/* интерактивная карточка (DESIGN-SPEC §4.1): подсветка. Подъём (.card-lift) —
   только для крупных кликабельных плиток, НИКОГДА для строк таблицы. */
.card-hover { cursor: pointer; transition: background-color var(--d-base) var(--ease),
                                           border-color var(--d-base) var(--ease),
                                           transform var(--d-base) var(--ease); }
.card-hover:hover { background: var(--card-2); }
.card-lift:hover  { transform: translateY(-2px); }

/* ---------- вертикальный ритм ---------- */
.stack > * + * { margin-top: var(--rhythm); }
.hr { border: none; border-top: 1px solid var(--hair); margin: var(--rhythm) 0; }

/* ---------- секция с заголовком (DESIGN-SPEC §4.2) ----------
   <div class="section">
     <div><div class="eyebrow">…</div><div class="section-title">…</div></div>
     <div class="section-actions">…</div>
   </div> */
.section { display: flex; align-items: flex-end; gap: 12px; margin-bottom: 16px; }
.section-title { font-size: 16px; font-weight: 600; color: var(--ink); line-height: 1.3; }
.section-actions { margin-left: auto; display: flex; align-items: center; gap: 8px; }

/* ---------- eyebrow: главный приём стиля (DESIGN-SPEC §2, §10.2) ---------- */
.eyebrow {
  font-size: 11px; font-weight: 500; line-height: 1.4;
  text-transform: uppercase; letter-spacing: .14em; color: var(--ink-muted);
}

/* ---------- крупное значение ---------- */
.metric {
  font-size: var(--fs-metric); font-weight: 600; line-height: 1.15;
  color: var(--ink); font-variant-numeric: tabular-nums; letter-spacing: -.01em;
}

/* ---------- статус-пилюля (DESIGN-SPEC §4.4) ----------
   Цвет несёт ТОЧКА, текст обязателен: статус никогда не только цветом (§7). */
.status-pill {
  display: inline-flex; align-items: center; gap: 6px; white-space: nowrap;
  padding: 4px 10px; border-radius: var(--r-pill);
  font-size: 11px; font-weight: 500; line-height: 1.4;
  background: var(--grey-soft); color: var(--ink-label);
}
.status-pill::before {
  content: ''; flex: none; width: 6px; height: 6px;
  border-radius: 50%; background: currentColor;
}
.pill-live  { background: var(--emerald-soft); color: var(--emerald-up); }     /* живой   */
.pill-warm  { background: var(--amber-soft);   color: var(--amber-bright); }   /* прогрев */
.pill-dead  { background: var(--loss-soft);    color: var(--loss-bright); }    /* бан     */
.pill-pause { background: var(--grey-soft);    color: var(--ink-label); }      /* пауза   */
.pill-ai    { background: var(--violet-soft);  color: var(--violet-text); }    /* ИИ      */
.pill-info  { background: var(--info-soft);    color: var(--info-bright); }    /* выбрано */

/* ---------- статус-точка (светофор) ---------- */
.sdot {
  display: inline-block; flex: none; width: 10px; height: 10px;
  border-radius: 50%; background: currentColor; color: var(--ink-muted);
}
.sdot.green  { color: var(--status-good); }
.sdot.yellow { color: var(--status-warning); }
.sdot.orange { color: var(--status-serious); }
.sdot.red    { color: var(--status-critical); }

/* пульс «живого» (DESIGN-SPEC §6.3): сокет подключён, акк онлайн, шлюз жив */
.live-dot {
  position: relative; display: inline-block; flex: none;
  width: 8px; height: 8px; border-radius: 50%;
  background: currentColor; color: var(--emerald-up);
}
.live-dot::after {
  content: ''; position: absolute; inset: 0; border-radius: 50%;
  background: currentColor; animation: live-ping 1.6s var(--ease) infinite;
}
@keyframes live-ping { 0% { transform: scale(1); opacity: .6 } 100% { transform: scale(2.2); opacity: 0 } }

/* ---------- иконо-чип (DESIGN-SPEC §4.3) ----------
   Тинт-фон + цветная иконка. Обводка иконок 1.75 — заметно тоньше дефолта. */
.ichip {
  display: inline-grid; place-items: center; flex: none;
  width: var(--ichip-size); height: var(--ichip-size);
  border-radius: var(--r-chip); line-height: 1;
  font-size: calc(var(--ichip-size) * .45);
  background: var(--emerald-soft); color: var(--emerald-up);
}
.ichip svg { width: 50%; height: 50%; fill: none; stroke: currentColor; stroke-width: 1.75; }
.ichip-sm { --ichip-size: 28px; }
.ichip-lg { --ichip-size: 44px; }
.ichip-emerald { background: var(--emerald-soft); color: var(--emerald-up); }
.ichip-amber   { background: var(--amber-soft);   color: var(--amber-bright); }
.ichip-info    { background: var(--info-soft);    color: var(--info-bright); }
.ichip-violet  { background: var(--violet-soft);  color: var(--violet-text); }
.ichip-loss    { background: var(--loss-soft);    color: var(--loss-bright); }
.ichip-neutral { background: var(--grey-soft);    color: var(--ink-label); }

/* ---------- таблица данных (DESIGN-SPEC §4.7) ----------
   Обёртка — живой `.table-wrap` (overflow-x: auto), страница вбок не едет.
   thead sticky на --card-2 в eyebrow-стиле; разделители только border-top;
   ЗЕБРЫ НЕТ — на тёмном она грязнит. Числовые колонки — класс `.num`.
   Sticky-шапка прибивается, когда обёртка ограничена по высоте (max-height). */
.data-table { width: 100%; border-collapse: collapse; }
.data-table thead th {
  position: sticky; top: 0; z-index: 2; background: var(--card-2);
  padding: var(--cell-y) var(--cell-x);
  text-align: left; white-space: nowrap; border-bottom: none;
  font-size: 11px; font-weight: 500; text-transform: uppercase;
  letter-spacing: .14em; color: var(--ink-muted);
}
.data-table tbody tr {
  height: var(--row-h); border-top: 1px solid var(--hair); border-bottom: none;
  transition: background-color var(--d-fast) var(--ease);
}
.data-table tbody tr:hover { background: var(--card-2); }
.data-table tbody td {
  padding: var(--cell-y) var(--cell-x); vertical-align: middle; color: var(--ink-value);
}
.data-table td.num, .data-table th.num { text-align: right; }

/* ---------- движение (DESIGN-SPEC §6) ----------
   КРАСНАЯ ЛИНИЯ: `.appear-stagger` каскадит ТОЛЬКО первые 8 детей. Дальше —
   тишина: на 300 строках лидов каскад = фриз. Строки таблиц и элементы длинных
   списков не анимируются никогда. Глобальный prefers-reduced-motion выше гасит всё.
   ⚠️ На время анимации transform делает элемент containing block: не вешай
   `.appear` на контейнер, внутри которого живёт position:fixed (модалка, тост). */
@keyframes appear { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
@keyframes fade-in { from { opacity: 0; } to { opacity: 1; } }
@keyframes modal-in { from { opacity: 0; transform: translateY(10px) scale(.985); } to { opacity: 1; transform: none; } }

.appear { animation: appear var(--d-slow) var(--ease) both; }
.appear-stagger > *:nth-child(-n+8) { animation: appear var(--d-slow) var(--ease) both; }
.appear-stagger > *:nth-child(1) { animation-delay: .04s }
.appear-stagger > *:nth-child(2) { animation-delay: .10s }
.appear-stagger > *:nth-child(3) { animation-delay: .16s }
.appear-stagger > *:nth-child(4) { animation-delay: .22s }
.appear-stagger > *:nth-child(5) { animation-delay: .28s }
.appear-stagger > *:nth-child(6) { animation-delay: .34s }
.appear-stagger > *:nth-child(7) { animation-delay: .40s }
.appear-stagger > *:nth-child(8) { animation-delay: .46s }

.modal-overlay.open { animation: fade-in var(--d-base) var(--ease); }
.modal-overlay.open .modal-card { animation: modal-in var(--d-base) var(--ease) both; }

/* ============================================================================
   УТИЛИТЫ. Контракт для задач A5–A8: они правят ТОЛЬКО шаблоны, theme.css не
   трогают — значит всё, что им нужно, должно быть здесь. Набор снят со статистики
   реальных инлайн-стилей 45 шаблонов, а не придуман.
   ============================================================================ */

/* --- flex-раскладка. `.flex-row`/`.inline-flex` несут align-items: center как
       дефолт «на 42 из 50 случаев» — и объявлены ВЫШЕ блока `.ai-*`, чтобы
       `class="inline-flex ai-start"` давал flex-start, а не center. --- */
.flex-row { display: flex; align-items: center; }
.flex-col { display: flex; flex-direction: column; }
.inline-flex { display: inline-flex; align-items: center; }
.flex-wrap { flex-wrap: wrap; }
.grow     { flex: 1 1 auto; min-width: 0; }
.grow-2   { flex: 2 1 auto; min-width: 0; }
.shrink-0 { flex: none; }
.minw-0   { min-width: 0; }
.ml-auto  { margin-left: auto; }

.gap-4  { gap: 4px  }
.gap-6  { gap: 6px  }
.gap-8  { gap: 8px  }
.gap-10 { gap: 10px }
.gap-12 { gap: 12px }
.gap-16 { gap: 16px }
.gap-24 { gap: 24px }

.jc-start   { justify-content: flex-start }
.jc-center  { justify-content: center }
.jc-end     { justify-content: flex-end }
.jc-between { justify-content: space-between }

.ai-start    { align-items: flex-start }
.ai-center   { align-items: center }
.ai-end      { align-items: flex-end }
.ai-stretch  { align-items: stretch }
.ai-baseline { align-items: baseline }

.as-start  { align-self: flex-start }
.as-center { align-self: center }
.as-end    { align-self: flex-end }

/* --- внешние отступы (ступени 0/4/8/12/16/24) --- */
.m-0  { margin: 0 }
.mt-0 { margin-top: 0 }    .mb-0 { margin-bottom: 0 }
.mt-4 { margin-top: 4px }  .mb-4 { margin-bottom: 4px }
.mt-8 { margin-top: 8px }  .mb-8 { margin-bottom: 8px }
.mt-12 { margin-top: 12px } .mb-12 { margin-bottom: 12px }
.mt-16 { margin-top: 16px } .mb-16 { margin-bottom: 16px }
.mt-24 { margin-top: 24px } .mb-24 { margin-bottom: 24px }

/* --- внутренние отступы. Та же лестница 0/4/8/12/16/24, что у gap и margin:
       новых магических чисел нет. Инлайновые 18px и 14px из шаблонов округляются
       к 16 и 12 — это нормализация, а не потеря. `.pad` (20px / dense 12px)
       остаётся отдельно: он единственный, кто читает шкалу плотности. --- */
.p-0  { padding: 0 }     .p-4  { padding: 4px }   .p-8  { padding: 8px }
.p-12 { padding: 12px }  .p-16 { padding: 16px }  .p-24 { padding: 24px }

.px-0  { padding-left: 0;    padding-right: 0 }
.px-4  { padding-left: 4px;  padding-right: 4px }
.px-8  { padding-left: 8px;  padding-right: 8px }
.px-12 { padding-left: 12px; padding-right: 12px }
.px-16 { padding-left: 16px; padding-right: 16px }
.px-24 { padding-left: 24px; padding-right: 24px }

.py-0  { padding-top: 0;    padding-bottom: 0 }
.py-4  { padding-top: 4px;  padding-bottom: 4px }
.py-8  { padding-top: 8px;  padding-bottom: 8px }
.py-12 { padding-top: 12px; padding-bottom: 12px }
.py-16 { padding-top: 16px; padding-bottom: 16px }
.py-24 { padding-top: 24px; padding-bottom: 24px }

.pt-0 { padding-top: 0 }     .pb-0 { padding-bottom: 0 }
.pt-4 { padding-top: 4px }   .pb-4 { padding-bottom: 4px }
.pt-8 { padding-top: 8px }   .pb-8 { padding-bottom: 8px }
.pt-12 { padding-top: 12px } .pb-12 { padding-bottom: 12px }
.pt-16 { padding-top: 16px } .pb-16 { padding-bottom: 16px }
.pt-24 { padding-top: 24px } .pb-24 { padding-bottom: 24px }

/* --- типографика (шкала DESIGN-SPEC §2) --- */
.fs-11 { font-size: 11px } .fs-12 { font-size: 12px } .fs-13 { font-size: 13px }
.fs-14 { font-size: 14px } .fs-16 { font-size: 16px } .fs-20 { font-size: 20px }
.fs-24 { font-size: 24px }
.fw-400 { font-weight: 400 } .fw-500 { font-weight: 500 }
.fw-600 { font-weight: 600 } .fw-700 { font-weight: 700 }
.lh-tight { line-height: 1.2 } .lh-normal { line-height: 1.5 }
/* число ВСЕГДА tabular-nums, иначе колонка «дышит» при обновлении (§10.5) */
.num { font-variant-numeric: tabular-nums; }
.nowrap { white-space: nowrap }
.prewrap { white-space: pre-wrap }
.ellipsis { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0 }
.ta-left { text-align: left } .ta-center { text-align: center } .ta-right { text-align: right }
.break-all { word-break: break-all }

/* --- цвет текста. Значения и подписи носят только --ink-*; цветной текст —
       только там, где цвет И ЕСТЬ смысл (дельта, ошибка, статус). §1.2 --- */
.txt-ink   { color: var(--ink) }
.txt-value { color: var(--ink-value) }
/* ⚠️ ПЕРЕЕЗД С `.muted`/`style="color:var(--muted)"` (36 инлайнов в шаблонах) — СЮДА.
   var(--muted) = --ink-label = #9ca3af, ≈7:1 на --card. Это `.txt-label`. */
.txt-label { color: var(--ink-label) }
/* ⚠️ НЕ замена `.muted`! --ink-muted = #6b7280 даёт 3.9:1 на --card — ниже порога 4.5:1.
   Только eyebrow, disabled и плейсхолдер, т.е. текст, который читать не обязательно. */
.txt-muted { color: var(--ink-muted) }
.txt-emerald { color: var(--emerald-up) }
.txt-amber   { color: var(--amber-bright) }
.txt-info    { color: var(--info-bright) }
.txt-violet  { color: var(--violet-text) }
.txt-loss    { color: var(--loss-bright) }

/* --- канты и поверхности. Граница ВСЕГДА 1px var(--hair) (DESIGN-SPEC §3.1).
       Инлайновые `border:1px solid var(--border)` в шаблонах светят --hair-strong
       (#2a2e37) — при переезде на `.bd` кант станет тоньше по контрасту, это по спеке. --- */
.bd        { border: 1px solid var(--hair) }
.bd-none   { border: none }
.bd-top    { border-top: 1px solid var(--hair) }
.bd-bottom { border-bottom: 1px solid var(--hair) }
.divide-y > * + * { border-top: 1px solid var(--hair); }
.sunken { background: var(--sf-sunken) }
.raised { background: var(--card-2) }

/* --- размеры и прокрутка --- */
.w-full { width: 100% }
.w-auto { width: auto }
.scroll-y { overflow-y: auto }
.resize-y { resize: vertical }
.pointer { cursor: pointer }

/* --- доступность: имя для скринридера без визуального следа (§7) --- */
.sr-only {
  position: absolute; width: 1px; height: 1px; padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0 0 0 0); clip-path: inset(50%);
  white-space: nowrap; border: 0;
}

/* --- display. ИДЁТ ПОСЛЕДНИМ: `.hidden` должен побеждать `.flex-row`/`.flex-col`/
       `.inline-flex`/`.block` при равной специфичности. Без !important — чтобы
       инлайновый el.style.display = 'flex' из JS по-прежнему показывал элемент. --- */
.block { display: block }
.hidden { display: none }
