:root {
  /* ---- Светлая/тёмная тема (решение владельца 19.09.2026, см. /settings) ----
     color-scheme: light dark - поддерживаем обе, light-dark() в каждом
     цветовом токене сам выбирает нужную ветку по ВЫЧИСЛЕННОМУ (унаследованному)
     color-scheme, а не по паре copy-paste блоков "светлая"/"тёмная" - забыть
     токен в одном из двух блоков физически невозможно, он один. Выбор
     пользователя (см. app/templates/settings.html) - через атрибут
     data-theme на <html>, который форсирует color-scheme ниже, в обход
     системного prefers-color-scheme; без атрибута - "как в системе".
     Не цветовые токены (radius/fs/space/dur/ease ниже) от темы не зависят. */
  color-scheme: light dark;
  /* Тёплая нейтральная гамма (решение владельца 20.09.2026, тот же референс
     личного финансового трекера, что и у --accent-2 ниже) - вместо
     нейтрально-серых/чисто-чёрных поверхностей: лёгкий зелёно-серый подтон
     во тьме, тёплый кремовый в свету. Сайдбар в референсе СВЕТЛЕЕ основного
     фона (а не темнее, как было раньше в тёмной ветке) - та же иерархия
     сохранена здесь: --sidebar-bg/--panel лежат на тон выше --bg. */
  --bg: light-dark(#f1f2ec, #141613);
  --sidebar-bg: light-dark(#ffffff, #1c1f1b);
  --panel: light-dark(#ffffff, #1c1f1b);
  --panel-hover: light-dark(#eceee6, #242822);
  --panel-deep: light-dark(#e5e7dd, #101210); /* sticky-заголовки таблиц - на тон глубже панели в обе стороны */
  --border: light-dark(#dcded4, #2c3029);
  --text: light-dark(#18181b, #f2f2f3);
  --muted: light-dark(#6c6c76, #9a9aa2);
  --accent: light-dark(#18181b, #f2f2f3);        /* первичная кнопка - инвертированный монохром, роль сохранена в обе стороны */
  --accent-text: light-dark(#ffffff, #0b0b0d);
  --danger: light-dark(#d94343, #ff6b6b);        /* темнее/насыщеннее в светлой - на белом фоне #ff6b6b терял контраст */

  /* ---- Фирменный акцент: тёплое золото вместо прежнего фиолетового
     (решение владельца 17.09.2026, по референсу дизайна личного
     финансового трекера - см. чат) - не тот же оттенок, что на референсе,
     и осознанно дальше по тону от --cat-ads (оранжевый, H~25°): золото
     здесь H~42° и заметно менее насыщенное/тусклее, чтобы бренд-акцент и
     категорийный "Реклама" не сливались в один и тот же "оранжевый".
     Светлая ветка - тот же тон, но темнее/насыщеннее (тот же приём, что и
     --danger выше): --accent-2-pale используется как ТЕКСТ на цветной
     подложке (.ai-card-live, .logo-accent) - в тёмной теме это светлый
     оттенок на чёрном, в светлой это должна быть та же роль наоборот, тёмный
     оттенок на светлом, а не "просто тот же цвет". ---- */
  --accent-2: light-dark(#9c7a2c, #c8a041);             /* базовый бренд-золотой */
  --accent-2-light: light-dark(#b8934a, #dfbb68);       /* светлый конец градиентов (.ai-card-icon, буллеты) */
  --accent-2-dark: light-dark(#7a5f20, #9b7427);        /* тёмный конец градиентов */
  --accent-2-pale: light-dark(#7a5f20, #f0dda8);        /* акцентный текст (.ai-card-live, .logo-accent) - тёмный на светлом, светлый на тёмном */

  /* Производные для точечного использования вне .ai-card - тот же rgb, что
     у --accent-2 выше, альфа приподнята в светлой ветке (то же rgba читается
     бледнее на белом, чем на чёрном). */
  --accent-2-wash:   light-dark(rgba(156, 122, 44, 0.10), rgba(200, 160, 65, 0.12));  /* самая слабая подложка/wash */
  --accent-2-soft:   light-dark(rgba(156, 122, 44, 0.18), rgba(200, 160, 65, 0.20));  /* hover-обводка, превью-состояния */
  --accent-2-glow:   light-dark(rgba(156, 122, 44, 0.32), rgba(200, 160, 65, 0.35));  /* рамка активного состояния, edge-glow (было .35 у border .ai-card) */
  --accent-2-glow-strong: light-dark(rgba(156, 122, 44, 0.38), rgba(200, 160, 65, 0.40)); /* было 0.4 у border .ai-card-live — отдельный токен, чтобы не терять оттенок при рефакторинге */
  --accent-2-strong: light-dark(rgba(156, 122, 44, 0.50), rgba(200, 160, 65, 0.55));  /* пик пульс-анимации (совпадает с текущим 0.55 в @keyframes ai-pulse) */

  --accent-2-ring: 0 0 0 3px var(--accent-2-soft);   /* готовый box-shadow для :focus-visible */

  /* ---- Категорийные цвета дашборда на главной (Панель Пульса) ----
     Каждый цвет закреплён за одним доменом данных везде на сайте, чтобы цвет
     стал легендой, которую пользователь запоминает один раз: Заказы/Остатки
     ФБС - фирменный акцент (переиспользует --accent-2, отдельного оттенка нет),
     Деньги - зелёный (формализация уже существовавшего в коде "успеха"),
     Остатки/аналитика WB - голубой, Реклама - оранжевый (осознанно далеко
     от жёлтого предупреждения ниже и от --danger, т.к. обычно рисуется в
     "нет доступа" состоянии, которое не должно читаться как ошибка).
     Светлая ветка каждого семейства - тот же тон, темнее/насыщеннее для
     контраста на белом (тот же приём, что и у --accent-2/--danger выше). */
  --cat-money: light-dark(#2f9c52, #5fd97f);
  --cat-money-text: light-dark(#1f7a3d, #7fe0a0);
  --cat-money-wash: light-dark(rgba(47, 156, 82, 0.08), rgba(95, 217, 127, 0.08));
  --cat-money-soft: light-dark(rgba(47, 156, 82, 0.16), rgba(95, 217, 127, 0.18));
  --cat-money-glow: light-dark(rgba(47, 156, 82, 0.22), rgba(95, 217, 127, 0.25));
  --cat-money-strong: light-dark(rgba(47, 156, 82, 0.40), rgba(95, 217, 127, 0.40));

  --cat-stock: light-dark(#1687a3, #3ec6e0);
  --cat-stock-text: light-dark(#0f6a80, #8fe3f2);
  --cat-stock-wash: light-dark(rgba(22, 135, 163, 0.08), rgba(62, 198, 224, 0.08));
  --cat-stock-soft: light-dark(rgba(22, 135, 163, 0.16), rgba(62, 198, 224, 0.18));
  --cat-stock-glow: light-dark(rgba(22, 135, 163, 0.22), rgba(62, 198, 224, 0.25));
  --cat-stock-strong: light-dark(rgba(22, 135, 163, 0.40), rgba(62, 198, 224, 0.40));

  --cat-ads: light-dark(#c96a1e, #ff9f5a);
  --cat-ads-text: light-dark(#a8551a, #ffc08a);
  --cat-ads-wash: light-dark(rgba(201, 106, 30, 0.08), rgba(255, 159, 90, 0.08));
  --cat-ads-soft: light-dark(rgba(201, 106, 30, 0.16), rgba(255, 159, 90, 0.18));
  --cat-ads-glow: light-dark(rgba(201, 106, 30, 0.22), rgba(255, 159, 90, 0.25));
  --cat-ads-strong: light-dark(rgba(201, 106, 30, 0.40), rgba(255, 159, 90, 0.40));

  /* ---- Radius — формализация уже существующих в коде значений, ни одно число не меняется ---- */
  --radius-sm: 6px;   /* инпуты, кнопки, .article-photo — уже везде 6px */
  --radius-md: 8px;   /* .stat-tile, .article, .error, .empty, .table-wrap */
  --radius-lg: 10px;  /* .login-card */
  --radius-xl: 13px;  /* .ai-card-icon */
  --radius-2xl: 16px; /* .ai-card */
  --radius-pill: 999px; /* .ai-card-live */

  /* ---- Тени — новые, используются только в двух местах (см. .ai-card:hover и .login-page) ---- */
  --shadow-edge-card: 0 12px 32px -14px var(--accent-2-glow); /* hover .ai-card */
  --shadow-login-glow: 0 0 60px var(--accent-2-wash);         /* амбиентная подсветка страницы логина */

  /* ---- Шрифтовые размеры — документирование существующей шкалы, значения не меняются;
     переменные не обязательны к внедрению в этом релизе ---- */
  --fs-h1: 22px;      /* .page-header h1 */
  --fs-logo: 20px;    /* .logo */
  --fs-card-title: 19px; /* .ai-card-title */
  --fs-body-lg: 15px; /* .ai-card-intro, .ai-card-bullets li */
  --fs-body: 14px;    /* .page-subtitle, table td/th text, кнопки */
  --fs-small: 13px;   /* .meta, .sidebar-user, .declare-input, .mgmt-input */
  --fs-xs: 12px;      /* th, .sidebar-user-role, .logout-button */
  --fs-micro: 11px;   /* .nav-section-title, .ai-card-live */

  /* Акцентный serif для заголовков (.logo, .page-header h1) - по референсу
     Family Finance: жирная антиква для "фирменных" надписей, весь остальной
     текст сайта остаётся на системном sans-serif (см. font-family на body). */
  --font-serif: Georgia, "Times New Roman", Times, serif;

  /* ---- Motion language: единые длительности и кривые для всех переходов/анимаций сайта ----
     Каждый сценарий использует один из этих токенов — новых "самопальных" значений
     в коде быть не должно, чтобы плавность ощущалась как единая система, а не набор
     случайных чисел. Все анимации, использующие эти токены, отключаются одним блоком
     в @media (prefers-reduced-motion: reduce) внизу файла. */
  --dur-fast: 150ms;       /* мгновенная реакция: hover/фокус (уже было — a,button,input...) */
  --dur-base: 200ms;       /* появление шапки страницы (main), поворот caret */
  --dur-moderate: 220ms;   /* появление строк/карточек (stagger), схлопывание строки при удалении */
  --dur-accordion: 250ms;  /* раскрытие/закрытие аккордеонов (было и осталось 0.25s) */
  --dur-flash: 300ms;      /* автосейв: проявление/угасание .flash-row */

  --ease-standard: cubic-bezier(0.4, 0, 0.2, 1);  /* базовый переход по умолчанию (цвет, hover, фокус) */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1);      /* появление нового: fade-in, stagger, flash-in */
  --ease-in: cubic-bezier(0.7, 0, 0.84, 0);       /* исчезновение: fade-out строки при удалении */
  --ease-in-out: cubic-bezier(0.65, 0, 0.35, 1);  /* симметричные переходы: аккордеон, высота строки */

  /* ---- Ритм отступов — формализация уже фактически используемых в коде
     значений в переиспользуемую шкалу (11.09.2026, аудит информационной
     плотности всех страниц). Ни одно число не меняется, только называется:
     расстояние МЕЖДУ двумя структурно разными блоками всегда один из этих
     токенов и всегда margin-top у НАЧАЛА следующего блока (не margin-bottom
     у предыдущего) - иначе оно снова "теряется", если блоки переставить. ---- */
  --space-1: 4px;   /* подпись → значение внутри одного показателя (.stat-label margin-top) */
  --space-2: 8px;   /* тесная группа внутри одной строки/карточки */
  --space-3: 12px;  /* между плитками/карточками в одном ряду (.stat-tiles/.pulse-grid gap) */
  --space-4: 16px;  /* блок внутри секции (.mgmt-add-form padding-top) */
  --space-5: 20px;  /* конец группы плиток перед следующим блоком (.stat-tiles margin-bottom) */
  --space-6: 24px;  /* граница между разными смысловыми секциями страницы (.page-header margin-bottom) */

  /* ---- "Крупные числа" — те же .stat-value/.pulse-hero-value, что и были,
     просто названы токеном: на одном экране одновременно должно быть не
     больше одного такого значения на карточку (см. правило типографики). ---- */
  --fs-stat: 24px;     /* .stat-value */
  --fs-stat-lg: 32px;  /* .pulse-hero-value */
}

/* Явный выбор темы (см. app/templates/settings.html) форсирует color-scheme
   в обход системного prefers-color-scheme - light-dark() выше пересчитает
   каждый токен по нему же, без отдельного блока переопределений. Без
   атрибута (человек не выбирал/выбрал "как в системе") - color-scheme
   остаётся "light dark" из :root, и решает система. */
:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"] { color-scheme: dark; }

* { box-sizing: border-box; }

html { scroll-behavior: smooth; }

body {
  margin: 0;
  font-family: -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
  background: var(--bg);
  color: var(--text);
}

a { color: inherit; }

/* Плавность по умолчанию: hover/active-переходы у ссылок, кнопок, полей и
строк таблицы вместо мгновенного переключения цвета/фона. */
a, button, input, select, .nav-item, tbody tr {
  transition: background-color var(--dur-fast) var(--ease-standard), border-color var(--dur-fast) var(--ease-standard),
    color var(--dur-fast) var(--ease-standard), opacity var(--dur-fast) var(--ease-standard),
    transform var(--dur-fast) var(--ease-standard);
}

main {
  animation: fade-in var(--dur-base) var(--ease-out);
}

@keyframes fade-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Переключение человека на "Задачах" (шлюз/вкладки Даниил-Илья-Руслан) -
   решение владельца 22.09.2026: без перезагрузки страницы, контент
   подгружается через fetch и подменяется в #tasks-body (см. tasks.html
   loadTasksBody), а этот класс проигрывает появление снизу заметнее
   обычного main{fade-in} (4px) - здесь смена контента откровенно заметна
   человеку, лёгкого фейда недостаточно, чтобы прочитаться как "появилось",
   а не "просто моргнуло". */
@keyframes tasks-body-reveal {
  from { opacity: 0; transform: translateY(20px); }
  to { opacity: 1; transform: translateY(0); }
}
#tasks-body.tasks-reveal { animation: tasks-body-reveal var(--dur-moderate) var(--ease-out); }

/* ---- Хореография появления списков: первые несколько карточек/строк
   проявляются с небольшим последовательным сдвигом, дальше — без задержки,
   чтобы длинный список не ощущался медленным. Работает поверх main{fade-in}. ---- */
@keyframes item-in {
  from { opacity: 0; transform: translateY(4px); }
  to { opacity: 1; transform: translateY(0); }
}

/* Строки .mgmt-table tbody tr сознательно НЕ участвуют в этой хореографии:
   эти таблицы плотные, рабочие, перечитываются много раз в день, и каждая
   полная перезагрузка (после любого «Добавить»/«Удалить» — это redirect)
   заново проигрывала бы каскад по всем строкам. Для CRUD-таблицы, которую
   сканируют взглядом много раз в день, повторяющаяся анимация на каждой
   строке — уже шум, а не польза. */
.stat-tile, .article {
  animation: item-in var(--dur-moderate) var(--ease-out) both;
}

.stat-tile:nth-child(1), .article:nth-child(1) { animation-delay: 0ms; }
.stat-tile:nth-child(2), .article:nth-child(2) { animation-delay: 25ms; }
.stat-tile:nth-child(3), .article:nth-child(3) { animation-delay: 50ms; }
.stat-tile:nth-child(4), .article:nth-child(4) { animation-delay: 75ms; }
.stat-tile:nth-child(5), .article:nth-child(5) { animation-delay: 100ms; }
.stat-tile:nth-child(6), .article:nth-child(6) { animation-delay: 125ms; }
.stat-tile:nth-child(7), .article:nth-child(7) { animation-delay: 150ms; }
/* Потолок хореографии: с 8-го элемента и далее — без нарастающей задержки. */
.stat-tile:nth-child(n+8), .article:nth-child(n+8) { animation-delay: 0ms; }

.layout {
  display: flex;
  min-height: 100vh;
}

/* --- Сайдбар --- */

/* position: sticky + height: 100vh (решение владельца 20.09.2026) - раньше
   сайдбар был обычным флекс-элементом без своей высоты, поэтому браузер
   растягивал его вровень с высотой основного контента (align-items: stretch
   у .layout) и прокручивал вместе со страницей: чтобы увидеть "Настройки"
   внизу меню на длинной странице, приходилось скроллить вниз. Теперь высота
   сайдбара всегда равна высоте окна и не зависит от контента. Подстраховка
   на случай совсем маленького окна (не основной способ поместить пункты
   меню - для этого см. плотные отступы .nav-item/.nav-section-title ниже) -
   overflow-y:auto НЕ на самом .sidebar (нашли 22.09.2026: overflow-y на
   элементе молча включает и обрезающий overflow-x, из-за чего абсолютно
   спозиционированная .notif-panel, которая по дизайну шире сайдбара и
   намеренно вылезает поверх контента, обрезалась по правому краю сайдбара),
   а на самом <nav> ниже - тогда скроллится только средний блок пунктов
   меню, а шапка с колокольчиком остаётся не обрезанной. */
.sidebar {
  width: 260px;
  flex-shrink: 0;
  position: sticky;
  top: 0;
  height: 100vh;
  background: var(--sidebar-bg);
  border-right: 1px solid var(--border);
  padding: 8px 0;
  display: flex;
  flex-direction: column;
}

/* Меню без прокрутки, пока все пункты помещаются (просьба владельца
   23.09.2026 - плотные отступы .nav-item/.nav-section-title ниже подобраны
   под это). 26.09.2026 overflow: hidden заменён на auto: после добавления
   разделов «Instagram» и «Контент Instagram» на невысоком окне (ноутбук,
   телефон) нижние пункты просто обрезались и были недоступны - владелец не
   видел свой раздел в меню. Теперь прокрутка появляется только тогда, когда
   пункты действительно не влезают; при обычной высоте всё как раньше. */
.nav { flex: 1 1 auto; min-height: 0; overflow-y: auto; overflow-x: hidden; overscroll-behavior: contain; scrollbar-width: thin; }

.sidebar-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  padding: 0 20px 10px;
  border-bottom: 1px solid var(--border);
  margin-bottom: 6px;
}

.logo {
  display: block;
  white-space: nowrap;
  font-family: var(--font-serif);
  font-size: 20px;
  font-weight: 700;
  letter-spacing: 0.03em;
  color: var(--text);
}

.logo-accent { color: var(--accent-2-pale); font-weight: 400; }

/* Свернуть/развернуть меню (просьба владельца 29.09.2026) - узкая полоска с
   иконками, название пункта - во всплывающей подсказке (title). Только на
   компьютере: на телефоне меню и так выезжает поверх (.mobile-menu-toggle).
   Класс .sidebar-collapsed ставится на <html> скриптом в <head> base.html. */
.sidebar-collapse {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 28px;
  height: 32px;
  margin-left: auto;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--muted);
}
.sidebar-collapse:hover { color: var(--text); background: var(--panel-hover); opacity: 1; box-shadow: none; }
.sidebar-collapse svg { transition: transform var(--dur-fast) var(--ease-standard); }
.sidebar { transition: width var(--dur-fast) var(--ease-standard); }

@media (max-width: 768px) {
  .sidebar-collapse { display: none; }
}

@media (min-width: 769px) {
  .sidebar-collapsed .sidebar { width: 68px; }
  .sidebar-collapsed .sidebar-header { flex-direction: column-reverse; gap: 6px; padding: 0 0 10px; }
  .sidebar-collapsed .logo { display: none; }
  .sidebar-collapsed .sidebar-collapse { margin-left: 0; }
  .sidebar-collapsed .sidebar-collapse svg { transform: rotate(180deg); }
  .sidebar-collapsed .nav-item { justify-content: center; gap: 0; margin: 0 10px; padding: 10px 0; }
  .sidebar-collapsed .nav-item > span:not(.nav-item-icon) { display: none; }
  .sidebar-collapsed .nav-section-title { visibility: hidden; height: 8px; padding: 0; margin: 4px 0; overflow: hidden; }
  .sidebar-collapsed .sidebar-user { display: none; }
}

/* Страницы на всю ширину (РНП) - без общего ограничения main в 1280px. */
main.main--wide { max-width: none; }

/* Колокольчик уведомлений (см. base.html, app/routers/notifications.py) -
   решение владельца 17.09.2026: заменить Telegram (нестабильный прокси)
   звуком и значком прямо на сайте. --- */
.notif-bell-wrap { position: relative; flex-shrink: 0; }

.notif-bell {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  transition: color var(--dur-fast) var(--ease-standard), border-color var(--dur-fast) var(--ease-standard);
}
.notif-bell:hover, .notif-bell[aria-expanded="true"] { color: var(--accent-2-pale); border-color: var(--accent-2-glow); }

/* var(--danger), а не фирменный акцент - бейдж непрочитанного сигнализирует
   "требует внимания", тот же цвет, что и у отрицательного остатка/просрочки
   везде на сайте, а не бренд-цвет ради заметности. */
.notif-bell-badge {
  position: absolute;
  top: -2px;
  right: -2px;
  min-width: 16px;
  height: 16px;
  padding: 0 4px;
  border-radius: var(--radius-pill);
  background: var(--danger);
  color: #ffffff;
  font-size: 10px;
  font-weight: 700;
  line-height: 16px;
  text-align: center;
}

/* Короткая вспышка-кольцо (2 повтора, не бесконечно - см. base.html:
   класс навешивается только в момент, когда счётчик реально вырос, не на
   каждый опрос) - тот же приём, что и .ai-card-live-dot, но в цвете самого
   бейджа (--danger), а не бренд-золоте: кольцо должно быть цветом объекта,
   который пульсирует, а не произвольным акцентом. */
.notif-bell-badge--pulse { animation: notif-badge-pulse 0.7s ease-out 2; }

@keyframes notif-badge-pulse {
  0% { box-shadow: 0 0 0 0 rgba(255, 107, 107, 0.6); }
  70% { box-shadow: 0 0 0 8px rgba(255, 107, 107, 0); }
  100% { box-shadow: 0 0 0 0 rgba(255, 107, 107, 0); }
}

/* left: 0 (не right: 0) - сайдбар всего 220px, а панель шире (280px);
   якорь за правый край внутри узкого сайдбара всегда обрезал бы панель
   слева за пределами экрана. Растёт вправо, поверх контента - обычное
   дело для выпадающих панелей, ничего страшного в перекрытии контента. */
.notif-panel {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  width: 280px;
  max-height: 360px;
  overflow-y: auto;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 32px -14px rgba(0, 0, 0, 0.6);
  z-index: 20;
}

.notif-panel-header {
  padding: 10px 14px;
  font-size: 12px;
  font-weight: 600;
  color: var(--muted);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  border-bottom: 1px solid var(--border);
}

.notif-panel-list { display: flex; flex-direction: column; }

.notif-item {
  display: block;
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  color: var(--text);
  text-decoration: none;
}
.notif-item:last-child { border-bottom: none; }
.notif-item:hover { background: var(--panel-hover); }

.notif-item--unread { background: var(--accent-2-wash); }
.notif-item--unread:hover { background: var(--accent-2-soft); }

.notif-item-text { font-size: 13px; line-height: 1.4; }
.notif-item-time { margin-top: 2px; font-size: 11px; color: var(--muted); }

.notif-empty { padding: 16px 14px; color: var(--muted); font-size: 13px; text-align: center; }

.nav-section { margin-bottom: 4px; }

/* Заголовки разделов - решение владельца 23.09.2026 (референс Family
   Finance): просто мелкий тракед-капс лейбл без иконки - иконка теперь
   только у самих пунктов ниже (.nav-item-icon), не у заголовка группы. */
.nav-section-title {
  width: 100%;
  font-size: 12px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.07em;
  color: var(--muted);
  padding: 13px 20px 4px;
}

/* Пункты меню - решение владельца 23.09.2026 (референс Family Finance).
   Размер иконки/шрифта сначала подняли до 20px/17px, но по следующей же
   правке владельца текст оказался слишком крупным - откатили ближе к
   середине (18px/16px). .nav { overflow: hidden } выше всё ещё держит без
   прокрутки. Активный/наведённый пункт - сплошная скруглённая "таблетка"
   с отступом от края сайдбара. */
.nav-item {
  display: flex;
  align-items: center;
  gap: 13px;
  margin: 0 12px;
  padding: 9px 13px;
  font-size: 16px;
  line-height: 1.3;
  text-decoration: none;
  color: var(--muted);
  border-radius: 13px;
  transition: background var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard);
}

.nav-item-icon {
  display: flex;
  flex-shrink: 0;
  width: 18px;
  height: 18px;
  color: var(--muted);
  transition: color var(--dur-fast) var(--ease-standard);
}
.nav-item-icon svg { width: 18px; height: 18px; }

.nav-item:hover {
  color: var(--text);
  background: var(--panel-hover);
}
.nav-item:hover .nav-item-icon { color: var(--text); }

.nav-item.active {
  color: var(--text);
  background: var(--accent-2-wash);
  font-weight: 600;
}
.nav-item.active .nav-item-icon { color: var(--accent-2-pale); }

.nav-toplevel { padding-bottom: 6px; margin-bottom: 6px; }

/* Счётчик необработанных справа от названия пункта меню. Компактный, чтобы
   «Отзывы и вопросы» оставалось в одну строку при ширине сайдбара 245px. */
.nav-badge {
  flex-shrink: 0;
  margin-left: auto;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: var(--radius-pill);
  background: var(--danger);
  color: #ffffff;
  font-size: 11px;
  font-weight: 700;
  line-height: 18px;
  text-align: center;
}
.nav-item-toplevel > span:nth-child(2) { white-space: nowrap; }
.nav-badge[hidden] { display: none; }

.nav-item-toplevel { font-weight: 500; }

/* Ссылка "Помощь" - не часть nav_sections (см. app/templating.py), не
раскрывающаяся группа, всегда одна ссылка. margin-top: auto (решение
владельца 21.09.2026, перенести "Настройки"/"Помощь" в левый нижний угол) -
раньше блок шёл сразу после списка разделов в потоке, теперь прижимается к
низу сайдбара сам; .sidebar-user ниже больше не держит собственный
margin-top: auto - ему уже достаточно идти последним в потоке сразу под
этим блоком, который и забирает всё свободное место. */
.nav-footer {
  margin-top: auto;
  padding-top: 8px;
  border-top: 1px solid var(--border);
}

/* --- Контент --- */

.content-area { flex: 1; min-width: 0; }

main { padding: 32px; max-width: 1280px; margin: 0 auto; }

/* Фирменный акцент при загрузке страницы: короткая градиентная линия
   "дорисовывается" под заголовком - тот же приём, что и .logo-accent/
   .nav-item.active, просто перенесённый в момент появления страницы.
   position:relative только здесь - не влияет на остальной поток. */
.page-header { position: relative; margin-bottom: 24px; padding-bottom: 14px; }
.page-header h1 { margin: 0 0 4px; font-family: var(--font-serif); font-size: 22px; font-weight: 700; }
.page-subtitle { margin: 0; color: var(--muted); font-size: 14px; }

.page-header::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 40px;
  height: 2px;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--accent-2), var(--accent-2-light));
  transform-origin: left center;
  animation: header-line-grow var(--dur-moderate) var(--ease-out) 120ms both;
}

@keyframes header-line-grow {
  from { transform: scaleX(0); opacity: 0; }
  to { transform: scaleX(1); opacity: 1; }
}

/* Облегчённый подзаголовок ВНУТРИ страницы (не новая страница) - без
   анимированной линии .page-header::after, та отыгрывает ровно один раз
   на странице. Заменяет собой все прежние точечные "заголовки для одного
   блока" (.fbo-shipment-title, повторный .page-header/<h1> на главной). */
/* Та же полоска-акцент, что и у .page-header::after, просто короче и без
   анимации роста - подзаголовок внутри страницы может переотрисовываться
   при каждом обновлении данных, повторный "выезд" читался бы как мигание,
   не как полировка. */
.section-heading { position: relative; font-size: var(--fs-card-title); font-weight: 700; margin: var(--space-6) 0 var(--space-2); padding-bottom: 8px; }
.section-heading:first-child { margin-top: 0; }

/* P&L: продажная фактура, себестоимость и движение запаса */
.pnl-heading-row, .pnl-syncbar, .pnl-section-heading { display: flex; align-items: center; justify-content: space-between; gap: 16px; flex-wrap: wrap; }
.pnl-period label, .pnl-expense-form label { display: grid; gap: 5px; color: var(--muted); font-size: var(--fs-small); }
.pnl-period input, .pnl-inline-form input, .pnl-expense-form input, .pnl-expense-form select, .pnl-cost-form input {
  min-height: 38px; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--radius-md);
  color: var(--text); background: var(--panel); font: inherit; color-scheme: inherit;
}
.pnl-api-state { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); font-size: var(--fs-small); }
.pnl-api-state::before { content: ""; width: 7px; height: 7px; border-radius: 50%; background: var(--danger); }
.pnl-api-state.is-connected::before { background: #4aa879; }
.pnl-sync-status { margin: 0 0 14px; padding: 9px 12px; border-radius: 8px; color: var(--muted); background: var(--panel); font-size: var(--fs-small); }
.pnl-sync-status.is-running { color: var(--text); border-left: 3px solid var(--accent-2); }
.pnl-note { margin-bottom: 16px; padding: 13px 15px; border: 1px solid var(--border); border-radius: 10px; background: var(--panel); color: var(--muted); line-height: 1.5; }
.pnl-note strong { color: var(--text); }
.pnl-note-warning { display: block; margin-top: 6px; color: #d9a844; }
.pnl-kpi small, .pnl-table td small { display: block; margin-top: 4px; color: var(--muted); font-size: var(--fs-xs); line-height: 1.4; }
.pnl-section { margin: 0 0 30px; }
.pnl-section-heading { margin-bottom: 12px; align-items: end; }
.pnl-section-heading h2 { margin: 0 0 4px; font-size: 18px; }
.pnl-section-heading p { margin: 0; color: var(--muted); font-size: var(--fs-small); }
.pnl-section .table-wrap { border-radius: 10px; }
.pnl-table { width: 100%; min-width: 760px; border-collapse: collapse; }
.pnl-table th, .pnl-table td { padding: 11px 12px; text-align: left; border-bottom: 1px solid var(--border); vertical-align: middle; font-variant-numeric: tabular-nums; }
.pnl-table th { color: var(--muted); font-size: var(--fs-xs); font-weight: 600; white-space: nowrap; }
.pnl-table td { font-size: var(--fs-small); }
.pnl-table tr:last-child td { border-bottom: 0; }
.pnl-caption { margin: 9px 0 0; color: var(--muted); font-size: var(--fs-xs); line-height: 1.5; }
.pnl-tax-grid { display: grid; grid-template-columns: repeat(2, minmax(260px, 1fr)); gap: 12px; }
.pnl-inline-form, .pnl-tax-card { padding: 14px; border: 1px solid var(--border); border-radius: 10px; background: var(--panel); }
.pnl-tax-card label { display: block; margin-bottom: 8px; font-weight: 600; }
.pnl-field-action { display: flex; gap: 8px; }
.pnl-field-action input { flex: 1; min-width: 0; }
.pnl-tax-card small { display: block; margin-top: 8px; color: var(--muted); font-size: var(--fs-xs); }
.pnl-cost-form { display: flex; align-items: center; gap: 7px; min-width: 270px; }
.pnl-cost-form input { width: 135px; }
.pnl-empty { padding: 15px; border: 1px dashed var(--border); border-radius: 10px; color: var(--muted); background: var(--panel); font-size: var(--fs-small); }
.pnl-expense-form { display: grid; grid-template-columns: minmax(150px, 1fr) minmax(190px, 1.5fr) minmax(120px, .7fr) auto; align-items: end; gap: 10px; margin-bottom: 12px; padding: 14px; border: 1px solid var(--border); border-radius: 10px; background: var(--panel); }
.pnl-inbound-form { grid-template-columns: minmax(125px, 1fr) minmax(140px, 1fr) minmax(90px, .55fr) minmax(95px, .55fr) minmax(145px, .8fr) auto; }
.pnl-mini-total { display: grid; gap: 3px; color: var(--muted); font-size: var(--fs-xs); text-align: right; }
.pnl-mini-total strong { color: var(--text); font-size: 17px; }
.pnl-mini-total span { color: var(--muted); }
.pnl-list { border: 1px solid var(--border); border-radius: 10px; overflow: hidden; background: var(--panel); }
.pnl-list-row { display: grid; grid-template-columns: 1fr auto auto; gap: 18px; align-items: center; padding: 10px 14px; border-bottom: 1px solid var(--border); }
.pnl-list-row:last-child { border-bottom: 0; }
.pnl-list-row span { display: block; color: var(--muted); font-size: var(--fs-xs); }
.pnl-actions { display: flex; gap: 5px; }
.button-quiet { min-height: 30px; padding: 4px 7px; color: var(--muted); font-size: var(--fs-xs); }
@media (max-width: 1120px) { .pnl-kpis { grid-template-columns: repeat(3, minmax(150px, 1fr)); } }
@media (max-width: 720px) {
  .pnl-tax-grid { grid-template-columns: 1fr; }
  .pnl-expense-form, .pnl-inbound-form { grid-template-columns: 1fr 1fr; }
  .pnl-expense-form button { grid-column: 1 / -1; }
  .pnl-list-row { grid-template-columns: 1fr auto; gap: 8px; }
  .pnl-list-row > form { grid-column: 2; }
}
@media (max-width: 420px) { .pnl-kpis { grid-template-columns: 1fr 1fr; } .pnl-expense-form, .pnl-inbound-form { grid-template-columns: 1fr; } }
.section-heading::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 24px;
  height: 2px;
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--accent-2), var(--accent-2-light));
}

.toolbar {
  display: flex;
  gap: 12px;
  align-items: center;
  flex-wrap: wrap;
  margin-bottom: 16px;
}

.inline-form { display: inline; margin: 0; }

.toolbar input, .toolbar select {
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  font-size: 14px;
  background: var(--panel);
  color: var(--text);
}

.toolbar input::placeholder { color: var(--muted); }

.toolbar input:focus, .toolbar select:focus {
  outline: none;
  border-color: var(--accent-2);
  box-shadow: var(--accent-2-ring);
}

button, .button {
  padding: 7px 16px;
  border-radius: 6px;
  border: 1px solid var(--accent);
  background: var(--accent);
  color: var(--accent-text);
  cursor: pointer;
  font-size: 14px;
  font-weight: 600;
}

button:hover { opacity: 0.85; }

button:hover, .button:hover,
button:focus-visible, .button:focus-visible {
  box-shadow: var(--accent-2-ring);
}

.button-secondary {
  background: transparent;
  color: var(--text);
  border: 1px solid var(--border);
  font-weight: 400;
}

.button-secondary:hover {
  border-color: var(--accent-2);
}

.meta { color: var(--muted); font-size: 13px; margin-bottom: 12px; }

/* --- Плашки заказов --- */

.stat-tiles {
  display: flex;
  gap: 12px;
  margin-bottom: 20px;
}

.stat-tile {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px 20px;
  min-width: 140px;
  transition: border-color var(--dur-fast) var(--ease-standard), box-shadow var(--dur-fast) var(--ease-standard),
    transform var(--dur-fast) var(--ease-standard);
}

/* Тот же приём, что и у .task-day-card:hover/.ai-card:hover - лёгкий
   подъём + золотое свечение по краю, даже у плиток, что сами по себе не
   ссылка: карточка всё равно должна ощущаться "живой", а не плоской
   картинкой, это и есть разница между "строго" и "сыро". */
.stat-tile:hover {
  border-color: var(--accent-2-glow);
  box-shadow: var(--shadow-edge-card);
  transform: translateY(-1px);
}

.stat-value { font-size: var(--fs-stat); font-weight: 700; line-height: 1.2; font-variant-numeric: tabular-nums; }
.stat-label { color: var(--muted); font-size: 13px; margin-top: 2px; }

/* Тонкий внутренний разделитель для второстепенной строки контекста внутри
   одной карточки (например "Выкуп за месяц" под 7-дневной воронкой) - не
   новая карточка, просто явная граница, чтобы не читалось одной строкой с
   тем, что выше. */
.tile-divider { margin-top: var(--space-2); padding-top: var(--space-2); border-top: 1px solid var(--border); }

/* Мини-полоска прогресса под плиткой "Целей недели выполнено" - те же
   токены длительности/кривой, что и у остального motion language, "рост"
   при загрузке страницы через CSS-переменную --pct, заданную инлайн. */
.stat-progress-track {
  margin-top: 8px;
  height: 4px;
  border-radius: var(--radius-pill);
  background: var(--border);
  overflow: hidden;
}

.stat-progress-fill {
  height: 100%;
  width: var(--pct, 0%);
  border-radius: var(--radius-pill);
  background: linear-gradient(90deg, var(--accent-2), var(--accent-2-light));
  animation: stat-progress-in var(--dur-accordion) var(--ease-out) 200ms both;
}

@keyframes stat-progress-in {
  from { width: 0%; }
  to { width: var(--pct, 0%); }
}

.stat-tiles-wrap { flex-wrap: wrap; }

/* Карточка "Рекомендации ИИ" - текст в 3-5 предложений плюс список пунктов
   не помещается в обычную узкую плитку (см. .stat-tile min-width) - растягиваем
   на всю ширину ряда вместо соседства с плитками фиксированной ширины. */
.stat-tile-wide { flex: 1 1 100%; }

.stat-tile-link {
  text-decoration: none;
  color: inherit;
  display: block;
  cursor: pointer;
}

.stat-tile-link:hover {
  border-color: var(--accent-2-glow);
  background: var(--panel-hover);
  box-shadow: 0 0 0 1px var(--accent-2-wash);
}

/* Сводка на главной (замена карточки ИИ) - те же .stat-tile, но с текстовым
   содержимым (задача/идеи) вместо одной большой цифры. */
.stat-tile-text { font-size: 15px; font-weight: 600; line-height: 1.4; color: var(--text); }

.stat-tile-list {
  list-style: none;
  margin: 4px 0 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.stat-tile-list li {
  font-size: 14px;
  line-height: 1.4;
  color: var(--text);
}

.stat-trend-up { color: var(--text); }
.stat-trend-down { color: var(--danger); }

/* --- KPI-плитки на вкладке "Задачи" (разбивка по статусам/исполнителям) ---
   Те же .stat-tile, что и везде, но со списком строк вместо одной цифры -
   компактная мини-таблица "подпись - число" внутри плитки. */
.stat-tile-rows {
  margin-top: 6px;
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.stat-tile-row {
  display: flex;
  justify-content: space-between;
  gap: 12px;
  font-size: 13px;
}

.stat-tile-row-label { color: var(--muted); }
.stat-tile-row-value { font-variant-numeric: tabular-nums; font-weight: 600; }

/* Акцентированная первая строка внутри плитки-разбивки (например "Выполнено
   X/Y" первой строкой в плитке "По статусам") - когда нужно и агрегат, и
   разбивку в одной плитке, а не в двух соседних. */
.stat-tile-row--lead {
  font-weight: 700;
  font-size: var(--fs-body);
  padding-bottom: var(--space-2);
  margin-bottom: var(--space-2);
  border-bottom: 1px solid var(--border);
}
.stat-tile-row--lead .stat-tile-row-label { color: var(--text); }

/* Отключает хореографию появления (.stat-tile { animation: item-in }) -
   там, где обновление плиток - всегда полная перезагрузка страницы (смена
   периода), а не первое появление контента: повторный каскад на каждый
   переход - шум, не польза (тот же довод, что и у .mgmt-table tr). */
.stat-tiles--static .stat-tile { animation: none; }

/* --- Панель Пульса: hero-график баланса + сетка виджетов на главной --- */

.pulse-hero {
  align-items: stretch;
  margin-bottom: 20px;
}

.pulse-hero-figure {
  flex-shrink: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  min-width: 160px;
}

.pulse-hero-value {
  font-size: var(--fs-stat-lg);
  font-weight: 700;
  line-height: 1.15;
  font-variant-numeric: tabular-nums;
  color: var(--text);
}

.pulse-hero-chart-wrap {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  justify-content: center;
  gap: 6px;
}

.pulse-hero-chart {
  width: 100%;
  height: 110px;
  overflow: visible;
}

/* Зелёный (var(--cat-money)), а не фирменный акцент - график про деньги,
   тот же цвет, что и у соседнего тайла "Деньги" (см. правило цвета: оба
   денежных сигнала на экране должны совпадать). */
.pulse-hero-dot {
  fill: var(--cat-money-text);
  filter: drop-shadow(0 0 6px var(--cat-money-glow));
}

.pulse-hero-caption {
  color: var(--muted);
  font-size: var(--fs-xs);
}

.pulse-chart-hover-area { position: relative; cursor: crosshair; }

.pulse-chart-tooltip {
  position: absolute;
  z-index: 5;
  min-width: 190px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 32px -14px rgba(0, 0, 0, 0.6);
  padding: 10px 14px;
  pointer-events: none;
}

.pulse-chart-tooltip-date { font-size: var(--fs-xs); color: var(--muted); margin-bottom: 6px; }

.pulse-chart-tooltip-row {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: var(--fs-small);
  color: var(--text);
  white-space: nowrap;
}

.pulse-chart-tooltip-row b { margin-left: auto; padding-left: 12px; font-variant-numeric: tabular-nums; }

.pulse-chart-tooltip-dot { width: 7px; height: 7px; border-radius: 50%; flex-shrink: 0; }
.pulse-chart-tooltip-dot--income { background: var(--cat-money); }
.pulse-chart-tooltip-dot--expense { background: var(--danger); }
.pulse-chart-tooltip-dot--net { background: var(--accent-2); }

.pulse-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(230px, 1fr));
  gap: 12px;
  margin-bottom: 8px;
}

.pulse-tile {
  border-top: 3px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* Нейтральная (не var(--accent-2)) - фирменный акцент теперь исключительно
   интерактив/фокус, не легенда категории (см. правило цвета) - у домена
   "Заказы/FBS" нет своего категорийного цвета, и заводить отдельный ради
   одной рамки не стоит. */
.pulse-tile--ops { border-top-color: var(--border); }
.pulse-tile--money { border-top-color: var(--cat-money); }
.pulse-tile--stock { border-top-color: var(--cat-stock); }
.pulse-tile--ads { border-top-color: var(--cat-ads); }
/* var(--danger) - тот же цвет, что и у отрицательного остатка/просрочки
   везде на сайте (.amount-negative) - расход как категория переиспользует
   уже существующий смысловой цвет, а не заводит свой заново. */
.pulse-tile--expense { border-top-color: var(--danger); }

.pulse-tile--locked {
  border-top-style: dashed;
  background: var(--panel);
  opacity: 0.85;
}

.pulse-tile-eyebrow {
  font-size: var(--fs-micro);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--muted);
}

.pulse-tile-link-wrap { color: inherit; text-decoration: none; display: block; }
.pulse-tile-link-wrap:hover .stat-value { color: var(--accent-2-pale); }

.pulse-tile-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
}

.pulse-tile-sub {
  color: var(--muted);
  font-size: var(--fs-small);
}

.pulse-sparkline { width: 60px; height: 24px; flex-shrink: 0; overflow: visible; }

.pulse-progress--money { background: linear-gradient(90deg, var(--cat-money), var(--cat-money-text)); }

.pulse-availability-bar {
  display: flex;
  height: 10px;
  border-radius: var(--radius-pill);
  overflow: hidden;
  background: var(--border);
}

.pulse-availability-seg { display: block; height: 100%; }
.pulse-availability-seg--deficient { background: var(--cat-ads); }
.pulse-availability-seg--actual { background: var(--cat-money); }
.pulse-availability-seg--balanced { background: var(--accent-2); }
.pulse-availability-seg--nonActual { background: var(--cat-stock); }
.pulse-availability-seg--nonLiquid { background: var(--border); }
.pulse-availability-seg--invalidData { background: var(--muted); }

.pulse-legend-dot {
  display: inline-block;
  width: 7px;
  height: 7px;
  border-radius: 50%;
  margin-right: 3px;
}


.pulse-buyout-rate { color: var(--cat-money-text); font-weight: 600; }

.pulse-dateline { text-align: right; }

@media (prefers-reduced-motion: reduce) {
  .pulse-hero:hover { transform: none; }
}

/* --- Карточка ИИ-рекомендаций на главной --- */

.ai-card {
  position: relative;
  overflow: hidden;
  display: flex;
  gap: 18px;
  align-items: flex-start;
  background: linear-gradient(160deg, var(--accent-2-wash), rgba(200, 160, 65, 0.03) 55%, var(--panel) 100%);
  border: 1px solid var(--accent-2-glow);
  border-radius: var(--radius-2xl);
  padding: 24px 28px;
  margin-bottom: 28px;
  transition: box-shadow 0.2s ease, transform 0.2s ease;
}

.ai-card:hover {
  transform: translateY(-1px);
  box-shadow: var(--shadow-edge-card);
}

.ai-card::before {
  content: "";
  position: absolute;
  top: -60px;
  right: -60px;
  width: 220px;
  height: 220px;
  background: radial-gradient(circle, rgba(200, 160, 65, 0.28), transparent 70%);
  pointer-events: none;
}

.ai-card-icon {
  position: relative;
  flex-shrink: 0;
  width: 48px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-xl);
  font-size: 22px;
  line-height: 1;
  background: linear-gradient(135deg, var(--accent-2-light), var(--accent-2-dark));
  box-shadow: 0 6px 18px var(--accent-2-strong);
}

.ai-card-body { position: relative; flex: 1; min-width: 0; }

.ai-card-header {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 8px 12px;
  margin-bottom: 12px;
}

.ai-card-title { flex: 1 1 auto; font-size: 19px; font-weight: 700; color: var(--text); letter-spacing: 0.01em; white-space: nowrap; }

.ai-card-live {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 11px;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--accent-2-pale);
  background: var(--accent-2-wash);
  border: 1px solid var(--accent-2-glow-strong);
  border-radius: var(--radius-pill);
  padding: 4px 10px 4px 8px;
  white-space: nowrap;
}

.ai-card-live-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent-2-light);
  box-shadow: 0 0 0 0 rgba(223, 187, 104, 0.6);
  animation: ai-pulse 2s infinite;
}

@keyframes ai-pulse {
  0% { box-shadow: 0 0 0 0 rgba(223, 187, 104, 0.55); }
  70% { box-shadow: 0 0 0 6px rgba(223, 187, 104, 0); }
  100% { box-shadow: 0 0 0 0 rgba(223, 187, 104, 0); }
}

@media (prefers-reduced-motion: reduce) {
  .ai-card-live-dot { animation: none; }
  .ai-card:hover { transform: none; }
  .notif-bell-badge--pulse { animation: none; }
  .stat-tile:hover { transform: none; }

  /* Весь остальной motion language выключается тем же блоком: контент
     появляется сразу целиком, строка при удалении убирается без схлопывания
     (дублирует matchMedia-проверку в JS, см. base.html), кнопка при отправке
     остаётся статично приглушённой с читаемым текстом, без спиннера,
     flash-row меняет фон мгновенно. */
  main { animation: none; }
  .stat-tile, .article { animation: none; }
  .mgmt-table tr.row-removing td { transition: none; }
  .mgmt-table td, .cashflow-table td, .opiu-table td { transition: none; }
  .article-body, .article-caret { transition: none; }

  button.is-loading, .button.is-loading { color: inherit; opacity: 0.6; }
  button.is-loading::after, .button.is-loading::after { content: none; }

  .toast-success { animation: none; }
  .page-header::after { animation: none; }
  .stat-progress-fill { animation: none; }
}

.ai-card-text { color: var(--muted); font-size: 14px; }
.ai-card-text-pre { white-space: pre-line; line-height: 1.5; }

.ai-card-intro {
  font-size: 15px;
  color: var(--text);
  line-height: 1.6;
  margin: 0 0 14px;
}

.ai-card-bullets {
  list-style: none;
  margin: 0 0 14px;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.ai-card-bullets li {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  font-size: 15px;
  line-height: 1.55;
  color: var(--text);
  background: rgba(255, 255, 255, 0.04);
  border: 1px solid var(--border);
  border-radius: 10px;
  padding: 12px 16px;
}

.ai-card-bullets li::before {
  content: "";
  flex-shrink: 0;
  width: 7px;
  height: 7px;
  margin-top: 8px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent-2-light), var(--accent-2-pale));
}

.ai-card-updated {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 12px;
  color: var(--muted);
}

/* --- Список артикулов (аккордеон) --- */

.article-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.article {
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow: hidden;
  background: var(--panel);
  transition: border-color var(--dur-fast) var(--ease-standard), box-shadow var(--dur-fast) var(--ease-standard);
}

/* Тот же приём, что и у .stat-tile:hover выше - золотое свечение по краю
   карточки товара/месяца, не только смена фона заголовка. */
.article:hover {
  border-color: var(--accent-2-glow);
  box-shadow: var(--shadow-edge-card);
}

.article-header {
  display: flex;
  align-items: center;
  gap: 12px;
  width: 100%;
  padding: 12px 16px;
  background: none;
  border: none;
  border-radius: 0;
  color: var(--text);
  font: inherit;
  text-align: left;
  cursor: pointer;
}

.article-header:hover { background: var(--panel-hover); }

.article-caret { display: inline-block; transform: rotate(0deg); color: var(--muted); transition: transform var(--dur-base) var(--ease-standard); }
.article-header.open .article-caret { transform: rotate(90deg); }

.article-vendor-code { font-weight: 600; }
.article-title { color: var(--muted); flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.article-totals { font-weight: 700; font-variant-numeric: tabular-nums; }

/* "Крупное число + мелкая подпись" в шапке аккордеона - когда одного title=
   на hover недостаточно и подпись должна быть видна всегда (например
   "Остаток"/"Загружено" рядом с итоговым числом артикула). */
.article-totals-group { display: flex; flex-direction: column; align-items: flex-end; gap: 0; }
.article-totals-caption { font-size: var(--fs-micro); font-weight: 400; color: var(--muted); }

.article-body {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--dur-accordion) var(--ease-in-out);
  border-top: 0px solid var(--border);
}

.article-body.open { grid-template-rows: 1fr; border-top-width: 1px; }

.article-body-inner { overflow-x: auto; overflow-y: hidden; min-height: 0; }

.article-body table { border-radius: 0; }

.amount-negative { color: var(--danger); font-weight: 700; font-variant-numeric: tabular-nums; }

.muted-cell { color: var(--muted); font-variant-numeric: tabular-nums; }

.declare-input {
  width: 80px;
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  color: var(--text);
  font-size: 13px;
}

.declare-input:focus {
  outline: none;
  border-color: var(--accent-2);
  box-shadow: var(--accent-2-ring);
  background: var(--bg);
}

/* --- Ручная запись остатка ФБС на WB (см. /fbs/stocks, write_wb_stock) --- */

.wb-write-cell { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.wb-write-current { min-width: 24px; }

.wb-write-input {
  width: 90px;
  padding: 5px 8px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  color: var(--text);
  font-size: 13px;
}

.wb-write-input:focus {
  outline: none;
  border-color: var(--accent-2);
  box-shadow: var(--accent-2-ring);
}

.wb-write-status { font-size: 12px; flex-basis: 100%; }
.wb-write-status.wb-write-success { color: var(--cat-money-text); }
.wb-write-status.wb-write-error { color: var(--danger); }

/* Автосейв: то же плавное появление/угасание фона, что и на других
   страницах (.mgmt-table td/.opiu-table td) - но класс здесь навешивается
   ПРЯМО на элемент, которому меняют фон (td/th), а не на строку-предка,
   поэтому и правило простое, без потомкового селектора. */
.article-body-inner td.flash-row,
.article-body-inner th.flash-row { background: rgba(95, 217, 127, 0.18); transition: background-color var(--dur-flash) var(--ease-standard); }

/* --- Фото товара в списке "Загрузить остатки" --- */

.article-photo {
  width: 48px;
  height: 48px;
  border-radius: 6px;
  object-fit: cover;
  flex-shrink: 0;
  background: #ffffff;
  border: 1px solid var(--border);
}

.article-photo-placeholder {
  border: 1px dashed var(--border);
}

/* --- Баннер-подтверждение об успешном действии (переиспользуемый компонент -
   см. app/templates/_toast.html) - "Применить" на "Загрузить остатки",
   "Обновить данные из WB", "Добавить" цель/идею. Тот же зелёный, что уже
   используется для .flash-row/status-done - не вводим новый цвет успеха.
   Сам исчезает через анимацию + JS убирает узел из DOM (см. base.html);
   крестик даёт закрыть раньше вручную. */
.toast-success {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 10px 8px 14px;
  margin-bottom: 16px;
  border-radius: var(--radius-md);
  background: rgba(95, 217, 127, 0.12);
  border: 1px solid rgba(95, 217, 127, 0.4);
  color: var(--cat-money-text);
  font-size: 14px;
  animation: toast-fade 2.4s var(--ease-standard) forwards;
}

.toast-success-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  border-radius: 50%;
  background: rgba(95, 217, 127, 0.25);
  font-size: 12px;
  line-height: 1;
  flex-shrink: 0;
}

.toast-close {
  padding: 0;
  width: 20px;
  height: 20px;
  border: none;
  background: transparent;
  color: inherit;
  opacity: 0.6;
  font-size: 15px;
  line-height: 1;
  flex-shrink: 0;
}

.toast-close:hover { opacity: 1; }
.toast-close:hover, .toast-close:focus-visible { box-shadow: none; }

@keyframes toast-fade {
  0% { opacity: 0; transform: translateY(-4px); }
  10% { opacity: 1; transform: translateY(0); }
  85% { opacity: 1; }
  100% { opacity: 0; }
}

/* --- Кнопка "Применить" внизу формы загрузки --- */

.apply-bar {
  position: sticky;
  bottom: 0;
  background: var(--bg);
  padding: 16px 0;
  margin-top: 8px;
  border-top: 1px solid var(--border);
}

.apply-button { padding: 10px 24px; }

/* --- Блок "Поставка в ФБО" на странице "Загрузить остатки" --- */

.fbo-shipment-block {
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 20px;
  margin-bottom: 20px;
}

.fbo-shipment-form { margin-top: 14px; }

/* Загрузка файла (слева) и настройки применения (справа) - на телефоне
   настройки просто уходят под форму (flex-wrap), см. также медиа-блок ниже. */
.fbo-shipment-body {
  display: flex;
  align-items: flex-start;
  gap: 28px;
  flex-wrap: wrap;
}

.fbo-shipment-upload {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 12px;
}

/* Нативный <input type=file> с зашитой кнопкой выбора - стилизуем именно
   кнопку (::file-selector-button - псевдоэлемент, свою transition ему
   нужно задавать отдельно, глобальное правило "input {...}" её не берёт),
   саму кнопку "Загрузить поставку" переносим отдельной строкой ниже него. */
.fbo-shipment-file-input {
  font-size: 14px;
  color: var(--muted);
}

.fbo-shipment-file-input::file-selector-button {
  padding: 8px 16px;
  margin-right: 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--panel-hover);
  color: var(--text);
  font-size: 14px;
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-standard), background-color var(--dur-fast) var(--ease-standard);
}

.fbo-shipment-file-input::file-selector-button:hover {
  border-color: var(--accent-2);
  background: var(--panel);
}

/* Настройки применения (галочки) - отдельная панель справа от загрузки,
   визуально отделена от неё как "своя группа полей", не просто ещё одна
   форм-строка. */
.fbo-shipment-options {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 18px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--bg);
  min-width: 240px;
}

.fbo-shipment-options-title {
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--muted);
  margin-bottom: 2px;
}

.fbo-shipment-checkbox {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  cursor: pointer;
}

.fbo-shipment-checkbox input[type="checkbox"] {
  width: 16px;
  height: 16px;
  accent-color: var(--accent-2);
  cursor: pointer;
}

.table-wrap {
  border: 1px solid var(--border);
  border-radius: 8px;
  overflow-x: auto;
}

table {
  width: 100%;
  border-collapse: collapse;
  background: var(--panel);
}

th, td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--border);
  text-align: left;
  font-size: 14px;
  white-space: nowrap;
}

th {
  background: var(--panel-deep);
  font-weight: 600;
  color: var(--muted);
  font-size: 12px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
}

tbody tr:hover { background: var(--panel-hover); }

tr:last-child td { border-bottom: none; }

.amount-zero { color: var(--danger); font-weight: 600; font-variant-numeric: tabular-nums; }

.error {
  background: rgba(255, 107, 107, 0.1);
  border: 1px solid var(--danger);
  color: var(--danger);
  padding: 12px 16px;
  border-radius: 8px;
  margin-bottom: 16px;
  font-size: 14px;
}

.empty {
  color: var(--muted);
  padding: 48px;
  text-align: center;
  border: 1px dashed var(--border);
  border-radius: 8px;
}

/* Едва заметный акцент вместо голого текста - без новых иконок/ассетов,
   тот же пунктирный мотив, что и у рамки .empty самой и у
   .article-photo-placeholder. */
.empty::before {
  content: "";
  display: block;
  width: 32px;
  height: 32px;
  margin: 0 auto 12px;
  border: 1.5px dashed var(--border);
  border-radius: 50%;
}

/* --- Переключатель сортировки списка товаров (FBS/FBO) - по умолчанию
   порядок цветов (см. app/ledger/sorting.py), опционально по остатку
   (сначала самые проблемные). Чисто на клиенте - см. base.html. --- */
.sort-toggle {
  display: inline-flex;
  gap: 2px;
  padding: 2px;
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  background: var(--panel);
}

.sort-toggle-btn {
  padding: 5px 10px;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--muted);
  font-size: 13px;
  font-weight: 400;
}

.sort-toggle-btn:hover { color: var(--text); }
.sort-toggle-btn:hover, .sort-toggle-btn:focus-visible { box-shadow: none; }

.sort-toggle-btn.active {
  background: var(--panel-hover);
  color: var(--text);
  font-weight: 600;
}

/* Лёгкое затемнение списка на время AJAX-обновления поиска (см. fbs_stocks.html) */
.article-list.is-refreshing, #stocks-results.is-refreshing {
  opacity: 0.5;
  transition: opacity var(--dur-fast) var(--ease-standard);
}

/* --- Вход --- */

.login-page {
  position: relative;
  min-height: 100vh;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--bg);
}

.login-page::before {
  content: '';
  position: absolute;
  width: 560px;
  height: 560px;
  left: 50%;
  top: 50%;
  transform: translate(-50%, -50%);
  background: radial-gradient(circle, var(--accent-2-wash), transparent 70%);
  filter: blur(40px);
  pointer-events: none;
}

.login-card {
  position: relative;
  width: 320px;
  background-image:
    linear-gradient(var(--panel), var(--panel)),
    linear-gradient(90deg, var(--accent-2), var(--accent-2-light));
  background-origin: border-box;
  background-clip: padding-box, border-box;
  border: 1px solid var(--border);
  border-top: 2px solid transparent;
  border-radius: var(--radius-lg);
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 14px;
}

.login-logo { text-align: center; padding: 0 0 8px; border: none; margin: 0; }

/* Тот же приём, что и у .ai-card-icon - монограмма перекликается с
   фавиконкой вкладки браузера, вместо голого текста на входе. */
.login-mark {
  width: 40px;
  height: 40px;
  margin: 0 auto 10px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--accent-2-light), var(--accent-2-dark));
  box-shadow: 0 6px 18px var(--accent-2-strong);
  color: var(--accent-text);
  font-weight: 700;
  font-size: 14px;
  letter-spacing: 0.02em;
}

.login-card label {
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: 13px;
  color: var(--muted);
}

.login-card input {
  padding: 8px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--bg);
  color: var(--text);
  font-size: 14px;
}

.login-card input:focus {
  outline: none;
  border-color: var(--accent-2);
  box-shadow: var(--accent-2-ring);
}

.login-card button { margin-top: 6px; }

/* --- Пользователь в сайдбаре --- */

.sidebar-user {
  padding: 6px 20px;
  border-top: 1px solid var(--border);
  font-size: 13px;
}

.sidebar-user-name { color: var(--text); font-weight: 600; }
.sidebar-user-role { color: var(--muted); font-size: 12px; margin-bottom: 8px; }

.sidebar-user form { margin: 0; }

.logout-button {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  font-size: 12px;
  font-weight: 400;
  padding: 5px 10px;
  width: 100%;
}

.logout-button:hover { color: var(--text); border-color: var(--accent-2-soft); }

/* --- Управление: Цели/Неделя, Идеи --- */

.week-label {
  font-weight: 600;
  white-space: nowrap;
}

.mgmt-table td { white-space: normal; vertical-align: top; }

.mgmt-input {
  width: 100%;
  min-width: 90px;
  padding: 6px 8px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  font-size: 13px;
  font-family: inherit;
}

.mgmt-input:hover { border-color: var(--border); }
.mgmt-input:focus {
  border-color: var(--accent-2);
  background: var(--bg);
  box-shadow: var(--accent-2-ring);
  outline: none;
}

.mgmt-input-wide { min-width: 200px; }
.mgmt-input-narrow { min-width: 56px; width: 56px; }

/* Закрепляет колонку при горизонтальной прокрутке широкой CRUD-таблицы -
   тот же приём, что и у .cashflow-row-label/.opiu-row-label, перенесённый
   на таблицы раздела "Управление". */
.mgmt-table .mgmt-sticky-col { position: sticky; left: 0; z-index: 1; background: var(--panel); border-right: 1px solid var(--border); min-width: 220px; }
.mgmt-table thead .mgmt-sticky-col { background: var(--panel-deep); }

.mgmt-delete {
  background: transparent;
  border: 1px solid var(--border);
  color: var(--muted);
  width: 28px;
  height: 28px;
  padding: 0;
  border-radius: 6px;
  font-size: 16px;
  line-height: 1;
  cursor: pointer;
}

.mgmt-delete:hover { color: var(--danger); border-color: var(--danger); opacity: 1; }

.mgmt-add-form {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
  margin-top: 16px;
  padding-top: 16px;
  border-top: 1px solid var(--border);
}

.mgmt-add-input { min-width: 240px; flex: 1; }

.mgmt-add-form input, .mgmt-add-form select {
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--panel);
  color: var(--text);
  font-size: 14px;
}

.mgmt-add-form input:focus, .mgmt-add-form select:focus {
  outline: none;
  border-color: var(--accent-2);
  box-shadow: var(--accent-2-ring);
}

.priority-auto { font-weight: 700; text-align: center; font-variant-numeric: tabular-nums; font-size: var(--fs-small); }

/* var(--fs-small) явно - иначе .muted-cell в CRUD-таблицах наследует общее
   th,td{font-size:14px}, а соседний .mgmt-input в той же строке - 13px, и
   статичные/редактируемые ячейки одной строки визуально не совпадают по
   размеру (только размер - вес/выравнивание .muted-cell не трогаем, он
   используется и для обычного текста, не только для чисел). */
.mgmt-table .muted-cell { font-size: var(--fs-small); }

/* Автосейв: фон ячейки плавно проявляется и гаснет вместо мгновенного скачка.
   Transition висит на td постоянно (не только пока есть .flash-row), поэтому
   работает симметрично что при добавлении, что при снятии класса.
   .cashflow-table сюда же - тот же приём для автосейва на странице Cash Flow. */
.mgmt-table td, .cashflow-table td, .opiu-table td { transition: background-color var(--dur-flash) var(--ease-standard); }

/* Подсветка строки при наведении - тот же приём и цвет (var(--panel-hover)),
   что уже был только у .mgmt-table--compact .goal-row-summary (см. выше),
   теперь и у обычных плоских таблиц (Идеи, ОПиУ, Cash Flow) - раньше там
   не было вообще никакой обратной связи на курсор, строки читались как
   статичная картинка. Липкую колонку (.mgmt-sticky-col/.opiu-row-label/
   .cashflow-row-label) красим отдельно - у неё свой непрозрачный фон для
   горизонтальной прокрутки, общее правило её не достанет. */
.mgmt-table tbody tr:hover td { background: var(--panel-hover); }
.mgmt-table tbody tr:hover .mgmt-sticky-col { background: var(--panel-hover); }
.opiu-table tbody tr:hover td { background: var(--panel-hover); }
.opiu-table tbody tr:hover .opiu-row-label { background: var(--panel-hover); }
.cashflow-table tbody tr:not(.cashflow-section-row):hover td { background: var(--panel-hover); }
.cashflow-table tbody tr:hover .cashflow-row-label { background: var(--panel-hover); }

/* Красный/жёлтый оставлены только там, где сама величина плохая прямо
   сейчас (см. правило цвета) - рабочий статус "Перенесено"/"В работе" сам
   по себе не тревога, поэтому обе строки нейтральны, как "Не выполнено".
   Просрочку показывает отдельная плитка "Просроченных задач" выше таблицы -
   дублировать её ещё и красным по всей строке не нужно. */
.goal-row.status-done td { background: rgba(95, 217, 127, 0.08); }
.goal-row.status-in-progress td,
.goal-row.status-postponed td,
.goal-row.status-not-done td { background: rgba(154, 154, 162, 0.12); }

/* Обобщённый маркер "эта строка/ячейка отличается от соседних" - левая
   цветная полоса. Используется точечно, где именно эта информация не
   покрыта уже существующими .amount-negative/.status-* (см. конкретные
   страницы). */
.row-flag { border-left: 3px solid transparent; padding-left: 11px; }
.row-flag--danger { border-left-color: var(--danger); }
.row-flag--accent { border-left-color: var(--accent-2); }
.row-flag--muted { border-left-color: var(--muted); }

/* Специфичность .mgmt-table .flash-row td (2 класса + tag) равна специфичности
   .goal-row.status-* td выше — при равной специфичности побеждает правило,
   расположенное НИЖЕ по файлу, поэтому это правило обязано идти именно здесь,
   иначе зелёная вспышка снова окажется перекрыта цветом статуса. У
   .cashflow-table такого конфликта нет, но правило держим рядом для единства. */
.mgmt-table .flash-row td, .cashflow-table .flash-row td, .opiu-table .flash-row td { background: rgba(95, 217, 127, 0.18); }

/* ---- Удаление строки: у ячеек схлопываются вертикальные отступы и нижняя
   граница, содержимое гаснет чуть быстрее (140ms), чем схлопывается
   геометрия (220ms) — так текст не "обрубается" на середине. Высота самой
   строки нигде не анимируется явно: в table-layout она — производная
   величина от высоты ячеек, поэтому схлопывание padding у td надёжно тянет
   за собой высоту <tr> без хрупкого transition на height у table-row.
   Соседние строки поднимаются обычным reflow, без анимаций на них самих. ---- */
.mgmt-table tr.row-removing td {
  overflow: hidden;
  padding-top: 0;
  padding-bottom: 0;
  border-bottom-width: 0;
  opacity: 0;
  transition: padding-top var(--dur-moderate) var(--ease-in-out),
              padding-bottom var(--dur-moderate) var(--ease-in-out),
              border-bottom-width var(--dur-moderate) var(--ease-in-out),
              opacity 140ms var(--ease-in);
}

/* ---- Кнопки форм с обычной (не-AJAX) отправкой: индикатор "идёт выполнение"
   до перезагрузки страницы браузером. Текст прячется (не удаляется — ширина
   кнопки не прыгает), по центру крутится фирменный золотой спиннер. ---- */
button.is-loading, .button.is-loading {
  position: relative;
  color: transparent !important;
  pointer-events: none;
  cursor: default;
}

button.is-loading::after, .button.is-loading::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 50%;
  width: 14px;
  height: 14px;
  margin: -8px 0 0 -8px;
  border-radius: 50%;
  border: 2px solid var(--accent-2-pale);
  border-top-color: transparent;
  animation: btn-spin 0.6s linear infinite;
}

@keyframes btn-spin {
  to { transform: rotate(360deg); }
}

/* --- Cash Flow: плотная таблица день×категория внутри аккордеона месяца.
   Первая колонка (название показателя) закреплена при горизонтальном
   скролле - иначе на 31 колонке для дня совсем теряется, что за строка. --- */

.cashflow-month-plan-row {
  display: flex;
  align-items: center;
  gap: 10px;
  margin-bottom: 12px;
  font-size: 13px;
  color: var(--muted);
}

.cashflow-month-plan-row .cashflow-value { font-weight: 600; color: var(--text); }

/* table-layout ОБЫЧНЫЙ (не fixed) - иначе браузер сжимает все 31-32 колонки
   дней в ширину контейнера вместо того, чтобы таблица стала шире и
   появилась горизонтальная прокрутка (как в самой Google-таблице). */
.cashflow-table { border-collapse: collapse; }

/* Облегчение таблицы (решение владельца 21.09.2026, "облегчи таблицу") -
   убираем сплошную сетку border-bottom на каждой строке (она унаследована
   от общего "th, td" правила и на 30+ колонках дней читается очень тяжело),
   добавляем чуть больше воздуха отступами и лёгкую зебру по строкам вместо
   линий - так проще держать взгляд на нужной строке в длинной таблице, не
   упираясь в сплошную сетку. У section-row/balance-row свои более
   специфичные правила border ниже - эта строка их не перебивает. */
.cashflow-table th, .cashflow-table td {
  padding: 6px 4px;
  text-align: center;
  white-space: nowrap;
  min-width: 68px;
  border-bottom: none;
}

.cashflow-table th { font-weight: 500; }

/* Разделитель шапка/тело - единственная граница, которую сознательно
   оставляем (без неё дни недели визуально сливались бы с первой строкой
   таблицы). */
.cashflow-table thead th { border-bottom: 1px solid var(--border); }

.cashflow-table tbody tr:not(.cashflow-section-row):not(.cashflow-balance-row):not(.cashflow-row-reference):not(.cashflow-row-dividends):nth-child(even) td {
  background: var(--panel-hover);
}

/* .cashflow-table .cashflow-row-label (а не просто .cashflow-row-label) -
   специфичность должна перебить общее ".cashflow-table td { min-width: 68px }"
   выше, иначе колонка с названием показателя тоже растягивается как день. */
.cashflow-table .cashflow-row-label {
  position: sticky;
  left: 0;
  z-index: 1;
  width: 190px;
  min-width: 190px;
  max-width: 190px;
  text-align: left !important;
  white-space: normal !important;
  background: var(--panel);
  border-right: 1px solid var(--border);
  font-size: 13px;
}

/* Зебра (см. выше) должна захватывать и закреплённую колонку названия, а
   не только "уезжающие" при скролле колонки дней - иначе на чётных строках
   был бы виден шов между подсвеченной областью значений и обычным фоном
   у названия показателя. Специфичность выше, чем у background: var(--panel)
   в правиле над этим - сюда добавлена ещё tr:nth-child(even). */
.cashflow-table tbody tr:not(.cashflow-section-row):not(.cashflow-balance-row):not(.cashflow-row-reference):not(.cashflow-row-dividends):nth-child(even) .cashflow-row-label {
  background: var(--panel-hover);
}

/* flex - на внутреннем div, не на самой <td>: display:flex прямо на <td>
   ломает её как ячейку таблицы (браузер выбрасывает её из потока строки -
   тот же баг уже был найден и исправлен для .task-check-cell/.task-text-cell
   в Задачах, см. соответствующий коммит). Текст и кнопка "🔎" - раздельные
   flex-элементы: текст получает свою "колонку" и переносится сколько нужно,
   кнопка - фиксированную соседнюю "колонку" и не переносится сама по себе
   на отдельную строку в одиночестве (баг, найденный при ревью 19.09.2026 -
   на узкой мобильной ширине колонки у пары длинных названий категорий
   значок "отваливался" один на новую строку). */
.cashflow-row-label-inner { display: flex; align-items: baseline; gap: 4px; }
.cashflow-row-label-text { min-width: 0; flex: 1 1 auto; }

.cashflow-row-label-muted { color: var(--muted); font-weight: 400; }

.cashflow-table thead .cashflow-row-label { background: var(--panel-deep); }

.cashflow-table th.cashflow-today {
  color: var(--text);
  background: var(--accent-2-wash);
  border-radius: var(--radius-sm);
}

/* Решение владельца 30.09.2026 ("оформление должно быть такое же, как у
   каждого месяца в гугл таблице") - цвета строк ниже (.cashflow-section-row,
   .cashflow-balance-row, .cashflow-row-reference, .cashflow-row-dividends)
   сверены напрямую с исходным листом "Cash Flow" через Google Sheets API
   (spreadsheets.get с userEnteredFormat) - "Приход"/"Расход"/"Остаток на
   конец дня" зелёные (#34a853), справочные строки-балансы розовые
   (#d5a6bd), "Дивиденды" - ярко-зелёная (#00ff00), и везде обычный чёрный
   текст без инверсии - ровно то же сочетание цветов, что и в самой
   таблице, одинаковое во всех проверенных месяцах (январь-октябрь), поэтому
   цвета зашиты как есть, а не через light-dark()/var(--text) - "то же
   самое" важнее, чем адаптация под тему сайта. */
.cashflow-section-row td {
  text-align: left !important;
  color: #000;
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding-top: 10px;
  background: #34a853;
  border-bottom: 1px solid var(--border);
}

/* Тот же приём, что и у .cashflow-section-row - разделитель-подпись при
   смене календарного дня в плоских таблицах-журналах (не только Cash Flow),
   поэтому отдельный класс, не привязанный к конкретной странице. */
.day-group-row td {
  text-align: left !important;
  color: var(--muted);
  font-size: var(--fs-micro);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding-top: var(--space-3);
  background: transparent;
  border-bottom: 1px solid var(--border);
}

/* Без display/padding здесь - внутри .cashflow-table это сам <td> (уже
   стилизован общим ".cashflow-table th, .cashflow-table td" правилом выше),
   а не вложенный элемент; inline-block нужен только там, где класс правда
   на <span> - см. ".cashflow-month-plan-row .cashflow-value" ниже. */
.cashflow-value { color: var(--text); font-size: 12px; }

.cashflow-balance-row .cashflow-value { font-weight: 700; }

/* Уголок-индикатор заметки ячейки (см. day.note_value() в cashflow.html) -
   тот же приём, что и жёлтый треугольник в самой Google-таблице: значение
   ячейки не трогаем. Подсказка - по клику (см. .cashflow-note-popup и
   скрипт ниже в cashflow.html), не по наведению - решение владельца
   21.09.2026, "чтобы не ждать" (нативный title у браузера всегда показывает
   подсказку с задержкой). */
.cashflow-value--noted { position: relative; cursor: pointer; }
.cashflow-value--noted::after {
  content: "";
  position: absolute;
  top: 0;
  right: 0;
  border-width: 6px 6px 0 0;
  border-style: solid;
  border-color: var(--accent-2) transparent transparent transparent;
}

/* Попап заметки ячейки - один элемент на страницу, создаётся и позиционируется
   в JS (position: fixed, координаты из getBoundingClientRect клика). */
.cashflow-note-popup {
  position: fixed;
  z-index: 50;
  max-width: 260px;
  padding: 8px 10px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--accent-2-glow);
  background: var(--panel);
  color: var(--text);
  font-size: var(--fs-small);
  line-height: 1.4;
  box-shadow: var(--shadow-edge-card);
  white-space: normal;
}

/* Тот же визуальный вес, что у .opiu-row-sum на соседней странице той же
   группы - итоговая строка остатка дня явно отделена от строк-категорий.
   Тот же зелёный, что и у .cashflow-section-row (см. комментарий там) - в
   исходной таблице "Остаток на конец дня" закрашена одинаково с "Приход"/
   "Расход". :not(.cashflow-computed) - у прогнозных (ещё не внесённых)
   дней остаётся свой золотистый курсив (см. .cashflow-computed ниже) -
   иначе этот сигнал "это расчёт, не факт" терялся бы под чёрным текстом. */
.cashflow-balance-row td { background: #34a853; border-top: 1px solid var(--border); }
.cashflow-balance-row td:not(.cashflow-computed) { color: #000; }
.cashflow-table .cashflow-balance-row .cashflow-row-label { background: #34a853; color: #000; }

/* Справочные строки-балансы ("Баланс OZON"/"План заказы"/"Вывод с баланс…",
   см. REFERENCE_CATEGORIES в app/cashflow/categories.py) и строка "Дивиденды"
   (единственная категория расхода, закрашенная в исходной таблице) - см.
   комментарий у .cashflow-section-row выше про сверку цветов с таблицей. */
.cashflow-row-reference td { background: #d5a6bd; color: #000; }
.cashflow-table .cashflow-row-reference .cashflow-row-label { background: #d5a6bd; color: #000; }

.cashflow-row-dividends td { background: #00ff00; color: #000; }
.cashflow-table .cashflow-row-dividends .cashflow-row-label { background: #00ff00; color: #000; }

.cashflow-computed {
  color: var(--accent-2-pale);
  font-style: italic;
}

/* Лёгкая сводка за выбранный месяц (см. dashboard_month в app/routers/
   cashflow.py) - доход/расход/доступно сейчас, донат крупнейших статей
   расхода и график их динамики по дням, не полноценная аналитика.
   Доход/расход - те же .stat-tile.pulse-tile, что и на главной
   (переиспользуют --cat-money/--danger, а не заводят свою палитру).

   Решение владельца 18.09.2026 (правки раздела Cash Flow, пункт 2):
   прежнее ранжирование однотонными горизонтальными барами (магнитуда через
   длину, без цвета на категорию - при 13 статьях расхода отдельный цвет на
   каждую был бы нечитаем) заменено на донат + график - цвет теперь нужен
   ровно на 5 категорий одновременно (top-5 + "Прочее"), это уже читаемо, а
   собственный цвет на категорию даёт "быстрый переход" (клик по легенде
   подсвечивает её же дугу и переключает график, см. cashflow.html) - без
   этого клик было бы не на что вешать. */
.cashflow-expense-ranking-title {
  font-size: var(--fs-small);
  color: var(--muted);
  margin-bottom: var(--space-2);
}

/* Переключатель периода (решение владельца 24.09.2026, референс - другое
   приложение) - месяцы растянуты во всю ширину слева, год раскрывающимся
   списком справа, вместо прежних двух отдельных рядов табов друг под
   другом. */
.cashflow-period-bar {
  display: flex;
  align-items: center;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
  flex-wrap: wrap;
}

.cashflow-tabs { flex-wrap: wrap; margin-bottom: var(--space-3); }

/* Месяц - каждый в своей мягкой овальной обводке (просьба владельца
   24.09.2026, референс - было раньше просто подчёркивание активного без
   рамки у соседей). --stretch делит доступную ширину поровну между всеми
   12 месяцами (flex: 1 на каждой пилюле), не переносится построчно, как
   раньше - на узком экране см. media-запрос ниже. Крупнее (padding/шрифт)
   и активная пилюля зелёная, не золотая (просьба владельца 26.09.2026,
   "того же цвета, размера и длины, как на референсе") - осознанное
   разовое исключение из монохром+золото на этом одном элементе, не новый
   токен для всего сайта (--cashflow-month-active ниже, а не --accent-2). */
.cashflow-tabs--stretch { flex: 1; min-width: 0; flex-wrap: nowrap; margin-bottom: 0; gap: 6px; }
.cashflow-month-pill {
  --cashflow-month-active: light-dark(#1e7a4e, #2f9c68);
  flex: 1;
  padding: 11px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  text-align: center;
  text-decoration: none;
  color: var(--muted);
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
}
.cashflow-month-pill:hover { border-color: var(--cashflow-month-active); color: var(--text); }
.cashflow-month-pill.active { background: var(--cashflow-month-active); border-color: var(--cashflow-month-active); color: #fff; }

/* Год - раскрывающийся список справа от месяцев (просьба владельца
   24.09.2026), тот же смысл, что и у прежних отдельных пилюль года (только
   текущий год кликабелен - см. app/routers/cashflow.py _AVAILABLE_YEARS),
   но одна кнопка-триггер вместо трёх пилюль рядом. */
.cashflow-year-picker { position: relative; flex-shrink: 0; }
.cashflow-year-trigger {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: transparent;
  color: var(--text);
  font-size: 13px;
  font-weight: 700;
  cursor: pointer;
}
.cashflow-year-trigger:hover, .cashflow-year-trigger[aria-expanded="true"] { border-color: var(--accent-2); }
.cashflow-year-trigger svg { width: 14px; height: 14px; color: var(--muted); }

.cashflow-year-popover {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
  min-width: 100px;
  padding: 6px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 32px -14px rgba(0, 0, 0, 0.6);
  z-index: 20;
}
/* display: flex выше - авторское правило, которое иначе побеждает UA-стиль
   [hidden]{display:none} независимо от специфичности (тот же баг, что уже
   один раз находили на этой странице - см. .cashflow-tile-detail[hidden]
   ниже) - попап был бы виден сразу при загрузке страницы, хотя JS и
   атрибут hidden расставлены верно. */
.cashflow-year-popover[hidden] { display: none; }
.cashflow-year-option {
  padding: 6px 10px;
  border-radius: 6px;
  text-align: center;
  text-decoration: none;
  color: var(--text);
  font-size: 13px;
  font-weight: 600;
}
.cashflow-year-option:hover { background: var(--panel-hover); }
.cashflow-year-option.active { background: var(--accent-2-wash); color: var(--accent-2-pale); }

.cashflow-tab-disabled {
  color: var(--muted);
  opacity: 0.4;
  cursor: default;
}

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

/* Курс $ → ₽ (просьба владельца 24.09.2026) - узкая инлайн-форма прямо на
   странице, единственное место, где это число вообще вводится (нигде в
   Google-таблице курса нет, см. app/cashflow/store.py cashflow_settings). */
.cashflow-rate-form {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
  flex-wrap: wrap;
}
.cashflow-rate-form label { font-size: 13px; color: var(--muted); }
.cashflow-rate-form input {
  width: 90px;
  padding: 6px 10px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--panel);
  color: var(--text);
  font-size: 13px;
}
.cashflow-rate-form input:focus { outline: none; border-color: var(--accent-2); box-shadow: var(--accent-2-ring); }

/* Строка "≈ N $" под рублёвым значением плитки (просьба владельца
   24.09.2026, "учитывай в двух валютах") - то же число, просто в другой
   валюте, не отдельная сумма, поэтому приглушённая и мельче основного
   .stat-value, тем же приёмом, что и .cashflow-tile-sources ниже. */
.cashflow-tile-usd { margin-top: 2px; font-size: 12px; color: var(--muted); font-variant-numeric: tabular-nums; }

/* "Расходы в {месяц}" + "Последние операции" рядом (решение владельца
   24.09.2026, референс - другое приложение) - заменяет прежние
   .cashflow-analytics (донат+линия) и отдельную .cashflow-year-strip-card
   (полоска по месяцам года, убрана целиком). */
.cashflow-columns {
  display: grid;
  grid-template-columns: minmax(280px, 1fr) minmax(260px, 380px);
  gap: var(--space-4);
  align-items: start;
  margin-bottom: var(--space-5);
}

.cashflow-expenses-card, .cashflow-recent-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 14px 20px;
}

.cashflow-card-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); }
.cashflow-card-head .cashflow-expense-ranking-title { margin-bottom: 0; }

/* Переключатель "◔ Круговая / 📈 Линейная" (просьба владельца 24.09.2026) -
   тот же приём компактных пилюль, что и .sort-toggle, только на 2 иконки. */
.cashflow-chart-toggle { display: inline-flex; gap: 2px; padding: 2px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--panel); flex-shrink: 0; }
.cashflow-chart-toggle-btn {
  width: 26px;
  height: 26px;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--muted);
  font-size: 13px;
  cursor: pointer;
}
.cashflow-chart-toggle-btn.active { background: var(--panel-hover); color: var(--text); }

.cashflow-pie-wrap {
  position: relative;
  width: 140px;
  height: 140px;
  margin: 0 auto var(--space-3);
}

/* Донат - концентрические дуги одного круга (stroke-dasharray/dashoffset на
   каждой), не один conic-gradient - клику по легенде нужно подсветить
   ИМЕННО одну дугу (добавить класс на конкретном <circle>, см. JS в
   cashflow.html), плоский градиент так просто не разбить на интерактивные
   куски. -90deg - чтобы первая дуга начиналась сверху (12 часов), а не
   справа (0deg - направление по умолчанию у SVG-окружности). */
.cashflow-pie { width: 100%; height: 100%; transform: rotate(-90deg); overflow: visible; }

.cashflow-pie-bg, .cashflow-pie-slice {
  fill: none;
  stroke-width: 16;
}

.cashflow-pie-bg { stroke: var(--border); }

.cashflow-pie-slice {
  transition: opacity var(--dur-fast) var(--ease-standard), stroke-width var(--dur-fast) var(--ease-standard);
}

.cashflow-pie:has(.cashflow-pie-slice.active) .cashflow-pie-slice:not(.active) { opacity: 0.35; }
.cashflow-pie-slice.active { stroke-width: 19; }

.cashflow-pie-total {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  pointer-events: none;
}

.cashflow-pie-total .stat-value { font-size: 18px; }
.cashflow-pie-total .stat-label { margin-top: 0; }

.cashflow-pie-legend { list-style: none; margin: 0; padding: 0; }

/* Иконка + название + сумма, и всё (просьба владельца 24.09.2026,
   референс - "указано просто название расхода и всё", "не нужно рядом с
   суммой раскрывающегося списка") - было 5 колонок (точка/название/
   полоска доли/сумма/процент), полоску и процент убрали, точку заменили
   на цветной кружок-иконку (см. .cashflow-legend-icon). */
.cashflow-legend-row {
  display: flex;
  align-items: center;
  gap: 10px;
  width: 100%;
  padding: 6px 8px;
  margin: 0 -8px;
  border: none;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--text);
  font-size: 13px;
  text-align: left;
  cursor: pointer;
}

.cashflow-legend-row:hover { background: var(--panel-hover); }
.cashflow-legend-row:hover, .cashflow-legend-row:focus-visible { box-shadow: none; }
.cashflow-legend-row.active { background: var(--panel-hover); font-weight: 600; }

.cashflow-legend-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 30px;
  height: 30px;
  flex-shrink: 0;
  border-radius: 50%;
  font-size: 14px;
}
.cashflow-legend-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; font-weight: 600; }
.cashflow-legend-value { flex-shrink: 0; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* График динамики - тот же приём, что .pulse-hero-chart на главной
   (см. app/dashboard/charts.py build_expense_series_charts): готовые
   <path> на сервере, здесь только показ/скрытие по клику (.cashflow-line-
   hidden), без JS-библиотек. Несколько рядов лежат в одном <svg> сразу -
   переключение мгновенное, без похода на сервер. */
.cashflow-line-chart { width: 100%; height: 130px; overflow: visible; }
.cashflow-line-hidden { display: none; }
.cashflow-line-caption { margin-top: var(--space-2); margin-bottom: 0; }

/* ---- Расширение дашбордов Cash Flow (решение владельца 19.09.2026):
   тренд-бейджи на плитках сводки, разбивка дохода по источникам, полоска
   расхода по месяцам года, карточка "Детали" по категории. ---- */

.cashflow-tile-sources { margin-top: var(--space-1); font-size: 12px; color: var(--muted); }

.cashflow-trend-badge {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  margin-top: var(--space-2);
  padding: 3px 8px;
  border: none;
  border-radius: var(--radius-pill);
  background: var(--panel-hover);
  font-size: 11px;
  font-weight: 600;
  cursor: pointer;
  color: var(--muted);
}
.cashflow-trend-badge:hover, .cashflow-trend-badge--open { box-shadow: inset 0 0 0 1px var(--border); }
.cashflow-trend-badge--good { color: var(--cat-money-text); background: var(--cat-money-wash); }
.cashflow-trend-badge--bad { color: var(--danger); background: light-dark(rgba(217, 67, 67, 0.1), rgba(255, 107, 107, 0.12)); }

.cashflow-tile-detail {
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
/* Баг найден 22.09.2026: собственный display:flex у .cashflow-tile-detail
   (авторский CSS) перебивает display:none из браузерного UA-стиля для
   [hidden] (авторские правила всегда сильнее UA, даже при равной
   специфичности) - панель показывалась развёрнутой сразу при загрузке
   страницы, хотя JS-тумблер и атрибут hidden были расставлены верно. На
   /cashflow это было незаметно (никто не смотрел на самую первую отрисовку
   не разворачивая), на главной - сразу бросилось в глаза (три новые
   плитки открыты по умолчанию). Специфичность класс+атрибут (0,2,0) выше
   голого класса (0,1,0) - побеждает без !important. */
.cashflow-tile-detail[hidden] { display: none; }
.cashflow-tile-detail-row { display: flex; justify-content: space-between; gap: var(--space-2); font-size: 12px; color: var(--text); }
.cashflow-tile-detail-row--sub { color: var(--muted); padding-left: var(--space-2); }

.cashflow-detail-trigger {
  flex-shrink: 0;
  width: 22px;
  height: 22px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font-size: 11px;
  line-height: 1;
}
.cashflow-detail-trigger:hover { color: var(--accent-2); border-color: var(--accent-2); }

/* Ссылка "Разбивка по категориям →" в плитке "Расход за месяц" - тот же
   .cashflow-detail-trigger (открывает общую модалку "Детали"), но текстом,
   а не иконкой 22x22 - переопределяем размер/рамку под текст. */
.cashflow-tile-detail-more {
  align-self: flex-start;
  width: auto;
  height: auto;
  margin-top: 2px;
  padding: 0;
  border: none;
  color: var(--accent-2-pale);
  font-size: 12px;
  font-weight: 600;
}
.cashflow-tile-detail-more:hover { color: var(--accent-2); border-color: transparent; text-decoration: underline; }

/* .cashflow-detail-trigger--inline: раньше был отдельный margin-left, но
   кнопка теперь flex-элемент в .cashflow-row-label-inner (gap там же) - свой
   отступ здесь больше не нужен. */

/* "Последние операции" (просьба владельца 24.09.2026) - см. .cashflow-
   recent-card/cashflow.html: ближайший доступный аналог при том, что в
   данных нет отдельных проводок со своим временем, только запись на
   (день, категория), см. app/cashflow/report.py recent_entries. */
.cashflow-recent-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; }
.cashflow-recent-row {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-2) 0;
  border-bottom: 1px solid var(--border);
}
.cashflow-recent-row:last-child { border-bottom: none; }

.cashflow-recent-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  flex-shrink: 0;
  border-radius: 50%;
  background: light-dark(rgba(217, 67, 67, 0.1), rgba(255, 107, 107, 0.12));
  color: var(--danger);
  font-weight: 700;
}
.cashflow-recent-icon--income { background: var(--cat-money-wash); color: var(--cat-money-text); }

.cashflow-recent-main { flex: 1; min-width: 0; }
.cashflow-recent-category { font-size: 13px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cashflow-recent-meta { margin-top: 2px; font-size: 12px; color: var(--muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.cashflow-recent-amount { flex-shrink: 0; font-variant-numeric: tabular-nums; font-weight: 600; color: var(--danger); }
.cashflow-recent-amount--income { color: var(--cat-money-text); }

/* Карточка "Детали" по категории расхода - тот же нативный <dialog>, что и
   #task-modal в app/templates/tasks.html (свой backdrop/Esc, закрытие через
   <form method="dialog"> без единой строчки JS), но шире - внутри
   прокручиваемый список до 31 строки, а не форма из нескольких полей. */
.cashflow-detail-modal {
  width: min(480px, calc(100vw - 32px));
  max-height: min(560px, calc(100vh - 64px));
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--panel);
  color: var(--text);
}
.cashflow-detail-modal::backdrop { background: rgba(0, 0, 0, 0.6); }
.cashflow-detail-modal-form { display: flex; flex-direction: column; max-height: min(560px, calc(100vh - 64px)); }
.cashflow-detail-modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: var(--space-4) var(--space-4) var(--space-3);
  border-bottom: 1px solid var(--border);
}
.cashflow-detail-modal-title { margin: 0; font-size: var(--fs-card-title); }
.cashflow-detail-modal-close {
  background: none;
  border: none;
  color: var(--muted);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  padding: 0 4px;
}
.cashflow-detail-modal-close:hover { color: var(--text); }
.cashflow-detail-modal-body { overflow-y: auto; padding: var(--space-2) var(--space-4) var(--space-4); }

.cashflow-detail-panel { list-style: none; margin: 0; padding: 0; }
.cashflow-detail-row {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-2);
  padding: 6px 0;
  border-bottom: 1px solid var(--border);
  font-size: 13px;
  min-width: 0;
}
.cashflow-detail-row:last-child { border-bottom: none; }
.cashflow-detail-row-date { flex-shrink: 0; color: var(--muted); font-variant-numeric: tabular-nums; }
.cashflow-detail-row-amount { font-weight: 600; font-variant-numeric: tabular-nums; }
/* Заметка - произвольный текст из Google Sheets (пасченная ссылка/номер
   заказа без пробелов - реальный случай в бухгалтерских пометках) -
   overflow-wrap, чтобы такая строка переносилась внутри модалки, а не
   раздвигала её шириной в одно "слово" горизонтальным скроллом. */
.cashflow-detail-row-note { color: var(--muted); font-size: 12px; flex-basis: 100%; min-width: 0; overflow-wrap: break-word; }
.cashflow-detail-row--compare {
  justify-content: space-between;
  font-weight: 600;
  color: var(--accent-2-pale);
  border-bottom: 1px solid var(--accent-2-glow);
}
.cashflow-detail-row--empty { color: var(--muted); justify-content: center; }

@media (max-width: 860px) {
  .cashflow-columns { grid-template-columns: 1fr; }
  .cashflow-tabs--stretch { flex-wrap: wrap; }
}

/* --- Плановый ОПиУ: небольшая таблица показатель×месяц. В отличие от
   Cash Flow тут почти всё вычисляется само - редактируемых полей мало
   ("Заказы" по месяцам и ставки), остальные ячейки - просто текст. --- */

.opiu-table th, .opiu-table td {
  padding: 6px 10px;
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}

.opiu-table th { font-weight: 500; color: var(--muted); font-size: 12px; text-transform: uppercase; letter-spacing: 0.03em; }

/* .opiu-table .opiu-row-label (а не просто .opiu-row-label) - та же причина,
   что и у .cashflow-table .cashflow-row-label выше: специфичность должна
   перебить общее ".opiu-table td { ... }", иначе sticky-колонка не
   применится. При горизонтальной прокрутке (месяцы вправо) название
   показателя должно оставаться на месте, как в исходной Google-таблице. */
.opiu-table .opiu-row-label {
  position: sticky;
  left: 0;
  z-index: 1;
  text-align: left !important;
  white-space: normal !important;
  min-width: 220px;
  font-size: 13px;
  background: var(--panel);
  border-right: 1px solid var(--border);
}

.opiu-table thead .opiu-row-label { background: var(--panel-deep); }

.opiu-row-sum .opiu-row-label, .opiu-row-sum td { font-weight: 700; background: var(--panel-hover); }

/* Фон .opiu-row-sum должен победить и на sticky-колонке тоже - иначе она
   "выпадает" из подсветки жирных строк-сумм при прокрутке. rgba() поверх
   прозрачного не сработает на sticky-ячейке (под ней просвечивал бы
   прокручиваемый контент) - тот же var(--panel-hover), что и выше, вместо
   вручную посчитанного смешения (то давало один фиксированный HEX и не
   переживало смену темы). */
.opiu-table .opiu-row-sum .opiu-row-label { background: var(--panel-hover); }

.opiu-total-cell { color: var(--text); font-weight: 700; }

/* Тот же приём, что и .cashflow-table .cashflow-today на соседней странице
   той же группы меню - подсветка текущего месяца, для единого языка внутри
   группы "План продаж/ОПиУ". Здесь - на весь столбец (th и td), не только
   на заголовок. */
.opiu-table th.opiu-today, .opiu-table td.opiu-today {
  color: var(--text);
  background: var(--accent-2-wash);
  border-radius: var(--radius-sm);
}

/* .opiu-today на td (в отличие от .cashflow-today, который только на th)
   имеет ту же специфичность, что .opiu-table .flash-row td выше - при
   автосейве в текущем месяце подсветка "текущий месяц" гасила бы зелёную
   вспышку. Добавляем более специфичное правило, а не переставляем блоки
   местами, чтобы не сломать порядок, важный для .mgmt-table (см. комментарий
   у .mgmt-table .flash-row td). */
.opiu-table .flash-row td.opiu-today { background: rgba(95, 217, 127, 0.18); }

.opiu-input {
  width: 76px;
  padding: 4px 6px;
  border: 1px solid transparent;
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  font-size: 12px;
  font-family: inherit;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.opiu-input:hover { border-color: var(--border); }
.opiu-input:focus {
  border-color: var(--accent-2);
  background: var(--bg);
  box-shadow: var(--accent-2-ring);
  outline: none;
}

.opiu-rate { width: 56px; color: var(--accent-2-pale); }

/* --- Глобальные состояния: фокус, выделение текста, скроллбар --- */

:focus-visible {
  outline: 2px solid var(--accent-2);
  outline-offset: 2px;
}

::selection { background: var(--accent-2-glow); color: var(--text); }

::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: var(--bg); }
::-webkit-scrollbar-thumb { background: var(--border); border-radius: var(--radius-pill); border: 2px solid var(--bg); }
::-webkit-scrollbar-thumb:hover { background: var(--accent-2-dark); }

/* Плавная инерционная прокрутка широких таблиц пальцем на iOS - на десктопе
   и Android ни на что не влияет, свойство там просто игнорируется. */
.table-wrap, .article-body-inner { -webkit-overflow-scrolling: touch; }

/* --- Мобильная адаптация ---------------------------------------------
   На десктопе сайдбар всегда виден в потоке (см. .sidebar выше). На узком
   экране ему негде поместиться рядом с контентом - он становится выезжающей
   поверх контента панелью (position: fixed, скрыта за левым краем через
   translateX, пока не добавлен .open), а кнопка-гамбургер и подложка-
   затемнение управляют её показом (см. JS в base.html). Кнопка/подложка
   лежат в разметке всегда, но display:none их скрывает на десктопе - ниже
   это единственное место, где они становятся видимыми. */

.mobile-menu-toggle {
  display: none;
  position: fixed;
  top: 12px;
  left: 12px;
  z-index: 210;
  width: 40px;
  height: 40px;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 4px;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  cursor: pointer;
}

.mobile-menu-toggle span {
  display: block;
  width: 18px;
  height: 2px;
  background: var(--text);
  border-radius: 1px;
  transition: transform var(--dur-fast) var(--ease-standard), opacity var(--dur-fast) var(--ease-standard);
}

.mobile-menu-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(6px) rotate(45deg); }
.mobile-menu-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.mobile-menu-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-6px) rotate(-45deg); }

.sidebar-backdrop {
  display: none;
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.55);
  z-index: 199;
}

.sidebar-backdrop.open { display: block; }

@media (max-width: 768px) {
  .mobile-menu-toggle { display: flex; }

  .sidebar {
    position: fixed;
    top: 0;
    left: 0;
    height: 100vh;
    width: min(280px, 82vw);
    z-index: 200;
    transform: translateX(-100%);
    transition: transform var(--dur-accordion) var(--ease-in-out);
    box-shadow: 0 0 40px rgba(0, 0, 0, 0.5);
    overflow-y: auto;
  }

  .sidebar.open { transform: translateX(0); }

  /* Пока открыт выезжающий сайдбар - страница за ним не должна прокручиваться
     (иначе на тач-устройствах палец скроллит фон сквозь затемнение). */
  body.sidebar-open-lock { overflow: hidden; }

  main { padding: 64px 16px 32px; max-width: 100%; }

  /* .stat-tiles без модификатора -wrap (Cash Flow, FBS) на десктопе не
     переносится по строкам - на узком экране плитки должны складываться
     в колонку, а не сжиматься до нечитаемой ширины. */
  .stat-tiles { flex-wrap: wrap; }

  /* Hero-панель баланса (число + график) на десктопе стоит в ряд - на
     телефоне графику просто не остаётся места по ширине, переносим вниз. */
  .pulse-hero { flex-direction: column; gap: 20px; }
  .pulse-hero-figure { min-width: 0; width: 100%; }
  .pulse-hero-chart-wrap { width: 100%; }

  .login-card { width: min(320px, calc(100vw - 32px)); }

  /* Таблицы с фиксированной шириной подписи (Cash Flow/ОПиУ) - несколько
     уже, чтобы больше данных влезало на экран до горизонтальной прокрутки. */
  .cashflow-table .cashflow-row-label { width: 130px; min-width: 130px; max-width: 130px; }
  .opiu-table .opiu-row-label { min-width: 160px; }

  /* Панель настроек поставки в ФБО на всю ширину под загрузкой файла -
     колонкой рядом с ней на узком экране просто не остаётся места. */
  .fbo-shipment-options { min-width: 0; width: 100%; }
}

@media (prefers-reduced-motion: reduce) {
  .sidebar { transition: none; }
  .mobile-menu-toggle span { transition: none; }
}
* { scrollbar-color: var(--border) var(--bg); } /* Firefox: без hover-эффекта — ограничение спецификации CSS, не баг реализации */

/* --- Страница "Помощь" (см. app/templates/help.html) - гид по разделам
   сайта для сотрудников. Секции идут одна под одной на общей странице,
   а не аккордеоном - это справочник, который открывают через поиск по
   странице (Ctrl+F) или через .help-jump, а не листают по порядку. --- */

.help-jump { display: flex; flex-wrap: wrap; gap: 8px; margin-bottom: 28px; }

.help-jump a {
  font-size: 13px;
  color: var(--muted);
  text-decoration: none;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  padding: 6px 14px;
}

.help-jump a:hover { color: var(--text); border-color: var(--accent-2); }

.help-section { padding: 28px 0; border-top: 1px solid var(--border); }
.help-section:first-of-type { border-top: none; padding-top: 8px; }

.help-section h2 { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; font-size: 19px; margin: 0 0 10px; }

.help-route {
  font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  font-size: 12px;
  font-weight: 400;
  color: var(--muted);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 3px 8px;
}

.help-lead { color: var(--muted); font-size: var(--fs-body); max-width: 72ch; margin-bottom: var(--space-4); }

.help-steps { list-style: none; margin: 0 0 16px; padding: 0; counter-reset: help-step; display: flex; flex-direction: column; gap: 10px; }

.help-steps li { counter-increment: help-step; display: flex; gap: 12px; font-size: var(--fs-body); line-height: 1.55; }

.help-steps li::before {
  content: counter(help-step);
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  margin-top: 2px;
  border-radius: 50%;
  background: var(--accent-2-wash);
  color: var(--accent-2-pale);
  font-size: 11.5px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
}

.help-tg {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 12px 15px;
  font-size: var(--fs-small);
  color: var(--muted);
  line-height: 1.55;
}

.help-tg + .help-tg { margin-top: 10px; }

.help-tg-from { font-size: 11px; color: var(--accent-2-pale); text-transform: uppercase; letter-spacing: 0.04em; margin-bottom: 6px; }

/* Лёгкий список справочных фактов - без индивидуальной рамки/подложки на
   пункт (в отличие от .ai-card-bullets, которые остаются только внутри
   настоящего .ai-card на главной). */
.help-list { list-style: none; margin: 0 0 var(--space-4); padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.help-list li { display: flex; gap: var(--space-2); align-items: flex-start; font-size: var(--fs-body); line-height: 1.55; color: var(--text); }
.help-list li::before {
  content: "";
  flex-shrink: 0;
  width: 6px;
  height: 6px;
  margin-top: 7px;
  border-radius: 50%;
  background: var(--muted);
}

/* Нейтральный callout "примечание/контекст" на фирменном акценте - для
   некритичной справочной информации, где .error (красный) был бы слишком
   тревожным сигналом для того, что не является ошибкой. */
.help-note {
  background: var(--accent-2-wash);
  border: 1px solid var(--accent-2-glow);
  border-radius: var(--radius-md);
  padding: 12px 15px;
  color: var(--muted);
  font-size: var(--fs-small);
  line-height: 1.55;
  margin-bottom: var(--space-4);
}

/* ---- Задачи, недельный вид: раскладка по дням (см. app/management/day_grid.py) ---- */

/* "Общее" (задачи без срока/вне недели) + 7 дней - все карточки одной
   ширины, горизонтальный скролл при нехватке места вместо сжатия в кашу.
   340px, не 280px (было) - просьба владельца 26.09.2026: по умолчанию
   видна только текущая и оставшиеся дни недели (см. initTasksPage в
   tasks.html - scrollLeft теперь ровно на todayCard, без "хвостика"
   прошлого дня), прошлых дней в кадре меньше, поэтому оставшимся можно
   отдать больше места - строки задач меньше переносятся, читаются длиннее
   одной строкой, а не коротким списком с кучей переносов. */
.task-day-grid {
  display: grid;
  grid-auto-flow: column;
  grid-auto-columns: minmax(340px, 1fr);
  gap: var(--space-3);
  overflow-x: auto;
  padding-bottom: var(--space-2);
}

.task-day-card {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-3);
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  transition: border-color var(--dur-fast) var(--ease-standard), box-shadow var(--dur-fast) var(--ease-standard);
}

.task-day-card:hover { border-color: var(--accent-2-glow); box-shadow: var(--shadow-edge-card); }

.task-day-card--today { border-color: var(--accent-2); }

.task-day-card-title {
  font-size: var(--fs-small);
  font-weight: 700;
  color: var(--text);
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding-bottom: var(--space-2);
  border-bottom: 1px solid var(--border);
}

.task-day-card--today .task-day-card-title { color: var(--accent-2-pale); border-bottom-color: var(--accent-2-glow); }

/* Название дня и кнопка "+" сгруппированы слева, донут - справа. Без этой
   обёртки justify-content: space-between на .task-day-card-title раскидал
   бы кнопку между ними, в оптический "подвес" посередине заголовка. */
.task-day-card-title-left { display: flex; align-items: center; gap: var(--space-2); }

/* Плотнее обычной .mgmt-table - карточка дня узкая, полей меньше, чем в
   плоской таблице день/месяц (та осталась как есть, см. tasks.html). Без
   табличных линий между строками (border-bottom у обычного td убран) - это
   список задач внутри карточки, а не мини-таблица; разделение строк даёт
   чередующийся фон каждой второй tbody вместо линий. */
/* min-height - реальный баг (владелец, 24.09.2026): у пустого дня (без
   единой задачи) <table> без строк схлопывался почти до 0px, поэтому
   перетащить задачу МЫШЬЮ в такой день было физически некуда - dragover
   ни разу не попадал в его (нулевые по площади) границы, значит и drop
   никогда не разрешался браузером (это отдельно от того, что сам перенос
   между днями уже работал правильно на сервере - см. reorder_tasks в
   app/management/store.py). Высота - примерно на одну строку задачи, тот
   же приём, что и у пустой "Общее" в самом верху. */
.mgmt-table--compact { border-collapse: separate; border-spacing: 0; min-height: 52px; }
.mgmt-table--compact td { padding: 8px; border-bottom: none; }
.mgmt-table--compact tbody:nth-child(odd) .goal-row-summary td { background: rgba(255, 255, 255, 0.015); }
.mgmt-table--compact .goal-row-summary:hover td { background: var(--panel-hover); }

.task-check-cell, .task-toggle-cell, .task-delete-cell { width: 1%; white-space: nowrap; }
.task-check-cell input[type="checkbox"] { width: 16px; height: 16px; cursor: pointer; accent-color: var(--accent-2); }
/* flex живёт на внутреннем div, не на самой <td> - display:flex на td
   ломает её как ячейку таблицы (браузер выбрасывает её из строки, она
   уезжает на отдельную "линию" под соседними ячейками той же <tr>). */
.task-text-inner { display: flex; align-items: flex-start; gap: var(--space-2); }
.task-text-cell .mgmt-input { min-width: 60px; }

/* Служебные колонки (чекбокс/раскрыть/удалить) в узкой карточке дня -
   решение владельца 21.09.2026: у стандартных .mgmt-table--compact td
   (padding: 8px со всех сторон) и .mgmt-delete (28×28px, рассчитан на
   широкую CRUD-таблицу) на три служебные колонки уходило больше места,
   чем оставалось тексту задачи (карточка минимум 240px, тексту доставалось
   меньше 60px) - "Проверка рекламы" не помещалось целиком даже одним
   словом и переносилось посимвольно. Здесь эти колонки уже, у текста
   стало заметно больше места. */
.mgmt-table--compact .task-check-cell,
.mgmt-table--compact .task-toggle-cell,
.mgmt-table--compact .task-delete-cell { padding-left: 2px; padding-right: 2px; }
.mgmt-table--compact .mgmt-delete { width: 22px; height: 22px; font-size: 14px; }
.mgmt-table--compact .goal-row-toggle { padding: 0 2px; }

/* Точка-приоритет для быстрого визуального сканирования списка задач без
   разворачивания detail-строки (см. task_tbody в _task_row.html) - решение
   владельца 21.09.2026 перевести точку с категории на приоритет (тем
   понятнее, что горит, а не к какому домену относится задача). "Высокий"
   переиспользует var(--danger) - тот же смысл "срочно", что и везде на
   сайте; для среднего/низкого своих доменных токенов нет, поэтому свои
   прямые цвета, подобранные по контрасту с --danger и друг другом. */
.priority-dot {
  display: inline-block;
  width: 8px;
  height: 8px;
  margin-top: 9px; /* оптически по центру первой строки .task-text-display при align-items: flex-start */
  border-radius: 50%;
  flex-shrink: 0;
}
.priority-dot[data-priority="Низкий"] { background: #3fbf63; }
.priority-dot[data-priority="Средний"] { background: #d9b310; }
.priority-dot[data-priority="Высокий"] { background: var(--danger); }

/* Разворачивание детальных полей задачи (категория/полный статус/приоритет/
   срок/результат) - стрелка поворачивается на 90° при раскрытии. */
.goal-row-toggle {
  background: none;
  border: none;
  cursor: pointer;
  color: var(--muted);
  padding: 0 4px;
  font-size: var(--fs-body);
  line-height: 1;
  transition: transform var(--dur-fast) var(--ease-standard);
}

.goal-row-toggle.open { transform: rotate(90deg); color: var(--accent-2); }

.goal-row-detail { display: none; }
.goal-row-detail.open { display: table-row; }

.goal-row-detail-fields {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: var(--space-2) 0;
}

/* "Дублировать на завтра"/"Дублировать на неделю" (см. _task_row.html) -
   решение владельца 21.09.2026. В столбик, не в ряд - карточка дня узкая
   (280px), в ряд текст кнопок обрезался бы. */
.goal-row-detail-actions { display: flex; flex-direction: column; gap: 6px; margin-top: 2px; }
.goal-row-detail-actions .task-duplicate-btn { width: 100%; font-size: 12px; padding: 6px 8px; }

/* "+" у даты, открывает общую модалку .task-modal (решение владельца
   18.09.2026 - заменяет прежнюю встроенную форму внизу карточки). */
.task-day-add-trigger {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--muted);
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
}
.task-day-add-trigger:hover { color: var(--accent-2); border-color: var(--accent-2); }

/* Модалка добавления задачи - нативный <dialog>, свой backdrop/Esc, без
   собственного JS-оверлея (см. #task-modal в tasks.html). */
.task-modal {
  width: min(360px, calc(100vw - 32px));
  padding: 0;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--panel);
  color: var(--text);
}
.task-modal::backdrop { background: rgba(0, 0, 0, 0.6); }

.task-modal-form { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-4); }
.task-modal-title { margin: 0; font-size: var(--fs-card-title); }
.task-modal-form label { display: flex; flex-direction: column; gap: 6px; font-size: 13px; color: var(--muted); }
.task-modal-actions { display: flex; justify-content: flex-end; gap: var(--space-2); margin-top: var(--space-1); }

/* Шлюз выбора человека (см. app/routers/management.py show_tasks) -
   раскладка по дням не показывается, пока не выбран явно. Визуальная
   полировка (решение владельца 23.09.2026, "красивее") - те же приёмы,
   что уже приняты в остальном интерфейсе (карточки .stat-tile/.ai-card,
   хореография item-in), а не что-то новое с нуля. */
.task-gate-summary { display: flex; gap: var(--space-3); margin-bottom: var(--space-5); }
.task-gate-summary-item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 16px 22px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--panel);
  box-shadow: var(--shadow-edge-card);
}
.task-gate-summary-item .stat-value { font-size: var(--fs-stat-lg); }
.task-gate-hint { color: var(--muted); font-size: 15px; margin-bottom: var(--space-4); }
.task-gate-cards { display: flex; gap: var(--space-4); flex-wrap: wrap; }
.task-gate-card {
  flex: 1;
  min-width: 240px;
  padding: 22px 24px;
  border: 1px solid var(--border);
  border-radius: var(--radius-2xl);
  background: var(--panel);
  color: inherit;
  text-decoration: none;
  animation: item-in var(--dur-moderate) var(--ease-out) both;
  transition: border-color var(--dur-fast) var(--ease-standard), box-shadow var(--dur-fast) var(--ease-standard), transform var(--dur-fast) var(--ease-standard);
}
.task-gate-card:nth-child(1) { animation-delay: 0ms; }
.task-gate-card:nth-child(2) { animation-delay: 40ms; }
.task-gate-card:nth-child(3) { animation-delay: 80ms; }
.task-gate-card:hover { border-color: var(--accent-2-glow); box-shadow: var(--shadow-edge-card); transform: translateY(-3px); }
.task-gate-card--me { border-color: var(--accent-2-glow); box-shadow: 0 0 0 1px var(--accent-2-glow), var(--shadow-edge-card); }

.task-gate-card-top { display: flex; align-items: center; gap: var(--space-3); margin-bottom: var(--space-4); padding-bottom: var(--space-3); border-bottom: 1px solid var(--border); }
.task-gate-avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  border-radius: var(--radius-pill);
  background: linear-gradient(135deg, var(--accent-2-light), var(--accent-2-dark));
  color: #fff;
  font-weight: 700;
  font-size: 16px;
}
.task-gate-card-name { display: flex; align-items: center; gap: var(--space-2); font-weight: 700; font-size: 16px; }
.task-gate-me-badge {
  padding: 1px 7px;
  border-radius: var(--radius-pill);
  background: var(--accent-2-glow);
  color: var(--accent-2-pale);
  font-size: var(--fs-micro);
  font-weight: 700;
  text-transform: uppercase;
}
.task-gate-card-body { display: flex; align-items: center; gap: var(--space-4); }
.task-gate-card-stats { display: flex; flex-direction: column; }
.task-gate-card-stats .stat-value { font-size: 21px; }
.task-gate-overdue-badge { margin-top: var(--space-1); color: var(--danger); font-size: 12px; font-weight: 600; }

/* Вкладки людей на "Задачах" (решение владельца 23.09.2026, укрупнено
   24.09.2026 - "иконки с именами больше") - пилюли с тем же
   кружком-инициалом, что и на карточках шлюза выше (.task-gate-avatar),
   согласует два соседних экрана одного флоу. */
.owner-tab-row { display: flex; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-5); }

.owner-tab {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  padding: 7px 20px 7px 7px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--panel);
  color: var(--muted);
  text-decoration: none;
  font-size: 17px;
  font-weight: 600;
  transition: border-color var(--dur-fast) var(--ease-standard), box-shadow var(--dur-fast) var(--ease-standard),
    transform var(--dur-fast) var(--ease-standard);
}

.owner-tab:hover { border-color: var(--accent-2-glow); color: var(--text); transform: translateY(-1px); }

.owner-tab.active {
  border-color: var(--accent-2-glow);
  background: var(--accent-2-wash);
  color: var(--text);
  box-shadow: 0 0 0 1px var(--accent-2-glow);
}

.owner-tab-avatar {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  flex-shrink: 0;
  border-radius: var(--radius-pill);
  background: linear-gradient(135deg, var(--accent-2-light), var(--accent-2-dark));
  color: #fff;
  font-weight: 700;
  font-size: 17px;
}

.owner-tab-name { display: flex; align-items: center; gap: var(--space-2); }

/* Текст задачи - читаемый span по умолчанию (перенос строк, не обрезается
   инпутом), инпут .mgmt-input появляется только на время редактирования
   (клик по тексту, см. initGoalRow в tasks.html) - решение владельца
   18.09.2026 "задача должна показываться полностью". */
.task-text-wrap { display: flex; flex-direction: column; gap: 2px; min-width: 0; flex: 1; }
.task-text-display {
  padding: 4px 2px;
  font-size: 13px;
  line-height: 1.4;
  color: var(--text);
  white-space: normal;
  word-break: break-word;
  cursor: text;
}
.task-text-display:hover { color: var(--accent-2-pale); }

/* Короткий статус-бейдж под текстом - только для "промежуточных" статусов
   (см. _STATUS_BADGE_CLASSES в _task_row.html), "Не начато"/"Выполнено" и
   так понятны по чекбоксу. */
.task-status-badge {
  align-self: flex-start;
  font-size: 10px;
  font-weight: 600;
  padding: 1px 6px;
  border-radius: var(--radius-pill);
  text-transform: uppercase;
  letter-spacing: 0.02em;
}
.task-status-badge--progress { background: var(--accent-2-wash); color: var(--accent-2-pale); }
.task-status-badge--postponed { background: var(--cat-ads-wash); color: var(--cat-ads-text); }
.task-status-badge--not-done { background: light-dark(rgba(217, 67, 67, 0.12), rgba(255, 107, 107, 0.15)); color: var(--danger); }

/* Время напоминания (см. input[name=reminder_time] в _task_row.html, tasks.html) -
   просьба владельца 06.10.2026: бот предупреждает в Telegram за 30 минут до
   этого времени. Бейдж - чисто информационная подсказка рядом с полем
   времени, не кликабельный. */
.task-reminder-badge {
  align-self: flex-start;
  font-size: 11px;
  font-weight: 600;
  padding: 2px 8px;
  border-radius: var(--radius-pill);
  background: var(--accent-2-wash);
  color: var(--accent-2-pale);
}

/* Приоритет - тёплая заливка всей строки вместо прежней полоски слева
   (та у двух соседних High-приоритетных задач сливалась в одну сплошную
   линию через всю карточку - решение владельца 18.09.2026 развести
   приоритет и категорию по разным, не путающимся сигналам). Селектор с
   .mgmt-table--compact (не просто .goal-row.priority-*) - специфичность
   должна перебить зебру нечётных строк (.mgmt-table--compact tbody:nth-
   child(odd) .goal-row-summary td ниже) - иначе заливка приоритета молча
   пропадала на каждой второй задаче (найдено при проверке светлой темы
   19.09.2026, баг был и в тёмной, просто незаметен на глаз). */
.mgmt-table--compact tbody.goal-row.priority-high td { background: var(--accent-2-wash); }
.mgmt-table--compact tbody.goal-row.priority-medium td { background: light-dark(rgba(0, 0, 0, 0.035), rgba(255, 255, 255, 0.025)); }

/* flex - на внутреннем div (.task-check-inner), не на самой <td> - см.
   комментарий у .task-text-inner выше. */
.task-check-inner { display: flex; align-items: center; }

/* Перетаскивание - draggable="true" на самой <tr class="goal-row-summary">
   (см. _task_row.html и initGoalRow в tasks.html), без отдельной ручки:
   решение владельца 21.09.2026 - зажать и потянуть можно из любой точки
   строки. cursor:grab показывает это на любом наведении на строку, не
   только на маленькой иконке, которой больше нет. */
.goal-row-summary { cursor: grab; }
.goal-row-summary:active { cursor: grabbing; }
.goal-row.dragging { opacity: 0.4; }
.mgmt-table--compact.drag-over { outline: 1px dashed var(--accent-2-glow); outline-offset: -2px; }

/* Карточка навигации по периоду на "Задачах" (решение владельца 23.09.2026)
   - объединяет стрелки Пред./След., заголовок периода и сетку недель в один
   визуальный узел (карточка панели, как у .stat-tile/.ai-card), вместо
   разрозненных текстовых кнопок и голой сетки квадратиков без подложки. */
.task-period-panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-5) var(--space-5);
  margin-bottom: var(--space-5);
}

.task-period-head {
  position: relative;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--space-4);
  margin-bottom: var(--space-4);
}

/* Круглые кнопки-стрелки вместо текстовых "Пред./След." - компактнее и
   симметрично обрамляют заголовок периода по центру. padding/background/
   font здесь явно сброшены (были не нужны, пока все .task-period-nav были
   ссылками <a> - те не задеты общим button{...} ниже по файлу) - с
   24.09.2026 те же стрелки переиспользуются и на настоящих <button>
   (шаг года в .cal-month-popover), которые без сброса тянули сплошной
   тёмный фон и прямоугольный паддинг из общего правила для button. */
.task-period-nav {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  flex-shrink: 0;
  border-radius: var(--radius-pill);
  border: 1px solid var(--border);
  background: transparent;
  color: var(--muted);
  font-weight: 400;
}

.task-period-nav svg { width: 18px; height: 18px; }

.task-period-nav:hover {
  border-color: var(--accent-2);
  color: var(--text);
  box-shadow: var(--accent-2-ring);
}

.task-period-title {
  display: flex;
  align-items: baseline;
  justify-content: center;
  flex-wrap: wrap;
  gap: var(--space-2);
  text-align: center;
  min-width: 0;
}

.task-period-kind { font-family: var(--font-serif); font-size: 17px; font-weight: 700; }
.task-period-range { color: var(--muted); font-size: 14px; }

.task-period-badge {
  padding: 2px 9px;
  border-radius: var(--radius-pill);
  background: var(--accent-2-wash);
  color: var(--accent-2-pale);
  font-size: var(--fs-micro);
  font-weight: 700;
  text-transform: uppercase;
  text-decoration: none;
  white-space: nowrap;
}

.task-period-badge--link { background: var(--panel-hover); color: var(--muted); }
.task-period-badge--link:hover { background: var(--accent-2-wash); color: var(--accent-2-pale); }

/* Два календаря рядом под тулбаром периода (решение владельца 24.09.2026 -
   "слева просто календарь недели, справа просто календарь месяца"):
   каждый - своя колонка (flex: 1, поровну), переносятся друг под друга на
   узком экране, а не сжимаются до нечитаемого. */
.task-calendars { display: flex; gap: var(--space-6); flex-wrap: wrap; align-items: flex-start; }
.task-calendar-col { flex: 1 1 320px; min-width: 0; }

.task-calendar-title {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  margin-bottom: var(--space-3);
  color: var(--muted);
  font-size: var(--fs-small);
  font-weight: 600;
  text-align: center;
}

/* Позиционирующий контекст для .cal-popover месяца (см. ниже) - именно
   эта строка, а не узкая кнопка-триггер внутри и не вся колонка целиком
   (та ниже ещё содержит саму сетку календаря - top: 100% от неё утащил бы
   попап далеко вниз, под всю сетку). Ширина строки уже равна ширине всей
   колонки (блочный div), поэтому попап центрируется по всей колонке, а не
   утыкается в край экрана на узкой кнопке (реальный баг, владелец,
   24.09.2026 - на мобильном попап недели вылезал за левый край экрана). */
.task-calendar-title--month { position: relative; }

/* Уменьшенный вариант круглой кнопки-стрелки .task-period-nav - для
   собственной навигации календаря месяца (не хочет визуально спорить с
   более крупными стрелками периода в шапке панели). */
.task-period-nav--sm { width: 26px; height: 26px; }
.task-period-nav--sm svg { width: 14px; height: 14px; }

/* Название месяца/недели - кликабельные кнопки, открывающие быстрый выбор
   (просьба владельца 24.09.2026, см. initCalMonthPicker/initWeekPeriodPicker
   в tasks.html) - визуально остаются тем же текстом, что и раньше, только
   курсор и hover намекают, что по ним можно кликнуть. Общий .cal-picker/
   .cal-trigger - у обоих одинаковая механика "кнопка + всплывающий попап",
   различаются только тем, что внутри попапа (месяцы против недель).
   Само .cal-picker БЕЗ position:relative - позиционирующий контекст для
   .cal-popover ниже намеренно задан на .task-period-head/
   .task-calendar-title--month (узкая кнопка-триггер на мобильном не
   давала попапу места для центрирования и уводила его за левый край
   экрана - реальный баг, владелец, 24.09.2026). */
.cal-trigger {
  padding: 2px 8px;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: inherit;
  font: inherit;
  font-weight: inherit;
  cursor: pointer;
}

.cal-trigger:hover, .cal-trigger[aria-expanded="true"] { background: var(--panel-hover); color: var(--text); }

.cal-month-trigger { min-width: 120px; }

/* Тот же приём позиционирования/тени, что и у .notif-panel в сайдбаре -
   выпадающая карточка поверх контента, растёт от кнопки вниз. Общая база
   для обоих попапов (месяц/неделя), различается только шириной - недельная
   сетка внутри на 10 колонок (см. .week-grid), ей нужно больше места, чем
   4х3 сетке месяцев. */
.cal-popover {
  position: absolute;
  top: calc(100% + 6px);
  left: 50%;
  transform: translateX(-50%);
  padding: var(--space-3);
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 32px -14px rgba(0, 0, 0, 0.6);
  z-index: 20;
  text-align: left;
  max-width: calc(100vw - 32px);
}

.cal-popover--month { width: 220px; }

.cal-popover-head {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-3);
  margin-bottom: var(--space-3);
  font-weight: 700;
  font-family: var(--font-serif);
}

.cal-month-popover-grid {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 6px;
}

.cal-month-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 8px 0;
  border-radius: 6px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 600;
  text-decoration: none;
  cursor: pointer;
}

.cal-month-cell:hover { border-color: var(--accent-2); color: var(--text); }
.cal-month-cell--today { border: 2px solid var(--accent-2); color: var(--text); font-weight: 700; }
.cal-month-cell--viewed { background: var(--accent-2-wash); border-color: transparent; color: var(--accent-2-pale); box-shadow: var(--accent-2-ring); }

/* Сетка недель (решение владельца 23.09.2026, расширена 24.09.2026 -
   "видно все недели", см. app/routers/management.py _week_grid) - ВСЕ
   недели года просматриваемой недели, прямоугольником (фиксированное
   число колонок - при 52-53 неделях получается явно широкий прямоугольник,
   не квадрат, как раньше на 25 клетках). Прошедшие залиты, сегодняшняя
   обведена, будущие пустые. 10 колонок, не 13 (было) - при том же
   .task-calendar-col раньше клетки получались заметно мельче клеток
   календаря месяца справа (13 колонок против 7 - почти вдвое мельче);
   просьба владельца 24.09.2026 "выровнять, чтобы не было сильного разбега
   по квадратикам" - те же шрифт/радиус, что у .month-calendar-cell, клетки
   крупнее, но по-прежнему меньше дневных (10 колонок и 53 недели против 7
   колонок и максимум ~35 дней месяца). */
.week-grid {
  display: grid;
  grid-template-columns: repeat(10, 1fr);
  gap: 4px;
}

.week-grid-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  border-radius: 7px;
  border: 1px solid var(--border);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  text-decoration: none;
  transition: transform var(--dur-fast) var(--ease-standard), border-color var(--dur-fast) var(--ease-standard),
    box-shadow var(--dur-fast) var(--ease-standard);
}

.week-grid-cell:hover { transform: scale(1.15); border-color: var(--accent-2); color: var(--text); z-index: 1; }

/* Прошедшие - мягкая акцентная заливка (не сплошная, чтобы полсотни клеток
   не сливались в тяжёлое пятно). */
.week-grid-cell--past { background: var(--accent-2-wash); border-color: transparent; color: var(--accent-2-pale); }

/* Сегодняшняя - только обводка, без заливки (решение владельца - "текущая обведена"). */
.week-grid-cell--today { background: transparent; border: 2px solid var(--accent-2); color: var(--text); font-weight: 700; }

/* Будущие - пустые, приглушённая рамка (решение владельца - "будущие не закрашены"). */
.week-grid-cell--future { background: transparent; border-color: var(--border); }

/* Просматриваемая сейчас неделя - кольцо поверх любого из трёх состояний
   выше, иначе после перехода по сетке не видно, "где ты" в самой сетке. */
.week-grid-cell--viewed { box-shadow: var(--accent-2-ring); border-color: var(--accent-2); z-index: 1; }

/* Календарь месяца (решение владельца 24.09.2026) - справа от сетки недель,
   обычная сетка Пн..Вс на 7 колонок. Те же три состояния и то же кольцо
   "просматриваемая неделя", что и у .week-grid-cell слева - согласованный
   визуальный язык у пары календарей. */
.month-calendar {
  display: flex;
  flex-direction: column;
  gap: 4px;
}

.month-calendar-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
}

.month-calendar-weekday {
  text-align: center;
  padding-bottom: 4px;
  color: var(--muted);
  font-size: var(--fs-micro);
  font-weight: 700;
  text-transform: uppercase;
}

/* Обвести каждую неделю месяца своей рамкой (просьба владельца 24.09.2026 -
   "если возвращаюсь на июль, обводи 4 недели месяца июля") - при
   независимом просмотре чужого месяца через попап месяца ни одна неделя
   не обязана совпасть с реально просматриваемой (той в этом месяце может
   не быть вовсе) - рамка вокруг каждой строки из 7 дней даёт опору "вот
   эти клетки - одна неделя, целиком кликабельна", даже когда акцентного
   кольца .month-calendar-cell--viewed нигде на странице нет. */
.month-calendar-week {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 4px;
  padding: 4px;
  border: 1px solid var(--border);
  border-radius: 10px;
}

.month-calendar-cell {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1;
  border-radius: 7px;
  border: 1px solid var(--border);
  font-size: 12px;
  font-variant-numeric: tabular-nums;
  color: var(--muted);
  text-decoration: none;
  transition: transform var(--dur-fast) var(--ease-standard), border-color var(--dur-fast) var(--ease-standard),
    box-shadow var(--dur-fast) var(--ease-standard);
}

.month-calendar-cell:hover { transform: scale(1.08); border-color: var(--accent-2); color: var(--text); z-index: 1; }

.month-calendar-cell--empty { border-color: transparent; }

.month-calendar-cell--past { background: var(--accent-2-wash); border-color: transparent; color: var(--accent-2-pale); }
.month-calendar-cell--today { background: transparent; border: 2px solid var(--accent-2); color: var(--text); font-weight: 700; }
.month-calendar-cell--future { background: transparent; border-color: var(--border); }

/* Все 7 дней просматриваемой сейчас недели - не только выбранная в сетке
   слева неделя целиком, но и её дни здесь, справа - те же кольца, тот же
   язык "где ты сейчас", что и у .week-grid-cell--viewed. */
.month-calendar-cell--viewed { box-shadow: var(--accent-2-ring); border-color: var(--accent-2); z-index: 1; }

/* Кольцевой индикатор процента (CSS conic-gradient, без SVG/JS-библиотек) -
   переиспользуется для большого "Выполнено всего" и маленьких "Выполнено
   сегодня" в шапках карточек дня (см. day_donut в _task_row.html). Толщина
   кольца задаётся в процентах (inset), поэтому одинаково выглядит на любом
   размере через модификатор. */
.day-donut {
  --size: 40px;
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--size);
  height: var(--size);
  border-radius: var(--radius-pill);
  background: conic-gradient(var(--accent-2) calc(var(--pct) * 1%), var(--border) 0);
  filter: drop-shadow(0 0 6px var(--accent-2-glow));
  flex-shrink: 0;
}

.day-donut::before {
  content: "";
  position: absolute;
  inset: 15%;
  border-radius: var(--radius-pill);
  background: var(--panel);
}

.day-donut-value {
  position: relative;
  z-index: 1;
  font-size: var(--fs-micro);
  font-weight: 700;
  color: var(--text);
}

.day-donut--lg { --size: 96px; }
.day-donut--lg .day-donut-value { font-size: var(--fs-stat); }

.day-donut--md { --size: 64px; }
.day-donut--md .day-donut-value { font-size: 15px; }

/* Панель "Аналитика недели" - большой донат + таблица показателей + бар-чарт
   по дням, три равные колонки на широком экране, стопкой на узком. */
.task-analytics-panel {
  position: relative;
  overflow: hidden;
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-6);
  align-items: center;
  background: linear-gradient(160deg, var(--accent-2-wash), rgba(200, 160, 65, 0.02) 55%, var(--panel) 100%);
  border: 1px solid var(--accent-2-glow);
  border-radius: var(--radius-lg);
  padding: var(--space-4) var(--space-6);
  margin-bottom: var(--space-5);
  box-shadow: var(--shadow-edge-card);
}

.task-analytics-panel::before {
  content: "";
  position: absolute;
  top: -50%;
  right: -10%;
  width: 260px;
  height: 260px;
  background: radial-gradient(circle, var(--accent-2-wash), transparent 70%);
  pointer-events: none;
}

.task-analytics-donut, .task-analytics-table, .task-analytics-chart { position: relative; }

.task-analytics-donut {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-2);
}

.task-analytics-donut-caption { font-size: var(--fs-small); color: var(--muted); }

/* Сравнение с прошлой неделей (просьба владельца 24.09.2026) - тот же
   монохром+var(--danger), что и у .stat-trend-up/.stat-trend-down (нет
   отдельного "зелёного успеха" нигде на сайте, см. --accent-2 в :root) -
   рост жирным обычным текстом, без изменений приглушённо, падение красным. */
.task-analytics-trend {
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  background: var(--panel-hover);
  font-size: var(--fs-micro);
  font-weight: 700;
  white-space: nowrap;
}

.task-analytics-trend--up { color: var(--text); }
.task-analytics-trend--down { color: var(--danger); }
.task-analytics-trend--flat { color: var(--muted); font-weight: 600; }

.task-analytics-table {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  min-width: 220px;
  flex: 1;
}

.task-analytics-row {
  display: flex;
  justify-content: space-between;
  gap: var(--space-3);
  font-size: var(--fs-body);
  padding: var(--space-1) 0;
  border-bottom: 1px solid var(--border);
}

.task-analytics-row:last-child { border-bottom: none; }
.task-analytics-row span:last-child { font-weight: 700; }

/* Разбивка по статусам (решение владельца 24.09.2026, см. tasks.html) -
   второстепенные строки внутри той же таблицы: "Всего/Выполнено/Осталось/
   Просрочено" выше остаются основным, самым заметным, эта разбивка -
   подробность помельче, приглушена и с отступом, чтобы взгляд сначала
   считывал главное. */
.task-analytics-row--sub { padding-left: var(--space-3); font-size: var(--fs-small); color: var(--muted); }
.task-analytics-row--sub span:last-child { font-weight: 600; }

.task-analytics-chart {
  flex: 1;
  min-width: 220px;
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
}

.task-analytics-chart-title { font-size: var(--fs-small); color: var(--muted); }

.week-progress-chart {
  display: flex;
  align-items: flex-end;
  gap: var(--space-2);
  height: 96px;
}

.week-progress-bar {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-1);
  flex: 1;
  height: 100%;
}

.week-progress-track {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: flex-end;
  border-radius: var(--radius-sm);
  background: var(--border);
  overflow: hidden;
}

.week-progress-fill {
  width: 100%;
  height: var(--pct, 0%);
  background: linear-gradient(180deg, var(--accent-2-light), var(--accent-2));
}

.week-progress-day { font-size: var(--fs-micro); color: var(--muted); }

/* Заметки дня - индивидуальные на владельца вкладки (см. day_notes в
   app/management/store.py, решение владельца 23.09.2026). */
.task-day-notes {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  margin-top: var(--space-2);
  padding-top: var(--space-2);
  border-top: 1px solid var(--border);
}

/* <textarea>, не <input> (решение владельца 24.09.2026, "заметка должна
   раскрываться, чтобы её было удобнее читать") - однострочная высота по
   умолчанию (не занимает лишнего места в компактной карточке дня), JS
   ниже растягивает под реальную высоту текста по фокусу/вводу и обратно
   схлопывает по потере фокуса - см. autoGrowNote в tasks.html. */
.task-day-note-input {
  width: 100%;
  height: 24px;
  padding: 4px 8px;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--muted);
  font-family: inherit;
  font-size: var(--fs-xs);
  line-height: 1.5;
  resize: none;
  overflow: hidden;
  transition: height var(--dur-fast) var(--ease-standard), border-color var(--dur-fast) var(--ease-standard),
    background var(--dur-fast) var(--ease-standard);
}

.task-day-note-input:hover { border-color: var(--border); }

.task-day-note-input:focus {
  outline: none;
  border-color: var(--accent-2);
  background: var(--bg);
  color: var(--text);
  box-shadow: var(--accent-2-ring);
  position: relative;
  z-index: 1;
}

/* Настройки - вкладки ("Оформление"/"Траты и события", см. settings.html) -
   видимость панели переключает JS, .sort-toggle сам по себе уже стилизован. */
.settings-tab-panel { margin-top: var(--space-6); }

/* Дашборд - виджет-календарь "Траты и события" внизу главной (референс
   владельца 22.09.2026, см. app/routers/home.py _build_recurring_calendar) -
   те же карточные токены, что и у .stat-tile/.ai-card. */
.recurring-calendar-panel {
  position: relative;
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 20px;
  margin-top: var(--space-6);
}

.recurring-calendar-header {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-3);
  flex-wrap: wrap;
}

.recurring-calendar-header .section-heading { margin: 0; }

.recurring-calendar-nav { display: flex; gap: 6px; }

.recurring-calendar-nav-btn {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  border: 1px solid var(--border);
  border-radius: 6px;
  color: var(--muted);
  text-decoration: none;
  transition: border-color var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard);
}

.recurring-calendar-nav-btn:hover { border-color: var(--accent-2); color: var(--accent-2-pale); }

.recurring-calendar-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 6px;
  margin-top: var(--space-4);
}

.recurring-calendar-weekday {
  text-align: center;
  color: var(--muted);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  padding-bottom: 4px;
}

.recurring-calendar-cell {
  min-height: 64px;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 6px 8px;
}

.recurring-calendar-cell--empty { border-color: transparent; }

.recurring-calendar-cell--today { border-color: var(--accent-2); box-shadow: var(--accent-2-ring); }

.recurring-calendar-cell--due { background: light-dark(rgba(217, 67, 67, 0.08), rgba(255, 107, 107, 0.12)); border-color: var(--danger); }

/* Событие без суммы (см. .recurring-calendar-due--event) - нейтральный
   акцент вместо красного, это не про деньги. */
.recurring-calendar-cell--event { background: var(--accent-2-soft); border-color: var(--accent-2); }

.recurring-calendar-cell[data-date] {
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-standard), box-shadow var(--dur-fast) var(--ease-standard);
}

.recurring-calendar-cell[data-date]:hover, .recurring-calendar-cell[data-date]:focus-visible {
  border-color: var(--accent-2);
  outline: none;
}

.recurring-calendar-cell--has-note { position: relative; }

.recurring-calendar-cell--has-note::after {
  content: "";
  position: absolute;
  top: 6px;
  right: 6px;
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--accent-2);
}

.recurring-calendar-daynum {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: var(--fs-small);
  color: var(--muted);
}

.recurring-calendar-cell--today .recurring-calendar-daynum { color: var(--accent-2-pale); font-weight: 700; }

/* "×N" - подсказка, что сумма ниже сложена из нескольких платежей/событий
   этого дня, а не один крупный платёж (решение владельца 22.09.2026). */
.recurring-calendar-count {
  font-size: 10px;
  font-weight: 700;
  color: var(--accent-2-pale);
  background: var(--accent-2-soft, rgba(200, 160, 65, 0.18));
  border-radius: var(--radius-pill);
  padding: 1px 5px;
  line-height: 1.4;
}

.recurring-calendar-due {
  margin-top: 4px;
  font-size: var(--fs-xs);
  font-weight: 600;
  color: var(--danger);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.recurring-calendar-due + .recurring-calendar-due { margin-top: 2px; }

/* Событие без суммы (просьба владельца 22.09.2026 - можно добавить "Траты и
   события" без указания суммы) - не про деньги, поэтому не красным. */
.recurring-calendar-due--event { color: var(--accent-2-pale); font-weight: 500; }

@media (max-width: 720px) {
  .recurring-calendar-grid { gap: 3px; }
  .recurring-calendar-cell { min-height: 44px; padding: 4px; }
  .recurring-calendar-weekday { font-size: 10px; }
}

/* Попап "подробнее" по клику на день календаря "Траты и события" -
   абсолютно спозиционирован внутри .recurring-calendar-panel (position:
   relative выше), JS считает top/left от прямоугольника ячейки. */
.recurring-day-popover {
  position: absolute;
  z-index: 5;
  width: 240px;
  background: var(--panel-deep, var(--panel));
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 12px 14px;
  box-shadow: 0 12px 32px -14px rgba(0, 0, 0, 0.4);
}

.recurring-day-popover-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-weight: 600;
  margin-bottom: 8px;
}

.recurring-day-popover-edit {
  background: transparent;
  border: none;
  cursor: pointer;
  font-size: 14px;
  line-height: 1;
  padding: 2px;
  opacity: 0.7;
}

.recurring-day-popover-edit:hover { opacity: 1; }

.recurring-day-popover-row {
  display: flex;
  justify-content: space-between;
  gap: 10px;
  font-size: var(--fs-small);
  padding: 3px 0;
}

.recurring-day-popover-row + .recurring-day-popover-row { border-top: 1px solid var(--border); }

.recurring-day-popover-note {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  font-size: var(--fs-small);
  color: var(--muted);
  white-space: pre-wrap;
}

.recurring-day-popover-note-form {
  margin-top: 8px;
  padding-top: 8px;
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 6px;
}

/* display:flex выше при равной специфичности перебивает UA-правило
   [hidden]{display:none} (побеждает как авторский стиль) - без этого
   переопределения el.hidden=true JS не прятал бы форму. */
.recurring-day-popover-note-form[hidden] { display: none; }

.recurring-day-popover-note-form textarea { resize: vertical; }

.recurring-day-popover-note-form button {
  align-self: flex-end;
  padding: 4px 12px;
  border: 1px solid var(--border);
  border-radius: 6px;
  background: var(--accent-2);
  color: var(--bg);
  font-weight: 600;
  cursor: pointer;
}

/* "Режим правок" (просьба владельца 23.09.2026, см. base.html) - плавающая
   кнопка ✏️ сверху справа поверх всего сайта, не часть .layout, поэтому
   position: fixed прямо от viewport, а не от .sidebar/.content-area. */
.feedback-mode-toggle {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 2000;
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text);
  font-size: 18px;
  line-height: 1;
  cursor: pointer;
  box-shadow: 0 4px 16px -6px rgba(0, 0, 0, 0.35);
  transition: border-color var(--dur-fast) var(--ease-standard), background var(--dur-fast) var(--ease-standard);
}

.feedback-mode-toggle:hover { border-color: var(--accent-2); }

.feedback-mode-toggle.active { background: var(--accent-2); border-color: var(--accent-2); }

/* !important - крестик "прицела" должен быть виден даже там, где элемент
   сам явно назначает свой cursor (ссылки, кнопки). */
body.feedback-picking, body.feedback-picking * { cursor: crosshair !important; }

.feedback-highlight { outline: 2px dashed var(--accent-2) !important; outline-offset: 2px; }

.feedback-hint {
  position: fixed;
  top: 16px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2000;
  background: var(--panel-deep);
  border: 1px solid var(--accent-2);
  color: var(--text);
  padding: 6px 14px;
  border-radius: var(--radius-pill);
  font-size: var(--fs-small);
}

.feedback-popover {
  position: fixed;
  z-index: 2001;
  width: 280px;
  background: var(--panel-deep);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: 12px;
  box-shadow: 0 12px 32px -14px rgba(0, 0, 0, 0.4);
}

.feedback-popover-context {
  font-size: var(--fs-xs);
  color: var(--muted);
  margin-bottom: 6px;
  word-break: break-word;
}

.feedback-popover textarea { width: 100%; resize: vertical; }

.feedback-popover-actions { display: flex; justify-content: flex-end; gap: 8px; margin-top: 8px; }

.feedback-popover-cancel {
  background: transparent;
  border: 1px solid var(--border);
  border-radius: 6px;
  padding: 4px 10px;
  cursor: pointer;
  color: var(--muted);
}

.feedback-popover-submit {
  background: var(--accent-2);
  border: none;
  border-radius: 6px;
  padding: 4px 12px;
  cursor: pointer;
  color: var(--bg);
  font-weight: 600;
}

.feedback-popover-submit:disabled { opacity: 0.6; cursor: default; }

/* Вкладка "Правки" в Настройках (список из виджета выше). */
.feedback-context { margin-top: 2px; color: var(--muted); font-size: var(--fs-xs); font-style: italic; }

.feedback-row--done { opacity: 0.55; }

.feedback-row--done td:not(.task-check-cell) { text-decoration: line-through; text-decoration-color: var(--muted); }

/* =====================================================================
   Раздел «Контент Instagram» (решение владельца 26.09.2026) - «Контент» и
   «Гипотезы», см. app/routers/ig_content.py. Все классы с префиксом ig-,
   цвета - только существующие токены темы (светлая/тёмная работают сами).
   Статусы роликов: 0 «Собираем данные» - голубой (как данные WB), 1
   «Повторить тест» - оранжевый, 2 «Использовать дальше» - зелёный, 3 «Не
   повторять» - красный.
   ===================================================================== */

.ig-page-header { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-4); flex-wrap: wrap; padding-right: 56px; /* место под плавающую кнопку ✏️ «Режим правок» (base.html) */ }
.ig-header-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.ig-back { display: inline-block; margin-bottom: 10px; color: var(--muted); text-decoration: none; font-size: var(--fs-small); }
.ig-back:hover { color: var(--text); }

.ig-toolbar { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-3); }
.ig-filters { display: flex; gap: var(--space-3); align-items: flex-end; flex-wrap: wrap; }
.ig-filter { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--fs-xs); color: var(--muted); }

.ig-input {
  width: 100%;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--panel);
  color: var(--text);
  font: inherit;
  font-size: var(--fs-body);
}
.ig-input:focus { outline: none; border-color: var(--accent-2); box-shadow: var(--accent-2-ring); }
.ig-input::placeholder { color: var(--muted); opacity: 0.7; }
textarea.ig-input { resize: vertical; line-height: 1.45; }
.ig-input--compact { width: auto; min-width: 120px; padding: 6px 8px; font-size: var(--fs-small); }

/* Кастомный пикер периода на "Контенте" (решение владельца 28.09.2026,
   см. app/templates/_daterange_picker.html) - переиспользует общий .cal-picker/
   .cal-trigger/.cal-popover приём и сетку .month-calendar из "Задач"
   (tasks.html/tasks.html), только своя ширина попапа и подсветка диапазона
   вместо ссылок на страницы.

   Баг 29.09.2026: .cal-picker сознательно идёт БЕЗ position:relative (см.
   комментарий выше, у .cal-trigger) - для "Задач" позиционирующий контекст
   .cal-popover берёт на себя широкая строка .task-calendar-title--month, а
   для "Контента" эквивалентную обёртку забыли завести вовсе. Без вообще
   ЛЮБОГО positioned-родителя рядом .cal-popover (position: absolute)
   всплывал у ближайшего позиционированного предка выше по дереву (случайно,
   не по замыслу) - выглядело так, будто календарь по клику просто не
   открывается. .daterange-trigger уже достаточно широкий (168px) сам по
   себе, чтобы не воспроизводить мобильный краевой баг 24.09.2026 - отдельная
   широкая строка тут не нужна, позиционирующий контекст достаточно дать
   прямо .cal-picker внутри этого фильтра. */
.daterange-filter { display: flex; flex-direction: column; gap: var(--space-1); font-size: var(--fs-xs); color: var(--muted); }
.daterange-filter .cal-picker { position: relative; }

.daterange-trigger {
  min-width: 168px;
  text-align: left;
  padding: 6px 8px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--panel);
  font-size: var(--fs-small);
}
.daterange-trigger:hover, .daterange-trigger[aria-expanded="true"] { border-color: var(--accent-2); background: var(--panel); color: var(--text); }

/* Попап выбора периода (переделан 29.09.2026 по референсу владельца) - все
   правила ниже ограничены .cal-popover--daterange, чтобы не задеть
   календарь месяца в "Задачах", у которого та же разметка .month-calendar-*,
   но другой смысл (рамка вокруг каждой недели, состояния прошло/сегодня/
   будет). Дни здесь - <button>, поэтому сначала гасим общий стиль всех
   кнопок сайта (тёмная заливка, отступы 7x16 - из-за них дни были чёрными
   квадратами и вылезали за край попапа). */
/* От левого края кнопки, а не по центру: кнопка узкая и стоит первой в
   строке фильтров - центрированный попап шириной 316px вылезал за левый
   край экрана. */
.cal-popover--daterange { width: 316px; padding: var(--space-4); left: 0; transform: none; }
.cal-popover--daterange .cal-popover-head { font-family: inherit; font-size: var(--fs-body); }

.cal-popover--daterange .month-calendar,
.cal-popover--daterange .month-calendar-weekdays { gap: 2px; }
.cal-popover--daterange .month-calendar-week { gap: 2px; padding: 0; border: none; border-radius: 0; }
.cal-popover--daterange .month-calendar-weekday { padding-bottom: 6px; }

.cal-popover--daterange .month-calendar-cell {
  aspect-ratio: auto;
  height: 36px;
  min-width: 0;
  padding: 0;
  border: none;
  border-radius: 6px;
  background: transparent;
  color: var(--text);
  font-size: var(--fs-small);
  font-weight: 500;
  opacity: 1;
  box-shadow: none;
  transition: background-color var(--dur-fast) var(--ease-standard);
}
.cal-popover--daterange .month-calendar-cell:hover { transform: none; background: var(--panel-hover); opacity: 1; box-shadow: none; }
.cal-popover--daterange .month-calendar-cell:focus-visible { box-shadow: var(--accent-2-ring); }
.cal-popover--daterange .month-calendar-cell--empty { pointer-events: none; }
.cal-popover--daterange .month-calendar-cell--today { border: none; color: var(--accent-2-pale); font-weight: 700; }
.cal-popover--daterange .month-calendar-cell--in-range,
.cal-popover--daterange .month-calendar-cell--in-range:hover { background: var(--accent-2-wash); color: var(--text); }
.cal-popover--daterange .month-calendar-cell--range-start,
.cal-popover--daterange .month-calendar-cell--range-end,
.cal-popover--daterange .month-calendar-cell--range-start:hover,
.cal-popover--daterange .month-calendar-cell--range-end:hover {
  background: var(--accent-2);
  color: var(--bg);
  font-weight: 700;
}

.daterange-heads { display: flex; gap: var(--space-4, 16px); margin-bottom: var(--space-4, 16px); }
.daterange-head {
  flex: 1 1 0;
  padding: 0 0 8px;
  border-bottom: 2px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 4px;
}
.daterange-head-label { font-size: var(--fs-micro); font-weight: 600; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.daterange-head-value { font-size: var(--fs-body); font-weight: 600; color: var(--text); }
.daterange-head--active { border-bottom-color: var(--accent-2); }

.daterange-actions { display: flex; align-items: center; justify-content: space-between; margin-top: var(--space-4, 16px); padding-top: var(--space-3); border-top: 1px solid var(--border); gap: var(--space-3); }
.daterange-actions-right { display: flex; gap: var(--space-2); }
.daterange-clear { background: none; border: none; padding: 0; cursor: pointer; font: inherit; }
.daterange-clear:hover { text-decoration: underline; }
.ig-prompt { font-family: ui-monospace, SFMono-Regular, Menlo, monospace; font-size: var(--fs-xs); min-height: 240px; }

.ig-table td { vertical-align: middle; }
.ig-row { cursor: pointer; }
.ig-row:hover { background: var(--panel-hover); }
.ig-row--selected, .ig-row--selected:hover { background: var(--accent-2-wash); }
.ig-col-check { width: 36px; text-align: center; padding-right: 0; }
.ig-col-check input { width: 16px; height: 16px; cursor: pointer; accent-color: var(--accent-2); }
.ig-num { text-align: right; font-variant-numeric: tabular-nums; }
.ig-muted { color: var(--muted); }
.ig-sub { font-size: var(--fs-xs); color: var(--muted); margin-top: 2px; }
.ig-small { font-size: var(--fs-small); }
.ig-nowrap { white-space: nowrap; }
.ig-wrap { white-space: normal; min-width: 180px; max-width: 360px; }
.ig-title-cell { white-space: normal; min-width: 180px; }
.ig-title-link { font-weight: 600; text-decoration: none; }
.ig-title-link:hover { text-decoration: underline; }
.ig-table-note { margin-top: var(--space-2); }
.ig-table--measures th, .ig-table--measures td { padding: 8px 10px; }
.ig-empty-small { padding: 28px; }

.ig-cover {
  width: 40px;
  height: 64px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border);
  background: var(--panel-deep);
  overflow: hidden;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: var(--fs-xs);
}
.ig-cover img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ig-cover--large { width: 100%; max-width: 220px; height: auto; aspect-ratio: 9 / 16; }

.ig-chips-cell { white-space: normal; min-width: 140px; }
.ig-chip {
  display: inline-block;
  padding: 2px 8px;
  margin: 2px 4px 2px 0;
  border-radius: var(--radius-pill);
  border: 1px solid var(--accent-2-soft);
  background: var(--accent-2-wash);
  color: var(--accent-2-pale);
  font-size: var(--fs-xs);
  white-space: nowrap;
}

.ig-status {
  display: inline-block;
  padding: 3px 10px;
  border-radius: var(--radius-pill);
  font-size: var(--fs-xs);
  font-weight: 600;
  white-space: nowrap;
}
.ig-status--0 { color: var(--cat-stock-text); background: var(--cat-stock-wash); }
.ig-status--1 { color: var(--cat-ads-text); background: var(--cat-ads-wash); }
.ig-status--2 { color: var(--cat-money-text); background: var(--cat-money-wash); }
.ig-status--3 { color: var(--danger); background: light-dark(rgba(217, 67, 67, 0.08), rgba(255, 107, 107, 0.10)); }

/* Карточка ролика */
.ig-card-grid { display: grid; grid-template-columns: 220px minmax(0, 1fr); gap: var(--space-6); align-items: start; }
.ig-card-side { position: sticky; top: var(--space-4); }
.ig-cover-form { display: flex; flex-direction: column; gap: 6px; align-items: flex-start; margin-top: var(--space-3); }
.ig-file-label { display: inline-block; cursor: pointer; padding: 7px 14px; border-radius: var(--radius-sm); font-size: var(--fs-body); }

.ig-panel {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-4);
}
.ig-panel--accent { border-color: var(--accent-2-glow); }
.ig-panel-title { margin: 0 0 var(--space-3); font-size: 15px; font-weight: 700; }
.ig-panel-head { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); margin-bottom: var(--space-3); }
.ig-panel-head .ig-panel-title { margin: 0; }
.ig-section-head { margin-top: var(--space-6); }
.ig-section-head .section-heading { margin: 0; }

.ig-fields { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-3) var(--space-4); }
.ig-field { display: flex; flex-direction: column; gap: 6px; font-size: var(--fs-small); color: var(--muted); }
.ig-field--wide { grid-column: 1 / -1; }
.ig-inline { display: flex; gap: var(--space-2); align-items: center; }
.ig-hint { margin: 0; font-size: var(--fs-xs); color: var(--muted); }

.ig-toggle-group { display: flex; flex-wrap: wrap; gap: var(--space-2); margin-bottom: var(--space-4); }
.ig-toggle { position: relative; }
.ig-toggle input, .ig-status-option input { position: absolute; opacity: 0; pointer-events: none; }
.ig-toggle span {
  display: inline-block;
  padding: 6px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  font-size: var(--fs-small);
  cursor: pointer;
  user-select: none;
  transition: background var(--dur-fast) var(--ease-standard), border-color var(--dur-fast) var(--ease-standard);
}
.ig-toggle span:hover { border-color: var(--accent-2); }
.ig-toggle input:checked + span { background: var(--accent-2-wash); border-color: var(--accent-2); color: var(--accent-2-pale); font-weight: 600; }
.ig-toggle input:focus-visible + span, .ig-status-option input:focus-visible + .ig-status { box-shadow: var(--accent-2-ring); }

.ig-status-picker { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-top: var(--space-3); }
.ig-status-option { position: relative; }
.ig-status-option .ig-status { cursor: pointer; padding: 6px 14px; font-size: var(--fs-small); opacity: 0.5; transition: opacity var(--dur-fast) var(--ease-standard); }
.ig-status-option .ig-status:hover { opacity: 0.8; }
.ig-status-option input:checked + .ig-status { opacity: 1; box-shadow: inset 0 0 0 1.5px currentColor; }

.ig-savebar {
  position: sticky;
  bottom: 0;
  z-index: 5;
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: var(--space-3);
  padding: var(--space-3) 0;
  background: linear-gradient(to bottom, transparent, var(--bg) 35%);
}
.ig-savebar-text { font-size: var(--fs-small); color: var(--muted); }
.ig-savebar--dirty .ig-savebar-text { color: var(--accent-2-pale); font-weight: 600; }

.ig-delete-form { text-align: right; margin-top: var(--space-1); }
.ig-link-danger, .ig-link-danger:hover { background: none; border: none; padding: 0; color: var(--danger); font-size: var(--fs-small); font-weight: 400; box-shadow: none; }
.ig-link-danger:hover { text-decoration: underline; opacity: 1; }
.ig-link-muted { color: var(--muted); font-size: var(--fs-small); }
.ig-icon-button, .ig-icon-button:hover {
  background: transparent;
  border: 1px solid transparent;
  color: var(--muted);
  padding: 2px 8px;
  font-size: 18px;
  line-height: 1;
  font-weight: 400;
  box-shadow: none;
}
.ig-icon-button:hover { color: var(--danger); border-color: var(--border); opacity: 1; }

/* Окна (dialog) - основа .task-modal, пошире для форм с несколькими полями */
.ig-dialog--wide { width: min(520px, calc(100vw - 32px)); }
.ig-metric-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 10px var(--space-3); }
.ig-metric-grid--3 { grid-template-columns: repeat(3, 1fr); }
.ig-quick-times { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.ig-chip-button { padding: 4px 10px; font-size: var(--fs-xs); }

/* Сравнение */
.ig-window-switch { display: flex; gap: var(--space-2); flex-wrap: wrap; margin-bottom: var(--space-4); }
.ig-window-pill { padding: 6px 14px; border-radius: var(--radius-pill); border: 1px solid var(--border); text-decoration: none; font-size: var(--fs-small); }
.ig-window-pill:hover { border-color: var(--accent-2); }
.ig-window-pill.active { background: var(--accent); border-color: var(--accent); color: var(--accent-text); font-weight: 600; }
.ig-compare-head { white-space: normal; min-width: 160px; text-transform: none; letter-spacing: 0; font-size: var(--fs-small); color: var(--text); vertical-align: top; }
.ig-compare-label { color: var(--muted); font-size: var(--fs-small); white-space: nowrap; }
/* Обе таблицы сравнения (цифры и подача) - с одинаковой сеткой колонок, чтобы ролики стояли друг под другом. */
.ig-compare-table { table-layout: fixed; min-width: 640px; }
.ig-compare-table th:first-child, .ig-compare-table td:first-child { width: 180px; }
.ig-compare-table td { white-space: normal; }
.ig-compare-table--text td { vertical-align: top; }
.ig-diff { display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: var(--radius-pill); font-size: var(--fs-xs); font-weight: 600; color: var(--muted); background: var(--panel-deep); }
.ig-diff--up { color: var(--cat-money-text); background: var(--cat-money-wash); }
.ig-diff--down { color: var(--danger); background: light-dark(rgba(217, 67, 67, 0.08), rgba(255, 107, 107, 0.10)); }
.ig-warn { color: var(--cat-ads-text); }

/* Гипотезы */
.ig-hyp-text { min-width: 220px; max-width: 340px; }
.ig-hyp-table select[name="test_video_id"] { max-width: 220px; }
.ig-hyp-table input[name="result_note"] { min-width: 140px; width: 100%; }
.ig-hyp-status[data-status-index="1"] { border-color: var(--cat-ads); color: var(--cat-ads-text); }
.ig-hyp-status[data-status-index="2"] { border-color: var(--cat-money); color: var(--cat-money-text); }
.ig-hyp-status[data-status-index="3"] { border-color: var(--danger); color: var(--danger); }

/* График набора просмотров (inline SVG, геометрия - app/instagram/analysis.py) */
.ig-chart-wrap { margin: 0 0 var(--space-4); overflow-x: auto; }
.ig-chart { width: 100%; max-width: 680px; min-width: 440px; height: auto; display: block; overflow: visible; }
.ig-chart-grid { stroke: var(--border); stroke-width: 1; }
.ig-chart-axis { fill: var(--muted); font-size: 12px; }
.ig-chart-line { fill: none; stroke: currentColor; stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.ig-chart-dot { fill: currentColor; stroke: var(--panel); stroke-width: 2; }
.ig-chart-legend { display: flex; flex-wrap: wrap; gap: 14px; margin-top: var(--space-2); font-size: var(--fs-small); color: var(--muted); }
.ig-legend-item { display: inline-flex; align-items: center; }
.ig-legend-swatch { display: inline-block; width: 10px; height: 10px; border-radius: 3px; background: currentColor; margin-right: 6px; }
.ig-series-0 { color: var(--accent-2); }
.ig-series-1 { color: var(--cat-stock); }
.ig-series-2 { color: var(--cat-ads); }
.ig-series-3 { color: var(--cat-money); }
.ig-series-4 { color: light-dark(#6f5fc7, #a99cf0); }

@media (max-width: 860px) {
  .ig-card-grid { grid-template-columns: 1fr; }
  .ig-card-side { position: static; display: flex; gap: var(--space-4); align-items: flex-start; }
  .ig-cover--large { max-width: 120px; }
  .ig-cover-form { margin-top: 0; }
}

@media (max-width: 640px) {
  .ig-fields, .ig-metric-grid, .ig-metric-grid--3 { grid-template-columns: 1fr; }
  .ig-toolbar { align-items: stretch; }
  .ig-compare-button { width: 100%; }
}

/* «Контент Instagram», вторая итерация: плитки, «что даёт результат»,
   сортировка, быстрый замер, ролик-тест из гипотезы. */
.ig-summary { flex-wrap: wrap; }
.ig-summary .stat-tile { flex: 1 1 180px; }
.ig-summary-best .stat-label a { color: inherit; font-weight: 600; }
.ig-insights {
  background: var(--panel);
  border: 1px solid var(--border);
  border-radius: var(--radius-md);
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-5);
}
.ig-insights-title { cursor: pointer; font-weight: 700; font-size: 15px; }
.ig-insights[open] .ig-insights-title { margin-bottom: var(--space-3); }
.ig-insights-empty { margin-top: var(--space-2); }
.ig-insights .table-wrap { border-color: var(--border); }
.ig-sortable { cursor: pointer; user-select: none; }
.ig-sortable:hover { color: var(--text); }
.ig-sortable[data-sort-dir="desc"]::after { content: " ↓"; opacity: 1; }
.ig-sortable[data-sort-dir="asc"]::after { content: " ↑"; opacity: 1; }
.ig-inline-form { margin: 4px 0 0; }
.ig-link-button, .ig-link-button:hover {
  background: none;
  border: none;
  padding: 0;
  color: var(--accent-2-pale);
  font-size: var(--fs-xs);
  font-weight: 600;
  box-shadow: none;
  cursor: pointer;
}
.ig-link-button:hover { text-decoration: underline; opacity: 1; }
.ig-table--list th, .ig-table--list td { padding: 10px 10px; }
.ig-table--list .ig-title-cell { min-width: 140px; }
.ig-table--list .ig-chips-cell { min-width: 120px; }
/* Дата публикации - коротко ДД.ММ.ГГ, время строкой ниже (20.10.2026). */
.ig-table--list .ig-date-cell { white-space: nowrap; width: 1%; }
.ig-quick-link { margin-top: 4px; display: inline-block; }
.ig-quick-link + .ig-quick-link { margin-left: 12px; }
a.ig-quick-link { text-decoration: none; }
.ig-button-link { display: inline-block; text-decoration: none; }

/* ---- РНП (решение владельца 29.09.2026) - раскладка как у imPulse/MPump
   Pro по скриншоту владельца: блок "Сводка" и по блоку на товар, карточка
   слева, в таблице строки - показатели, столбцы - дни (прокрутка вбок, первые
   три столбца закреплены). См. app/templates/rnp.html. ---- */
:root {
  --rnp-series: light-dark(#2a78d6, #4a94ec);
  --rnp-series-wash: light-dark(rgba(42, 120, 214, 0.18), rgba(74, 148, 236, 0.22));
  --rnp-good: var(--cat-money-text);
  --rnp-bad: var(--danger);
}

.rnp-toolbar { display: flex; align-items: flex-end; gap: var(--space-3) var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-4); }
.rnp-compare { font-size: var(--fs-xs); color: var(--muted); padding-bottom: 8px; }
.rnp-threshold { margin-bottom: 1px; }
.rnp-notice { margin-bottom: var(--space-4); padding: 10px 14px; border-radius: var(--radius-md); background: var(--accent-2-wash); font-size: var(--fs-small); }

.rnp-switch { display: inline-flex; align-items: center; gap: var(--space-2); padding-bottom: 6px; font-size: var(--fs-small); cursor: pointer; user-select: none; }
.rnp-switch input { position: absolute; opacity: 0; width: 1px; height: 1px; }
.rnp-switch i { position: relative; width: 36px; height: 20px; border-radius: 999px; background: var(--border); transition: background var(--dur-fast) var(--ease-standard); }
.rnp-switch i::after { content: ""; position: absolute; top: 2px; left: 2px; width: 16px; height: 16px; border-radius: 50%; background: var(--panel); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); transition: transform var(--dur-fast) var(--ease-standard); }
.rnp-switch input:checked + i { background: var(--accent); }
.rnp-switch input:checked + i::after { transform: translateX(16px); }
.rnp-switch input:focus-visible + i { box-shadow: var(--accent-2-ring); }

.rnp-menu { position: relative; }
.rnp-menu > summary { list-style: none; display: inline-flex; align-items: center; gap: 6px; padding: 6px 12px; border-radius: var(--radius-sm); cursor: pointer; font-size: var(--fs-small); }
.rnp-menu > summary::-webkit-details-marker { display: none; }
.rnp-menu > summary b { min-width: 18px; padding: 0 5px; border-radius: 999px; background: var(--panel-hover); font-size: var(--fs-xs); text-align: center; }
.rnp-menu-panel { position: absolute; top: calc(100% + 6px); left: 0; z-index: 30; display: flex; flex-direction: column; gap: 8px; min-width: 200px; padding: var(--space-3); background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-md); box-shadow: 0 12px 32px -14px rgba(0, 0, 0, 0.6); font-size: var(--fs-small); }
.rnp-menu-panel label { display: flex; align-items: center; gap: 8px; cursor: pointer; }
.rnp-metrics .rnp-menu-panel { max-height: min(70vh, 560px); overflow-y: auto; gap: 6px; }
.rnp-menu-group { margin-top: 4px; padding-top: 6px; border-top: 1px solid var(--border); color: var(--muted); font-size: var(--fs-xs); font-weight: 700; letter-spacing: .05em; text-transform: uppercase; }
.rnp-menu-group:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.rnp-help .rnp-menu-panel { left: auto; right: 0; width: min(420px, calc(100vw - 32px)); }
.rnp-help-panel p { margin: 0; line-height: 1.45; color: var(--text); }

.rnp-toolbar-right { display: flex; align-items: center; gap: var(--space-2); margin-left: auto; padding-bottom: 2px; }
.rnp-counter { display: inline-flex; align-items: center; gap: 5px; height: 34px; padding: 0 10px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--panel); color: var(--muted); font-size: var(--fs-small); font-weight: 400; text-decoration: none; }
.rnp-counter b { color: var(--text); font-variant-numeric: tabular-nums; }
.rnp-counter:hover { border-color: var(--accent-2); color: var(--text); opacity: 1; box-shadow: none; }
button.rnp-counter { cursor: pointer; }
.rnp-save { height: 34px; }

.rnp-block { display: flex; gap: var(--space-4); align-items: stretch; margin-bottom: var(--space-4); padding: var(--space-4); background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-md); }
.rnp-card { flex: 0 0 176px; display: flex; flex-direction: column; gap: 4px; min-width: 0; font-size: var(--fs-small); }
.rnp-block--summary .rnp-card { gap: var(--space-2); }
.rnp-summary-head { display: flex; flex-direction: column; align-items: center; padding: 14px 8px; border-radius: var(--radius-md); background: var(--panel-hover); }
.rnp-summary-label { font-size: var(--fs-micro); font-weight: 700; letter-spacing: 0.06em; text-transform: uppercase; color: var(--muted); }
.rnp-summary-count { font-size: 40px; font-weight: 700; line-height: 1.1; font-variant-numeric: tabular-nums; }
.rnp-sort-label { margin-top: 4px; font-size: var(--fs-xs); color: var(--muted); }
.rnp-sort-dir { display: flex; gap: 6px; }
.rnp-icon-btn { width: 34px; height: 34px; padding: 0; border-radius: 50%; border: 1px solid var(--border); background: transparent; color: var(--text); font-size: 15px; }
.rnp-icon-btn.is-active { background: var(--accent); border-color: var(--accent); color: var(--accent-text); }
.rnp-download { margin-top: auto; }
.rnp-block--summary .rnp-download { margin-top: 0; }

.rnp-photo { width: 100%; aspect-ratio: 3 / 4; max-width: 100%; margin-bottom: 6px; border-radius: var(--radius-md); background: var(--panel-hover); overflow: hidden; }
.rnp-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }
.rnp-card-name { font-weight: 600; line-height: 1.3; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.rnp-card-meta { font-size: var(--fs-xs); color: var(--muted); font-variant-numeric: tabular-nums; }
.rnp-card-vc { color: var(--text); }
.rnp-card-hint { font-size: var(--fs-xs); color: var(--accent-2-pale); }

.rnp-grid-wrap { flex: 1 1 auto; min-width: 0; overflow-x: auto; }
table.rnp-grid { border-collapse: separate; border-spacing: 0; font-variant-numeric: tabular-nums; }
.rnp-grid th, .rnp-grid td { padding: 10px 12px; border-bottom: 1px solid var(--border); background: var(--panel); text-align: right; vertical-align: middle; white-space: nowrap; }
.rnp-grid tbody tr:last-child > * { border-bottom: none; }
.rnp-grid thead th { font-size: var(--fs-micro); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.rnp-grid thead th.rnp-c-day { font-size: var(--fs-small); font-weight: 600; letter-spacing: 0; text-transform: none; color: var(--text); }
.rnp-grid thead th.rnp-c-day small { display: block; font-size: var(--fs-micro); font-weight: 400; color: var(--muted); }
.rnp-grid .rnp-c-name { position: sticky; left: 0; z-index: 2; width: 178px; min-width: 178px; text-align: left; font-weight: 500; font-size: var(--fs-body); }
/* Заголовки строк - это <th scope="row">, общий стиль th сайта сделал бы их
   мелкими заглавными; у imPulse там обычный текст. */
.rnp-grid tbody th.rnp-c-name { color: var(--text); text-transform: none; letter-spacing: 0; }
.rnp-grid .rnp-c-total { position: sticky; left: 178px; z-index: 2; width: 128px; min-width: 128px; }
.rnp-grid .rnp-c-chart { position: sticky; left: 306px; z-index: 2; width: 170px; min-width: 170px; padding: 4px 10px; border-right: 1px solid var(--border); text-align: center; }
.rnp-grid td.rnp-c-day, .rnp-grid th.rnp-c-day { min-width: 96px; }
.rnp-grid .rnp-c-day.is-today { background: light-dark(#fafaf6, #20231f); }
.rnp-unit { color: var(--muted); font-weight: 400; font-size: var(--fs-small); }
.rnp-v { font-size: 17px; font-weight: 600; line-height: 1.25; }
.rnp-c-total .rnp-v { font-size: 18px; }
.rnp-d { display: block; margin-top: 2px; font-size: var(--fs-xs); font-weight: 600; }
.rnp-d.is-good { color: var(--rnp-good); }
.rnp-d.is-bad { color: var(--rnp-bad); }
.rnp-d.is-flat { color: var(--muted); }
.rnp-no-deltas .rnp-d { display: none; }
.rnp-grid td.is-anomaly { box-shadow: inset 0 0 0 2px var(--rnp-bad); border-radius: 8px; }

.rnp-mini { display: block; width: 100%; height: 52px; }
.rnp-mini rect { fill: var(--rnp-series); }
.rnp-mini-area { fill: var(--rnp-series-wash); }
.rnp-mini-line { fill: none; stroke: var(--rnp-series); stroke-width: 2; stroke-linejoin: round; vector-effect: non-scaling-stroke; }
.rnp-mini--area-money .rnp-mini-area { fill: var(--cat-money-soft); }
.rnp-mini--area-money .rnp-mini-line { stroke: var(--cat-money); }
.rnp-muted { color: var(--muted); font-size: var(--fs-xs); }

/* Переключатель у строки - график по дням прямо под ней, столбик под каждым
   днём (строка таблицы, поэтому столбики всегда ровно под своими датами и
   прокручиваются вместе с ними). */
.rnp-grid tbody th.rnp-c-name { display: table-cell; }
.rnp-grid tbody th.rnp-c-name > span { vertical-align: middle; }
.rnp-row-toggle { display: inline-block; vertical-align: middle; width: 30px; height: 18px; margin-right: 8px; padding: 0; border: none; border-radius: 999px; background: var(--border); }
.rnp-row-toggle i { display: block; width: 14px; height: 14px; margin-left: 2px; border-radius: 50%; background: var(--panel); box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25); transition: transform var(--dur-fast) var(--ease-standard); }
.rnp-row-toggle:hover { opacity: 1; box-shadow: none; }
.rnp-row-toggle[aria-pressed="true"] { background: var(--rnp-series); }
.rnp-row-toggle[aria-pressed="true"] i { transform: translateX(12px); }
.rnp-row-toggle:focus-visible { box-shadow: var(--accent-2-ring); }
.rnp-bars-row > * { padding-top: 4px; padding-bottom: 6px; }
.rnp-daybar-box { display: flex; align-items: flex-end; justify-content: center; height: 64px; }
.rnp-daybar { display: block; width: 60%; min-height: 2px; border-radius: 4px 4px 0 0; background: var(--rnp-series); }
.rnp-daybar.is-money { background: var(--cat-money); }

.rnp-pending { font-size: var(--fs-xs); font-style: italic; color: var(--muted); }
.rnp-grid td.is-pending { background: light-dark(#f7f7f3, #1f221e); }
.rnp-notice--error { background: light-dark(rgba(217, 67, 67, 0.08), rgba(255, 107, 107, 0.10)); }
.rnp-notice--error b { display: block; margin-bottom: 2px; }
.rnp-scroll-btns { display: flex; gap: 6px; padding-bottom: 2px; }

/* "Компактно" - без фото и мини-графиков: на экране помещается больше дней. */
.rnp-compact .rnp-photo, .rnp-compact .rnp-c-chart { display: none; }
.rnp-compact .rnp-card { flex-basis: 140px; }
.rnp-compact .rnp-grid .rnp-c-total { border-right: 1px solid var(--border); }

/* Заголовок дня - кнопка "добавить заметку к дню"; общий стиль кнопок сайта
   (тёмная заливка) гасим. */
.rnp-day-btn { position: relative; display: block; width: 100%; padding: 2px 0; border: none; border-radius: 6px; background: transparent; color: inherit; font: inherit; text-align: right; cursor: pointer; }
.rnp-day-btn:hover { background: var(--panel-hover); opacity: 1; box-shadow: none; }
.rnp-day-btn small { display: block; font-size: var(--fs-micro); font-weight: 400; color: var(--muted); }
.rnp-note-dot { position: absolute; top: -2px; left: 4px; min-width: 16px; height: 16px; padding: 0 4px; border-radius: 999px; background: var(--accent-2); color: var(--bg); font-size: 10px; font-weight: 700; line-height: 16px; text-align: center; }
.rnp-grid td[data-cell] { cursor: pointer; position: relative; }
.rnp-grid td[data-cell]:hover { background: var(--panel-hover); }
.rnp-grid td.is-focus { box-shadow: inset 0 0 0 3px var(--rnp-bad); }
.rnp-task-mark { position: absolute; top: 4px; left: 6px; font-size: 11px; line-height: 1; color: var(--accent-2-pale); }
.rnp-task-mark.is-done { color: var(--rnp-good); }

.rnp-hide-empty [data-empty="1"] { display: none; }
.rnp-card-tag { align-self: flex-start; padding: 1px 8px; border-radius: 999px; background: var(--accent-2-wash); color: var(--accent-2-pale); font-size: var(--fs-xs); }

.rnp-group { margin-bottom: var(--space-4); }
.rnp-block--group { margin-bottom: 0; border-color: var(--accent-2-glow); background: linear-gradient(var(--accent-2-wash), var(--accent-2-wash)), var(--panel); }
.rnp-block--group .rnp-grid th, .rnp-block--group .rnp-grid td { background: light-dark(#fbf9f3, #22241e); }
.rnp-group-head { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border-radius: var(--radius-md); background: var(--panel); }
.rnp-group-name { font-size: 18px; font-weight: 700; line-height: 1.2; }
.rnp-group-members { margin: var(--space-3) 0 0 var(--space-4); padding-left: var(--space-3); border-left: 2px solid var(--accent-2-glow); }
.rnp-group-members .rnp-block:last-child { margin-bottom: 0; }

/* Общий ползунок прокрутки дней внизу экрана - для мыши без горизонтальной
   прокрутки; таблицы свои полосы прокрутки при этом не показывают. */
.rnp-grid-wrap { scrollbar-width: none; }
.rnp-grid-wrap::-webkit-scrollbar { display: none; }
.rnp-hscroll { position: sticky; bottom: 0; z-index: 25; height: 16px; margin-bottom: var(--space-4); overflow-x: auto; overflow-y: hidden; background: var(--bg); }
.rnp-hscroll-inner { height: 1px; }

.rnp-link-btn { padding: 2px 6px; border: none; background: transparent; color: var(--muted); font-size: var(--fs-xs); font-weight: 400; }
.rnp-link-btn:hover { color: var(--danger); opacity: 1; box-shadow: none; }
.rnp-note-form { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; margin: var(--space-3) 0; }
.rnp-note-form select { max-width: 260px; }
.rnp-note-text { flex: 1 1 260px; min-width: 0; }
.rnp-log-cols { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); }
.rnp-log-title { margin-bottom: 6px; font-size: var(--fs-micro); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.rnp-log-item { display: flex; align-items: baseline; gap: var(--space-2); padding: 6px 0; border-top: 1px solid var(--border); font-size: var(--fs-small); }
.rnp-log-date { flex: none; width: 42px; color: var(--muted); font-variant-numeric: tabular-nums; }
.rnp-log-text { flex: 1; min-width: 0; overflow-wrap: anywhere; }
.rnp-log-item form { margin: 0; }
.rnp-status { flex: none; padding: 1px 8px; border-radius: 999px; background: var(--panel-hover); font-size: var(--fs-xs); }
.rnp-status.is-done { background: var(--cat-money-wash); color: var(--cat-money-text); }
.rnp-tag-input { width: 140px; }
.rnp-sheet-badge { padding: 1px 7px; border-radius: 999px; background: var(--cat-money-wash); color: var(--cat-money-text); font-size: var(--fs-micro); font-weight: 600; white-space: nowrap; }
.rnp-costs-status { margin: 0 0 12px; font-size: var(--fs-xs); color: var(--text); }
.rnp-cost-input[readonly] { background: var(--panel-hover); color: var(--muted); }
.rnp-costs-empty td { opacity: 0.6; }

.rnp-pop { position: absolute; z-index: 60; width: min(380px, calc(100vw - 32px)); padding: var(--space-3); background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-md); box-shadow: 0 16px 40px -14px rgba(0, 0, 0, 0.6); }
.rnp-pop-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-2); margin-bottom: var(--space-2); font-size: var(--fs-small); }
.rnp-pop-tabs { display: flex; gap: 4px; margin-bottom: var(--space-2); }
.rnp-pop-tab { padding: 4px 12px; border: 1px solid var(--border); border-radius: 999px; background: transparent; color: var(--muted); font-size: var(--fs-small); font-weight: 500; }
.rnp-pop-tab.is-active { border-color: var(--accent); background: var(--accent); color: var(--accent-text); }
.rnp-pop-form { display: flex; flex-direction: column; gap: 8px; margin: 0; font-size: var(--fs-xs); color: var(--muted); }
.rnp-pop-form[hidden] { display: none; }
.rnp-pop-row { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.rnp-pop-row label { display: flex; flex-direction: column; gap: 3px; }
.rnp-pop-form button[type="submit"] { align-self: flex-start; }

@media (max-width: 900px) {
  .rnp-log-cols { grid-template-columns: 1fr; }
  .rnp-group-members { margin-left: var(--space-2); padding-left: var(--space-2); }
  .rnp-toolbar-right { margin-left: 0; flex-wrap: wrap; }
}

.rnp-costs { margin-bottom: var(--space-4); padding: var(--space-4); background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-md); }
.rnp-costs > summary { cursor: pointer; font-weight: 700; }
.rnp-costs-sub { margin: 8px 0 12px; max-width: 70ch; font-size: var(--fs-xs); color: var(--muted); }
table.rnp-costs-table { width: 100%; border-collapse: collapse; font-size: var(--fs-small); }
table.rnp-costs-table th, table.rnp-costs-table td { padding: 10px 14px; border-top: 1px solid var(--border); text-align: left; }
table.rnp-costs-table th { font-size: var(--fs-micro); font-weight: 700; text-transform: uppercase; letter-spacing: 0.03em; color: var(--muted); }
table.rnp-costs-table .rnp-num { text-align: right; }
.rnp-cost-input { width: 110px; min-width: 0; text-align: right; }

@media (max-width: 900px) {
  .rnp-block { flex-direction: column; padding: var(--space-3); }
  .rnp-card { flex-basis: auto; flex-direction: row; flex-wrap: wrap; align-items: center; gap: 6px 12px; }
  .rnp-photo { width: 56px; aspect-ratio: 3 / 4; margin: 0; }
  .rnp-card-name { flex: 1 1 140px; }
  .rnp-summary-head { flex-direction: row; gap: 8px; padding: 8px 12px; }
  .rnp-summary-count { font-size: 24px; }
  .rnp-download { margin-top: 0; }
  .rnp-grid .rnp-c-chart { display: none; }
  .rnp-grid .rnp-c-name { width: 140px; min-width: 140px; font-size: var(--fs-small); }
  .rnp-grid .rnp-c-total { left: 140px; width: 104px; min-width: 104px; border-right: 1px solid var(--border); }
  .rnp-row-toggle { margin-right: 6px; }
  .rnp-v { font-size: 15px; }
}

/* --- ИИ Ассистент --- */

.ai-assistant-header { margin-bottom: var(--space-5); }
.ai-assistant-header .page-subtitle { max-width: 72ch; line-height: 1.55; color: var(--text); opacity: 0.82; }

.ai-assistant-subnav {
  display: flex;
  gap: var(--space-2);
  margin-bottom: var(--space-4);
  flex-wrap: wrap;
}

.ai-assistant-subnav-item {
  display: inline-flex;
  align-items: center;
  min-height: 40px;
  padding: 8px 15px;
  border-radius: var(--radius-md);
  border: 1px solid var(--border);
  background: var(--panel);
  color: var(--text);
  font-size: var(--fs-small);
  font-weight: 550;
  text-decoration: none;
  transition: border-color var(--dur-fast) var(--ease-standard), background-color var(--dur-fast) var(--ease-standard);
}

.ai-assistant-subnav-item:hover { border-color: var(--accent-2); background: var(--panel-hover); }
.ai-assistant-subnav-item:focus-visible,
.ai-chat-suggestion:focus-visible,
.ai-chat-attach-label:focus-within { outline: 2px solid var(--accent-2); outline-offset: 2px; }

.ai-assistant-subnav-item.active {
  background: var(--accent-2-wash);
  border-color: var(--accent-2);
  color: var(--accent-2-pale);
  font-weight: 700;
}

.ai-chat {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  max-width: 960px;
}

.ai-chat-history {
  display: flex;
  flex-direction: column;
  gap: var(--space-3);
  min-height: 360px;
  max-height: 62vh;
  overflow-y: auto;
  padding: clamp(12px, 2vw, 20px);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--panel);
  scroll-behavior: smooth;
}

.ai-chat-empty {
  display: flex;
  flex: 1;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  padding: 32px 16px;
  text-align: center;
}
.ai-chat-empty-icon {
  display: grid;
  place-items: center;
  width: 42px;
  height: 42px;
  margin-bottom: 12px;
  border: 1px solid var(--accent-2-soft);
  border-radius: 50%;
  background: var(--accent-2-wash);
  color: var(--accent-2-pale);
  font-size: 21px;
}
.ai-chat-empty h2 { margin: 0; font-size: 18px; }
.ai-chat-empty p { margin: 7px 0 16px; color: var(--text); opacity: 0.78; line-height: 1.5; }
.ai-chat-suggestions { display: flex; justify-content: center; flex-wrap: wrap; gap: var(--space-2); }
.ai-chat-suggestion {
  min-height: 36px;
  padding: 7px 12px;
  border: 1px solid var(--border);
  border-radius: var(--radius-pill);
  background: var(--bg);
  color: var(--text);
  font: inherit;
  font-size: var(--fs-small);
  cursor: pointer;
  transition: border-color var(--dur-fast) var(--ease-standard), background-color var(--dur-fast) var(--ease-standard);
}
.ai-chat-suggestion:hover { border-color: var(--accent-2); background: var(--accent-2-wash); }

.ai-chat-msg {
  max-width: 92%;
  padding: 13px 16px;
  border-radius: var(--radius-lg);
  border: 1px solid var(--border);
  background: var(--bg);
}

.ai-chat-msg--user { align-self: flex-end; }

.ai-chat-msg--assistant {
  align-self: flex-start;
  border-color: var(--accent-2-soft);
  background: var(--accent-2-wash);
}

.ai-chat-msg-role {
  margin-bottom: 6px;
  color: var(--text);
  font-size: var(--fs-xs);
  font-weight: 700;
  letter-spacing: 0.01em;
}

.ai-chat-msg-content { white-space: pre-line; line-height: 1.6; color: var(--text); overflow-wrap: anywhere; }

.ai-chat-msg-attachment {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  margin-top: 9px;
  padding: 5px 9px;
  border: 1px solid var(--border);
  border-radius: var(--radius-sm);
  background: var(--panel);
  color: var(--text);
  font-size: var(--fs-small);
}

.ai-chat-msg-tools { margin-top: 12px; display: flex; flex-direction: column; gap: 6px; }
.ai-chat-tool-call { border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--panel); }
.ai-chat-tool-summary { display: flex; align-items: center; gap: 8px; padding: 9px 11px; cursor: pointer; list-style: none; }
.ai-chat-tool-summary::-webkit-details-marker { display: none; }
.ai-chat-tool-summary::after { content: "⌄"; margin-left: 2px; color: var(--text); font-size: 15px; transition: transform var(--dur-fast) var(--ease-standard); }
.ai-chat-tool-call[open] .ai-chat-tool-summary::after { transform: rotate(180deg); }
.ai-chat-tool-mark { display: grid; place-items: center; flex: 0 0 20px; height: 20px; border-radius: 50%; background: var(--accent-2-wash); color: var(--accent-2-pale); font-size: 12px; font-weight: 800; }
.ai-chat-tool-name { color: var(--text); font-size: var(--fs-small); font-weight: 650; }
.ai-chat-tool-more { margin-left: auto; color: var(--text); opacity: 0.72; font-size: var(--fs-xs); }
.ai-chat-tool-result { padding: 0 12px 12px 39px; color: var(--text); font-size: var(--fs-small); line-height: 1.55; white-space: pre-line; overflow-wrap: anywhere; }

.ai-chat-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-2);
  padding: 14px;
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--panel);
}
.ai-chat-input-label { color: var(--text); font-size: var(--fs-small); font-weight: 700; }
.ai-chat-input { resize: vertical; min-height: 76px; width: 100%; line-height: 1.5; }
.ai-chat-input::placeholder { color: var(--muted); opacity: 1; }
.ai-chat-file-hint { color: var(--text); opacity: 0.74; font-size: var(--fs-xs); line-height: 1.45; }
.ai-chat-form-status { min-height: 0; color: var(--text); font-size: var(--fs-small); }
.ai-chat-form-status:empty { display: none; }
.ai-chat-form-status.is-error { color: var(--danger); }

.ai-chat-form-actions {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: var(--space-2);
  margin-top: 2px;
}

.ai-chat-attach-label { display: inline-flex; align-items: center; gap: 7px; font-size: var(--fs-small); }
.ai-chat-attach-label span:first-of-type { font-size: 15px; }

@media (max-width: 700px) {
  .ai-chat-history { min-height: 300px; max-height: 58vh; padding: 10px; }
  .ai-chat-msg { max-width: 100%; padding: 11px 12px; }
  .ai-chat-form { padding: 11px; }
  .ai-chat-form-actions { align-items: stretch; }
  .ai-chat-attach-label, .ai-chat-form-actions > .button { justify-content: center; }
  .ai-chat-empty { padding: 24px 6px; }
}
/* --- Анализ ИИ на /rnp (решение владельца 30.09.2026, см. app/ai/rnp_insights.py) --- */

.rnp-ai-body { display: flex; flex-direction: column; gap: var(--space-3); align-items: flex-start; }
#rnp-ai-result:empty { display: none; }
#rnp-ai-result .ai-card-text { max-width: 70ch; }

/* --- Регламенты (решение владельца 30.09.2026, см. app/routers/reglaments.py) ---
   Описанные повторяющиеся процессы сотрудников: карточка с галочкой за
   текущий период, полоска истории последних периодов и раскрывающаяся
   инструкция (зачем / шаги / результат / ссылки). Вкладки людей и шлюз-свод
   переиспользуют .owner-tab/.task-gate-* со страницы "Задачи". */

.reg-toolbar { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-6); }
.reg-owner-tabs { margin-bottom: 0; }
.reg-add-button { flex-shrink: 0; text-decoration: none; }
.owner-tab-avatar--team svg { width: 20px; height: 20px; }

.reg-progress {
  display: flex;
  align-items: center;
  gap: var(--space-6);
  flex-wrap: wrap;
  padding: var(--space-4) var(--space-5);
  margin-bottom: var(--space-6);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--panel);
}
.reg-progress-main { display: flex; align-items: center; gap: var(--space-3); }
.reg-progress-periods { display: flex; gap: var(--space-5); flex-wrap: wrap; flex: 1; min-width: 240px; }
.reg-progress-period { display: flex; flex-direction: column; gap: 6px; min-width: 110px; flex: 1; }
.reg-progress-period-head { display: flex; justify-content: space-between; gap: var(--space-2); font-size: var(--fs-small); color: var(--muted); }
.reg-progress-period-value { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.reg-gate-period { font-size: var(--fs-xs); color: var(--muted); font-variant-numeric: tabular-nums; }

.reg-section { margin-bottom: var(--space-6); }
.reg-section-title {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0 0 var(--space-3);
  font-size: var(--fs-body-lg);
  font-weight: 700;
}
.reg-section-count {
  padding: 1px 8px;
  border-radius: var(--radius-pill);
  background: var(--panel-hover);
  color: var(--muted);
  font-size: var(--fs-xs);
  font-weight: 600;
}
.reg-list { display: flex; flex-direction: column; gap: var(--space-2); }

.reg-card {
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--panel);
  transition: border-color var(--dur-fast) var(--ease-standard), background-color var(--dur-fast) var(--ease-standard);
  scroll-margin-top: 80px;
}
.reg-card:hover { border-color: var(--accent-2-soft); }
.reg-card:target { border-color: var(--accent-2-glow); box-shadow: 0 0 0 1px var(--accent-2-glow); }
.reg-card--done { background: var(--cat-money-wash); border-color: var(--cat-money-soft); }

.reg-card-head { display: flex; align-items: flex-start; gap: var(--space-3); padding: 14px 16px 10px; }
.reg-check-form { margin: 0; }

/* Сброс глобального стиля button (тёмная заливка + отступы) - иначе
   галочка превращается в обычную тёмную кнопку. */
.reg-check {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 2px solid var(--border);
  border-radius: 8px;
  background: transparent;
  color: transparent;
  cursor: pointer;
}
.reg-check:hover { opacity: 1; border-color: var(--cat-money); }
.reg-check svg { width: 18px; height: 18px; }
.reg-check[aria-pressed="true"] { border-color: var(--cat-money); background: var(--cat-money); color: #fff; }
.reg-check:disabled { cursor: progress; opacity: 0.6; }

.reg-card-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 4px; }
.reg-card-title { font-size: var(--fs-body-lg); font-weight: 600; line-height: 1.35; overflow-wrap: anywhere; }
.reg-card-meta { display: flex; flex-wrap: wrap; gap: 6px; }
.reg-meta-item {
  padding: 1px 8px;
  border-radius: var(--radius-pill);
  background: var(--panel-hover);
  color: var(--muted);
  font-size: var(--fs-xs);
}
.reg-meta-due { background: var(--accent-2-wash); color: var(--accent-2-pale); font-weight: 600; }
.reg-done-note { font-size: var(--fs-xs); color: var(--cat-money-text); font-weight: 600; }
.reg-done-note[hidden] { display: none; }

.reg-history { display: flex; align-items: center; gap: 4px; padding-top: 8px; flex-shrink: 0; }
.reg-history-dot { width: 10px; height: 10px; border-radius: 3px; background: var(--panel-hover); }
.reg-history-dot--done { background: var(--cat-money); }
.reg-history-dot--missed { background: var(--danger); opacity: 0.55; }
.reg-history-dot--current { background: transparent; box-shadow: inset 0 0 0 1.5px var(--muted); }
.reg-history-dot--none { background: transparent; box-shadow: inset 0 0 0 1px var(--border); }

.reg-details { border-top: 1px solid var(--border); }
.reg-card--done .reg-details { border-top-color: var(--cat-money-soft); }
.reg-details-toggle {
  padding: 8px 16px 8px 56px;
  color: var(--muted);
  font-size: var(--fs-small);
  font-weight: 600;
  cursor: pointer;
  list-style: none;
}
.reg-details-toggle::-webkit-details-marker { display: none; }
.reg-details-toggle::after { content: " ▾"; }
.reg-details[open] .reg-details-toggle::after { content: " ▴"; }
.reg-details-toggle:hover { color: var(--text); }

.reg-body { display: flex; flex-direction: column; gap: var(--space-4); padding: 4px 16px 16px 56px; }
.reg-block { display: flex; flex-direction: column; gap: 6px; }
.reg-block-label { font-size: var(--fs-xs); font-weight: 700; color: var(--muted); }
.reg-text { margin: 0; line-height: 1.5; white-space: pre-line; max-width: 75ch; overflow-wrap: anywhere; }
.reg-block--result .reg-text {
  padding: 10px 12px;
  border-radius: var(--radius-md);
  background: var(--accent-2-wash);
}
.reg-steps { margin: 0; padding-left: 22px; display: flex; flex-direction: column; gap: 6px; line-height: 1.5; max-width: 75ch; }
.reg-steps li { padding-left: 4px; overflow-wrap: anywhere; }
.reg-steps li::marker { color: var(--accent-2); font-weight: 700; }
.reg-links { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: 4px; overflow-wrap: anywhere; }
.reg-empty-body { margin: 0; color: var(--muted); }
.reg-actions { display: flex; gap: var(--space-2); flex-wrap: wrap; }
.reg-actions .button { text-decoration: none; }
.reg-inline-form { margin: 0; }

.reg-empty {
  max-width: 640px;
  padding: var(--space-6);
  border: 1px dashed var(--border);
  border-radius: var(--radius-lg);
  background: var(--panel);
  line-height: 1.55;
}
.reg-empty-title { margin: 0 0 var(--space-2); font-size: var(--fs-card-title); }
.reg-empty p { margin: 0 0 var(--space-3); color: var(--muted); }
.reg-empty .button { text-decoration: none; display: inline-block; }

.reg-archive { margin-top: var(--space-6); color: var(--muted); }
.reg-archive summary { cursor: pointer; font-weight: 600; }
.reg-archive-list { list-style: none; margin: var(--space-3) 0 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-2); }
.reg-archive-list li { display: flex; align-items: center; justify-content: space-between; gap: var(--space-3); color: var(--text); }

/* Форма регламента */
.reg-form-layout { display: grid; grid-template-columns: minmax(0, 720px) minmax(220px, 300px); gap: var(--space-6); align-items: start; }
.reg-form {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  padding: var(--space-5);
  border: 1px solid var(--border);
  border-radius: var(--radius-lg);
  background: var(--panel);
}
.reg-field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.reg-field-label { font-size: var(--fs-small); font-weight: 600; }
.reg-field-hint { font-size: var(--fs-xs); color: var(--muted); margin-top: -2px; }
.reg-field-row { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-3); }
/* .mgmt-input без рамки задуман для правки прямо в таблице задач - в
   отдельной форме поле должно быть видно сразу, до наведения. */
.reg-form .mgmt-input { padding: 9px 12px; border-color: var(--border); background: var(--bg); font-size: var(--fs-body); }
.reg-form .mgmt-input:hover { border-color: var(--accent-2-soft); }
.reg-form .mgmt-input:focus { border-color: var(--accent-2); }
.reg-form textarea.mgmt-input { resize: vertical; line-height: 1.5; font-family: inherit; }
.reg-steps-input { min-height: 180px; }
.reg-form-actions { display: flex; justify-content: flex-end; gap: var(--space-2); }
.reg-form-actions .button { text-decoration: none; }
.reg-form-error {
  padding: 10px 12px;
  border-radius: var(--radius-md);
  background: color-mix(in srgb, var(--danger) 12%, transparent);
  color: var(--danger);
  font-weight: 600;
}
.reg-form-tips {
  position: sticky;
  top: var(--space-5);
  padding: var(--space-4) var(--space-5);
  border-radius: var(--radius-lg);
  background: var(--accent-2-wash);
  font-size: var(--fs-small);
  line-height: 1.5;
}
.reg-form-tips-title { margin: 0 0 var(--space-2); font-size: var(--fs-body); }
.reg-form-tips ol { margin: 0; padding-left: 18px; display: flex; flex-direction: column; gap: var(--space-2); }

@media (max-width: 900px) {
  .reg-form-layout { grid-template-columns: 1fr; }
  .reg-form-tips { position: static; }
}
@media (max-width: 600px) {
  .reg-field-row { grid-template-columns: 1fr; }
  .reg-card-head { flex-wrap: wrap; }
  .reg-history { order: 3; width: 100%; padding: 0 0 0 40px; }
  .reg-details-toggle, .reg-body { padding-left: 16px; }
  .reg-progress { gap: var(--space-4); }
}

/* ---- «Отзывы и вопросы» ---- */
.reviews-page { max-width: 1320px; margin: 0 auto; padding-bottom: var(--space-6); }
.reviews-mode-banner { display: flex; align-items: flex-start; gap: 12px; margin-bottom: var(--space-4); padding: 14px 16px; border: 1px solid var(--accent-2-glow); border-radius: var(--radius-md); background: var(--accent-2-wash); }
.reviews-mode-banner--live { border-color: color-mix(in srgb, var(--rnp-good) 38%, var(--border)); background: color-mix(in srgb, var(--rnp-good) 9%, var(--panel)); }
.reviews-mode-mark { flex: 0 0 24px; display: grid; place-items: center; width: 24px; height: 24px; border-radius: 50%; background: var(--accent-2-glow); color: var(--accent-2-pale); font-size: var(--fs-small); font-weight: 700; }
.reviews-mode-banner--live .reviews-mode-mark { background: color-mix(in srgb, var(--rnp-good) 20%, transparent); color: var(--rnp-good); }
.reviews-mode-banner strong { display: block; margin: 1px 0 3px; color: var(--text); }
.reviews-mode-banner p { margin: 0; color: var(--muted); font-size: var(--fs-small); line-height: 1.5; }

.reviews-ops-card { display: flex; flex-direction: column; gap: 16px; margin-bottom: var(--space-6); padding: 18px 20px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--panel); }
.reviews-ops-top { display: flex; justify-content: space-between; align-items: center; gap: var(--space-4); flex-wrap: wrap; }
.reviews-eyebrow { color: var(--accent-2-pale); font-size: var(--fs-micro); font-weight: 700; letter-spacing: 0.08em; }
.reviews-ops-intro h2 { margin: 3px 0 2px; font-size: var(--fs-card-title); }
.reviews-ops-intro p { margin: 0; color: var(--muted); font-size: var(--fs-small); }
.reviews-ops-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.reviews-poll-form { margin: 0; }
.reviews-poll-switch { padding: 8px 12px; border: 1px solid var(--border); border-radius: 999px; background: var(--panel-hover); }
.reviews-poll-switch i { flex: 0 0 auto; }
.reviews-poll-switch span { color: var(--text); font-weight: 600; }
.reviews-counts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px; }
.reviews-counts > div { display: flex; align-items: center; gap: 9px; min-width: 0; padding: 10px 12px; border-radius: var(--radius-sm); background: var(--panel-hover); }
.reviews-counts strong { color: var(--text); font-size: 20px; font-variant-numeric: tabular-nums; }
.reviews-counts span { color: var(--muted); font-size: var(--fs-small); }

.reviews-section-heading { display: flex; justify-content: space-between; align-items: flex-end; gap: var(--space-3); margin: 0 0 var(--space-3); }
.reviews-section-heading h2 { margin: 0 0 3px; font-size: var(--fs-card-title); }
.reviews-section-heading p { margin: 0; color: var(--muted); font-size: var(--fs-small); }
.reviews-queue-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); margin-bottom: var(--space-6); align-items: start; }
.reviews-queue-grid--one { grid-template-columns: minmax(0, 1fr); }
.reviews-card { display: flex; flex-direction: column; gap: 16px; min-width: 0; margin: 0; padding: 20px; border: 1px solid var(--border); background: var(--panel); }
.reviews-card-head { display: flex; flex-direction: column; align-items: stretch; gap: 12px; padding-bottom: 13px; border-bottom: 1px solid var(--border); }
.reviews-card-heading { display: flex; justify-content: space-between; align-items: center; gap: 12px; }
.reviews-card-title-row { display: flex; align-items: center; gap: 10px; min-width: 0; }
.reviews-card-title-row h2 { margin: 0; font-size: 18px; }
.reviews-card-rating { display: inline-flex; align-items: center; gap: 4px; padding: 4px 8px; border-radius: 999px; background: var(--accent-2-wash); color: var(--accent-2-pale); font-size: var(--fs-small); font-weight: 600; white-space: nowrap; }
.reviews-card-rating span { color: var(--accent); }
.reviews-card-queue-count { color: var(--muted); font-size: var(--fs-small); white-space: nowrap; }
.reviews-card-product { display: flex; flex-direction: column; gap: 3px; min-width: 0; color: var(--text); font-size: var(--fs-body); }
.reviews-card-product > span { color: var(--muted); font-size: var(--fs-xs); }
.reviews-card-product strong { overflow-wrap: anywhere; }
.reviews-customer-message { display: flex; flex-direction: column; gap: 7px; }
.reviews-field-label { display: flex; flex-direction: column; gap: 3px; color: var(--text); font-size: var(--fs-small); font-weight: 700; }
.reviews-field-label > span { color: var(--muted); font-size: var(--fs-xs); font-weight: 400; }
.reviews-card-source { padding: 12px 14px; border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--panel-hover); color: var(--text); font-size: var(--fs-body); line-height: 1.55; white-space: pre-wrap; overflow-wrap: anywhere; }
.reviews-card-no-text { color: var(--muted); font-style: italic; }
.reviews-card-highlights { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.reviews-card-highlights > div { min-width: 0; padding: 9px 11px; border-radius: var(--radius-sm); background: var(--panel-hover); }
.reviews-card-highlights span { color: var(--muted); font-size: var(--fs-xs); }
.reviews-card-highlights p { margin: 3px 0 0; color: var(--text); font-size: var(--fs-small); line-height: 1.45; overflow-wrap: anywhere; }
.reviews-edit-form { display: flex; flex-direction: column; gap: var(--space-2); min-width: 0; }
.reviews-draft-input { min-height: 140px; line-height: 1.55; }
.reviews-card-actions { display: flex; align-items: center; gap: var(--space-2); flex-wrap: wrap; }
.reviews-inline-form { display: flex; gap: var(--space-2); align-items: center; min-width: 0; }
.reviews-card-tools { display: flex; align-items: flex-end; gap: 12px; padding-top: 13px; border-top: 1px solid var(--border); }
.reviews-regen-form { display: flex; flex: 1 1 320px; flex-direction: column; gap: 7px; min-width: 0; }
.reviews-regen-form .reviews-inline-form { width: 100%; }
.reviews-regen-form input[name="remark"] { flex: 1 1 auto; min-width: 120px; }
.reviews-defer-form { flex: 0 0 auto; }
.reviews-queue-empty { display: flex; align-items: center; gap: 13px; padding: 20px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--panel); }
.reviews-empty-mark { display: grid; flex: 0 0 34px; place-items: center; width: 34px; height: 34px; border-radius: 50%; background: var(--accent-2-wash); color: var(--accent-2-pale); font-weight: 700; }
.reviews-queue-empty strong { color: var(--text); }
.reviews-queue-empty p { margin: 3px 0 0; color: var(--muted); font-size: var(--fs-small); }

.reviews-knowledge { margin-top: var(--space-6); border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--panel); overflow: hidden; }
.reviews-knowledge-summary { display: flex; align-items: center; gap: 12px; min-height: 70px; padding: 14px 18px; cursor: pointer; list-style: none; }
.reviews-knowledge-summary::-webkit-details-marker { display: none; }
.reviews-knowledge-summary::after { content: "⌄"; margin-left: 3px; color: var(--muted); font-size: 20px; transition: transform var(--dur-fast) var(--ease-standard); }
.reviews-knowledge[open] .reviews-knowledge-summary::after { transform: rotate(180deg); }
.reviews-knowledge-mark { display: grid; flex: 0 0 34px; place-items: center; width: 34px; height: 34px; border-radius: 10px; background: var(--accent-2-wash); color: var(--accent-2-pale); }
.reviews-knowledge-copy { display: flex; flex: 1 1 auto; flex-direction: column; gap: 2px; min-width: 0; }
.reviews-knowledge-copy strong { color: var(--text); font-size: var(--fs-card-title); }
.reviews-knowledge-copy > span { color: var(--muted); font-size: var(--fs-small); }
.reviews-knowledge-action { color: var(--accent-2-pale); font-size: var(--fs-small); white-space: nowrap; }
.reviews-knowledge-grid { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: var(--space-4); padding: 0 16px 16px; align-items: start; }
.reviews-knowledge-block { display: flex; flex-direction: column; align-items: stretch; gap: var(--space-3); min-width: 0; margin: 0; padding: 16px; }
.reviews-knowledge-block-head h3 { margin: 0 0 3px; font-size: var(--fs-body); }
.reviews-knowledge-block-head p { margin: 0; color: var(--muted); font-size: var(--fs-small); }
.reviews-rules-list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: var(--space-1); }
.reviews-rules-list li { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-2); min-width: 0; padding: 7px 0; border-bottom: 1px solid var(--border); }
.reviews-rules-list li > span { flex: 1 1 auto; min-width: 0; line-height: 1.45; overflow-wrap: anywhere; }
.reviews-rules-list .reviews-card-empty { color: var(--muted); font-size: var(--fs-small); }
.reviews-add-rule-form input, .reviews-add-alias-form input { flex: 1 1 auto; min-width: 120px; }
.reviews-reseed { display: flex; justify-content: space-between; align-items: center; gap: var(--space-3); margin-top: var(--space-2); padding-top: var(--space-3); border-top: 1px solid var(--border); }
.reviews-reseed > div { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.reviews-reseed strong { color: var(--text); font-size: var(--fs-small); }
.reviews-reseed span { color: var(--muted); font-size: var(--fs-xs); }
.reviews-products-search input[name="search"] { flex: 1 1 auto; min-width: 120px; }
.reviews-products-list { list-style: none; margin: 0; padding: 0; max-height: 220px; overflow-y: auto; display: flex; flex-direction: column; gap: 3px; }
.reviews-products-list a { display: block; padding: 7px 9px; border: 1px solid transparent; border-radius: var(--radius-sm); line-height: 1.4; overflow-wrap: anywhere; }
.reviews-products-list a:hover { background: var(--panel-hover); }
.reviews-product-active { background: var(--accent-2-wash); border-color: var(--accent-2-glow) !important; font-weight: 600; }
.reviews-product-detail { display: flex; flex-direction: column; gap: var(--space-4); margin-top: 2px; padding-top: var(--space-4); border-top: 1px solid var(--border); }
.reviews-product-detail-head { display: flex; justify-content: space-between; align-items: baseline; gap: var(--space-2); flex-wrap: wrap; }
.reviews-product-detail-head h4 { margin: 0; font-size: var(--fs-body); overflow-wrap: anywhere; }
.reviews-product-detail-head span { color: var(--muted); font-size: var(--fs-xs); }
.reviews-knowledge-field { display: flex; flex-direction: column; gap: 7px; }

@media (max-width: 900px) {
  .reviews-queue-grid, .reviews-knowledge-grid { grid-template-columns: 1fr; }
  .reviews-ops-top { align-items: flex-start; }
}
@media (max-width: 600px) {
  .reviews-page { padding-bottom: var(--space-4); }
  .reviews-card { padding: 14px; }
  .reviews-ops-card { padding: 14px; }
  .reviews-ops-actions { width: 100%; align-items: flex-start; }
  .reviews-counts { gap: 7px; }
  .reviews-counts > div { align-items: flex-start; flex-direction: column; gap: 2px; padding: 9px; }
  .reviews-card-tools { align-items: stretch; flex-direction: column; }
  .reviews-card-actions > button { flex: 1 1 150px; }
  .reviews-reseed { align-items: flex-start; flex-direction: column; }
  .reviews-knowledge-grid { padding: 0 10px 10px; }
  .reviews-knowledge-summary { padding: 12px; }
  .reviews-knowledge-action { display: none; }
  .reviews-card-highlights { grid-template-columns: 1fr; }
}

/* P&L: ключевые показатели, продажи и понятный обзор запасов */
.pnl-page { --pnl-card-radius: 14px; }
.pnl-refresh { min-height: 40px; white-space: nowrap; }
.pnl-refresh span { margin-right: 3px; font-size: 18px; line-height: 0; }
.pnl-sync-status { display: flex; align-items: center; min-height: 39px; gap: 8px; margin-bottom: 16px; border: 1px solid var(--border); }
.pnl-sync-status::before { content: "i"; display: grid; flex: 0 0 18px; place-items: center; width: 18px; height: 18px; border-radius: 50%; color: var(--accent-2-pale); background: var(--accent-2-wash); font-size: 12px; font-weight: 700; }
.pnl-sync-status.is-running::before { content: "↻"; }
.pnl-sync-status.is-success { color: var(--cat-money-text); border-color: var(--cat-money-soft); background: var(--cat-money-wash); }
.pnl-sync-status.is-success::before { content: "✓"; color: var(--cat-money-text); background: var(--cat-money-soft); }
.pnl-sync-status.is-warning { color: var(--cat-ads-text); border-color: var(--cat-ads-soft); background: var(--cat-ads-wash); }
.pnl-sync-status.is-warning::before { content: "!"; color: var(--cat-ads-text); background: var(--cat-ads-soft); }
.pnl-sync-status.is-error { color: var(--danger); border-color: color-mix(in srgb, var(--danger) 30%, var(--border)); background: color-mix(in srgb, var(--danger) 8%, var(--panel)); }
.pnl-sync-status.is-error::before { content: "×"; color: var(--danger); background: color-mix(in srgb, var(--danger) 12%, var(--panel)); }
.pnl-data-alert { display: flex; align-items: center; gap: 11px; margin: 0 0 14px; padding: 12px 14px; border: 1px solid var(--cat-ads-soft); border-radius: var(--pnl-card-radius); color: var(--cat-ads-text); background: var(--cat-ads-wash); }
.pnl-alert-mark { display: grid; flex: 0 0 25px; place-items: center; width: 25px; height: 25px; border-radius: 50%; color: var(--cat-ads-text); background: var(--cat-ads-soft); font-weight: 800; }
.pnl-data-alert > div { display: grid; flex: 1 1 auto; gap: 2px; min-width: 0; }
.pnl-data-alert > div span { font-size: var(--fs-small); }
.pnl-data-alert a { color: var(--text); font-size: var(--fs-small); font-weight: 700; text-decoration: underline; text-underline-offset: 3px; white-space: nowrap; }
.pnl-how, .pnl-fee-details { margin: 0 0 13px; border: 1px solid var(--border); border-radius: 11px; background: var(--panel); }
.pnl-how summary, .pnl-fee-details summary { padding: 11px 14px; color: var(--text); cursor: pointer; font-size: var(--fs-small); font-weight: 650; list-style: none; }
.pnl-how summary::-webkit-details-marker, .pnl-fee-details summary::-webkit-details-marker { display: none; }
.pnl-how summary::after, .pnl-fee-details summary::after { float: right; content: "＋"; color: var(--accent-2-pale); }
.pnl-how[open] summary::after, .pnl-fee-details[open] summary::after { content: "−"; }
.pnl-how-body { padding: 0 14px 12px; color: var(--muted); font-size: var(--fs-small); line-height: 1.55; }
.pnl-how-body p { margin: 5px 0; }
.pnl-section { scroll-margin-top: 14px; }
.pnl-section-heading h2 { font-size: 19px; }
.pnl-sales-table { min-width: 690px; }
.pnl-sales-table th:not(:first-child), .pnl-sales-table td:not(:first-child), .pnl-fee-table th:not(:first-child), .pnl-fee-table td:not(:first-child) { text-align: right; }
.pnl-sales-table td:first-child strong { display: inline-flex; align-items: center; min-width: 45px; }
.pnl-total-row td { border-top: 1px solid var(--border); color: var(--text); background: var(--panel-hover); font-weight: 700; }
.pnl-total-row td:first-child { border-radius: 0 0 0 9px; }
.pnl-total-row td:last-child { border-radius: 0 0 9px 0; }
.pnl-sales-footnote { display: flex; align-items: center; flex-wrap: wrap; gap: 7px 18px; margin: 10px 1px 13px; color: var(--muted); font-size: var(--fs-xs); }
.pnl-sales-footnote strong { color: var(--text); }
.pnl-sales-footnote a { margin-left: auto; color: var(--accent-2-pale); }
.pnl-fee-details { margin-top: 4px; }
.pnl-fee-details .table-wrap { margin: 0 10px; }
.pnl-fee-details > .pnl-caption { margin: 8px 14px 12px; }
.pnl-section-badge { padding: 6px 9px; border: 1px solid var(--cat-ads-soft); border-radius: var(--radius-pill); color: var(--cat-ads-text); background: var(--cat-ads-wash); font-size: var(--fs-xs); font-weight: 650; }
.pnl-cost-search { display: flex; align-items: center; gap: 10px; width: min(100%, 380px); margin: 0 0 10px; color: var(--muted); font-size: var(--fs-small); }
.pnl-cost-search input { flex: 1 1 auto; min-width: 0; min-height: 38px; padding: 8px 10px; border: 1px solid var(--border); border-radius: var(--radius-md); color: var(--text); background: var(--panel); font: inherit; }
.pnl-cost-search input:focus-visible { outline: none; border-color: var(--accent-2); box-shadow: var(--accent-2-ring); }
.pnl-cost-table tr[hidden] { display: none; }

@media (max-width: 1180px) {
}
@media (max-width: 760px) {
  .pnl-data-alert { align-items: flex-start; flex-wrap: wrap; }
  .pnl-data-alert a { margin-left: 36px; }
  .pnl-sales-footnote a { margin-left: 0; }
}
@media (max-width: 560px) {
  .pnl-controls > form:last-child, .pnl-refresh { width: 100%; }
}

/* P&L: сворачиваемые разделы (себестоимость по SKU, товар на складах) */
.pnl-collapsible > summary.pnl-section-heading { margin-bottom: 0; padding: 12px 14px; border: 1px solid var(--border); border-radius: 11px; background: var(--panel); cursor: pointer; list-style: none; }
.pnl-collapsible > summary::-webkit-details-marker { display: none; }
.pnl-collapsible > summary::after { content: "＋"; margin-left: auto; color: var(--accent-2-pale); font-size: 18px; }
.pnl-collapsible[open] > summary::after { content: "−"; }
.pnl-collapsible[open] > summary.pnl-section-heading { margin-bottom: 12px; }

/* P&L: строки расчёта внутри карточки «Замороженные средства» */
.pnl-kpi-lines { display: grid; gap: 4px; margin: 4px 0 0; padding-top: 8px; border-top: 1px solid var(--border); font-size: var(--fs-xs); }
.pnl-kpi-lines div { display: flex; justify-content: space-between; gap: 8px; }
.pnl-kpi-lines dt { color: var(--muted); }
.pnl-kpi-lines dd { margin: 0; font-weight: 600; font-variant-numeric: tabular-nums; white-space: nowrap; }

/* P&L: налоговая база, доп. расходы и поставки - внизу страницы, компактно */
.pnl-bottom { margin-top: 8px; padding-top: 14px; border-top: 1px solid var(--border); }
.pnl-compact { margin-bottom: 16px; }
.pnl-compact .pnl-section-heading { margin-bottom: 8px; }
.pnl-compact .pnl-section-heading h2 { margin: 0 0 2px; font-size: 15px; }
.pnl-compact .pnl-section-heading p { font-size: var(--fs-xs); }
.pnl-compact .pnl-mini-total { font-size: var(--fs-xs); }
.pnl-compact .pnl-tax-grid { grid-template-columns: repeat(2, minmax(220px, 1fr)); gap: 8px; }
.pnl-compact .pnl-tax-card { padding: 8px 10px; }
.pnl-compact .pnl-tax-card label { margin-bottom: 4px; font-size: var(--fs-small); }
.pnl-compact .pnl-tax-card small { margin-top: 4px; }
.pnl-compact .pnl-expense-form { gap: 8px; margin-bottom: 8px; padding: 8px 10px; }
.pnl-compact .pnl-expense-form label { gap: 3px; font-size: var(--fs-xs); }
.pnl-compact input, .pnl-compact select { padding-top: 6px; padding-bottom: 6px; }
.pnl-compact .pnl-table th, .pnl-compact .pnl-table td { padding-top: 6px; padding-bottom: 6px; }
.pnl-compact .pnl-list-row { padding-top: 6px; padding-bottom: 6px; }
.pnl-compact .pnl-empty { padding: 10px; font-size: var(--fs-small); }

/* P&L: вкладки площадок (ВБ / Озон / Итого) */

/* P&L: читаемые таблицы (владелец 10.10.2026: «захожу в P&L и глаза в разные стороны») - колонки не растягиваются
   на всю ширину, числа выровнены вправо и одинаково во всех таблицах, строки в полоску, шапка закреплена. */
.pnl-section .table-wrap { width: fit-content; max-width: 100%; }
.pnl-table { width: auto; min-width: 0; }
.pnl-table th, .pnl-table td { padding: 9px 16px; }
.pnl-table thead th { position: sticky; top: 0; z-index: 1; background: var(--panel); border-bottom: 2px solid var(--border); }
.pnl-table tbody tr:nth-child(even) { background: color-mix(in srgb, var(--text) 3%, transparent); }
.pnl-table tbody tr:hover { background: color-mix(in srgb, var(--text) 8%, transparent); }
.pnl-table td:first-child { min-width: 200px; }
/* числовые колонки - вправо, с одинаковой минимальной шириной, заголовок выровнен так же, как цифры */
.pnl-sales-table th:not(:first-child), .pnl-sales-table td:not(:first-child),
.pnl-fee-table th:not(:first-child), .pnl-fee-table td:not(:first-child),
.pnl-cost-table th:nth-child(n+3):nth-child(-n+4), .pnl-cost-table td:nth-child(n+3):nth-child(-n+4),
.pnl-inventory-table th:nth-child(n+3), .pnl-inventory-table td:nth-child(n+3),
.pnl-inbound-table th:nth-child(n+3):nth-child(-n+6), .pnl-inbound-table td:nth-child(n+3):nth-child(-n+6) { text-align: right; min-width: 110px; white-space: nowrap; }
.pnl-total-row td { border-top: 2px solid var(--border); font-weight: 700; }
/* длинные списки (себестоимость, остатки) - в окне с прокруткой, чтобы страница не растягивалась на километр */
.pnl-section .table-wrap:has(.pnl-cost-table), .pnl-section .table-wrap:has(.pnl-inventory-table) { max-height: 560px; overflow: auto; }

/* P&L: отчёт о прибыли сверху вниз */

/* ===== P&L: оформление как у Cash Flow и Дашборда (владелец 13.10.2026: «компактно и удобно») =====
   Те же элементы, что и там: плитки с цветной верхней кромкой (.pulse-tile), месячные пилюли (.cashflow-month-pill),
   карточки .pnl-card с заголовком-подписью, две колонки (прибыль + где товар), плотные таблицы без лишних отступов. */
.pnl-page .page-header { margin-bottom: 14px; }
.pnl-bar { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-bottom: 8px; }
.pnl-tabs { display: inline-flex; gap: 2px; padding: 3px; border: 1px solid var(--border); border-radius: var(--radius-pill); background: var(--panel); flex-shrink: 0; }
.pnl-tabs a { padding: 6px 16px; border-radius: var(--radius-pill); color: var(--muted); font-size: 13px; font-weight: 600; text-decoration: none; }
.pnl-tabs a:hover { color: var(--text); }
.pnl-tabs a.is-active { background: light-dark(#1e7a4e, #2f9c68); color: #fff; }
.pnl-months { flex: 1 1 380px; min-width: 0; margin: 0; }
.pnl-months .cashflow-month-pill { padding: 6px 4px; font-size: 13px; }
.pnl-year { display: inline-flex; align-items: center; gap: 2px; padding: 2px; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--panel); flex-shrink: 0; }
.pnl-year a { width: 26px; height: 26px; display: grid; place-items: center; border-radius: 6px; color: var(--muted); font-size: 16px; text-decoration: none; }
.pnl-year a:hover { color: var(--text); background: var(--panel-hover); }
.pnl-year strong { padding: 0 6px; font-size: 13px; font-variant-numeric: tabular-nums; }
.pnl-sync-form { margin: 0; flex-shrink: 0; }
.pnl-refresh { min-height: 34px; padding: 6px 14px; font-size: 13px; white-space: nowrap; }
.pnl-refresh span { margin-right: 3px; font-size: 16px; line-height: 0; }
.pnl-meta { display: flex; align-items: center; flex-wrap: wrap; gap: 4px 16px; margin: 0 0 8px; color: var(--muted); font-size: var(--fs-xs); }
.pnl-meta .pnl-api-state { font-size: var(--fs-xs); }
.pnl-meta-period { margin-left: auto; }
.pnl-page .pnl-sync-status { min-height: 0; margin-bottom: 8px; padding: 6px 10px; font-size: var(--fs-xs); }
.pnl-page .pnl-data-alert { margin-bottom: 8px; padding: 8px 12px; border-radius: 8px; }

/* плитки показателей */
.pnl-kpis { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 12px; margin: 0 0 12px; }
.pnl-kpi { min-width: 0; padding: 12px 16px; gap: 3px; animation: none; }
.pnl-kpi .stat-value { font-size: 22px; overflow-wrap: anywhere; }
.pnl-kpi-profit .stat-value { color: var(--cat-money-text); }
.pnl-kpi-profit.is-negative .stat-value { color: var(--danger); }
.pnl-kpi .pulse-tile-sub { font-size: var(--fs-xs); line-height: 1.35; }

/* карточки и две колонки */
.pnl-card { min-width: 0; padding: 12px 16px; border: 1px solid var(--border); border-radius: 8px; background: var(--panel); }
.pnl-card-head { display: flex; align-items: baseline; justify-content: space-between; flex-wrap: wrap; gap: 2px 12px; margin-bottom: 8px; }
.pnl-card-head h2 { margin: 0; font-size: 15px; font-weight: 700; }
.pnl-card-head span { color: var(--muted); font-size: var(--fs-xs); }
.pnl-columns { display: grid; grid-template-columns: minmax(0, 1.35fr) minmax(300px, 1fr); gap: 12px; align-items: start; margin-bottom: 12px; }
.pnl-page .pnl-section { margin-bottom: 12px; }
.pnl-page .pnl-section-heading { margin-bottom: 8px; }
.pnl-page .pnl-section-heading h2 { margin: 0 0 2px; font-size: 15px; }
.pnl-page .pnl-section-heading p { font-size: var(--fs-xs); }
.pnl-card .table-wrap { width: 100%; max-width: 100%; border: 0; border-radius: 0; background: none; }

/* плотные таблицы */
.pnl-page .pnl-table { width: 100%; min-width: 0; }
.pnl-page .pnl-table th, .pnl-page .pnl-table td { padding: 5px 10px; font-size: 13px; }
.pnl-page .pnl-table th { font-size: var(--fs-xs); }
.pnl-page .pnl-table td:first-child { min-width: 0; }
.pnl-page .pnl-sales-table th:not(:first-child), .pnl-page .pnl-sales-table td:not(:first-child) { min-width: 0; }
.pnl-statement-table th:not(:first-child), .pnl-statement-table td:not(:first-child) { min-width: 96px; text-align: right; white-space: nowrap; }
.pnl-statement-table td:first-child { width: 100%; }
.pnl-st-0 td { font-size: 14px; font-weight: 700; }
.pnl-st-1 td:first-child { padding-left: 20px; color: var(--muted); }
.pnl-st-2 td { border-top: 2px solid var(--border); background: color-mix(in srgb, var(--accent-2) 10%, transparent); font-size: 15px; font-weight: 800; }
.pnl-st-pct { color: var(--muted); }
.pnl-st-bar { display: inline-block; min-width: 62px; padding: 0 6px; border-radius: 4px; text-align: right; }
.pnl-st-1 .pnl-st-bar { background: linear-gradient(90deg, color-mix(in srgb, var(--danger) 24%, transparent) var(--w), transparent var(--w)); }
.pnl-st-note { margin: 6px 0 0; }

/* где сейчас товар - компактный список этапов */
.pnl-flow-summary { display: flex; flex-wrap: wrap; gap: 2px 14px; margin: 0 0 6px; color: var(--muted); font-size: var(--fs-xs); }
.pnl-flow-summary strong { color: var(--text); font-variant-numeric: tabular-nums; }
.pnl-flow { display: flex; flex-direction: column; }
.pnl-flow-card { display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 2px 10px; padding: 8px 0 8px 10px; border-left: 3px solid var(--accent-2); border-top: 1px solid var(--border); }
.pnl-flow-card:first-child { border-top: 0; }
.pnl-flow-china { border-left-color: var(--cat-ads); }
.pnl-flow-stock { border-left-color: var(--cat-stock); }
.pnl-flow-sold { border-left-color: var(--cat-money); }
.pnl-flow-step { color: var(--muted); font-size: 10px; font-weight: 700; letter-spacing: .07em; }
.pnl-flow-card h3 { margin: 1px 0 0; font-size: 13px; }
.pnl-flow-quantity { font-size: 18px; line-height: 1.2; text-align: right; font-variant-numeric: tabular-nums; }
.pnl-flow-quantity small { color: var(--muted); font-size: 12px; font-weight: 500; }
.pnl-flow-card dl { grid-column: 1 / -1; display: flex; flex-wrap: wrap; gap: 2px 14px; margin: 0; }
.pnl-flow-card dl div { display: flex; align-items: baseline; gap: 5px; }
.pnl-flow-card dt { color: var(--muted); font-size: var(--fs-xs); }
.pnl-flow-card dd { margin: 0; font-size: var(--fs-xs); font-weight: 650; font-variant-numeric: tabular-nums; }
.pnl-flow-section > .pnl-caption { margin-top: 6px; }

/* навигация по разделам и сворачиваемые блоки */
.pnl-jumpnav { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; }
.pnl-jumpnav a { padding: 4px 10px; border: 1px solid var(--border); border-radius: var(--radius-pill); color: var(--muted); background: var(--panel); font-size: var(--fs-xs); text-decoration: none; }
.pnl-jumpnav a:hover { color: var(--text); border-color: var(--accent-2-glow); }
.pnl-statement .pnl-how { margin: 8px 0 0; border: 0; background: none; }
.pnl-statement .pnl-how summary { padding: 4px 0; color: var(--muted); font-size: var(--fs-xs); }
.pnl-page .pnl-collapsible > summary.pnl-section-heading { padding: 8px 14px; border-radius: 8px; }
.pnl-page .pnl-collapsible[open] > summary.pnl-section-heading { margin-bottom: 8px; }

@media (max-width: 1100px) {
  .pnl-columns { grid-template-columns: minmax(0, 1fr); }
  .pnl-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .pnl-months { flex-basis: 100%; order: 3; }
}
@media (max-width: 600px) {
  .pnl-bar { gap: 8px; }
  .pnl-months { overflow-x: auto; flex-wrap: nowrap; padding: 2px 0; scrollbar-width: none; }
  .pnl-months::-webkit-scrollbar { display: none; }
  .pnl-months .cashflow-month-pill { flex: 0 0 auto; padding: 6px 12px; }
  .pnl-kpis { gap: 8px; }
  .pnl-kpi-goods { grid-column: 1 / -1; }
  .pnl-kpi { padding: 10px 12px; }
  .pnl-kpi .stat-value { font-size: 18px; }
  .pnl-card { padding: 10px 12px; }
  .pnl-meta-period { margin-left: 0; width: 100%; }
}

/* ===== Наш склад: партии из Китая (запрос владельца 15.10.2026) ===== */
.pnl-flow-ordered { border-left-color: var(--muted); }
.wh-kpis { grid-template-columns: repeat(4, minmax(0, 1fr)); }
@media (max-width: 1100px) { .wh-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
.wh-form-card { margin: 0 0 12px; }
.wh-form-card > summary { cursor: pointer; font-size: 14px; font-weight: 700; list-style: none; }
.wh-form-card > summary::-webkit-details-marker { display: none; }
.wh-form-card[open] > summary { margin-bottom: 10px; }
.wh-fields { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 8px 10px; margin-bottom: 10px; }
.wh-fields label { display: grid; gap: 3px; color: var(--muted); font-size: var(--fs-xs); }
.wh-comment { grid-column: span 2; }
.wh-page .wh-grid th, .wh-page .wh-grid td { padding: 4px 8px; text-align: center; }
.wh-page .wh-grid th:first-child, .wh-page .wh-grid td:first-child { text-align: left; min-width: 110px; }
.wh-grid input { width: 66px; padding: 4px 6px; text-align: center; }
.wh-row-total { font-weight: 700; }
.wh-grid tfoot td { border-top: 2px solid var(--border); font-weight: 700; }
.wh-list { display: grid; gap: 12px; }
.wh-dates { margin: 0 0 8px; color: var(--muted); font-size: var(--fs-xs); }
.wh-dates b { color: var(--text); font-weight: 600; }
.wh-badge { margin-left: 8px; padding: 2px 8px; border-radius: var(--radius-pill); font-size: 11px; font-weight: 600; vertical-align: middle; color: var(--text); }
.wh-badge--ordered { background: var(--cat-ads-wash); }
.wh-badge--in_transit { background: var(--cat-stock-wash); }
.wh-badge--received { background: var(--cat-money-wash); }
.wh-flash { margin: 0 0 10px; padding: 9px 12px; border-radius: 10px; font-size: var(--fs-sm); background: var(--cat-money-wash); color: var(--text); }
.wh-flash--warn { background: var(--cat-ads-wash); }
.wh-files { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin: 10px 0 0; padding-top: 10px; border-top: 1px solid var(--border); }
.wh-files-title { color: var(--muted); font-size: var(--fs-xs); font-weight: 600; }
.wh-file { position: relative; display: grid; gap: 3px; width: 92px; margin: 0; }
.wh-file a { display: block; height: 92px; border: 1px solid var(--border); border-radius: 8px; overflow: hidden; background: var(--panel-hover); }
.wh-file img { width: 100%; height: 100%; object-fit: cover; display: block; }
.wh-file-doc { display: grid; place-items: center; height: 100%; font-weight: 700; color: var(--muted); }
.wh-file figcaption { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; color: var(--muted); font-size: 11px; }
.wh-file form { position: absolute; top: 3px; right: 3px; margin: 0; }
.wh-file-del { width: 20px; height: 20px; padding: 0; border: 0; border-radius: 50%; background: rgba(0, 0, 0, .65); color: #fff; line-height: 20px; cursor: pointer; }
.wh-file-del:hover { background: var(--danger); }
.wh-file-add { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin: 0; }
.wh-file-add input[type=file] { max-width: 260px; font-size: var(--fs-xs); }
.wh-files-edit { margin: 0 0 10px; color: var(--muted); font-size: var(--fs-xs); }
.whs-delivery { margin: 6px 0 0; color: var(--muted); font-size: var(--fs-xs); }
.wh-actions { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-top: 10px; }
.wh-actions form { margin: 0; }
@media (max-width: 720px) {
  .wh-kpis { grid-template-columns: minmax(0, 1fr); }
  .wh-comment { grid-column: auto; }
}

/* Режим правки Cash Flow (кнопка «Править данные»): ячейки с данными подсвечиваются как кликабельные. */
.cashflow-editing .cashflow-value[data-day] { cursor: cell; }
.cashflow-editing .cashflow-value[data-day]:hover { outline: 2px solid var(--accent, #4f8cff); outline-offset: -2px; }
#cashflow-entry-dialog input[type="text"], #cashflow-entry-dialog textarea { width: 100%; box-sizing: border-box; }

/* ===== Наш склад: живая картинка пути товара (запрос владельца 20.10.2026, app/warehouse/scene.py) ===== */
.whs { margin: 0 0 var(--space-4); }
.whs-stage {
  position: relative; width: 100%; overflow: hidden; border-radius: var(--radius-lg);
  border: 1px solid var(--border); background: #2b4a2f; image-rendering: auto;
}
.whs-bg { position: absolute; inset: 0; width: 100%; height: 100%; display: block; user-select: none; }
.whs-bg-video { object-fit: cover; opacity: 0; transition: opacity .6s; pointer-events: none; }
.whs-bg-video.is-playing { opacity: 1; }

/* Кликабельные зоны зданий - невидимые, подсвечиваются при наведении */
.whs-hot {
  position: absolute; padding: 0; border: 2px solid transparent; border-radius: 10px; background: transparent;
  box-shadow: none; cursor: pointer; transition: border-color .15s, background .15s;
}
.whs-hot:hover, .whs-hot:focus-visible { border-color: rgba(255, 216, 74, .9); background: rgba(255, 216, 74, .12); box-shadow: none; opacity: 1; }

/* Таблички с цифрами - в духе пиксельной игры */
.whs-badge {
  position: absolute; transform: translate(-50%, -50%); display: flex; flex-direction: column; align-items: center; gap: 2px;
  padding: 5px 9px 6px; border: 2px solid #111; border-radius: 4px; background: rgba(17, 17, 17, .86); color: #fff;
  box-shadow: 3px 3px 0 rgba(0, 0, 0, .45); font-family: ui-monospace, "SF Mono", Menlo, monospace; line-height: 1.1;
  cursor: pointer; white-space: nowrap; animation: whs-float 3.2s ease-in-out infinite;
}
.whs-badge:hover { opacity: 1; box-shadow: 3px 3px 0 rgba(0, 0, 0, .45), 0 0 0 3px rgba(255, 216, 74, .7); }
.whs-badge-title { font-size: clamp(8px, .75vw, 12px); font-weight: 600; text-transform: uppercase; letter-spacing: .04em; opacity: .8; }
.whs-badge-num { font-size: clamp(11px, 1.15vw, 18px); font-weight: 800; color: #ffd84a; }
.whs-badge-row { display: flex; align-items: baseline; gap: 6px; }
.whs-badge-sub { font-size: clamp(7px, .62vw, 10px); opacity: .75; }
.whs-badge-num--ready { color: #7dff9a; }
.whs-truck--ready { color: #2f9e57; animation: none; }
.whs-truck--ready svg { animation: none; }
.whs-badge--wb { border-color: #4b1a7a; } .whs-badge--wb .whs-badge-num { color: #d7a8ff; }
.whs-badge--ozon { border-color: #0b3d9e; } .whs-badge--ozon .whs-badge-num { color: #8ec5ff; }
.whs-badge--border { animation-delay: -.8s; } .whs-badge--ff { animation-delay: -1.6s; } .whs-badge--ozon { animation-delay: -2.4s; }
@keyframes whs-float { 50% { transform: translate(-50%, calc(-50% - 4px)); } }

/* Фура: подъезжает от начала дороги к своему месту, потом слегка покачивается */
.whs-truck {
  position: absolute; left: var(--x); top: var(--y); width: clamp(26px, 3vw, 54px); padding: 0; border: 0; background: none;
  box-shadow: none; color: #d8262c; transform: translate(-50%, -70%); cursor: pointer; z-index: 2;
  animation: whs-drive 2.4s cubic-bezier(.3, .7, .3, 1) var(--delay) both;
}
.whs-truck svg { display: block; width: 100%; height: auto; filter: drop-shadow(2px 3px 0 rgba(0, 0, 0, .45)); animation: whs-bob .5s steps(2) infinite; }
.whs-truck.is-flip svg { transform: scaleX(-1); }
.whs-truck--wb { color: #7b2ec9; } .whs-truck--ozon { color: #1d5fe0; }
.whs-truck:hover { opacity: 1; box-shadow: none; }
.whs-truck:hover svg { filter: drop-shadow(0 0 5px #ffd84a) drop-shadow(2px 3px 0 rgba(0, 0, 0, .45)); }
.whs-truck-tag {
  position: absolute; left: 50%; bottom: 100%; transform: translate(-50%, -3px); padding: 1px 5px; border-radius: 3px;
  background: rgba(17, 17, 17, .85); color: #fff; font: 700 clamp(7px, .65vw, 11px)/1.3 ui-monospace, Menlo, monospace; white-space: nowrap;
}
@keyframes whs-drive { from { left: var(--sx); top: var(--sy); } }
@keyframes whs-bob { 50% { transform: translateY(-1px); } }
.whs-truck.is-flip svg { animation-name: whs-bob-flip; }
@keyframes whs-bob-flip { 0%, 100% { transform: scaleX(-1); } 50% { transform: scaleX(-1) translateY(-1px); } }

/* Облака медленно плывут над картой */
.whs-clouds { position: absolute; inset: 0; pointer-events: none; overflow: hidden; }
.whs-clouds span {
  position: absolute; top: 4%; left: -25%; width: 22%; height: 16%; border-radius: 50%;
  background: radial-gradient(closest-side, rgba(255, 255, 255, .55), rgba(255, 255, 255, 0)); animation: whs-cloud 70s linear infinite;
}
.whs-clouds span:nth-child(2) { top: 62%; width: 26%; animation-duration: 95s; animation-delay: -40s; }
.whs-clouds span:nth-child(3) { top: 30%; width: 18%; animation-duration: 82s; animation-delay: -65s; opacity: .7; }
@keyframes whs-cloud { to { transform: translateX(560%); } }
@media (prefers-reduced-motion: reduce) {
  .whs-badge, .whs-truck, .whs-truck svg, .whs-clouds span { animation: none; }
}
.whs-hint { margin-top: 6px; }

/* Окна по клику на здание */
.whs-dialog {
  width: min(980px, calc(100vw - 32px)); max-height: calc(100vh - 48px); padding: 0; overflow: auto;
  border: 1px solid var(--border); border-radius: var(--radius-lg); background: var(--panel); color: var(--text);
}
.whs-dialog::backdrop { background: rgba(0, 0, 0, .65); }
.whs-dialog[open] { animation: whs-pop .18s ease-out; }
@keyframes whs-pop { from { transform: scale(.96); opacity: 0; } }
.whs-media { position: relative; background: #111; }
.whs-media img { display: block; width: 100%; height: auto; }
.whs-media video {
  position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .4s;
}
.whs-media video.is-playing { opacity: 1; }
.whs-dialog-body { padding: var(--space-4); }
.whs-dialog-body h2 { margin: 0 0 var(--space-3); font-size: var(--fs-card-title); }
.whs-dialog-body h3 { margin: var(--space-3) 0 var(--space-2); font-size: 14px; color: var(--muted); }
.whs-dialog form[method="dialog"] { position: absolute; top: 8px; right: 8px; margin: 0; }
.whs-close {
  width: 34px; height: 34px; padding: 0; border-radius: 50%; border: 1px solid rgba(255, 255, 255, .5);
  background: rgba(17, 17, 17, .75); color: #fff; font-size: 20px; line-height: 1;
}
.whs-batch { padding: var(--space-2) 0; border-top: 1px solid var(--border); }
.whs-batch:first-of-type { border-top: 0; }
.whs-batch-head { display: flex; justify-content: space-between; gap: var(--space-2); flex-wrap: wrap; margin-bottom: 6px; }
.whs-batch-head span { color: var(--muted); font-size: 13px; }
.whs-table { width: 100%; border-collapse: collapse; font-size: 13px; }
.whs-table td { padding: 5px 8px 5px 0; border-bottom: 1px solid var(--border); vertical-align: top; }
.whs-table tr:last-child td { border-bottom: 0; }
.whs-num { white-space: nowrap; font-weight: 700; text-align: right; }
.whs-sizes { color: var(--muted); }
.whs-sizes span { display: inline-block; margin: 0 10px 2px 0; white-space: nowrap; }
.whs-sizes b { color: var(--text); }
.whs-empty { color: var(--muted); margin: 0; }
.wh-dispatches { margin-top: var(--space-5, 28px); }
@media (max-width: 700px) {
  .whs-badge-title { display: none; }
  .whs-badge { padding: 1px 4px; border-width: 1px; box-shadow: 1px 1px 0 rgba(0, 0, 0, .45); }
  .whs-badge-num { font-size: 9px; }
  .whs-badge-sub { display: none; }
  .whs-truck { width: 18px; }
  .whs-truck-tag { display: none; }
}
/* В ожившей карте свои облака - нарисованные поверх больше не нужны */
.whs-stage:has(.whs-bg-video.is-playing) .whs-clouds { display: none; }

/* ===== Регламенты: база знаний, документ, проверка знаний, «что регламентировать» (курс, 21.10.2026) ===== */
.reg-tabs { display: inline-flex; gap: 2px; padding: 3px; margin-bottom: var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-pill); background: var(--panel); flex-wrap: wrap; }
.reg-tabs a { padding: 6px 16px; border-radius: var(--radius-pill); color: var(--muted); font-size: 13px; font-weight: 600; text-decoration: none; }
.reg-tabs a:hover { color: var(--text); }
.reg-tabs a.is-active { background: light-dark(#1e7a4e, #2f9c68); color: #fff; }
a.reg-card-title { color: var(--text); text-decoration: none; display: block; }
a.reg-card-title:hover { text-decoration: underline; }

.reg-doc { max-width: 820px; display: flex; flex-direction: column; gap: var(--space-3); }
.reg-doc-block { padding: var(--space-3) var(--space-4); border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--panel); }
.reg-doc-block h2 { margin: 0 0 8px; font-size: 13px; font-weight: 700; letter-spacing: .03em; text-transform: uppercase; color: var(--muted); }
.reg-doc-block .reg-text { margin: 0 0 6px; line-height: 1.55; }
.reg-doc-block--why { border-left: 3px solid light-dark(#c2410c, #fb923c); }
.reg-doc-block--examples { border-left: 3px solid light-dark(#1e7a4e, #2f9c68); }

.reg-quiz { max-width: 820px; margin-top: var(--space-4); }
.reg-quiz-form { display: flex; flex-direction: column; gap: var(--space-3); padding: var(--space-3) var(--space-4); border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--panel); }
.reg-quiz-form button { align-self: flex-start; }
.reg-quiz-subtitle { margin: var(--space-4) 0 var(--space-2); font-size: 15px; }
.reg-quiz-status { display: inline-block; padding: 2px 8px; border-radius: var(--radius-pill); font-size: 12px; font-weight: 600; }
.reg-quiz-status--pending { background: light-dark(#fff4d6, #3a3216); color: light-dark(#8a5a00, #ffd76a); }
.reg-quiz-status--passed { background: light-dark(#dcf3e6, #17321f); color: light-dark(#1e7a4e, #6ee7a0); }
.reg-quiz-status--redo { background: light-dark(#fde2e2, #3a1a1a); color: var(--danger); }
.reg-quiz-result { margin-bottom: var(--space-2); padding: var(--space-2) var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--panel); }
.reg-quiz-result summary { cursor: pointer; display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.reg-quiz-answers { margin: var(--space-2) 0; padding-left: 20px; }
.reg-quiz-answers li { margin-bottom: 8px; }
.reg-quiz-q { color: var(--muted); font-size: 13px; }
.reg-quiz-a { white-space: pre-wrap; }
.reg-quiz-meta { color: var(--muted); font-size: 13px; }
.reg-quiz-review { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.reg-quiz-review input { flex: 1 1 220px; }

.reg-library-head { display: flex; justify-content: space-between; align-items: flex-start; gap: var(--space-3); flex-wrap: wrap; }
.reg-library-list { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: var(--space-2); }
.reg-library-item { display: flex; flex-direction: column; gap: 8px; padding: var(--space-3); border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--panel); color: var(--text); text-decoration: none; }
.reg-library-item:hover { border-color: light-dark(#1e7a4e, #2f9c68); }
.reg-library-title { font-weight: 600; line-height: 1.35; }
.reg-library-filled { display: flex; flex-wrap: wrap; gap: 4px; }
.reg-library-filled span { padding: 1px 6px; border-radius: var(--radius-pill); font-size: 11px; color: var(--muted); border: 1px dashed var(--border); }
.reg-library-filled span.is-ok { color: light-dark(#1e7a4e, #6ee7a0); border-style: solid; border-color: currentColor; }

.reg-plan-table td { vertical-align: top; }
.reg-plan-table textarea { min-width: 220px; }
.reg-plan-table input[name=topic] { min-width: 180px; }
.reg-score { width: 64px; }
.reg-plan-total { font-weight: 800; font-size: 16px; text-align: center; }
.reg-plan-row.is-done { opacity: .55; }
.reg-plan-actions { display: flex; gap: 6px; }
.reg-plan-actions form { margin: 0; }
.reg-plan-add { max-width: 820px; margin-top: var(--space-4); display: flex; flex-direction: column; gap: var(--space-3); }
.reg-plan-add button { align-self: flex-start; }
.reg-plan-scores { display: grid; grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); gap: var(--space-2); }
.reg-plan-table .mgmt-input.reg-score { width: 58px; min-width: 58px; padding-left: 6px; padding-right: 2px; }
.reg-plan-table th, .reg-plan-table td { padding-left: 6px; padding-right: 6px; }
.reg-plan-table textarea.mgmt-input { min-width: 200px; }
.reg-plan-table input.mgmt-input[name=topic] { min-width: 160px; }
.reg-plan-table select.mgmt-input[name=owner], .reg-plan-table select.mgmt-input[name=status] { min-width: 110px; width: auto; }
.reg-assign { border: 0; padding: 0; margin: 0; }
.reg-assign-people { display: flex; flex-wrap: wrap; gap: 6px 14px; }
.reg-assign-person { display: inline-flex; align-items: center; gap: 6px; font-size: 14px; cursor: pointer; }
.reg-reread { margin: 4px 0; color: var(--muted); }
.reg-assigned { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; margin-bottom: var(--space-3); }
.reg-assigned-label { color: var(--muted); font-size: 13px; }
.reg-quiz-status--none, .reg-quiz-status--reread { background: light-dark(#eceee6, #242822); color: var(--muted); }
.reg-quiz-status--reread { background: light-dark(#e7ecff, #1b2240); color: light-dark(#3446a8, #9fb0ff); }
.reg-media-edit { grid-column: 1 / -1; max-width: 820px; margin-top: var(--space-4); }
.reg-media-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--space-2); margin: var(--space-2) 0; }
.reg-media-grid--doc { grid-template-columns: repeat(auto-fill, minmax(260px, 1fr)); }
.reg-media-item { margin: 0; display: flex; flex-direction: column; gap: 6px; }
.reg-media-item img, .reg-media-item video { width: 100%; border-radius: var(--radius-sm); border: 1px solid var(--border); background: #111; }
.reg-media-item figcaption { font-size: 13px; color: var(--muted); }
.reg-media-upload { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.reg-media-upload .mgmt-input { flex: 1 1 220px; }
.reg-comment { display: flex; flex-direction: column; gap: 6px; }
.reg-comment-answer { padding-left: 12px; border-left: 3px solid light-dark(#1e7a4e, #2f9c68); }
.reg-versions summary.section-heading { cursor: pointer; }
.reg-study { max-width: 820px; margin-bottom: var(--space-3); padding: var(--space-3) var(--space-4); border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--panel); }
.reg-study--mine { border-color: light-dark(#1e7a4e, #2f9c68); }
.reg-study summary { cursor: pointer; }
.reg-study-list { margin: 8px 0 0; padding-left: 18px; display: flex; flex-direction: column; gap: 6px; }
/* РНП: доля рекламы от суммы заказов в ячейке «Рекл расход» (21.10.2026) */
.rnp-share { margin-top: 2px; font-size: 11px; color: var(--muted); white-space: nowrap; }

/* Регламенты: передача другому участнику (22.10.2026) */
.reg-handover-form{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin-top:12px}
.reg-handover-form .mgmt-input{width:auto;min-width:160px;flex:1 1 200px}
.reg-handover-label{font-size:13px;color:var(--muted,#6b7280);flex-basis:100%}
.reg-handover-log{margin:10px 0 0;padding-left:18px;font-size:13px;color:var(--muted,#6b7280);display:flex;flex-direction:column;gap:4px}
.reg-handover-all{margin-top:16px}

/* РНП по размерам (этап 1 ТЗ от 23.10.2026) */
.rnp-viewswitch { display: inline-flex; gap: 4px; margin: var(--space-2) 0; padding: 3px; background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-md); }
.rnp-viewswitch-item { padding: 6px 14px; border-radius: calc(var(--radius-md) - 3px); color: var(--muted); font-size: var(--fs-small); text-decoration: none; }
.rnp-viewswitch-item--active { background: var(--accent); color: var(--accent-text); }
.rsz-card { margin-bottom: var(--space-5); padding: var(--space-4); background: var(--panel); border: 1px solid var(--border); border-radius: var(--radius-md); }
.rsz-title { color: var(--muted); font-weight: 400; font-size: var(--fs-small); margin-left: 8px; }
.rsz-scroll { overflow-x: auto; }
.rsz-table { border-collapse: collapse; width: 100%; font-variant-numeric: tabular-nums; }
.rsz-table th, .rsz-table td { padding: 8px 10px; border-bottom: 1px solid var(--border); text-align: right; white-space: nowrap; }
.rsz-table thead th { font-size: var(--fs-micro); font-weight: 700; letter-spacing: 0.04em; text-transform: uppercase; color: var(--muted); }
.rsz-table th.rsz-size { text-align: left; position: sticky; left: 0; background: var(--panel); }
.rsz-table .rsz-total { font-weight: 700; }
.rsz-table .rsz-zero { color: var(--muted); }
.rsz-table tfoot th, .rsz-table tfoot td { font-weight: 700; border-bottom: none; border-top: 2px solid var(--border); }
.rsz-table th.rsz-status, .rsz-table td.rsz-status { text-align: left; }
.rsz-row--buy td, .rsz-row--buy th { color: var(--danger); }
.rsz-row--ship td.rsz-status { font-weight: 700; }
.rsz-row--ok td, .rsz-row--nodata td { color: var(--muted); }
.rsz-eventgrid { display: grid; grid-template-columns: repeat(auto-fit, minmax(160px, 1fr)); gap: var(--space-3); margin-bottom: var(--space-3); }
.rsz-eventgrid label { display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-small); color: var(--muted); }
.rsz-eventcomment { grid-column: 1 / -1; }
.rsz-summary { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: var(--space-3); margin-bottom: var(--space-3); }
.rsz-stat { display: flex; flex-direction: column; gap: 4px; margin-bottom: 0; }
.rsz-stat-label { font-size: var(--fs-small); color: var(--muted); }
.rsz-stat-value { font-size: 22px; font-weight: 700; font-variant-numeric: tabular-nums; }

/* Вкладка «Таблицы» (24.10.2026) */
.tables-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr)); gap: var(--space-4); }
.tables-card { display: block; margin-bottom: 0; color: inherit; text-decoration: none; transition: border-color 0.15s; }
.tables-card:hover { border-color: var(--accent-2); }
.tables-card .section-heading { margin-top: 0; }

/* Жалобы на отзывы (28.10.2026): список плохих отзывов и окно с разбором ИИ */
.cmp-list { display: flex; flex-direction: column; gap: 8px; }
.cmp-item { display: grid; grid-template-columns: auto 1fr auto; gap: 14px; align-items: center; width: 100%; padding: 12px 14px; text-align: left; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--panel); color: inherit; font: inherit; cursor: pointer; }
.cmp-item:hover { border-color: var(--accent-2); }
.cmp-item-main { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.cmp-item-product { font-size: var(--fs-micro); color: var(--muted); }
.cmp-item-text { font-size: var(--fs-small); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.cmp-stars { color: var(--accent-2); letter-spacing: 1px; white-space: nowrap; }
.cmp-badge { padding: 4px 10px; border-radius: 999px; font-size: var(--fs-micro); font-weight: 700; white-space: nowrap; border: 1px solid var(--border); color: var(--muted); }
.cmp-badge--sent { color: var(--accent-2); border-color: var(--accent-2); }
.cmp-badge--ok { color: #2f8f46; border-color: #2f8f46; }
.cmp-badge--bad { color: var(--danger); border-color: var(--danger); }
@media (max-width: 640px) { .cmp-item { grid-template-columns: 1fr; gap: 6px; } .cmp-item-text { white-space: normal; } }
.cmp-dialog { width: min(720px, calc(100vw - 32px)); max-height: calc(100vh - 48px); padding: 0; border: 1px solid var(--border); border-radius: var(--radius-md); background: var(--bg, var(--panel)); color: inherit; }
.cmp-dialog::backdrop { background: rgba(0, 0, 0, 0.55); }
.cmp-dialog-head { position: sticky; top: 0; display: flex; justify-content: space-between; align-items: center; padding: 12px 16px; background: var(--panel); border-bottom: 1px solid var(--border); font-weight: 700; z-index: 1; }
#cmp-dialog-body { padding: 16px; }
.cmp-loading { padding: 40px 0; text-align: center; color: var(--muted); }
.cmp-section { padding: 12px 0; border-bottom: 1px solid var(--border); }
.cmp-section:last-child { border-bottom: none; }
.cmp-section h3 { margin: 0 0 8px; font-size: var(--fs-body); }
.cmp-card-head { display: flex; justify-content: space-between; gap: 8px; }
.cmp-review { white-space: pre-wrap; margin: 8px 0; }
.cmp-photos { display: flex; flex-wrap: wrap; gap: 8px; }
.cmp-photos img { width: 88px; height: 116px; object-fit: cover; border-radius: 8px; border: 1px solid var(--border); }
.cmp-analysis { white-space: pre-wrap; font-size: var(--fs-small); }
.cmp-text { width: 100%; box-sizing: border-box; font: inherit; margin-top: 8px; }
.cmp-counter { text-align: right; color: var(--muted); font-size: var(--fs-micro); }
.cmp-counter--over { color: var(--danger); font-weight: 700; }
.cmp-redo { display: flex; gap: 8px; margin-top: 10px; }
.cmp-redo input { flex: 1; }
.cmp-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.cmp-ok { background: #2f8f46; color: #fff; border-color: #2f8f46; }
.cmp-bad { background: var(--danger); color: #fff; border-color: var(--danger); }

/* Остаток на складах WB и Ozon в окне карты: фото · артикул · размер · кол-во (29.10.2026) */
.whs-stock { width: 100%; border-collapse: collapse; font-size: 13px; }
.whs-stock th { padding: 6px 8px; text-align: center; font-weight: 700; color: var(--muted); border-bottom: 1px solid var(--border); }
.whs-stock td { padding: 4px 8px; border: 1px solid var(--border); text-align: center; vertical-align: middle; }
.whs-stock tbody { border-top: 2px solid var(--border); }
.whs-stock-photo { width: 92px; padding: 4px !important; }
.whs-stock-photo img { width: 84px; height: 112px; object-fit: cover; border-radius: 6px; display: block; margin: 0 auto; }
.whs-stock-art b { display: block; }
.whs-stock-art span { display: block; color: var(--muted); font-size: 12px; margin-top: 2px; }
.whs-stock-size { width: 56px; }
.whs-stock-qty { width: 64px; font-weight: 700; font-variant-numeric: tabular-nums; }
.whs-stock-qty--zero { color: var(--muted); font-weight: 400; }
.whs-stock-days { width: 84px; white-space: nowrap; color: var(--muted); }
.whs-stock-days--low { color: var(--danger); font-weight: 700; }
.whs-stock tfoot td { font-weight: 700; border-top: 2px solid var(--border); }

/* Акт сверки приёмки (29.10.2026) */
.acc-pick, .acc-upload, .acc-apply { display: flex; flex-wrap: wrap; gap: 10px; align-items: flex-end; margin-bottom: var(--space-3); }
.acc-pick label, .acc-apply label, .acc-note { display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-small); color: var(--muted); }
.acc-upload { align-items: center; font-size: var(--fs-small); }
.acc-table { max-width: 720px; margin-bottom: var(--space-3); }
.acc-fact input { width: 64px; text-align: center; font: inherit; padding: 4px; border: 1px solid var(--border); border-radius: 6px; background: transparent; color: inherit; }
.acc-diff { width: 72px; font-weight: 700; }
.acc-diff--minus { color: var(--danger); }
.acc-diff--plus { color: #2f8f46; }
.acc-note { max-width: 720px; margin-bottom: var(--space-3); }

/* Сколько отгрузить на WB (29.10.2026) */
.sp-table { margin-bottom: var(--space-3); }
.sp-ship { font-weight: 700; width: 90px; }
.sp-short { display: block; color: var(--danger); font-size: 11px; font-weight: 400; }

/* Отчёт по продажам (29.10.2026) */
.sr-table { margin-bottom: var(--space-3); }
.sr-lead { width: 90px; }
.sr-signal { white-space: nowrap; color: var(--muted); }
.sr-row--reorder .sr-signal { color: var(--danger); font-weight: 700; }
.sr-row--top_up .sr-signal { color: var(--cat-ads-text); font-weight: 700; }
.sr-topup-note { margin-bottom: var(--space-3); padding: 8px 12px; border-radius: 8px; background: var(--cat-ads-wash); color: var(--cat-ads-text); font-size: var(--fs-small); }

/* Распределение поставки ФБО по округам (29.10.2026) */
.fs-shares { max-width: 720px; margin-bottom: var(--space-3); }
.fs-table { margin-bottom: var(--space-3); }
.fs-subtotal td { font-weight: 700; }
.fs-subtotal td span { display: block; color: var(--muted); font-size: 11px; font-weight: 400; }
