/*
 * app.css — Оформление панели.
 *
 * Система цветов интерфейса перенесена из панели Quick SnacksB: кастомные
 * свойства, светлая и тёмная темы, тёмный сайдбар. Она уже согласована с
 * оператором, переизобретать нечего.
 *
 * Цвета графиков живут отдельно (--viz-*) и подобраны по правилам построения
 * данных, а не по вкусу: они проверены валидатором на обеих подложках панели
 * (белой и #161C23) на различимость при нарушениях цветовосприятия. Золото
 * заведения осталось цветом интерфейса — кнопок и выделения; данные им не
 * красятся, иначе «фирменное» и «значимое» перестают различаться.
 *
 * Инлайновых стилей нет ни одного: политика безопасности запрещает
 * `style-src 'unsafe-inline'`. Размеры столбиков задаются из скрипта через
 * CSS-переменные (см. dom.js, ключ `vars`).
 */

:root {
  --bg:#F3F4F6; --panel:#FFFFFF; --ink:#161C24; --muted:#68727F; --line:#E5E8EC;
  --side:#141922; --side-ink:#C4CBD4; --side-mut:#7E8894; --side-line:#232A34;
  --accent:#C79A3E; --accent-ink:#1c1405;
  --ok:#1F9D6B; --ok-bg:#E4F5EE; --warn:#B9820E; --warn-bg:#FBF0D8;
  --crit:#D0574A; --crit-bg:#FBE7E4;
  --shadow:0 1px 2px rgba(16,24,40,.06),0 4px 16px rgba(16,24,40,.06);

  /* ── Цвета данных ──────────────────────────────────────────────────────
     Одна серия всегда --viz-solo. Категориальные слоты назначаются по
     порядку и никогда не «прокручиваются»: седьмой оттенок неотличим от
     одного из первых, поэтому хвост сворачивается в «Прочие».
     Порядковая шкала (--viz-ord-*) только для упорядоченных этапов. */
  --viz-solo:#2a78d6;
  --viz-1:#2a78d6; --viz-2:#eb6834; --viz-3:#1baf7a;
  --viz-4:#eda100; --viz-5:#e87ba4; --viz-6:#008300;
  --viz-rest:#898781;
  --viz-ord-1:#86b6ef; --viz-ord-2:#3987e5; --viz-ord-3:#256abf; --viz-ord-4:#104281;
  --viz-grid:#E1E0D9; --viz-axis:#C3C2B7; --viz-zero:#EDEEF0;
  --st-good:#0ca30c; --st-warn:#fab219; --st-crit:#d03b3b;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg:#0E1216; --panel:#161C23; --ink:#E7ECF2; --muted:#94A0AD; --line:#252D37;
    --ok-bg:#12241D; --warn-bg:#2A2413; --crit-bg:#2A1815;
    --viz-solo:#3987e5;
    --viz-1:#3987e5; --viz-2:#d95926; --viz-3:#199e70;
    --viz-4:#c98500; --viz-5:#d55181; --viz-6:#008300;
    --viz-ord-1:#184f95; --viz-ord-2:#256abf; --viz-ord-3:#3987e5; --viz-ord-4:#86b6ef;
    --viz-grid:#2c2c2a; --viz-axis:#383835; --viz-zero:#1D242C;
  }
}

/* Переключатель темы обязан побеждать системную настройку в обе стороны. */
:root[data-theme="dark"] {
  --bg:#0E1216; --panel:#161C23; --ink:#E7ECF2; --muted:#94A0AD; --line:#252D37;
  --ok-bg:#12241D; --warn-bg:#2A2413; --crit-bg:#2A1815;
  --viz-solo:#3987e5;
  --viz-1:#3987e5; --viz-2:#d95926; --viz-3:#199e70;
  --viz-4:#c98500; --viz-5:#d55181; --viz-6:#008300;
  --viz-ord-1:#184f95; --viz-ord-2:#256abf; --viz-ord-3:#3987e5; --viz-ord-4:#86b6ef;
  --viz-grid:#2c2c2a; --viz-axis:#383835; --viz-zero:#1D242C;
}
:root[data-theme="light"] {
  --bg:#F3F4F6; --panel:#FFFFFF; --ink:#161C24; --muted:#68727F; --line:#E5E8EC;
  --ok-bg:#E4F5EE; --warn-bg:#FBF0D8; --crit-bg:#FBE7E4;
  --viz-solo:#2a78d6;
  --viz-1:#2a78d6; --viz-2:#eb6834; --viz-3:#1baf7a;
  --viz-4:#eda100; --viz-5:#e87ba4; --viz-6:#008300;
  --viz-ord-1:#86b6ef; --viz-ord-2:#3987e5; --viz-ord-3:#256abf; --viz-ord-4:#104281;
  --viz-grid:#E1E0D9; --viz-axis:#C3C2B7; --viz-zero:#EDEEF0;
}

* { box-sizing:border-box; margin:0; padding:0; }

html { -webkit-text-size-adjust:100%; }

body {
  font-family:-apple-system,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;
  background:var(--bg); color:var(--ink); -webkit-font-smoothing:antialiased;
}

.hidden { display:none !important; }
.muted-note { color:var(--muted); font-size:13px; }

/* Видимый фокус обязателен: панелью пользуются с клавиатуры, а без обводки
   непонятно, где ты находишься. */
:focus-visible {
  outline:2px solid var(--accent);
  outline-offset:2px;
  border-radius:6px;
}

.skip {
  position:absolute; left:-9999px; top:0; z-index:300;
  background:var(--panel); color:var(--ink); padding:10px 14px; border-radius:0 0 10px 0;
  font-weight:700; text-decoration:none;
}
.skip:focus { left:0; }

/* ── Форма входа ─────────────────────────────────────────────────────────── */

.login-page { min-height:100vh; display:grid; place-items:center; padding:24px; }
.login-card {
  background:var(--panel); border:1px solid var(--line); border-radius:16px;
  box-shadow:var(--shadow); padding:28px; width:100%; max-width:380px;
}
.login-card h1 { font-size:20px; font-weight:800; letter-spacing:-.2px; }
.login-card .sub { color:var(--muted); font-size:13.5px; margin:6px 0 20px; }
.field { display:block; margin-bottom:14px; }
.field span { display:block; font-size:13px; font-weight:600; color:var(--muted); margin-bottom:6px; }
.field input {
  font:inherit; width:100%; padding:12px 13px; border-radius:10px;
  border:1px solid var(--line); background:var(--bg); color:var(--ink);
}
.err {
  color:var(--crit); background:var(--crit-bg); border-radius:9px;
  padding:9px 12px; font-size:13.5px; font-weight:600; margin-bottom:14px;
}

/* ── Каркас приложения ───────────────────────────────────────────────────── */

.app { display:grid; grid-template-columns:264px 1fr; min-height:100vh; }

.side {
  background:var(--side); color:var(--side-ink); display:flex; flex-direction:column;
  padding:22px 16px; position:sticky; top:0; height:100vh;
}
.brand { display:flex; align-items:center; gap:12px; padding:6px 8px 20px; }
.brand .mark {
  width:44px; height:44px; border-radius:10px; background:var(--accent);
  color:var(--accent-ink); display:grid; place-items:center; font-weight:800; font-size:16px;
}
.brand .t { font-weight:800; font-size:17px; letter-spacing:.2px; }
.brand .t small {
  display:block; font-weight:600; font-size:11px; color:var(--side-mut);
  letter-spacing:2px; text-transform:uppercase; margin-top:2px;
}
.nav { display:flex; flex-direction:column; gap:3px; margin-top:8px; }
.nav a {
  display:flex; align-items:center; gap:12px; padding:12px; border-radius:9px;
  color:var(--side-ink); text-decoration:none; font-size:15px; font-weight:600; cursor:pointer;
  min-height:44px;
}
.nav a .i { width:20px; text-align:center; opacity:.85; }
.nav a:hover { background:#1d2530; }
.nav a.on { background:var(--accent); color:var(--accent-ink); }
.nav .sep { height:1px; background:var(--side-line); margin:12px 4px; }
.side .foot {
  margin-top:auto; font-size:12px; color:var(--side-mut); padding:8px; line-height:1.5;
  display:flex; flex-direction:column; gap:10px; align-items:flex-start;
}
/* Выход живёт рядом с именем вошедшего, а не в шапке: в шапке он на телефоне
   переносился на вторую строку и ломал её. */
/* Специфичность выше, чем у .btn: иначе выигрывало правило .btn ниже по
   файлу и кнопка получала светлую подложку на тёмном сайдбаре. */
.side .side-btn {
  background:transparent; border-color:var(--side-line); color:var(--side-ink); width:100%;
  justify-content:center;
}
.side .side-btn:hover:not(:disabled) { background:#1d2530; filter:none; }

.scrim {
  position:fixed; inset:0; background:rgba(0,0,0,.45); z-index:150;
  opacity:0; pointer-events:none; transition:opacity .25s;
}
.scrim.on { opacity:1; pointer-events:auto; }

.main { display:flex; flex-direction:column; min-width:0; }
.top {
  display:flex; align-items:center; gap:12px; padding:14px 28px; background:var(--panel);
  border-bottom:1px solid var(--line); position:sticky; top:0; z-index:5;
}
.venue { display:flex; align-items:center; gap:10px; font-weight:700; font-size:16px; min-width:0; }
.venue .pin {
  background:var(--accent); color:var(--accent-ink); width:30px; height:30px;
  border-radius:8px; display:grid; place-items:center; font-weight:800; flex:none;
  font-size:14px;
}
.venue .pin:empty { display:none; }
.venue select {
  font:inherit; font-weight:700; border:1px solid var(--line); background:var(--panel);
  color:var(--ink); border-radius:9px; padding:9px 12px; max-width:220px; min-height:40px;
}
.venue select:disabled { opacity:.55; }
.top .sp { flex:1; }

.btn {
  font:inherit; font-weight:700; font-size:14px; border:1px solid var(--line);
  background:var(--panel); color:var(--ink); border-radius:9px; padding:10px 14px;
  cursor:pointer; display:inline-flex; align-items:center; gap:8px; min-height:40px;
}
.btn.pri { background:var(--accent); border-color:var(--accent); color:var(--accent-ink); }
.btn.wide { width:100%; justify-content:center; padding:13px; }
.btn:hover:not(:disabled) { filter:brightness(.97); }
.btn:disabled { opacity:.55; cursor:default; }

.icobtn {
  width:40px; height:40px; border-radius:9px; border:1px solid var(--line);
  background:var(--panel); color:var(--ink); cursor:pointer; font-size:17px; flex:none;
}
.burger {
  display:none; width:44px; height:44px; border-radius:10px; border:1px solid var(--line);
  background:var(--panel); color:var(--ink); cursor:pointer; flex:none;
  align-items:center; justify-content:center;
}
/* Три полоски рисуем стилями: символ «≡» есть не во всех системных шрифтах,
   и на части устройств кнопка оказывалась пустым квадратом. */
.burger .bars, .burger .bars::before, .burger .bars::after {
  content:""; display:block; width:20px; height:2.5px; background:var(--ink); border-radius:2px;
}
.burger .bars { position:relative; }
.burger .bars::before { position:absolute; top:-6px; left:0; }
.burger .bars::after { position:absolute; top:6px; left:0; }

.wrap { padding:26px 28px 48px; max-width:1180px; width:100%; }
.wrap:focus { outline:none; }
h1.pg { font-size:24px; font-weight:800; letter-spacing:-.2px; }
.pg-sub { color:var(--muted); font-size:14px; margin-top:4px; margin-bottom:18px; max-width:70ch; }
.period-note { color:var(--muted); font-size:13px; margin:-6px 0 16px; }
.foot-link { margin-top:18px; }

/* ── Строка фильтров ─────────────────────────────────────────────────────── */
/* Одна на экран, выше всего, что она ограничивает. Фильтр внутри карточки
   графика означал бы, что соседние графики показывают другой период. */

.filters {
  display:flex; align-items:center; gap:12px; flex-wrap:wrap; margin-bottom:18px;
}
.filters-label { font-size:13px; font-weight:700; color:var(--muted); }
.seg {
  display:inline-flex; gap:2px; background:var(--bg); border:1px solid var(--line);
  border-radius:11px; padding:3px; flex-wrap:wrap;
}
.seg-btn {
  font:inherit; font-size:13.5px; font-weight:700; border:0; background:transparent;
  color:var(--muted); border-radius:8px; padding:8px 14px; cursor:pointer; min-height:36px;
}
.seg-btn:hover { color:var(--ink); }
.seg-btn.on { background:var(--panel); color:var(--ink); box-shadow:var(--shadow); }

/* ── Плитки показателей ──────────────────────────────────────────────────── */

/* Сетка подстраивается под число плиток: экраны показывают их от трёх до
   пяти, и фиксированное число колонок оставляло бы дыру в ряду. */
.kpis {
  display:grid; grid-template-columns:repeat(auto-fit,minmax(184px,1fr));
  gap:14px; margin-bottom:20px;
}
.kpi {
  background:var(--panel); border:1px solid var(--line); border-radius:14px;
  padding:16px 18px; box-shadow:var(--shadow); min-width:0;
}
.kpi .l { font-size:13px; color:var(--muted); font-weight:600; }
/* Крупное число — пропорциональными цифрами: моноширинные на таком кегле
   выглядят разреженно. Табличные оставлены столбцам таблиц. */
.kpi .v { font-size:30px; font-weight:800; margin-top:6px; letter-spacing:-.5px; }
.kpi .d { font-size:12px; font-weight:600; margin-top:4px; color:var(--muted); }
.kpi-hero .v { font-size:48px; line-height:1.05; }
.kpi-warn .v { color:var(--warn); }
.kpi .hint { margin-top:10px; }

/* ── Карточки ────────────────────────────────────────────────────────────── */

.cols-2 { display:grid; grid-template-columns:1fr 1fr; gap:18px; align-items:start; }
.card {
  background:var(--panel); border:1px solid var(--line); border-radius:16px;
  box-shadow:var(--shadow); overflow:hidden; margin-bottom:18px;
}
.card h2 {
  font-size:16px; font-weight:800; padding:16px 18px; border-bottom:1px solid var(--line);
  display:flex; align-items:center; gap:10px;
}
.card h2 .cnt {
  margin-left:auto; font-size:12px; font-weight:700; color:var(--muted);
  background:var(--bg); padding:3px 9px; border-radius:20px;
}
.card-pad { padding:18px; }
.card .empty { padding:26px 18px; text-align:center; color:var(--muted); font-size:14px; }
.card .empty p { margin-bottom:14px; max-width:52ch; margin-left:auto; margin-right:auto; }

.row { display:flex; align-items:center; gap:14px; padding:14px 18px; border-bottom:1px solid var(--line); }
.row:last-child { border-bottom:0; }
.row .ico {
  width:42px; height:42px; border-radius:11px; display:grid; place-items:center;
  font-size:16px; font-weight:700; background:var(--bg); flex:none;
}
.row .nm { font-weight:700; font-size:15px; }
.row .ds { font-size:13px; color:var(--muted); margin-top:1px; }
.row .sp { flex:1; }
.row.link { cursor:pointer; }
.row.link:hover { background:var(--bg); }

.pill { font-size:12px; font-weight:800; padding:5px 11px; border-radius:20px; white-space:nowrap; }
.pill.ok { color:var(--ok); background:var(--ok-bg); }
.pill.warn { color:var(--warn); background:var(--warn-bg); }
.pill.crit { color:var(--crit); background:var(--crit-bg); }
.pill.mut { color:var(--muted); background:var(--bg); }

.tags { display:flex; gap:6px; flex-wrap:wrap; margin-top:6px; }
.tag {
  font-size:11px; font-weight:700; color:var(--muted); background:var(--bg);
  border:1px solid var(--line); border-radius:20px; padding:2px 8px;
}
.tag.mono { font-family:ui-monospace,SFMono-Regular,Menlo,monospace; }

.loading { padding:40px; text-align:center; color:var(--muted); font-size:14px; }

/* ── Каналы заведения ────────────────────────────────────────────────────── */
/* Маленькие ссылки под названием: сайт, бот, соцсети, карта. Ровно настолько
   заметные, чтобы найти их взглядом, и не настолько, чтобы спорить с
   кнопками смены. Подпись живёт в title и aria-label: значок и так узнаваем,
   а строка из пяти слов рядом с заголовком читалась бы как меню. */

.chans { display:flex; flex-wrap:wrap; gap:8px; margin:-4px 0 16px; }
.chan {
  display:inline-flex; align-items:center; justify-content:center;
  width:30px; height:30px; border-radius:50%;
  border:1px solid var(--line); background:var(--panel); color:var(--muted);
  font-size:14px; line-height:1; text-decoration:none;
}
.chan svg { display:block; }
.chan:hover { color:var(--ink); border-color:var(--muted); }
.chan:focus-visible { outline:2px solid var(--accent); outline-offset:2px; }


/* ── Каталог возможностей заведения ──────────────────────────────────────── */
/* Витрина: что включено и что можно подключить. Карточки в сетке, состояние
   всегда словом на плашке, а не только цветом рамки. «Скоро» приглушена и не
   притворяется нажимаемой. */

.cap-h { margin-top:26px; }
.cap-group { margin-top:20px; }
.cap-cat { font-size:15px; font-weight:800; letter-spacing:-.2px; }
.cap-cap { font-size:13px; color:var(--muted); margin:2px 0 12px; }

.cap-grid {
  display:grid; grid-template-columns:repeat(auto-fill,minmax(280px,1fr)); gap:14px;
}
.cap {
  display:flex; align-items:flex-start; gap:13px;
  background:var(--panel); border:1px solid var(--line); border-radius:14px;
  padding:16px; box-shadow:var(--shadow); min-width:0;
}
.cap-state { margin-top:11px; }
.cap-ico {
  flex:0 0 auto; width:38px; height:38px; border-radius:10px;
  display:grid; place-items:center; background:var(--bg); color:var(--muted);
  border:1px solid var(--line);
}
.cap-ico svg { display:block; }
.cap-body { min-width:0; flex:1; }
.cap-name { font-weight:700; font-size:14.5px; }
.cap-desc { font-size:12.5px; color:var(--muted); line-height:1.45; margin-top:4px; }

/* Включённое выделяем рамкой и подсветкой значка: на витрине сразу видно, что
   у заведения уже есть, а что предлагается. */
.cap-on { border-color:var(--ok); }
.cap-on .cap-ico { background:var(--ok-bg); color:var(--ok); border-color:var(--ok-bg); }
/* Скоро и заблокированное приглушаем: это не то, что можно нажать сейчас. */
.cap-soon, .cap-locked { opacity:.72; }

/* ── Свёрнутые подсказки ─────────────────────────────────────────────────── */
/* Скрыты по умолчанию: опытному человеку они мешают, новому нужны. Нативный
   details работает без скрипта, доступен с клавиатуры и ищется поиском по
   странице в развёрнутом виде. */

.hint { margin-top:12px; }
/* Пояснение относится к блоку НАД ним. Без этого оно вставало ближе к
   следующей карточке и читалось как её подзаголовок: человек открывал
   «Что это значит» у счётчиков смены и получал текст про движок. */
#view > .hint { margin-top:2px; margin-bottom:24px; }
.hint > summary {
  cursor:pointer; font-size:12.5px; font-weight:700; color:var(--muted);
  list-style:none; display:inline-flex; align-items:center; gap:6px;
  padding:6px 10px; border:1px solid var(--line); border-radius:20px; min-height:32px;
}
.hint > summary::-webkit-details-marker { display:none; }
.hint > summary::before { content:"?"; font-weight:800; opacity:.7; }
.hint > summary:hover { color:var(--ink); }
.hint[open] > summary { color:var(--ink); background:var(--bg); }
.table-view > summary::before { content:"▤"; }
.hint-body {
  margin-top:10px; font-size:13.5px; line-height:1.55; color:var(--muted);
  border-left:2px solid var(--line); padding-left:12px; max-width:74ch;
}

/* ── Выводы ──────────────────────────────────────────────────────────────── */
/* Состояние никогда не передаётся одним цветом: рядом всегда знак и слово. */

.insights { display:grid; gap:1px; background:var(--line); }
.ins { display:flex; gap:14px; padding:14px 18px; background:var(--panel); }
.ins-mark {
  width:26px; height:26px; border-radius:50%; flex:none; display:grid; place-items:center;
  font-size:13px; font-weight:800; color:#fff; background:var(--muted);
}
.ins-ok .ins-mark { background:var(--st-good); }
.ins-warn .ins-mark { background:var(--st-warn); color:#2a2413; }
.ins-crit .ins-mark { background:var(--st-crit); }
.ins-title { font-weight:700; font-size:14.5px; display:flex; align-items:center; gap:8px; flex-wrap:wrap; }
.ins-word {
  font-size:11px; font-weight:800; text-transform:uppercase; letter-spacing:.6px;
  color:var(--muted); background:var(--bg); border-radius:20px; padding:2px 8px;
}
.ins-text { font-size:13.5px; color:var(--muted); margin-top:3px; line-height:1.5; max-width:74ch; }

/* ── Графики ─────────────────────────────────────────────────────────────── */

.viz + .viz { margin-top:22px; }
.viz-head { margin-bottom:14px; }
.viz-title { font-weight:800; font-size:15px; }
.viz-sub { font-size:12.5px; color:var(--muted); margin-top:2px; }
.viz-empty {
  padding:34px 12px; text-align:center; color:var(--muted); font-size:13.5px;
  border:1px dashed var(--line); border-radius:12px;
}

/* Столбики. Разрыв между соседними метками делает подложка, а не рамка.
   Верхний отступ — полоса под подпись пика: без него подпись легла бы
   поверх самого высокого столбика и стала нечитаемой. */
.cols {
  display:flex; align-items:flex-end; gap:2px; height:200px;
  border-bottom:1px solid var(--viz-axis); padding-top:20px;
}
.col {
  flex:1 1 0; min-width:0; display:flex; flex-direction:column; justify-content:flex-end;
  height:100%; position:relative; cursor:default;
}
/* Подписи вынесены под ось отдельным рядом: внутри поля они съедали высоту
   столбиков, а линия оси оказывалась под текстом, а не под данными. */
.cols-labels { display:flex; gap:2px; align-items:flex-start; }
.cols-labels > .col-label { flex:1 1 0; min-width:0; }
.col-track { flex:1; display:flex; align-items:flex-end; padding:0 1px; }
.col-fill {
  width:100%; max-width:24px; margin:0 auto; height:var(--h);
  min-height:2px; background:var(--viz-solo);
  border-radius:4px 4px 0 0;   /* скругление только со стороны значения */
}
.col-fill.zero { background:var(--viz-zero); min-height:2px; }
.col-peak {
  position:absolute; top:-19px; left:50%; transform:translateX(-50%);
  font-size:11.5px; font-weight:800; color:var(--ink); white-space:nowrap;
}
/* Подпись переносится, а не обрезается: обрезанное слово читается как
   опечатка, а «опоздание больше 30 ми» это брак, а не экономия места. */
/* По умолчанию подпись не переносится: в узкой ячейке перенос разбивал
   «03.07» на столбик из отдельных цифр. Подпись шире своей ячейки заезжает
   на соседние, но прорежённые соседи скрыты, поэтому наложения нет.
   Длинные подписи ячеек распределения включают перенос по словам. */
.col-label {
  font-size:11px; line-height:1.25; color:var(--muted); text-align:center;
  padding:6px 2px 0; font-variant-numeric:tabular-nums; white-space:nowrap;
}
.cols-labels.wrap .col-label { white-space:normal; overflow-wrap:break-word; }
.col-label.faint { visibility:hidden; }
.col:hover .col-fill, .col:focus-visible .col-fill { filter:brightness(1.12); }

/* Горизонтальные полосы */
.bars { display:flex; flex-direction:column; gap:10px; }
.bar-row { display:grid; grid-template-columns:minmax(96px,1.1fr) 3fr minmax(92px,auto); gap:12px; align-items:center; }
.bar-name { font-size:13.5px; font-weight:600; }
.bar-track { background:var(--viz-zero); border-radius:6px; height:22px; overflow:hidden; }
.bar-fill { width:var(--w); min-width:3px; height:100%; background:var(--key); border-radius:4px; }
.bar-value { font-size:13.5px; text-align:right; font-variant-numeric:tabular-nums; }
.bar-value b { font-weight:800; }
.bar-note { display:block; font-size:11.5px; color:var(--muted); font-weight:600; }
.bar-row:hover .bar-fill, .bar-row:focus-visible .bar-fill { filter:brightness(1.12); }

/* Доли одной полосой */
.share { display:flex; gap:2px; height:34px; border-radius:8px; overflow:hidden; }
.share-seg { width:var(--w); min-width:3px; background:var(--key); }
.share-seg:hover, .share-seg:focus-visible { filter:brightness(1.12); }
.viz-legend { display:flex; flex-wrap:wrap; gap:8px 16px; margin-top:12px; }
.viz-leg { display:inline-flex; align-items:center; gap:7px; font-size:12.5px; color:var(--muted); }
.viz-swatch { width:11px; height:11px; border-radius:3px; background:var(--key); flex:none; }

/* Всплывающая подсказка. Значение впереди: читатель уже знает, на что навёл. */
.viz-tip {
  position:fixed; z-index:400; pointer-events:none; opacity:0; transition:opacity .12s;
  background:var(--panel); border:1px solid var(--line); border-radius:10px;
  box-shadow:0 8px 28px rgba(16,24,40,.18); padding:8px 12px; max-width:260px;
}
.viz-tip.on { opacity:1; }
.viz-tip-value { font-size:15px; font-weight:800; }
.viz-tip-label { font-size:12.5px; color:var(--muted); display:flex; align-items:center; gap:7px; margin-top:2px; }
.viz-tip-key { width:14px; height:2px; border-radius:2px; background:var(--key); flex:none; }

/* Таблица под графиком: то же значение без наведения */
.table-scroll { overflow-x:auto; margin-top:10px; }
.viz-table { border-collapse:collapse; width:100%; font-size:13px; }
.viz-table th, .viz-table td {
  text-align:left; padding:7px 12px 7px 0; border-bottom:1px solid var(--line);
  white-space:nowrap;
}
.viz-table td { font-variant-numeric:tabular-nums; }
.viz-table thead th { color:var(--muted); font-size:12px; font-weight:700; }
.viz-table tbody th { font-weight:600; }
.glossary .viz-table td { white-space:normal; }

/* ── Действия над бронью ─────────────────────────────────────────────────── */

.row.booking { align-items:flex-start; }
.booking-body { min-width:0; }
.booking .comment {
  margin-top:6px; padding-left:10px; border-left:2px solid var(--line);
  font-style:italic;
}
.row-actions { display:flex; gap:8px; flex-wrap:wrap; margin-top:10px; }
.mini {
  font:inherit; font-size:13px; font-weight:700; border:1px solid var(--line);
  background:var(--panel); color:var(--ink); border-radius:8px; padding:8px 12px;
  cursor:pointer; min-height:36px;
}
.mini:hover:not(:disabled) { background:var(--bg); }
.mini:disabled { opacity:.55; cursor:default; }
.mini.pri { background:var(--accent); border-color:var(--accent); color:var(--accent-ink); }
/* Опасное действие отличается цветом И словом на кнопке: цвет один опознавать
   нельзя, а «Отменить» рядом с «Принять» должно читаться без раздумий. */
.mini.danger { color:var(--crit); border-color:var(--crit-bg); background:var(--crit-bg); }
.mini.danger:hover:not(:disabled) { filter:brightness(.97); }

/* ── Диалоги ─────────────────────────────────────────────────────────────── */

.dlg {
  border:1px solid var(--line); border-radius:16px; background:var(--panel);
  color:var(--ink); padding:22px; max-width:460px; width:calc(100vw - 32px);
  box-shadow:0 24px 70px rgba(0,0,0,.28);
}
.dlg::backdrop { background:rgba(8,10,14,.5); }
.dlg-title { font-size:18px; font-weight:800; }
.dlg-text { font-size:14px; color:var(--muted); margin-top:8px; line-height:1.5; }
.dlg-group { margin-top:18px; }
.dlg-group-title { font-size:13px; font-weight:700; color:var(--muted); margin-bottom:8px; }
.dlg-empty {
  font-size:13.5px; color:var(--muted); border:1px dashed var(--line);
  border-radius:10px; padding:12px; text-align:center;
}
.dlg-actions { display:flex; gap:10px; justify-content:flex-end; margin-top:22px; flex-wrap:wrap; }
.btn.danger { background:var(--crit); border-color:var(--crit); color:#fff; }

.chips { display:flex; flex-wrap:wrap; gap:8px; max-height:240px; overflow-y:auto; }
.chip {
  font:inherit; font-size:13.5px; font-weight:700; border:1px solid var(--line);
  background:var(--bg); color:var(--ink); border-radius:9px; padding:9px 13px;
  cursor:pointer; min-height:38px;
}
.chip:hover { background:var(--panel); border-color:var(--accent); }

/* ── Сообщение о результате ──────────────────────────────────────────────── */

.toast {
  position:fixed; left:50%; transform:translateX(-50%) translateY(12px);
  bottom:calc(24px + env(safe-area-inset-bottom)); z-index:500;
  background:var(--panel); border:1px solid var(--line); border-radius:12px;
  box-shadow:0 12px 36px rgba(16,24,40,.22); padding:12px 18px;
  font-size:14px; font-weight:700; max-width:min(440px, calc(100vw - 32px));
  opacity:0; pointer-events:none; transition:opacity .18s, transform .18s;
}
.toast.on { opacity:1; transform:translateX(-50%) translateY(0); }
.toast-crit { color:var(--crit); border-color:var(--crit-bg); }
.toast-ok { color:var(--ok); }

/* ── Мобильная раскладка ─────────────────────────────────────────────────── */

@media (max-width:900px) {
  .app { grid-template-columns:1fr; }
  .side {
    position:fixed; left:0; top:0; width:262px; height:100vh; z-index:200;
    transform:translateX(-104%); transition:transform .25s ease;
  }
  .side.open { transform:translateX(0); box-shadow:0 0 44px rgba(0,0,0,.45); }
  .burger { display:inline-flex; align-items:center; justify-content:center; }
  .cols-2 { grid-template-columns:1fr; }
}

@media (max-width:640px) {
  .top {
    padding:10px 14px; padding-top:calc(10px + env(safe-area-inset-top));
    gap:8px; flex-wrap:wrap;
  }
  .venue select { max-width:44vw; }
  /* «Обновить» на телефоне занимает место ради редкого действия: на узком
     экране страницу обновляют жестом, а данные тянутся при переходе. */
  #refresh { display:none; }
  .wrap { padding:16px 14px calc(40px + env(safe-area-inset-bottom)); }
  h1.pg { font-size:20px; }
  .pg-sub { font-size:13px; }
  .kpis { gap:10px; grid-template-columns:repeat(2,1fr); }
  .kpi { padding:13px 14px; border-radius:12px; }
  .kpi .v { font-size:24px; }
  .kpi-hero .v { font-size:36px; }
  .card h2 { font-size:15px; padding:14px 15px; }
  .card-pad { padding:14px; }
  .row { padding:12px 14px; gap:10px; flex-wrap:wrap; }
  /* На телефоне время и состояние встают в первую строку, а карточка брони
     под них: иначе состояние оказывалось под кнопками, в самом низу, и его
     приходилось искать. */
  .row.booking .ico { order:0; }
  .row.booking .pill { order:1; margin-left:auto; }
  .row.booking .sp { display:none; }
  .row.booking .booking-body { order:2; width:100%; }
  /* Кнопки действий на телефоне занимают строку целиком: в три колонки они
     сжимаются до целей, в которые не попасть пальцем. */
  .row-actions { width:100%; }
  .row-actions .mini { flex:1 1 auto; justify-content:center; text-align:center; }
  .dlg { padding:18px; border-radius:14px; }
  .cols { height:170px; }
  /* Названия полос на узком экране переезжают над самой полосой: в три
     колонки они сжимаются до нечитаемых переносов. */
  .bar-row { grid-template-columns:1fr auto; grid-template-areas:"name value" "track track"; }
  .bar-name { grid-area:name; }
  .bar-value { grid-area:value; }
  .bar-track { grid-area:track; }
  .viz-legend { gap:6px 12px; }
  .seg { width:100%; }
  .seg-btn { flex:1; padding:9px 10px; }
}

/* Уважение к системной настройке «меньше движения» */
@media (prefers-reduced-motion: reduce) {
  * { transition:none !important; animation:none !important; }
}
