/* Общая вёрстка каркаса дашборда СПРУТ (сайдбар/топбар/карточки/таблицы/
   статусы) — вынесена из dashboard.html при разбивке на страницы по отделам
   (2026-08-03, architecture/modules.md). Подключается на каждой странице
   вместе с design-tokens.css/components.css. */

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

/* ---------- Каркас: сайдбар + основной контент ---------- */
/* 100vh на мобильном Safari — высота с учётом адресной строки, которая
   то есть на экране, то нет: жест (пролистывание, жест масштабирования)
   меняет её видимость на лету, и всё, что посчитано от 100vh, дёргается или
   застревает не в том размере (Анна, 11.09.2026 — меню «съехало» после
   масштабирования пальцами на телефоне). 100dvh — «динамическая» высота
   видимой области, она и должна была решать ровно это; 100vh оставлен
   первой строкой как отступление для браузеров без поддержки dvh. */
.shell { display: flex; min-height: 100vh; min-height: 100dvh; align-items: flex-start; }

.sidebar {
  width: 220px;
  flex: 0 0 220px;
  background: var(--color-surface);
  border-right: var(--border-width) solid var(--color-border);
  padding: var(--space-6) var(--space-4);
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
  overflow-y: auto;
}
.sidebar-brand {
  font-family: var(--font-heading);
  font-weight: 600;
  font-size: var(--text-md);
  line-height: var(--leading-lg);
  margin-bottom: var(--space-8);
  padding: 0 var(--space-3);
}
/* Маскот 🐙 (вордмарк СПРУТа, design-system.md §6) — на 20% крупнее текста
   рядом, чтобы читался как знак, а не как символ в строке (2026-08-08). */
.brand-emoji { font-size: 1.2em; line-height: 1; }

.sidebar-nav { display: flex; flex-direction: column; gap: var(--space-1); }
.sidebar-link {
  display: block;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  border: var(--border-width) solid transparent;
  color: var(--color-muted);
  font-size: var(--text-base);
  font-weight: 500;
  text-decoration: none;
  transition: background-color var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
}
/* Акцент меню — только --color-accent (#2F6FED). До 2026-08-09 здесь висел
   фиолетовый #5B4FC7 из сиреневой эпохи фона — второй акцент, запрещённый §6.
   Тогда же активный пункт был синей заливкой 14% — крупное цветное пятно,
   которое глаз ловит постоянно. Теперь выделение контуром, как в кабинете
   Финтабло: белая поверхность + тонкая рамка акцентом (правка 2026-08-09,
   design-system.md §7). Прозрачная рамка у покоя — чтобы строка не прыгала
   на ширину рамки при переходе в активное состояние. */
.sidebar-link:hover { background: rgba(47, 111, 237, 0.05); color: var(--color-text); }

/* Подменю раздела (25.08.2026). Команда Анны: «я нажимаю на финансы, и под
   финансами раскрывается, где есть планирование — потому что там будут ещё
   другие финансовые моменты: отчёты, ОПиУ; чтобы это всё было не на одной
   странице в каше». Раскрыто только внутри своего раздела: постоянно
   развёрнутое меню превращает боковину в список из двадцати строк. */
.sidebar-sub { display: none; flex-direction: column; gap: 2px; margin: 2px 0 var(--space-2); }
.sidebar-sub.open { display: flex; }
.sidebar-sublink {
  display: block;
  padding: var(--space-1) var(--space-3) var(--space-1) var(--space-6);
  border-radius: var(--radius-sm);
  border: var(--border-width) solid transparent;
  color: var(--color-muted);
  font-size: var(--text-sm);
  text-decoration: none;
  transition: background-color var(--transition-fast), color var(--transition-fast), border-color var(--transition-fast);
}
.sidebar-sublink:hover { background: rgba(47, 111, 237, 0.05); color: var(--color-text); }
.sidebar-sublink.active {
  background: var(--color-surface);
  border-color: var(--color-accent);
  color: var(--color-accent);
  font-weight: 600;
}
.sidebar-link.active {
  background: var(--color-surface);
  border-color: var(--color-accent);
  color: var(--color-accent);
  font-weight: 600;
}

/* Волшебный режим — единственный пункт меню, который выглядит иначе.
   Просьба Анны 21.08.2026: «сделай вот эту кнопку волшебный режим — пусть она
   будет волшебная». Повод серьёзнее, чем украшение: это раздел, ради которого
   у неё поднимается энергия («у меня мурашки, я сижу улыбаюсь, ещё ничего не
   произошло»), и он не должен теряться в списке рабочих отделов.

   Что здесь НЕ нарушено (design-system.md §6): второго акцентного цвета нет —
   вся «магия» сделана прозрачностями одного #2F6FED; градиент одноцветный
   (меняется только альфа), как в заливке графика выручки; иконка — SVG, а не
   эмодзи. Движение выключается системной настройкой «уменьшить движение». */
.sidebar-link--magic { position: relative; overflow: hidden; }
.sidebar-link--magic .magic-spark {
  width: 14px; height: 14px; margin-right: 6px;
  vertical-align: -2px; color: var(--color-accent);
  animation: magic-twinkle 3.4s ease-in-out infinite;
}
.sidebar-link--magic::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(100deg,
    rgba(47, 111, 237, 0) 35%,
    rgba(47, 111, 237, 0.14) 50%,
    rgba(47, 111, 237, 0) 65%);
  transform: translateX(-120%);
  animation: magic-sweep 6s ease-in-out infinite;
  pointer-events: none;
}
.sidebar-link--magic:hover .magic-spark { color: var(--color-accent); }

@keyframes magic-twinkle {
  0%, 70%, 100% { opacity: .55; transform: scale(1); }
  80% { opacity: 1; transform: scale(1.18); }
}
@keyframes magic-sweep {
  0%, 55% { transform: translateX(-120%); }
  85%, 100% { transform: translateX(120%); }
}
@media (prefers-reduced-motion: reduce) {
  .sidebar-link--magic .magic-spark,
  .sidebar-link--magic::after { animation: none; }
  .sidebar-link--magic .magic-spark { opacity: 1; }
}

.sidebar-backdrop { display: none; }

.sidebar-toggle {
  display: none;
  width: 40px; height: 40px;
  align-items: center; justify-content: center;
  border-radius: var(--radius-md);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface);
  cursor: pointer;
  font-size: var(--text-md);
  flex: 0 0 auto;
}

.main { flex: 1; min-width: 0; padding: var(--space-8); }

/* ---------- Топ-бар ---------- */
.topbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-4);
  flex-wrap: wrap;
  margin-bottom: var(--space-6);
}
.topbar-left { display: flex; align-items: center; gap: var(--space-3); }
.topbar-right { display: flex; flex-direction: column; align-items: flex-end; gap: var(--space-1); }
.topbar h1 { font-size: var(--text-lg); line-height: var(--leading-lg); margin: 0; }
.sub { color: var(--color-muted); font-size: var(--text-sm); margin-top: var(--space-1); }
.topbar-note { color: var(--color-muted); font-size: var(--text-xs); }

.badge {
  display: inline-flex;
  align-items: center;
  padding: 4px 10px;
  border-radius: var(--radius-sm);
  font-size: var(--text-xs);
  font-weight: 600;
}
.badge.sandbox { background: var(--color-bg); color: var(--color-muted); border: var(--border-width) solid var(--color-border); }
.badge.offline { background: rgba(208, 65, 58, 0.12); color: var(--color-danger); border: var(--border-width) solid rgba(208, 65, 58, 0.35); }

#error-banner {
  display: none;
  background: rgba(208, 65, 58, 0.10);
  border: var(--border-width) solid rgba(208, 65, 58, 0.35);
  color: var(--color-danger);
  padding: var(--space-3) var(--space-4);
  border-radius: var(--radius-sm);
  margin-bottom: var(--space-6);
  font-size: var(--text-sm);
}

/* ---------- Секции / карточки ---------- */
/* Селектор был сужен до тега `section` и не касался `<details class=
   "page-section">` (сворачиваемые разделы — ceo.html, finance.html,
   marketing.html): между такой карточкой и следующим заголовком не было ни
   пикселя отступа (найдено 09.09.2026 на /ceo — «Школа директора» вплотную
   к «Команда и её планы»). Правило .hyp-list > .page-section { margin-bottom:
   0 } в hypotheses.css уже сбрасывает именно этот отступ — значит его
   и раньше считали общим для всех .page-section, а не только для <section>. */
.page-section { margin-bottom: var(--space-6); scroll-margin-top: var(--space-6); }

/* Заголовок карточки — один размер на весь дашборд (--text-md), без
   «своего, чуть другого» кегля у отдельных карточек: правило §7
   design/design-system.md, 2026-08-06. */
.card h2 {
  font-size: var(--text-md);
  line-height: var(--leading-md);
  color: var(--color-text);
  margin: 0 0 var(--space-4) 0;
}
.hero-card h2, .risks-card h2 {
  display: flex;
  align-items: center;
  gap: var(--space-2);
}
.agent-avatar {
  width: 32px; height: 32px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  font-family: var(--font-heading); font-weight: 700; font-size: var(--text-sm);
  color: #FFFFFF; flex: 0 0 auto;
}
.agent-icon {
  width: 32px; height: 32px; border-radius: var(--radius-md);
  overflow: hidden; display: inline-flex; flex: 0 0 auto;
  border: var(--border-width) solid var(--color-border);
}
.agent-icon svg { display: block; width: 100%; height: 100%; }
.source-dot { display: inline-block; width: 9px; height: 9px; border-radius: 50%; margin-right: var(--space-2); vertical-align: middle; flex: 0 0 auto; }

.grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(420px, 1fr));
  gap: var(--card-gutter);
}
.grid > * { min-width: 0; }

.empty { color: var(--color-muted); font-size: var(--text-sm); padding: var(--space-2) 0; }

/* Пустая карточка с морской картинкой вместо сухого «нет данных»
   (design/design-system.md §7, правка 2026-08-09). Ставится только там, где
   данных действительно нет: у «загрузка…» и у сообщений об ошибке картинки
   быть не должно — это разные состояния, и картинка их бы уравняла.
   --seaweed — данных ещё нет; --octopus — пусто, и это нормально.
   До 09.08.2026 «данных ещё нет» рисовалось ракушкой — заменено на водоросли
   (решение Анны), толщина линии выровнена с осьминогом. */
.empty-art {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-6) 0;
  color: var(--color-muted);
  font-size: var(--text-sm);
  text-align: center;
}
.empty-art::before {
  content: "";
  width: 56px;
  height: 56px;
  background-repeat: no-repeat;
  background-position: center;
  background-size: contain;
  opacity: 0.42;
}
.empty-art--seaweed::before { background-image: url("/static/empty-seaweed.svg"); }
.empty-art--octopus::before { background-image: url("/static/empty-octopus.svg"); }

/* ---------- Таблицы (наследуют .table из components.css) ---------- */
#agents, #pipeline-tasks, #decisions, #reports, #lead-sources-daily, #risks { overflow-x: auto; }
table { width: 100%; min-width: 480px; border-collapse: collapse; font-size: var(--text-sm); }
th, td { text-align: left; padding: var(--space-2) var(--space-3); border-bottom: var(--border-width) solid var(--color-border); vertical-align: top; }
th { color: var(--color-muted); font-weight: 500; font-size: var(--text-xs); letter-spacing: 0.02em; }
tr:last-child td { border-bottom: none; }

/* Моноширинный остался ровно в одном месте — в коде и путях к файлам, где
   он и нужен. В цифрах его нет: правило Анны 25.08.2026 (см. components.css). */
code { font-size: var(--text-xs); color: var(--color-muted); font-family: var(--font-mono); }

/* ---------- Статусы: точки/бейджи ---------- */
.dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: var(--space-2); }
.dot.idle, .dot.initialized { background: var(--color-success); }
.dot.executing { background: var(--color-accent); }
.dot.error { background: var(--color-danger); }
.dot.external { background: var(--color-accent); }

.status-pill { padding: 2px 8px; border-radius: var(--radius-sm); font-size: var(--text-xs); font-weight: 600; }
.status-pending { background: rgba(47, 111, 237, 0.10); color: var(--color-accent); }
.status-approved { background: var(--color-bg); color: var(--color-muted); }
.status-executing { background: rgba(47, 111, 237, 0.10); color: var(--color-accent); }
.status-completed { background: rgba(26, 157, 108, 0.12); color: var(--color-success); }
.status-failed, .status-timeout { background: rgba(208, 65, 58, 0.12); color: var(--color-danger); }
/* Отклонено человеком — не ошибка, а решение владельца: нейтральный серый,
   не красный (05.08.2026). */
.status-rejected { background: var(--color-bg); color: var(--color-muted); }
.status-success, .status-resolved { background: rgba(26, 157, 108, 0.12); color: var(--color-success); }
.status-error { background: rgba(208, 65, 58, 0.12); color: var(--color-danger); }
.status-open { background: var(--color-bg); color: var(--color-muted); }

/* ---------- Отчёт агентов за день (renderDailyReport в common.js) ---------- */
.day-report { display: flex; flex-direction: column; }
.day-item {
  display: grid;
  grid-template-columns: 52px minmax(140px, 200px) 1fr;
  gap: var(--space-3);
  align-items: baseline;
  padding: var(--space-3) 0;
  border-bottom: var(--border-width) solid var(--color-border);
  font-size: var(--text-sm);
}
.day-item:last-child { border-bottom: none; }
.day-time { color: var(--color-muted); font-variant-numeric: tabular-nums; font-size: var(--text-xs); }
.day-agent { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--color-muted); min-width: 0; }
.day-agent .agent-icon, .day-agent .agent-avatar { width: 20px; height: 20px; font-size: var(--text-xs); border-radius: var(--radius-sm); }
.day-text { color: var(--color-text); min-width: 0; }
.day-text .status-pill { margin-left: var(--space-1); white-space: nowrap; }
.day-detail { color: var(--color-muted); font-size: var(--text-xs); margin-top: 2px; }

@media (max-width: 700px) {
  .day-item { grid-template-columns: 52px 1fr; }
  .day-agent { grid-column: 2; }
  .day-text { grid-column: 2; }
}

/* ---------- Что вышло на сайт (renderPublications в common.js) ----------
   Лента публикаций Статейника на /content: дата и заголовок статьи, по строке
   на публикацию. Своя сетка, а не .day-item: там три колонки (время, агент,
   текст), здесь агент всегда один и колонка под него была бы пустой.
   Дата набрана тем же кеглем, что и заголовок, отличается только цветом —
   §7 дизайн-системы, правка 06.08.2026: внутри одного блока кегль не скачет. */
.pub-list { display: flex; flex-direction: column; }
.pub-item {
  display: grid;
  grid-template-columns: 120px 1fr;
  gap: var(--space-3);
  align-items: baseline;
  padding: var(--space-3) 0;
  border-bottom: var(--border-width) solid var(--color-border);
}
.pub-item:last-child { border-bottom: none; }
.pub-date { color: var(--color-muted); font-variant-numeric: tabular-nums; }
.pub-title { color: var(--color-text); min-width: 0; }
/* Общего стиля ссылок в дашборде не было — до этой ленты кликабельных ссылок
   в тексте карточек не встречалось. Браузерный дефолт (сине-фиолетовый,
   подчёркнутый) вводит на экран цвет, которого нет в палитре, поэтому ссылка
   красится акцентом; подчёркивание — только при наведении. */
.pub-title a { color: var(--color-accent); text-decoration: none; }
.pub-title a:hover { text-decoration: underline; }

@media (max-width: 700px) {
  .pub-item { grid-template-columns: 1fr; gap: var(--space-1); }
}

/* ---------- Итог дня на дашборде (renderDailySummary в common.js) ----------
   Свод вместо ленты: одна строка на действие с числом слева, чтобы 40 писем
   рассылки читались одной строкой «40 · выполнено: письмо клиенту»
   (06.08.2026). Лента .day-report выше осталась на страницах отделов. */
.day-summary { display: flex; flex-direction: column; gap: var(--space-4); }
.day-sum-agent { display: flex; flex-direction: column; gap: var(--space-2); }
.day-sum-head { display: flex; align-items: center; gap: var(--space-2); }
.day-sum-head .agent-icon, .day-sum-head .agent-avatar { width: 20px; height: 20px; font-size: var(--text-xs); border-radius: var(--radius-sm); }
.day-sum-name { font-weight: 700; color: var(--color-text); font-size: var(--text-sm); }
.day-sum-last { color: var(--color-muted); font-size: var(--text-xs); margin-left: auto; font-variant-numeric: tabular-nums; }
.day-sum-line {
  display: grid;
  grid-template-columns: 56px 1fr;
  gap: var(--space-3);
  align-items: baseline;
  padding: var(--space-2) 0;
  border-bottom: var(--border-width) solid var(--color-border);
  font-size: var(--text-sm);
}
.day-sum-agent .day-sum-line:last-child { border-bottom: none; }
.day-sum-count { font-weight: 700; font-variant-numeric: tabular-nums; text-align: right; }
.day-sum-text { color: var(--color-text); min-width: 0; }
.day-sum-line.tone-ok .day-sum-count { color: var(--color-success); }
.day-sum-line.tone-warn .day-sum-count { color: var(--color-accent); }
.day-sum-line.tone-bad .day-sum-count { color: var(--color-danger); }

.btn-chip {
  font-size: var(--text-xs);
  font-weight: 600;
  padding: 3px 10px;
  border-radius: var(--radius-sm);
  border: var(--border-width) solid var(--color-border);
  background: var(--color-surface);
  color: var(--color-text);
  cursor: pointer;
  transition: background-color var(--transition-fast), transform var(--transition-fast), border-color var(--transition-fast);
}
.btn-chip:hover { background: rgba(47, 111, 237, 0.06); border-color: rgba(47, 111, 237, 0.4); }
.btn-chip:active { transform: scale(0.98); }

.triggered-yes { color: var(--color-success); font-weight: 600; }
.triggered-no { color: var(--color-muted); }

.schedule-item { margin-bottom: var(--space-3); padding-bottom: var(--space-3); border-bottom: var(--border-width) solid var(--color-border); }
.schedule-item:last-child { margin-bottom: 0; padding-bottom: 0; border-bottom: none; }
.schedule-item h3 { font-size: var(--text-sm); margin: 0 0 var(--space-1) 0; font-family: var(--font-body); font-weight: 600; }
.schedule-item .row { font-size: var(--text-sm); color: var(--color-muted); }
.schedule-item .row b { color: var(--color-text); font-weight: 500; }
.sched-running { color: var(--color-success); font-weight: 600; }
.sched-stopped { color: var(--color-muted); }

.report-status-success { color: var(--color-success); font-weight: 600; }
.report-status-error { color: var(--color-danger); font-weight: 600; }
.report-status-pending { color: var(--color-muted); font-weight: 600; }

.metrics-source { margin-bottom: var(--space-4); }
.metrics-source:last-child { margin-bottom: 0; }
/* h3 везде одного кегля (--text-sm), как у .schedule-item h3 — акцент здесь
   даётся цветом и начертанием, не уменьшенным размером (§7, 2026-08-06). */
.metrics-source h3 { font-size: var(--text-sm); color: var(--color-accent); margin: 0 0 var(--space-2) 0; font-weight: 700; }
.metrics-kv { display: flex; flex-wrap: wrap; gap: var(--space-2) var(--space-4); font-size: var(--text-sm); }
.metrics-kv span.k { color: var(--color-muted); }

.risk-dot { display: inline-block; width: 10px; height: 10px; border-radius: 50%; }
.risk-dot.critical { background: var(--color-danger); }
.risk-dot.warning { background: var(--color-accent); }
.risk-dot.info { background: var(--color-muted); }
.risk-desc { color: var(--color-muted); font-size: var(--text-xs); margin-top: 2px; }
/* Длинное описание находки свёрнуто до трёх строк — разворачивается кнопкой
   «показать целиком» (static/common.js, правка 27.08.2026). */
.risk-desc--clip {
  display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden;
}
.risk-more { margin-top: var(--space-2); }

/* ---------- Hero: план продаж ---------- */
.hero-card { margin-bottom: var(--space-6); }
.hero-body { display: grid; grid-template-columns: 1fr; gap: var(--space-8); align-items: stretch; }
.hero-body > * { min-width: 0; }

/* Переключатель месяца — один цельный блок на светло-сером фоне, стрелки
   внутри него без собственных рамок и кубиков (правка 2026-08-06). */
.month-nav {
  display: inline-flex; align-items: center; gap: var(--space-2);
  margin-bottom: var(--space-4);
  padding: var(--space-2) var(--space-3);
  background: var(--color-bg); border-radius: var(--radius-md);
}
.month-nav-btn {
  width: 28px; height: 28px; border-radius: var(--radius-sm);
  border: none; background: transparent;
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  color: var(--color-text); font-size: var(--text-lg); line-height: 1;
  transition: background-color var(--transition-fast), transform var(--transition-fast);
}
.month-nav-btn:hover { background: var(--color-surface); }
.month-nav-btn:active { transform: scale(0.94); }
.month-nav-btn:disabled { opacity: 0.4; cursor: not-allowed; }
.month-nav-label { font-size: var(--text-sm); font-weight: 600; color: var(--color-text); min-width: 110px; text-align: center; }

.sales-row { display: flex; align-items: flex-end; gap: var(--space-6); flex-wrap: wrap; margin-bottom: var(--space-3); }
/* Все денежные суммы карточки (факт, план, поступления) — один класс:
   одинаковый кегль и одинаковое начертание, разница между ними передаётся
   подписью и цветом, не размером (правило §7 design/design-system.md,
   2026-08-06). Отдельного мелкого стиля для поступлений больше нет. */
.sales-num { font-family: var(--font-heading); font-variant-numeric: tabular-nums; font-size: var(--text-2xl); line-height: var(--leading-2xl); font-weight: 600; }
.sales-num .cur { font-size: var(--text-md); font-weight: 500; color: var(--color-muted); font-family: var(--font-body); }
.sales-num-plan { color: var(--color-accent-active); }
/* Дельта к прошлому месяцу — значок у самой суммы, не строка текста
   (27.08.2026: сравнение сначала вышло лишней строкой в «Пульсе», Анна
   остановила — «мы уходим от этих простыней»). Полупрозрачная заливка + текст
   того же цвета — форма бейджа из §1 дизайн-системы; кегль xs — тот, что §1
   и отводит бейджам. */
.sales-delta {
  display: inline-flex; align-items: center; gap: 4px;
  margin-left: var(--space-3); padding: 3px 8px;
  border-radius: var(--radius-sm);
  font-family: var(--font-heading); font-size: var(--text-xs); font-weight: 600;
  font-variant-numeric: tabular-nums; line-height: 1.2;
  vertical-align: middle;
  cursor: default;
}
.sales-delta svg { width: 8px; height: 8px; fill: currentColor; }
.sales-delta.up { background: rgba(26, 157, 108, 0.12); color: var(--color-success); }
.sales-delta.down { background: rgba(208, 65, 58, 0.12); color: var(--color-danger); }
.sales-num-placeholder { font-size: var(--text-md); font-weight: 500; color: var(--color-muted); font-family: var(--font-body); display: inline-block; }
.sales-num-placeholder-danger { color: var(--color-danger); }
.sales-label { font-size: var(--text-sm); color: var(--color-text); margin-bottom: var(--space-1); }
.sales-pct { font-size: var(--text-base); font-weight: 600; }
.sales-cash-row { margin-top: var(--space-4); padding-top: var(--space-3); border-top: var(--border-width) solid var(--color-border); }
.sales-bar-track { width: 100%; height: 8px; border-radius: var(--radius-sm); background: var(--color-bg); overflow: hidden; margin-bottom: var(--space-2); }
.sales-bar-fill { height: 100%; border-radius: var(--radius-sm); background: var(--color-success); transition: width 0.3s ease; }
.sales-bar-fill.low { background: var(--color-danger); }
.sales-bar-fill.mid { background: var(--color-accent); }
.sales-period { font-size: var(--text-xs); color: var(--color-muted); }

/* ---------- Каналы: откуда пришли деньги месяца (МойСклад) ---------- */
/* Внутри блока кегль не прыгает — все строки --text-md, как в «Пульсе»
   (правило §7 design/design-system.md, 2026-08-06). «Сайт» и «Авито» выделены
   начертанием и цветом полосы, не размером шрифта. Второй акцентный цвет не
   вводится: полоса — тот же синий --color-accent, у второстепенных каналов он
   же с прозрачностью. */
.channel-row { margin-bottom: var(--space-4); }
.channel-row:last-child { margin-bottom: 0; }
.channel-head { display: flex; align-items: baseline; justify-content: space-between; gap: var(--space-4); margin-bottom: var(--space-2); }
.channel-title { font-size: var(--text-md); line-height: var(--leading-md); color: var(--color-text); }
.channel-sum { font-size: var(--text-md); line-height: var(--leading-md); font-weight: 500; font-variant-numeric: tabular-nums; white-space: nowrap; }
.channel-sum .cur { color: var(--color-muted); }
.channel-note { font-size: var(--text-md); line-height: var(--leading-md); color: var(--color-muted); }
.channel-spend { font-size: var(--text-md); line-height: var(--leading-md); color: var(--color-muted); margin-top: var(--space-1); }
.channel-bar { background: rgba(47, 111, 237, 0.35); }

.channel-row-main .channel-title { font-weight: 600; }
.channel-row-main .channel-sum { font-weight: 600; color: var(--color-accent-active); }
.channel-row-main .channel-bar { background: var(--color-accent); }

/* Каналы вне двух главных — тем же кеглем, но отделены линией: это фон, а не
   то, ради чего блок открывают. */
.channel-rest { margin-top: var(--space-4); padding-top: var(--space-4); border-top: var(--border-width) solid var(--color-border); }
.channel-row-unassigned .channel-title { color: var(--color-muted); }
.channel-total {
  margin-top: var(--space-4); padding-top: var(--space-3);
  border-top: var(--border-width) solid var(--color-border);
  font-size: var(--text-md); line-height: var(--leading-md); color: var(--color-muted);
}

/* ---------- Пульс: вердикт "идём к цели / отстаём" + действие на сегодня ---------- */
/* Отступ под линией — --space-6: токена --space-5 в системе нет, из-за
   опечатки margin-bottom не применялся вообще и переключатель месяца
   прилипал к разделительной линии (правка 2026-08-06). */
.pulse-block { margin-bottom: var(--space-6); padding-bottom: var(--space-4); border-bottom: var(--border-width) solid var(--color-border); }
.pulse-pill { display: inline-block; margin-bottom: var(--space-4); font-size: var(--text-sm); padding: 5px 14px; }
/* Все строки блока — один кегль (--text-md): внутри одного блока размер
   шрифта не прыгает от строки к строке, акцент даётся начертанием и
   иконкой, не размером (правило §7 design/design-system.md, 2026-08-06). */
.pulse-verdict { font-size: var(--text-md); line-height: var(--leading-md); color: var(--color-text); margin-bottom: var(--space-2); }
.pulse-need {
  display: flex; align-items: baseline; gap: var(--space-2);
  font-size: var(--text-md); line-height: var(--leading-md); color: var(--color-text);
  margin-bottom: var(--space-3);
}
.pulse-need-icon { font-size: inherit; line-height: inherit; }
.sales-target-edit { display: flex; align-items: center; gap: var(--space-2); margin-top: var(--space-3); font-size: var(--text-sm); flex-wrap: wrap; }
.sales-target-edit input {
  width: 140px; padding: 8px 10px; border: var(--border-width) solid var(--color-border); border-radius: var(--radius-sm);
  font-size: var(--text-sm); font-family: inherit;
}
.sales-target-edit input:focus { outline: none; border-color: var(--color-accent); box-shadow: 0 0 0 3px rgba(47, 111, 237, 0.15); }
.sales-target-edit .saved { color: var(--color-success); font-size: var(--text-xs); }

/* ---------- «Заявки по дням — Авито и Сайт» — две параллельные линии ----------
   Обе линии синие (--color-accent-active — Авито, --color-accent — Сайт) —
   §6 дизайн-системы запрещает второй акцентный цвет, идентичность линии
   несёт легенда и подпись в тултипе, не второй тон. Легенда и тултип
   помечают серию короткой линией, не квадратом («line keys, not boxes»,
   interaction.md) — так же читается сам график. */
/* Шапка блока с выбором периода (правка 2026-08-27): заголовок слева, чипы
   «Месяц / Квартал / Год» справа. Чипы — того же семейства, что .audit-chip,
   второго стиля кнопок под ту же роль в системе не заводим. */
.chart-head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-4);
}
.chart-head h2 { margin: 0; }
.period-chips { display: flex; gap: var(--space-2); flex-wrap: wrap; }

/* «Было → стало» под графиком — закон Анны 2026-08-25: период сравнивается с
   предыдущим таким же, и только цифрами. Зелёный/красный здесь не второй
   акцент, а конвенция полярности (§6 дизайн-системы). */
.daily-summary {
  display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2) var(--space-6);
  margin-bottom: var(--space-3); font-size: var(--text-sm); line-height: var(--leading-sm);
  color: var(--color-text);
}
/* Подпись периода — своей строкой под цифрами: в одном ряду с ними она
   слипалась с последним каналом (поймано на скриншоте 27.08.2026). */
.daily-summary-note { flex-basis: 100%; }
.daily-summary-item { display: inline-flex; align-items: baseline; gap: var(--space-2); }
.daily-summary-item b { font-weight: 600; font-variant-numeric: tabular-nums; }
.daily-delta { font-size: var(--text-xs); font-variant-numeric: tabular-nums; }
.daily-delta.up { color: var(--color-success); }
.daily-delta.down { color: var(--color-danger); }
.daily-delta.flat { color: var(--color-muted); }
.daily-summary-note { color: var(--color-muted); font-size: var(--text-xs); }
.daily-summary-gap { color: var(--color-muted); font-size: var(--text-xs); margin-bottom: var(--space-3); }

.daily-chart-legend { display: flex; gap: var(--space-4); margin-bottom: var(--space-3); }
.daily-legend-item { display: inline-flex; align-items: center; gap: var(--space-2); font-size: var(--text-xs); color: var(--color-muted); }
.daily-legend-swatch { width: 14px; height: 3px; border-radius: 2px; flex: 0 0 auto; }

.daily-chart-wrap { position: relative; }
.daily-chart-svg { width: 100%; height: 170px; display: block; }
.daily-grid-line { stroke: var(--color-border); stroke-width: 1; }
.daily-axis-label { fill: var(--color-muted); font-family: var(--font-body); font-size: var(--text-xs); letter-spacing: 0.02em; }
.daily-line { fill: none; stroke-width: 2; stroke-linejoin: round; stroke-linecap: round; }
.daily-dot { opacity: 0.9; }
.daily-hover-dot { stroke: var(--color-surface); stroke-width: 2; }
.daily-crosshair { stroke: var(--color-border); stroke-width: 1; }
.daily-hit { fill: transparent; cursor: pointer; }

.daily-tooltip {
  position: absolute; z-index: 5; pointer-events: none;
  background: var(--color-surface); border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-sm);
  padding: var(--space-2) var(--space-3); min-width: 150px;
}
.daily-tooltip-date { font-size: var(--text-xs); color: var(--color-muted); margin-bottom: var(--space-1); }
.daily-tooltip-row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); font-size: var(--text-sm); padding: 2px 0; }
.daily-tooltip-key { display: inline-flex; align-items: center; gap: var(--space-2); color: var(--color-text); }
.daily-tooltip-swatch { width: 12px; height: 2px; border-radius: 1px; flex: 0 0 auto; }
.daily-tooltip-val { color: var(--color-text); font-weight: 600; font-variant-numeric: tabular-nums; }
.daily-tooltip-total { border-top: var(--border-width) solid var(--color-border); margin-top: var(--space-1); padding-top: var(--space-2); }

.chart-table-details { margin-top: var(--space-3); }
.chart-table-details > summary { cursor: pointer; list-style: none; color: var(--color-muted); font-size: var(--text-xs); padding: var(--space-1) 0; }
.chart-table-details > summary::-webkit-details-marker { display: none; }
.chart-table-details > summary::before { content: "Показать ▸ "; }
.chart-table-details[open] > summary::before { content: "Скрыть ▾ "; }
.chart-table-details table { margin-top: var(--space-2); }

/* ---------- Очередь фоновых задач ---------- */
.pipeline-form { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-4); flex-wrap: wrap; }
.pipeline-form select {
  padding: 8px 10px; border: var(--border-width) solid var(--color-border); border-radius: var(--radius-sm);
  font-size: var(--text-sm); font-family: inherit; background: var(--color-surface);
  min-width: 0; max-width: 100%; flex: 1 1 240px;
}
.pipeline-form select:focus { outline: none; border-color: var(--color-accent); box-shadow: 0 0 0 3px rgba(47, 111, 237, 0.15); }
.pipeline-tick-button { border-color: var(--color-accent); color: var(--color-accent); }
.pipeline-live-dot { display: inline-block; width: 6px; height: 6px; border-radius: 50%; background: var(--color-accent); margin-right: var(--space-2); }

.pipeline-status-pending { background: var(--color-bg); color: var(--color-muted); }
.pipeline-status-processing { background: rgba(47, 111, 237, 0.10); color: var(--color-accent); }
.pipeline-status-done { background: rgba(26, 157, 108, 0.12); color: var(--color-success); }
.pipeline-status-failed { background: rgba(208, 65, 58, 0.12); color: var(--color-danger); }

/* ---------- Аудит кабинета Директа (страница маркетинга) ----------
   Разбор чек-листа: шапка с датой прогона и вердиктом ревьюера, счётчики,
   находки по приоритетам. Внутри блока находки кегль один на все строки —
   что/почему/основание/что сделать различаются цветом и начертанием, но не
   размером (design/design-system.md §7, правка 2026-08-06). */
.audit-card { margin-bottom: var(--space-6); }
.audit-head { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2) var(--space-3); margin-bottom: var(--space-4); }
.audit-meta { color: var(--color-muted); font-size: var(--text-sm); line-height: var(--leading-sm); }
.audit-warning {
  background: rgba(208, 65, 58, 0.10);
  color: var(--color-danger);
  border-radius: var(--radius-sm);
  padding: var(--space-3) var(--space-4);
  font-size: var(--text-sm);
  line-height: var(--leading-sm);
  margin-bottom: var(--space-4);
}
.audit-counts {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
  gap: var(--space-4);
  padding-bottom: var(--space-4);
  border-bottom: var(--border-width) solid var(--color-border);
}
.audit-count-num {
  font-family: var(--font-heading);
  font-size: var(--text-xl);
  line-height: var(--leading-xl);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.audit-count-num.tone-bad { color: var(--color-danger); }
.audit-count-num.tone-ok { color: var(--color-success); }
.audit-count-num.tone-accent { color: var(--color-accent); }
.audit-count-label { font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--color-muted); }

/* Переключатель кампаний: работаем с одной, но остальные включённые — в один
   клик, не спрятаны. Кнопки того же семейства, что .btn-chip. */
.audit-chips { display: flex; flex-wrap: wrap; gap: var(--space-2); margin: var(--space-4) 0; }
.audit-chip {
  background: transparent;
  border: var(--border-width) solid var(--color-border);
  border-radius: var(--radius-sm);
  padding: 6px 12px;
  font-family: var(--font-body);
  font-size: var(--text-sm);
  line-height: var(--leading-sm);
  color: var(--color-text);
  cursor: pointer;
  transition: background-color var(--transition-fast), border-color var(--transition-fast);
}
.audit-chip:hover { background: rgba(47, 111, 237, 0.06); border-color: rgba(47, 111, 237, 0.4); }
.audit-chip:active { transform: scale(0.98); }
.audit-chip.active { background: rgba(47, 111, 237, 0.12); border-color: var(--color-accent); color: var(--color-accent); font-weight: 600; }
.audit-filter-note { font-size: var(--text-sm); line-height: var(--leading-sm); color: var(--color-muted); margin-bottom: var(--space-2); }

.audit-group { border-bottom: var(--border-width) solid var(--color-border); }
.audit-group > summary {
  display: flex; align-items: center; gap: var(--space-2);
  cursor: pointer;
  list-style: none;
  padding: var(--space-4) 0;
  font-family: var(--font-heading);
  font-size: var(--text-sm);
  line-height: var(--leading-sm);
  font-weight: 600;
}
/* Стрелка раскрытия — SVG, не текстовый треугольник и не эмодзи
   (design/design-system.md §6: функциональные иконки только SVG). */
.audit-group > summary::-webkit-details-marker { display: none; }
.audit-caret { margin-left: auto; color: var(--color-muted); transition: transform var(--transition-fast); flex: 0 0 auto; }
.audit-group[open] > summary .audit-caret { transform: rotate(180deg); }
.audit-group-body { padding-bottom: var(--space-4); }

.audit-finding { padding: var(--space-3) 0; border-bottom: var(--border-width) solid var(--color-border); }
.audit-finding:last-child { border-bottom: none; }
.audit-finding-head { display: flex; align-items: center; gap: var(--space-2); margin-bottom: var(--space-1); }
.audit-check { font-family: var(--font-heading); font-size: var(--text-base); color: var(--color-accent); }
.audit-title { font-size: var(--text-base); color: var(--color-muted); }
.audit-campaign { font-size: var(--text-base); color: var(--color-muted); }
.audit-campaign::before { content: "· "; }
.audit-line { font-size: var(--text-base); line-height: var(--leading-base); }
.audit-line .k { color: var(--color-muted); }
.audit-what { font-weight: 600; }
.audit-examples { margin: var(--space-2) 0 0; padding-left: var(--space-6); color: var(--color-muted); font-size: var(--text-base); line-height: var(--leading-base); }

.audit-disclaimers { margin-top: var(--space-4); color: var(--color-muted); font-size: var(--text-sm); line-height: var(--leading-sm); }
.audit-disclaimers-title { font-weight: 600; margin-bottom: var(--space-2); }
.audit-disclaimers ul { margin: 0; padding-left: var(--space-6); }

.fade-in { animation: card-fade-in 200ms ease-out; }
@keyframes card-fade-in { from { opacity: 0; } to { opacity: 1; } }

/* ---------- Адаптив ---------- */
@media (max-width: 768px) {
  .sidebar {
    position: fixed;
    left: 0; top: 0;
    width: 260px;
    transform: translateX(-100%);
    transition: transform var(--transition-panel);
    z-index: 40;
    box-shadow: var(--shadow-md);
  }
  .sidebar.open { transform: translateX(0); }
  .sidebar-backdrop.open {
    display: block;
    position: fixed; inset: 0;
    background: rgba(26, 26, 26, 0.4);
    z-index: 35;
  }
  .sidebar-toggle { display: inline-flex; }
  .main { padding: var(--space-4); }
  .grid { grid-template-columns: 1fr; }
  .card { padding: var(--space-4); }
  .pipeline-live-dot { display: none; }
  /* 44 px — и у пунктов, и у подпунктов: подпункт «Совет директоров» жил
     30-пиксельным, палец в него не попадал (найдено прогоном 28.08.2026). */
  .sidebar-link,
  .sidebar-sublink { min-height: 44px; display: flex; align-items: center; }
  .sidebar-toggle { width: 44px; height: 44px; }
  .month-nav-btn { width: 44px; height: 44px; }
  .btn-chip {
    display: inline-flex; align-items: center; justify-content: center;
    min-height: 44px; padding: 10px 16px;
  }
  .sales-target-edit input,
  .pipeline-form select,
  .dialog-panel .field-input {
    font-size: var(--text-md);
    min-height: 44px;
  }
  .sales-pct { font-size: var(--text-md); }
}

/* ---------- «Было → стало» по кабинету Директа (Фаза 9 плана 2026-08-06) ----
   Блок стоит над находками: он отвечает на вопрос «изменилось ли что-то от
   нашей работы». Цифры — Golos Text с табличными нулями, без моноширинного
   (правило Анны 25.08.2026). Строки-подробности набраны тем же кеглем, что
   и остальной блок, и отличаются цветом, а не размером. */
.changes-table td.num, .changes-table th.num { text-align: right; }
.changes-table td.num {
  font-family: var(--font-heading);
  font-variant-numeric: tabular-nums;
  font-weight: 600;
  white-space: nowrap;
}
.changes-table td.num.tone-ok { color: var(--color-success); }
.changes-table td.num.tone-bad { color: var(--color-danger); }
.changes-detail td { color: var(--color-muted); padding-top: 0; padding-left: var(--space-6); }
.changes-detail td::before { content: "· "; }
.changes-none { color: var(--color-muted); font-size: var(--text-sm); line-height: var(--leading-sm); padding: var(--space-3) 0; }
.changes-findings { margin-top: var(--space-4); padding-top: var(--space-4); border-top: var(--border-width) solid var(--color-border); }
.changes-sub { font-size: var(--text-sm); line-height: var(--leading-sm); }
.changes-sub-title { margin-top: var(--space-3); font-size: var(--text-sm); color: var(--color-muted); }

/* ---------- Таблица на узком экране ----------
   Широкая таблица прокручивается сама внутри своего места, а не тянет всю
   страницу вбок. Повод (замер 27.08.2026 на ширине 390 px): «Финансы»,
   «Планирование» и «Гипотезы» ехали по горизонтали на 106 px — страница
   «вылезала за рамки» ровно на min-width таблицы. Минимальная ширина нужна,
   чтобы колонки не слипались, поэтому её не убирают, а перекладывают на
   внутреннюю таблицу: у элемента display:block содержимое thead и tbody
   остаётся ОДНОЙ анонимной таблицей, и колонки продолжают совпадать. */
@media (max-width: 720px) {
  table { display: block; overflow-x: auto; max-width: 100%; }
  table, table.weeks-table { min-width: 0; }
}

/* ---------- Риски на узком экране: карточка вместо таблицы ----------
   «Риски и рекомендации — общее окно всех агентов» — шесть колонок (важность,
   когда, агент, что нашёл, что нужно от вас, кнопка). В 390 px они не
   помещаются ни при каком кегле, и правило выше (table { overflow-x: auto })
   спасало страницу ценой того, что само окно ездит вбок: Анна читала находки,
   двигая их пальцем влево-вправо (её слова 28.08.2026: «плавает внутри, надо
   двигать туда-сюда»).

   Поэтому на телефоне строка таблицы разбирается в карточку: сверху точка
   важности, время и агент одной строкой, ниже — находка во всю ширину, под ней
   «Что нужно от вас» с подписью (без шапки таблицы иначе не понять, что это за
   текст), внизу — кнопка «Сделала» во всю ширину. Ничего не прячется: видно
   ровно то же, что на большом экране, только сверху вниз. */
@media (max-width: 720px) {
  .risks-table { display: block; min-width: 0; overflow-x: visible; }
  .risks-table tbody { display: block; }
  /* Шапка не нужна: подписи переехали к самим значениям. */
  .risks-table tr:first-child { display: none; }
  .risks-table tr {
    display: grid;
    grid-template-columns: auto auto 1fr;
    grid-template-areas:
      "dot when agent"
      "what what what"
      "need need need"
      "act  act  act";
    align-items: baseline;
    gap: var(--space-1) var(--space-2);
    padding: var(--space-4) 0;
    border-bottom: var(--border-width) solid var(--color-border);
  }
  .risks-table tr:last-child { border-bottom: none; }
  .risks-table td {
    display: block;
    padding: 0;
    border-bottom: none;
    min-width: 0;
  }
  .risks-table td:nth-child(1) { grid-area: dot; }
  .risks-table td:nth-child(2) { grid-area: when; color: var(--color-muted); font-size: var(--text-xs); }
  .risks-table td:nth-child(3) { grid-area: agent; color: var(--color-muted); font-size: var(--text-xs); }
  .risks-table td:nth-child(4) { grid-area: what; margin-top: var(--space-1); }
  .risks-table td:nth-child(5) { grid-area: need; margin-top: var(--space-2); }
  .risks-table td:nth-child(6) { grid-area: act; margin-top: var(--space-3); }
  /* Подпись к рекомендации: на большом экране её несёт шапка столбца. */
  .risks-table td:nth-child(5)::before {
    content: "Что нужно от вас: ";
    color: var(--color-muted);
    font-size: var(--text-xs);
  }
  .risks-table td:nth-child(6) .btn-chip { width: 100%; }
}

/* ---------- Палец на телефоне ----------
   44 px — минимальная цель, ниже которой нажатие промахивается (Apple HIG,
   Material). Правило общее для всех кнопок СПРУТа: до 28.08.2026 его знал
   только .btn-chip, и на «Волшебном режиме» с «Каталогом желаний» жили цели
   по 24–30 px — «Не моё», «Хочу», «Править», «Готово». Найдено прогоном
   scripts/mobile_screens_check.py. */
@media (max-width: 768px) {
  .btn, .btn-chip, .btn-dismiss, .btn-small,
  .audit-chip, .alarm-chip, .drawer-close {
    min-height: 44px;
    display: inline-flex; align-items: center; justify-content: center;
  }
}

/* ---------- Широкая таблица на телефоне: карточка вместо строки ----------
   Пара к .risks-table выше, но общая: класс cards-on-mobile навешивает
   common.js вместе с подписями столбцов (data-label). Строка таблицы
   разворачивается сверху вниз, у каждого значения слева его подпись из шапки —
   на месте той шапки, которую на узком экране всё равно не видно.
   Заведено 28.08.2026 для плана платежей: 616 px таблицы против 358 видимых. */
@media (max-width: 720px) {
  .cards-on-mobile { display: block; min-width: 0; overflow-x: visible; }
  .cards-on-mobile tbody { display: block; }
  /* Шапка не нужна: подписи переехали к значениям. */
  .cards-on-mobile tr:has(th) { display: none; }
  .cards-on-mobile tr {
    display: block;
    padding: var(--space-3) 0;
    border-bottom: var(--border-width) solid var(--color-border);
  }
  .cards-on-mobile tr:last-child { border-bottom: none; }
  .cards-on-mobile td {
    display: flex; gap: var(--space-3); justify-content: space-between;
    align-items: baseline;
    padding: 2px var(--space-3);
    border-bottom: none;
    text-align: right;
  }
  .cards-on-mobile td::before {
    content: attr(data-label);
    color: var(--color-muted);
    font-size: var(--text-xs);
    text-align: left;
    flex: 0 0 auto;
  }
  /* Пустая подпись не должна съедать половину строки. */
  .cards-on-mobile td:not([data-label])::before { content: ""; }
  .cards-on-mobile td.actions { white-space: normal; }
  /* В таблице недель первая ячейка — название статьи, а не значение: она
     заголовок карточки, а не пара «подпись — число». */
  .cards-on-mobile td.row-label {
    justify-content: flex-start; text-align: left;
    font-weight: 600; margin-bottom: var(--space-1);
  }
  .cards-on-mobile td.row-label::before { content: ""; }
}
