/* ==========================================================================
   WB REDASH ANALYTICS DASHBOARD - STYLESHEET
   ========================================================================== */

/* Inter лежит в public/fonts — не тянется с fonts.googleapis.com. Внешний CDN
   блокировал первую отрисовку ожиданием чужого домена, а если он недоступен,
   интерфейс молча падал на Segoe UI.

   Ось вариативная (font-weight: 300 800) намеренно. Раньше разметка просила
   начертания 550, 650, 720, 750 и 760, которых не было в наборе статических
   файлов, — браузер молча округлял. Теперь начертаний четыре (--fw-text,
   --fw-label, --fw-title, --fw-num), но вариативный файл остаётся: он даёт
   ровно 500 и 600, а не ближайшее из имеющегося.

   unicode-range обязателен: без него браузер скачает все subset'ы разом.
   Про обновление файлов — public/fonts/Inter.LICENSE.txt. */
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url(fonts/inter-cyrillic-ext.woff2) format('woff2');
  unicode-range: U+0460-052F, U+1C80-1C8A, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url(fonts/inter-cyrillic.woff2) format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url(fonts/inter-latin-ext.woff2) format('woff2');
  unicode-range: U+0100-02BA, U+02BD-02C5, U+02C7-02CC, U+02CE-02D7, U+02DD-02FF, U+0304, U+0308, U+0329, U+1D00-1DBF, U+1E00-1E9F, U+1EF2-1EFF, U+2020, U+20A0-20AB, U+20AD-20C0, U+2113, U+2C60-2C7F, U+A720-A7FF;
}
@font-face {
  font-family: 'Inter';
  font-style: normal;
  font-weight: 300 800;
  font-display: swap;
  src: url(fonts/inter-latin.woff2) format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}

/* ==========================================================================
   ТОКЕНЫ — визуальный язык «Пульт»
   ==========================================================================

   Значения выведены из OKLCH, но в CSS попадают посчитанными шестнадцатеричными
   кодами: сборщика у проекта нет, а браузерное `oklch()` при выходе за охват
   sRGB подгоняет цвет по-своему — макет и стенд начинают расходиться.

   Светлота в OKLCH перцептивная: одинаковая L даёт одинаковую видимую громкость
   на любом тоне, поэтому жёлтый перестаёт кричать громче синего без ручной
   подгонки каждого оттенка. Меняете цвет — меняйте L и H в рецепте и
   пересчитывайте семейство целиком; точечная правка одного hex ломает
   равновесие ряда.

   Имена токенов исторические — их знает не только этот файл, но и инлайновые
   стили в public/js и разметка. Поэтому менялись значения, а не имена.

   17.09 — значения переведены на палитру референса A (переработка дизайна/
   Referens-A-Smena): тёплая нейтраль, янтарный акцент, три семейства
   состояний из макета. Холодные info/discovery/replacement у макета нет —
   оставлены. Контрасты: text-dim 4.86:1 к --bg-input, белый на заливке
   кнопки 5.08:1, чернила семейств на своих плашках 5.0–6.1:1 (светлая),
   5.7–8.2:1 (тёмная).
   ========================================================================== */

:root {
  /* НЕЙТРАЛЬ. Холодная, под фирменный стиль WB (17.09, журнал 16): белый с
     графитовым текстом; прежняя тёплая бежевая референса A снята.
     Ни чистого белого фона, ни чистого чёрного текста: предельный контраст
     даёт halation — текст вибрирует, и на восьмом часу смены это чувствуется.
     Отношение основного текста к карточке держим около 14:1, а не 21:1. */
  --bg-dark: #f3f3f6;        /* фон страницы                       */
  --bg-card: #fbfbfd;        /* карточка, таблица                  */
  --bg-card-hover: #ececf1;  /* наведение, выделенная строка       */
  --bg-header: #fbfbfd;      /* шапка и рельс навигации            */
  --bg-input: #ebebf0;       /* поле ввода, зебра, шапка таблицы   */

  --border-color: #dcdce3;   /* волосяная граница между блоками    */
  /* ТОЛЬКО разделитель секций: 1.4–1.9:1 к поверхностям. Границей органа
     управления и планкой состояния его ставить нельзя — порог 3:1 не берётся.
     Для этого есть --line-ctl и солидный слой семейств. */
  --border-strong: #c6c6d0;
  /* Граница органа управления: поле, селект, вторичная кнопка. 3.52:1 к худшей
     поверхности. До «Пульта» здесь стоял --border-color — 1.2:1, то есть поля
     на экране были практически без границ. */
  --line-ctl: #77778a;
  --border-accent: #cb11ab;

  --text-main: #1a1a24;   /* основной текст, 16.7:1 к карточке              */
  --text-muted: #55556a;  /* вторичный,       7.0:1                         */
  --text-dim: #63637a;    /* подписи, мета,   4.91:1 к худшей (--bg-input)  */

  /* АКЦЕНТ — фирменная фуксия Wildberries #CB11AB (17.09, журнал 16) вместо
     оранжевой референса A; глубокий фиолет #481173 — у --accent-purple.
     Контрасты пересчитаны под те же пороги (4.5:1 текст, 3:1 обводка). */
  --accent-primary: #a30d89;        /* акцентный текст и планка, 6.83:1     */
  --accent-primary-fill: #cb11ab;   /* заливка главной кнопки, белый 4.99:1 */
  --accent-primary-hover: #b30f97;  /* она же под курсором                  */
  --accent-primary-soft: #fbe6f6;   /* выделенная строка, подсветка         */
  --accent-primary-border: #cb11ab; /* обводка активного, планка            */
  --accent-on-primary: #ffffff;

  /* СОСТОЯНИЕ — пять семейств, три слоя, одна формула светлоты.
     Рецепт: ink L .430 · rail L .585 · wash L .955
     Тона: свободна 250 · в работе 82 · закрыта 150 · срочно 27 · чужая 300

     ink  — текст на плашке и цветное число.  Порог 4.5:1, держит 6.8–8.2.
     rail — планка, точка, иконка, обводка.   Порог 3:1,   держит 3.8–4.3.
     wash — заливка плашки и подсветка строки. Фон, не носитель смысла.

     Раньше слои были полупрозрачными rgba: оттенок плашки зависел от того, на
     какой строке она лежит, и на зебре бейджи выцветали. Плотный цвет читается
     одинаково на карточке, на зебре и на подсвеченной строке. */

  /* Солидный слой (rail) — планки inset 4px, обводки чипов, иконки. */
  --info-solid: #2c7fcb;
  /* Чернила предупреждения на фоне --warning-soft (аудит 11.09): прежний
     #9d7413 давал 3,73:1 при норме 4,5 — «Б и V, сумма» в календаре,
     «проверить» в заменах, «Сотрудник неактивен»; #7a5a0c — 5,6:1. */
  --warning-solid: #8a5a06;
  --success-solid: #1f6b45;
  --danger-solid: #9a2f28;
  --discovery-solid: #1a6e7f;

  /* Раздел «Замены» — своя пара цветов, НЕ семантические токены выше.
     Исходящие («из моей группы») голубые, входящие («пришли в группу»)
     фиолетовые: пара несёт направление замены, а не статус.

     Почему отдельные токены, а не --info-solid/--discovery-solid: соседи по
     смыслу уже заняты и стоят рядом в той же легенде календаря. --info-* —
     это «Н, рабочий день» (.calendar-day-work), и «З» на голубом --info-solid
     слился бы с «Н» в одной сетке. --discovery-* — статус «В работе у другого
     модератора», а --accent-primary — «S, обучение» (.calendar-day-study) и
     вся интерфейсная хрома. Взяв их, мы бы ещё и привязали цвет замены к
     чужой настройке: перекрасят статус — поедет замена. Ровно этот рассинхрон
     уже был багом однажды (см. .calendar-day-replacement ниже).
     Контрасты: --replacement-out 5.93:1 к карточке, --replacement-in 6.98:1. */
  --replacement-out: #0369a1;
  --replacement-in: #7e22ce;

  /* «Запрос видео» — своё семейство (владелец, 30.09): жёлтый --warning-* —
     это «В работе», и пауза сливалась со статусом; --discovery-* — «У
     другого модератора», --info-* — «Согласование». Контрасты: 5.0:1 на
     --video-soft, 5.2:1 на белом. */
  --video-solid: #c2410c;
  --video-soft: #fdebdd;

  /* Чернильный слой семейств. Имена исторические: разметка использует их как
     цвет текста поверх соответствующей заливки (.badge-good, .badge-warning,
     .ticket-stat-*), поэтому здесь ink, а не rail — иначе текст просядет. */
  --accent-cyan: var(--accent-primary);
  --accent-blue: #185287;
  --accent-info: #185287;
  --accent-green: #1f6b45;
  --accent-amber: #8a5a06;
  --accent-orange: #8a5a06;
  --accent-rose: #9a2f28;
  --accent-purple: #481173;
  --accent-indigo: #481173;

  /* Заливка (wash) и обводка (rail) плашек.
     Имена --info-soft и --warning-soft прибиты tests/test_frontend_modules.py:
     тест требует буквальных строк `background: var(--info-soft)` и
     `let statusStyle = "background: var(--warning-soft)` в public/js/tickets.js.
     Убрать имена можно только вместе с правкой теста — иначе npm test зелёный,
     а фон плашек молча пропал. */
  --info-soft: #e5f2ff;
  --info-border: #2c7fcb;
  --success-soft: #e0efe6;
  --success-border: #1f6b45;
  --warning-soft: #f7ebd4;
  --warning-border: #8a5a06;
  --danger-soft: #f8e3e0;
  --danger-border: #9a2f28;

  /* Отдельная пара для «В работе у другого модератора» — бирюза, а не фиолет:
     фиолет теперь занят акцентом WB. Раньше плашка брала
     --accent-primary-soft, но это токен интерфейсной хромы (подсветка,
     выделение, ховеры), и поднимать его до плотности плашек нельзя —
     покраснеет половина экрана. Статусу нужен свой слой. */
  --discovery-soft: #e4f3f6;
  --discovery-border: #1a6e7f;

  /* Тихий слой для больших поверхностей — ячеек календаря и фоновых плиток.
     Заливка плашек на них была бы пёстрой: площадь несопоставима. Это тот же
     wash, разбавленный карточкой наполовину. */
  --info-wash: #f0f7fe;
  --warning-wash: #f8f1e4;
  --success-wash: #ecf3ed;
  --danger-wash: #f8edea;

  /* Подсветка строки — полный wash: строка таблицы это не фоновая плитка,
     а сообщение, и оно должно читаться на прокрутке. */
  --danger-row: #f8e3e0;
  --warning-row: #f7ebd4;

  /* ТИПОГРАФИКА. Семь ступеней с малым шагом: плотный интерфейс не терпит
     большой типографической разницы — она рвёт сетку. Значения в px, а не в
     rem: rem считается от базы 16px, и вся шкала уезжала на дробные размеры
     (13.6, 11.84, 14.4), которых нет ни в одном рецепте. */
  --fs-1: 12px;  /* мета, единицы, подпись под числом */
  --fs-2: 13px;  /* чипы, бейджи, вторичный текст     */
  --fs-3: 14px;  /* базовый в таблицах                */
  --fs-4: 15px;  /* базовый интерфейсный              */
  --fs-5: 17px;  /* заголовок карточки                */
  --fs-6: 20px;  /* заголовок раздела                 */
  --fs-7: 28px;  /* крупное число                     */

  --lh-tight: 1.25;
  --lh-table: 1.4;
  --lh-text: 1.5;

  /* Четыре начертания. Больше ступеней глаз не различает, а сетка от них
     расползается. До «Пульта» их было четырнадцать, включая 550, 650, 720,
     750 и 760. */
  /* Редизайн 16.09 (референс Linear): плотность держится на размере и цвете,
     не на жирности — начертания вернулись к сдержанным. Толстые/чёрные из
     версии 15.09 не подошли. */
  --fw-text: 400;
  --fw-label: 500;
  --fw-title: 600;
  --fw-num: 600;

  /* ФОРМА. Редизайн 16.09: острые углы 15.09 читались как «плакат», не как
     рабочий инструмент — Linear держит малый, единообразный радиус. */
  --radius-sm: 5px;
  --radius-md: 7px;
  --radius-lg: 10px;

  /* ВЫСОТА ОРГАНОВ УПРАВЛЕНИЯ. Раньше её не задавал никто: высота собиралась
     из паддинга и `line-height: normal` того шрифта, который подставит
     браузер. На 120 видимых кнопках это давало 12 разных высот, а в подвале
     модалки автораспределения главная кнопка стояла на 2px ниже «Отмены» —
     у неё инлайновый `border: none`, у соседней рамка `.btn` в 1px.
     30px — рост органов в шапке эталонного экрана «Смена» (сегмент, шаговик
     периода, кнопки действий); с 24.09 он один на весь проект. Прежние 34px
     давали две системы размеров: шапка переопределяла кнопки до 30px в трёх
     местах. */
  --h-ctl: 30px;     /* кнопка, поле, селект   */
  --h-ctl-sm: 26px;  /* чип внутри группы      */
  --h-ctl-lg: 42px;  /* кнопка во всю ширину   */

  /* ГЛУБИНА в три уровня, тень только у третьего:
     0 — фон страницы; 1 — карточка: поверхность на ступень выше плюс
     волосяная граница, без тени; 2 — настоящий оверлей: модалка, поповер,
     нижняя кромка липкой шапки. Граница вместо тени держит плотность: тени на
     плотной сетке дают грязь и съедают воздух, которого и так нет. */
  /* Редизайн 16.09: жёсткая оффсет-тень 15.09 была даже громче исходных
     мягких — на плотном экране это шум. Linear почти не использует тень на
     карточках (глубину даёт разница фона, не отбрасываемая тень); тень
     остаётся только у настоящего оверлея (модалка, поповер), и она мягкая. */
  --elev-1: 0 0 0 1px var(--border-color);
  --shadow-sm: var(--elev-1);
  --shadow-md: 0 12px 32px -8px rgba(15, 18, 23, 0.28), 0 0 0 1px var(--border-color);
  --shadow-sticky: 0 4px 10px -6px rgba(15, 18, 23, 0.35);

  /* Кольцо фокуса видно на любой поверхности: сначала подложка цветом панели,
     затем акцент. Без подложки акцент сливается с тёмной строкой таблицы. */
  --focus: 0 0 0 2px var(--bg-card), 0 0 0 4px var(--accent-primary-fill);
  --shadow-glow: var(--focus);

  /* Aliases used by dynamically rendered cards. */
  --panel-2: var(--bg-input);
  --border: var(--border-color);
  --text-2: var(--text-main);

  --transition: background-color 0.12s ease, border-color 0.12s ease, color 0.12s ease, box-shadow 0.12s ease, transform 0.12s ease;

  /* Шкала отступов и движения — панель фильтров и переключатель разделов
     (визуальный слой «Пульт») собраны на ней. */
  --s-2: 4px;
  --s-3: 6px;
  --s-4: 8px;
  --s-5: 12px;
  --s-6: 16px;
  --dur-1: 120ms;   /* ховер, смена цвета */
  --dur-2: 170ms;   /* появление и уход мелкого элемента, поворот каретки */
  --dur-3: 260ms;   /* панель, выпадающий список */
  --ease-out: cubic-bezier(0.22, 0.61, 0.36, 1);   /* вход: быстро → мягко */
  --ease-in-out: cubic-bezier(0.4, 0, 0.2, 1);     /* перемещение */
}

/* Смена темы (public/js/ui.js, btnToggleTheme) добавляет этот класс на
   <html> ровно на один кадр. Без него смена data-theme дёргает --transition
   (строка выше) сразу на каждой .btn и каждой строке каждой таблицы во
   всех вкладках разом — сотни элементов красились вразнобой одним тяжёлым
   style-recalc, часть кнопок на кадр рендерилась пустой. Пробовали
   View Transition (кросс-фейд снимка до/после) — на дашборде с плотными
   таблицами он размывал весь экран в "лагающее" пятно, ощущалось хуже.
   Поэтому переход не анимируем вообще — тема переключается мгновенно. */
.theme-switching,
.theme-switching * {
  transition: none !important;
}

/* ТЁМНАЯ ТЕМА. Не осветление светлой и не её инверсия: тот же рецепт,
   прочитанный в другую сторону — заливка темнее карточки, чернила светлее.
   Рецепт состояний: ink L .815 · rail L .700 · wash L .290 */
:root[data-theme="dark"] {
  --bg-dark: #121218;
  --bg-card: #1a1a22;
  --bg-card-hover: #22222c;
  --bg-header: #1a1a22;
  --bg-input: #22222c;

  --border-color: #30303c;
  --border-strong: #3d3d4a;
  --line-ctl: #7f7f92;
  --border-accent: #f07ad9;

  --text-main: #e8e8ee;   /* 14.2:1 к карточке — не #fff, иначе halation */
  --text-muted: #a9a9b8;  /*  7.45:1 */
  --text-dim: #8e8e9e;    /*  4.89:1 к худшей (--bg-input) */

  --accent-primary: #f07ad9;        /* 6.99:1 к карточке — светлая фуксия для текста */
  --accent-primary-fill: #cb11ab;   /* та же фирменная заливка, что в светлой; белый текст 4.99:1 */
  --accent-primary-hover: #dc2bbd;
  --accent-primary-soft: #33162e;
  --accent-primary-border: #f07ad9;
  --accent-on-primary: #ffffff;   /* фуксия тёмная — на ней белый текст, 4.99:1 */

  /* Здесь порог 3:1 проходили все и раньше, правка — про баланс громкости
     внутри семьи: жёлтый кричал заметно громче соседей, красный был тише всех.
     Теперь пять статусов звучат в один голос. */
  --info-solid: #57a3ef;
  --warning-solid: #e0b04a;
  --success-solid: #57c98b;
  --danger-solid: #e2756a;
  --discovery-solid: #5fc2d2;

  /* Тёмная тема оставляет ровно те значения, что были захардкожены в разметке:
     7.96:1 и 6.45:1 к карточке — здесь исходные цвета читались и менять их
     незачем. */
  --replacement-out: #38bdf8;
  --replacement-in: #c084fc;
  --video-solid: #fb923c;
  --video-soft: #3a2012;

  --accent-cyan: var(--accent-primary);
  --accent-blue: #93c8fe;
  --accent-info: #93c8fe;
  --accent-green: #57c98b;
  --accent-amber: #e0b04a;
  --accent-orange: #e0b04a;
  --accent-rose: #e2756a;
  --accent-purple: #c9a6f0;
  --accent-indigo: #c9a6f0;

  --info-soft: #1c2d3e;
  --info-border: #57a3ef;
  --success-soft: #122419;
  --success-border: #57c98b;
  --warning-soft: #251e10;
  --warning-border: #e0b04a;
  --danger-soft: #2a1614;
  --danger-border: #e2756a;

  --discovery-soft: #12303a;
  --discovery-border: #5fc2d2;

  --info-wash: #1a2530;
  --warning-wash: #1d1b13;
  --success-wash: #131e18;
  --danger-wash: #1f1715;

  --danger-row: #2a1614;
  --warning-row: #251e10;

  --elev-1: 0 0 0 1px var(--border-color);
  --shadow-sm: var(--elev-1);
  --shadow-md: 0 16px 40px -10px rgba(0, 0, 0, 0.55), 0 0 0 1px var(--border-color);
  --shadow-sticky: 0 4px 12px -6px rgba(0, 0, 0, 0.6);
  --shadow-glow: var(--focus);
}

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

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif;
  background-color: var(--bg-dark);
  color: var(--text-main);
  min-height: 100vh;
  display: flex;
  overflow-x: hidden;
  /* База интерфейса — 14px, а не унаследованные от браузера 16: плотный
     инструмент из чисел и подписей на 16px рассыпается по вертикали. */
  font-size: var(--fs-4);
  line-height: var(--lh-text);
  -webkit-font-smoothing: antialiased;
}

/* Контролы не наследуют шрифт от body — так устроены UA-таблицы браузеров.
   Без этого правила Chrome набирал кнопки, поля и селекты своим `13.333px
   Arial`, а `textarea` и `input[type=date]` — моноширинным. Замер на живой
   странице давал 244 контрола Arial, 32 monospace и 2 Inter из 278.

   Больно это било по реестру заявок: там почти каждая ячейка — живой `select`,
   и строка таблицы набиралась двумя шрифтами сразу при одинаковом 13px. Arial
   при том же кегле на 5% уже Inter (x-height 6.73 против 7.09), поэтому
   контролы выглядели мельче собственных подписей, а цифры в них шли
   пропорциональными вместо табличных.

   `line-height` намеренно не наследуется: у контролов это `normal` (≈1.21), у
   body — 1.5, и наследование добавило бы каждой кнопке ~4px. Высота кнопок
   задаётся явно ниже, в `.btn`.

   Правило стоит выше частных: `--fs-2` на чипах и `--fs-3` в таблице заявок
   объявлены позже и перебивают `inherit` сами. */
button,
input,
select,
textarea,
optgroup {
  font-family: inherit;
  font-size: inherit;
  font-weight: inherit;
  letter-spacing: inherit;
}

/* Chrome рисует поля даты и месяца собственным моноширинным шрифтом и не
   отдаёт их правилу выше через `font-family: inherit` на всех контролах —
   у них своя внутренняя разметка. Задаём отдельно. */
input[type="date"],
input[type="month"],
input[type="time"],
input[type="datetime-local"] {
  font-family: inherit;
}

/* Браузер даёт заголовкам `font-weight: bold`, то есть 700, а 700 в этом языке
   отдано числам. Без явной ступени каждый h1…h6 без собственного правила
   приезжал жирнее метрики, ради которой экран и сделан. */
h1, h2, h3, h4, h5, h6 {
  font-weight: var(--fw-title);
}

/* Нативные флажок и переключатель приходят от браузера по 13px. Рядом с
   органами управления в 34px это выглядит недоделанным, а попасть по ним
   мышью тяжело. Порог WCAG 2.5.8 они и так проходят — в разметке каждый
   лежит внутри `<label>`, и кликается вся подпись, — но сам квадратик
   поднимаем до 16px и красим в акцент, чтобы он был из того же набора,
   что и всё остальное. */
input[type="checkbox"],
input[type="radio"] {
  width: 16px;
  height: 16px;
  flex: 0 0 auto;
  accent-color: var(--accent-primary-fill);
  cursor: pointer;
}

.ui-icon {
  width: 1.1em;
  height: 1.1em;
  display: inline-block;
  flex: 0 0 auto;
  vertical-align: -0.16em;
  pointer-events: none;
}

.ui-icon.is-spinning { animation: icon-spin 0.8s linear infinite; }
.ui-icon.sort-up { transform: rotate(180deg); }

.icon-heading,
.icon-label {
  display: inline-flex;
  align-items: center;
  gap: 0.45rem;
}

.icon-heading .ui-icon { color: var(--accent-cyan); }
.ui-icon-lg { width: 1.35em; height: 1.35em; }
.ui-icon-hero { width: 2.5rem; height: 2.5rem; }
.text-success { color: var(--accent-green); }
.text-danger { color: var(--accent-rose); }

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

/* ==========================================================================
   РЕЙЛ РАЗДЕЛОВ — 60 px, только иконки (этап 4, обвязка по референсу A)
   Пункты .nav-item — квадраты 38×38 с подсказкой в title; подписи спрятаны.
   Хабы («Моя группа», «Мой кабинет») раскрывают подпункты флайаутом справа
   по наведению/фокусу (.nav-submenu). Панель фильтров реестра больше здесь
   не живёт — она внутри вкладки «Заявки» (.ticket-filter-col ниже).
   ========================================================================== */
.sidebar {
  width: 60px;
  flex: 0 0 60px;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding: 14px 0;
  background: var(--bg-header);
  border-right: 1px solid var(--border-color);
  z-index: 10;
  position: sticky;
  top: 0;
  align-self: flex-start;
  height: 100vh;
}

#navMenuHost {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  width: 100%;
}

.brand {
  width: 32px;
  height: 32px;
  display: grid;
  place-items: center;
  border-radius: var(--radius-sm);
  background: var(--accent-primary-fill);
  color: var(--accent-on-primary);
  margin-bottom: 10px;
}

.brand .ui-icon { width: 16px; height: 16px; }

.nav-menu {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  list-style: none;
  width: 100%;
}

.nav-menu > li { position: relative; }

.nav-item {
  position: relative;
  width: 38px;
  height: 38px;
  display: grid;
  place-items: center;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  color: var(--text-dim);
  cursor: pointer;
  transition: var(--transition);
  text-decoration: none;
}

/* Подписи пунктов остаются в разметке ради скринридера и флайаута, на рейле
   их не видно. */
.nav-item > span:not(.nav-icon):not(.nav-badge) {
  position: absolute;
  width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap;
}

.nav-item:hover {
  background: var(--bg-card-hover);
  color: var(--text-main);
}

.nav-item.active {
  border-color: var(--line-ctl);
  background: var(--bg-input);
  color: var(--text-main);
}

.nav-icon {
  width: 17px;
  height: 17px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: currentColor;
}

.nav-item .nav-badge {
  position: absolute;
  top: 2px;
  right: 2px;
  min-width: 14px;
  height: 14px;
  padding: 0 4px;
  font-size: 9px;
  line-height: 14px;
}

/* Флайаут подпунктов хаба: появляется справа от иконки по наведению и по
   клавиатурному фокусу внутри. */
.nav-item-accordion { list-style: none; }

.nav-submenu {
  display: none;
  position: absolute;
  left: 46px;
  top: -4px;
  z-index: 20;
  width: 200px;
  padding: 6px;
  list-style: none;
  border: 1px solid var(--line-ctl);
  border-radius: var(--radius-md);
  background: var(--bg-card);
  box-shadow: var(--shadow-md);
}

.nav-submenu::before {
  /* Невидимый мост между иконкой и флайаутом: курсор не теряет hover на зазоре. */
  content: '';
  position: absolute;
  left: -10px;
  top: 0;
  width: 10px;
  height: 100%;
}

.nav-item-accordion:hover .nav-submenu,
.nav-item-accordion:focus-within .nav-submenu { display: block; }

.nav-subitem {
  display: flex;
  align-items: center;
  gap: 0.6rem;
  padding: 7px 9px;
  color: var(--text-main);
  text-decoration: none;
  font-size: var(--fs-3);
  border-radius: var(--radius-sm);
  transition: var(--transition);
  white-space: nowrap;
}

.nav-subitem:hover { background: var(--bg-card-hover); }

.nav-subitem.active {
  color: var(--accent-primary);
  background: var(--accent-primary-soft);
  font-weight: var(--fw-title);
}

.subitem-icon {
  width: 16px;
  height: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: currentColor;
}

/* ==========================================================================
   ПАНЕЛЬ ФИЛЬТРОВ РЕЕСТРА — левая колонка вкладки «Заявки»
   Вкладка .tab-with-rail — флекс-строка: колонка 236px + .ticket-main.
   Спрятанное состояние (data-filters="hidden" на <html>): колонка сжимается до
   56px со счётчиками статусов (.rail-stub), сама панель уезжает за край и
   выезжает по наведению/фокусу поверх таблицы.
   ========================================================================== */
.tab-with-rail {
  display: flex;
  align-items: stretch;
  min-width: 0;
  /* Вкладка занимает всю ширину контента без отступов .content-area. */
  margin: calc(-1 * var(--content-pad));
  min-height: calc(100vh - 48px);
}

.ticket-main {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: 0;
  padding: 0;
  margin: 0;
}

.ticket-filter-col {
  --rail-w: 264px;
  --rail-stub: 52px;
  position: sticky;
  top: 48px;
  align-self: flex-start;
  flex: 0 0 var(--rail-w);
  width: var(--rail-w);
  min-width: var(--rail-w);
  max-width: var(--rail-w);
  height: calc(100vh - 48px);
  display: flex;
  flex-direction: column;
  background: var(--bg-header);
  border-right: 1px solid var(--border-color);
  z-index: 8;
  overflow-x: hidden;
}

:root[data-filters="hidden"] .ticket-filter-col {
  flex: 0 0 var(--rail-stub);
  width: var(--rail-stub);
  min-width: var(--rail-stub);
  max-width: var(--rail-stub);
  overflow-x: hidden;
}

/* Свёрнутая панель скрыта полностью, без выезда по ховеру: от неё остаётся полоса со счётчиками. */
:root[data-filters="hidden"] .ticket-filter-rail { display: none; }

/* Раскрытие панели слева направо при клике на стрелку полосы */
:root.filters-expanding:not([data-filters="hidden"]) .ticket-filter-rail {
  animation: railReveal var(--dur-3) var(--ease-out) both;
}
@keyframes railReveal {
  from { clip-path: inset(0 100% 0 0); opacity: .5; transform: translateX(-10px); }
  to   { clip-path: inset(0 0 0 0);    opacity: 1;  transform: none; }
}

.rail-peek-tab { display: none; }

:root[data-filters="hidden"] .rail-peek-tab {
  order: -1;
  display: flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  width: 100%;
  height: 32px;
  padding: 0;
  border: none;
  border-bottom: 1px solid var(--border-color);
  border-radius: 0;
  box-sizing: border-box;
  background: var(--bg-input);
  color: var(--text-muted);
  cursor: pointer;
  transition: var(--transition);
  animation: railFadeIn var(--dur-2) var(--ease-out);
}

:root[data-filters="hidden"] .rail-peek-tab:hover {
  background: var(--bg-card-hover);
  color: var(--text-main);
}

.rail-peek-tab:focus-visible {
  outline: 2px solid var(--accent-primary);
  outline-offset: -2px;
  box-shadow: none;
}

.rail-peek-tab .ui-icon {
  width: 15px;
  height: 15px;
  flex-shrink: 0;
}

.rail-stub { display: none; }

:root[data-filters="hidden"] .rail-stub {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 4px 2px;
  overflow-x: hidden;
  overflow-y: auto;
  width: 100%;
  box-sizing: border-box;
  animation: railFadeIn var(--dur-2) var(--ease-out);
}

@keyframes railFadeIn {
  from { opacity: 0; }
  to   { opacity: 1; }
}

.rail-stub-item {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 1px;
  height: var(--h-ctl);
  width: 100%;
  margin: 0;
  padding: 0;
  border: 1px solid transparent;
  border-radius: 0;
  background: transparent;
  color: var(--text-main);
  font: inherit;
  cursor: pointer;
  box-sizing: border-box;
  overflow: hidden;
  white-space: nowrap;
  transition: background-color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out);
}

.rail-stub-item:hover {
  background: var(--bg-card-hover);
}

.rail-stub-item:focus-visible {
  outline: none;
  box-shadow: var(--focus);
}

.rail-stub-item.active {
  background: var(--accent-primary-soft) !important;
  border-color: var(--accent-primary-border);
  color: var(--accent-primary);
}

.rail-stub-item.active .ui-icon {
  color: var(--accent-primary) !important;
}

.rail-stub-item .ui-icon { width: 15px; height: 15px; color: var(--text-muted); flex-shrink: 0; }

.rail-stub-num {
  font-size: var(--fs-1);
  font-weight: var(--fw-num);
  font-variant-numeric: tabular-nums;
  line-height: 1;
}

.rail-stub-item.is-info.has-value { color: var(--accent-primary); background: var(--accent-primary-soft); }
.rail-stub-item.is-info.has-value .ui-icon { color: var(--accent-primary); }
.rail-stub-item.is-warning.has-value,
.rail-stub-item.is-attention.has-value { color: var(--accent-amber); background: var(--warning-soft); }
.rail-stub-item.is-warning.has-value .ui-icon,
.rail-stub-item.is-attention.has-value .ui-icon { color: var(--accent-amber); }
.rail-stub-item.is-danger.has-value { color: var(--accent-rose); background: var(--danger-soft); }
.rail-stub-item.is-danger.has-value .ui-icon { color: var(--accent-rose); }

/* Main Content Area */
/* overflow-y здесь был и молча ломал всё липкое: обёртка объявляла себя
   областью прокрутки, но у body задана только min-height, поэтому обёртка
   тянулась во всю высоту содержимого и не прокручивалась ни разу — ехал весь
   документ. Прокрутка одна — документ, от неё же считается sticky у левой
   колонки. */
.main-wrapper {
  flex: 1;
  display: flex;
  flex-direction: column;
  min-width: 0;
}

/* Шапка A: 57px, кикер над заголовком, sticky. */
.top-bar {
  background: var(--bg-header);
  border-bottom: 1px solid var(--border-color);
  padding: 8px 20px;
  min-height: 57px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 14px;
  position: sticky;
  top: 0;
  z-index: 9;
}

.page-kicker {
  font-size: 11px;
  font-weight: var(--fw-title);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.header-title {
  font-size: 19px;
  font-weight: var(--fw-title);
  letter-spacing: -0.01em;
  line-height: 1.2;
}

.top-controls {
  display: flex;
  align-items: center;
  gap: 0.75rem;
}

.top-bar-left {
  display: flex;
  align-items: center;
  gap: 1rem;
  min-width: 0;
}

/* Иконочная кнопка — квадрат в рост обычной. Было три разных размера:
   переключатель темы 38px, .icon-btn 30px и крестик модалки 12×23. */
.theme-toggle {
  width: var(--h-ctl);
  height: var(--h-ctl);
  padding: 0;
  justify-content: center;
  font-size: var(--fs-5);
}

/* Высота задаётся токеном, а не паддингом: иначе её меняет каждый локальный
   отступ и каждая снятая рамка, и ряд кнопок в подвале модалки разъезжается.
   Паддинг остаётся только горизонтальным — он про ширину, не про рост.
   `white-space: nowrap` тоже про рост: при фиксированной высоте перенос
   строки вылезал бы за кнопку, а кнопке переноситься и не положено. */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  height: var(--h-ctl);
  padding: 0 12px;
  border-radius: var(--radius-sm);
  font-size: var(--fs-2);
  font-weight: var(--fw-title);
  line-height: var(--lh-tight);
  white-space: nowrap;
  cursor: pointer;
  border: 1px solid transparent;
  transition: var(--transition);
}

.btn .ui-icon { width: 14px; height: 14px; }

.btn-primary {
  background: var(--accent-primary-fill);
  color: var(--accent-on-primary);
  box-shadow: none;
}

.btn-primary:hover {
  background: var(--accent-primary-hover);
}

.btn-secondary {
  background: var(--bg-input);
  color: var(--text-main);
  border-color: var(--line-ctl);
}

.btn-secondary:hover {
  background: var(--bg-card-hover);
  border-color: var(--accent-primary-border);
}

.btn-accent {
  background: var(--accent-primary-soft);
  color: var(--accent-cyan);
  border-color: var(--accent-primary-border);
}

.btn-accent:hover {
  background: var(--bg-card-hover);
}

.btn:disabled {
  cursor: not-allowed;
  opacity: 0.55;
}

/* Отклик на нажатие (аудит 11.09): 0.96 — заметно, но без театра; transform
   уже в --transition у .btn, возврат плавный. */
.btn:active:not(:disabled) {
  transform: scale(0.96);
}

/* Page Layout */
.content-area {
  --content-pad: 2rem;
  padding: var(--content-pad);
  display: flex;
  flex-direction: column;
  gap: 1.75rem;
}

/* Data Connection & Date Filter Card */

/* Date Filter Controls Styling */

/* Key Metrics KPI Grid */

/* Charts Section */

/* Data Table Section */
.table-card {
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: 1.5rem;
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}

.table-toolbar {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 1rem;
  flex-wrap: wrap;
}

.search-input {
  width: 100%;
  height: var(--h-ctl);
  background: var(--bg-input);
  border: 1px solid var(--line-ctl);
  border-radius: var(--radius-sm);
  padding: 0 10px;
  color: var(--text-main);
  font-size: var(--fs-3);
  outline: none;
}

/* Рост поля — токен, как у кнопки. Инлайновые `padding: 0.5rem` из разметки
   и js раздували бы поле по вертикали, поэтому вертикаль снимается здесь. */
input.search-input,
select.search-input {
  padding-top: 0 !important;
  padding-bottom: 0 !important;
}

textarea.search-input {
  height: auto;
  padding: 8px 10px;
}

/* Плоское поле времени для flush-таблиц СВ (Перерывы, отгулы/больничные):
   без скругления и высоты .search-input, в один ряд со строкой таблицы.
   Заливка иконки-часов берётся браузером из color-scheme (:root выше) — свою
   не красим. */
.time-input {
  width: 88px;
  padding: 0.25rem 0.35rem;
  font-size: var(--fs-3);
  font-variant-numeric: tabular-nums;
  background: var(--bg-input);
  color: var(--text-main);
  border: 1px solid var(--border-color);
  border-radius: 0;
  outline: none;
}

.time-input:focus {
  border-color: var(--accent-primary-border);
}

.table-container {
  width: 100%;
  overflow-x: auto;
}

table {
  width: 100%;
  border-collapse: collapse;
  text-align: left;
  /* Таблица — не текст: своя ступень (13px) и своя интерлиньяжа, иначе строки
     разъезжаются и на экран влезает вдвое меньше заявок. */
  font-size: var(--fs-3);
  line-height: var(--lh-table);
}

/* Стиль A: шапка uppercase 11px, липкая внутри прокрутки контейнера, строки
   зеброй (tbody ниже). */
th {
  background: var(--bg-input);
  color: var(--text-dim);
  font-weight: var(--fw-title);
  text-transform: uppercase;
  font-size: 11px;
  letter-spacing: 0.04em;
  padding: 8px 10px;
  border-bottom: 1px solid var(--border-strong);
  white-space: nowrap;
  position: sticky;
  top: 0;
  z-index: 1;
}

tbody tr:nth-child(even) { background: var(--bg-page); }

td {
  padding: 7px 10px;
  border-bottom: 1px solid var(--border-color);
  color: var(--text-main);
  white-space: nowrap;
  /* Моноширинные цифры: в таблицах здесь всюду столбцы дат, времени, ID и ШК,
     а у пропорциональных цифр Inter разная ширина — колонка «плывёт», и взгляд
     не может идти по ней вертикально. На буквы не влияет. */
  font-variant-numeric: tabular-nums;
}

tbody tr {
  transition: var(--transition);
  cursor: pointer;
}

tbody tr:hover {
  background: var(--bg-card-hover) !important;
}

.pill-badge {
  display: inline-flex;
  align-items: center;
  padding: 0.2rem 0.55rem;
  border-radius: var(--radius-sm);
  font-size: var(--fs-2);
  font-weight: var(--fw-label);
}

.badge-good { background: var(--info-soft); color: var(--accent-info); border: 1px solid var(--info-border); }
.badge-warning { background: var(--warning-soft); color: var(--accent-amber); border: 1px solid var(--warning-border); }
.badge-danger { background: var(--danger-soft); color: var(--accent-rose); border: 1px solid var(--danger-border); }

/* Modal Styling */
.modal-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100vw;
  height: 100vh;
  background: rgba(0, 0, 0, 0.48);
  backdrop-filter: blur(2px);
  display: flex;
  align-items: center;
  justify-content: center;
  z-index: 100;
  opacity: 0;
  pointer-events: none;
  /* Закрытое окно прячем и от клавиатуры (аудит 11.09): одних opacity и
     pointer-events мало — кнопки и поля 28 закрытых окон (176 штук) оставались
     в обходе по Tab, фокус и Enter попадали в невидимые кнопки, экранные
     дикторы читали их содержимое. visibility: hidden убирает их и оттуда. */
  visibility: hidden;
  /* Фейд подложки: opacity в --transition не входит, и окно появлялось и
     исчезало рывком. visibility гаснет после фейда (задержка), а при
     открытии включается сразу — см. .active ниже. */
  transition: opacity var(--dur-2) var(--ease-out), visibility 0s linear var(--dur-2);
}

.modal-overlay.active {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
  transition: opacity var(--dur-2) var(--ease-out), visibility 0s;
}

.modal-card {
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  width: 90%;
  max-width: 650px;
  max-height: 85vh;
  overflow-y: auto;
  padding: 16px 18px;
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  gap: 14px;
  transform: translateY(20px);
  transition: transform var(--dur-2) var(--ease-out);
}

.modal-overlay.active .modal-card {
  transform: translateY(0);
}

/* Дровер (боковая карточка заявки) — выезжает справа */
.ticket-drawer-overlay {
  position: fixed;
  inset: 0;
  background: rgba(0, 0, 0, 0.48);
  backdrop-filter: blur(2px);
  display: flex;
  justify-content: flex-end;
  opacity: 0;
  pointer-events: none;
  visibility: hidden; /* то же, что у .modal-overlay выше */
  transition: opacity var(--dur-2) var(--ease-out), visibility 0s linear var(--dur-2); /* как у .modal-overlay */
  z-index: 120;
}

.ticket-drawer-overlay.active {
  opacity: 1;
  pointer-events: auto;
  visibility: visible;
  transition: opacity var(--dur-2) var(--ease-out), visibility 0s;
}

.ticket-drawer-panel {
  width: 460px;
  max-width: 94vw;
  height: 100%;
  background: var(--bg-card);
  border-left: 1px solid var(--border-color);
  box-shadow: var(--shadow-md);
  display: flex;
  flex-direction: column;
  transform: translateX(30px);
  transition: transform var(--dur-2) var(--ease-out);
  overflow: hidden;
}

.ticket-drawer-overlay.active .ticket-drawer-panel {
  transform: translateX(0);
}

.modal-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Редизайн 16.09 (референс Linear): цветная плашка на весь верх из версии
     15.09 была слишком громкой для окна, которое открывается десятки раз за
     смену — тонкая линия без своего фона и без цвета, как в Linear. */
  padding-bottom: 12px;
  border-bottom: 1px solid var(--border-color);
}

/* Крестик закрытия был зоной клика 12×23 — меньше минимума WCAG 2.5.8 в
   24×24. Сам глиф остаётся прежним, растёт только площадь попадания. */
.modal-close {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--h-ctl);
  height: var(--h-ctl);
  flex: 0 0 auto;
  padding: 0;
  background: transparent;
  border: none;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
  font-size: var(--fs-6);
  line-height: 1;
  cursor: pointer;
  transition: var(--transition);
}

.modal-close:hover {
  color: var(--text-main);
}

/* ==========================================================================
   LOGIN SCREEN STYLES
   ========================================================================== */
.login-overlay {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background: var(--bg-dark);
  display: none;
  align-items: center;
  justify-content: center;
  padding: 1rem;
  z-index: 9999;
}

.login-overlay.active {
  display: flex;
}

/* Признак ставится инлайновым скриптом в <head> до первой отрисовки — иначе на
   каждой перезагрузке успевает мелькнуть карточка входа: разметка приходит с
   классом .active, а снимают его модули уже на DOMContentLoaded. Селектор
   специфичнее .login-overlay.active, поэтому перекрывает его. */
:root[data-auth="in"] .login-overlay {
  display: none;
}

/* Переключатель темы на экране входа: топбара там нет, кнопка живёт в углу
   оверлея. */
.login-theme-toggle {
  position: absolute;
  top: 1rem;
  right: 1rem;
}

.login-card {
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  padding: 2.5rem;
  width: 100%;
  max-width: 420px;
  box-shadow: var(--shadow-md);
  text-align: center;
}

/* Мягкая заливка намеренно: единственный сплошной фуксиевый элемент на
   экране — кнопка «Войти», логотип с ней не спорит. */
.login-logo {
  --brand-cut: var(--accent-primary-soft); /* галочка знака — цветом подложки */
  width: 48px;
  height: 48px;
  background: var(--accent-primary-soft);
  color: var(--accent-primary);
  font-size: var(--fs-6);
  font-weight: var(--fw-title);
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-md);
  margin: 0 auto 1.25rem auto;
}

.login-logo .ui-icon { width: 28px; height: 28px; }

.login-title {
  font-size: var(--fs-6);
  font-weight: var(--fw-title);
  color: var(--text-main);
  margin-bottom: 0.5rem;
}

.login-subtitle {
  font-size: var(--fs-4);
  color: var(--text-muted);
  margin-bottom: 2rem;
}

.form-group {
  text-align: left;
  margin-bottom: 1.25rem;
}

.form-group label {
  display: block;
  font-size: var(--fs-2);
  color: var(--text-muted);
  margin-bottom: 0.5rem;
  font-weight: var(--fw-label);
}

.form-group input {
  width: 100%;
  background: var(--bg-input);
  border: 1px solid var(--line-ctl);
  border-radius: var(--radius-sm);
  height: var(--h-ctl);
  padding: 0 10px;
  color: var(--text-main);
  font-size: var(--fs-3);
  outline: none;
  transition: var(--transition);
}

/* Чекбокс/радио внутри .form-group не должны наследовать стили текстовых
   полей выше — та же специфичность (0,1,1), но .form-group input идёт позже
   в файле и побеждала, растягивая чекбокс на всю ширину лейбла (см. отгул
   модератора в модалке «Смена»). */
.form-group input[type="checkbox"],
.form-group input[type="radio"] {
  width: 16px;
  height: 16px;
  padding: 0;
  flex: 0 0 auto;
}

.form-group input:focus {
  border-color: var(--accent-cyan);
}

/* Кнопка во всю ширину — вход и подтверждение в модалке. Ей нужен свой рост:
   рядом стоят поля формы, и 30px рабочей области смотрелись бы куцо. */
.btn-block {
  width: 100%;
  height: var(--h-ctl-lg);
  padding: 0 1.1rem;
  font-size: var(--fs-3);
  font-weight: var(--fw-title);
}

/* На входе поля в рост кнопки «Войти»: карточка одна на экране, 30px рядом
   с 42px смотрелись бы недоделанными. */
.login-card .form-group input { height: var(--h-ctl-lg); padding: 0 12px; font-size: var(--fs-4); }

.login-error-msg {
  color: var(--accent-rose);
  background: var(--danger-soft);
  border: 1px solid var(--danger-border);
  border-radius: var(--radius-sm);
  padding: 0.75rem;
  font-size: var(--fs-4);
  margin-bottom: 1.25rem;
}
/* ==========================================================================
   CALENDAR & SCHEDULE STYLES
   ========================================================================== */
.calendar-table {
  width: 100%;
  border-collapse: collapse;
  margin-top: 1rem;
}

.calendar-table th, .calendar-table td {
  border: 1px solid var(--border-color);
  padding: 0.65rem 0.5rem;
  text-align: center;
  font-size: var(--fs-3);
  min-width: 35px;
}

.calendar-table th {
  background: var(--bg-header);
  font-weight: var(--fw-label);
  color: var(--text-muted);
}

/* Ячейки календаря берут тихий слой: заливка плашек на сетке из тридцати
   клеток даёт рябь, а не информацию. */
.calendar-day-work {
  background: var(--info-wash) !important;
  color: var(--accent-info);
  font-weight: var(--fw-title);
}

.calendar-day-off {
  background: rgba(156, 163, 175, 0.05) !important;
  color: var(--text-dim);
}

.calendar-day-sick {
  background: var(--danger-wash) !important;
  color: var(--accent-rose);
  font-weight: var(--fw-title);
}

.calendar-day-vacation {
  background: var(--success-wash) !important;
  color: var(--accent-green);
  font-weight: var(--fw-title);
}

.calendar-day-study {
  background: var(--accent-primary-soft) !important;
  color: var(--accent-primary);
  font-weight: var(--fw-title);
}

/* Цвет замены — тот же самый, что и во всём разделе «Замены» (index.html,
   replacements.js): бейджи, заголовки групп, лейблы. Раньше клетка «З» на
   графике красилась в amber — цвет замены не совпадал с её же цветом в
   разделе «Замены», и рассинхрон пришлось чинить.
   Единый источник теперь один — --replacement-out (см. :root): цвет по-прежнему
   свой, не привязан к семантическим статусам, но у него есть отдельное значение
   на каждую тему. До этого здесь стоял литерал #38bdf8, который в светлой теме
   давал 2.14:1. */
.calendar-day-replacement {
  background: rgba(56, 189, 248, 0.10) !important;
  color: var(--replacement-out);
  font-weight: var(--fw-title);
}

.schedule-legend-code {
  display: inline-flex;
  min-width: 1.8rem;
  justify-content: center;
  padding: 0.15rem 0.5rem;
  border-radius: var(--radius-sm);
}

.legend-inline-code {
  background: transparent !important;
}

.sv-only {
  display: inherit;
}

.staff-filter-chip {
  background: transparent;
  color: var(--text-muted);
  border: none;
  padding: 0.35rem 0.75rem;
  font-size: var(--fs-3);
  font-weight: var(--fw-label);
  border-radius: var(--radius-sm);
  cursor: pointer;
  transition: var(--transition);
}

.staff-filter-chip:hover {
  color: var(--text-main);
  background: var(--accent-primary-soft);
}

.staff-filter-chip.active {
  background: var(--accent-primary-fill);
  color: var(--accent-on-primary);
  box-shadow: none;
}

.badge-warning-rose {
  background: var(--danger-soft) !important;
  color: var(--accent-rose) !important;
  border: 1px solid var(--danger-border) !important;
  font-weight: var(--fw-label);
}

.badge-warning-cyan {
  background: var(--info-soft) !important;
  color: var(--accent-info) !important;
  border: 1px solid var(--info-border) !important;
  font-weight: var(--fw-label);
}

/* Tickets workspace */
.ticket-toolbar,
.ticket-filter-panel,
.ticket-summary-bar {
  background: var(--bg-card);
  border: 1px solid var(--border-color);
}

.ticket-toolbar {
  display: grid;
  grid-template-columns: minmax(240px, 1fr) minmax(0, auto);
  align-items: start;
  gap: 1rem 1.5rem;
  margin-bottom: 1rem;
  padding: 1.15rem 1.25rem;
  border-radius: var(--radius-lg);
}

.ticket-heading {
  display: flex;
  align-items: flex-start;
  gap: 0.75rem;
}

.ticket-heading h2 {
  color: var(--text-main);
  font-size: var(--fs-5);
  font-weight: var(--fw-title);
  letter-spacing: -0.02em;
}

.ticket-heading p {
  color: var(--text-muted);
  font-size: var(--fs-3);
  margin-top: 0.18rem;
}

.ticket-actions {
  display: flex;
  justify-content: flex-end;
  align-items: center;
  gap: 0.55rem;
  flex-wrap: wrap;
}

.ticket-scope-btn,
.ticket-chip,
.ticket-chip-group button {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 0.42rem;
}

.sheet-health {
  min-height: var(--h-ctl);
  display: inline-flex;
  align-items: center;
  padding: 0.32rem 0.6rem;
  border-radius: 999px;
  font-size: var(--fs-2);
  font-weight: var(--fw-label);
  white-space: nowrap;
}

/* ==========================================================================
   ПАНЕЛЬ ФИЛЬТРОВ РЕЕСТРА
   Живёт в левой колонке (#sidebarPanel, см. «Левая колонка» выше) и заполняет
   её целиком: фон, рамку и отступы несёт она, а не .sidebar — так спрятанное
   состояние сводится к сдвигу одного элемента.

   Порядок внутри: поиск, статус, категория, решение, команда, период.
   «Решение» и «Команда» свёрнуты по умолчанию (RAIL_GROUPS_DEFAULT в
   js/tickets.js).
   ========================================================================== */
.ticket-filter-rail {
  display: flex;
  flex: 1;
  min-height: 0;
  flex-direction: column;
  gap: var(--s-4);
  padding: var(--s-6) var(--s-5);
  background: var(--bg-header);
  border-right: 1px solid var(--border-color);
  /* Страховка: если групп станет больше, чем высоты окна, прокрутится сама
     панель, а не уедет за нижний край. */
  overflow-y: auto;
  overscroll-behavior: contain;
}

.rail-head {
  display: flex;
  align-items: center;
  gap: var(--s-3);
  padding-bottom: var(--s-4);
  border-bottom: 1px solid var(--border-color);
  flex-wrap: nowrap;
  min-width: 0;
}

.rail-title {
  color: var(--text-main);
  font-size: var(--fs-3);
  font-weight: var(--fw-title);
  flex-shrink: 0;
}

.rail-count {
  margin-left: auto;
  color: var(--text-muted);
  font-size: var(--fs-1);
  font-weight: var(--fw-title);
  white-space: nowrap;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  flex-shrink: 1;
}

/* Кнопки в шапке панели: сброс фильтров и булавка/сворачивание. Обе --h-ctl-sm, обе молчат
   цветом, пока их не трогают. Подписи и состояния ставят
   renderFilterPanelToggle() (js/ui.js) и syncTicketRailReset() (js/tickets.js). */
.rail-head-btn {
  flex-shrink: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--h-ctl-sm);
  height: var(--h-ctl-sm);
  min-width: var(--h-ctl-sm);
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text-dim);
  cursor: pointer;
  transition: var(--transition);
}

.rail-head-btn:hover { background: var(--bg-input); color: var(--text-main); }
.rail-head-btn .ui-icon { width: 15px; height: 15px; flex-shrink: 0; }
.rail-head-btn.is-collapse .ui-icon { width: 15px; height: 15px; flex-shrink: 0; }

/* Сброс появляется, только когда есть что сбрасывать. Красным при наведении:
   действие разрушительное для того, что пользователь настроил. */
.rail-head-btn.is-reset:hover { background: var(--danger-soft); color: var(--accent-rose); }

.rail-group {
  display: flex;
  flex-direction: column;
  gap: var(--s-2);
  padding-top: var(--s-4);
  border-top: 1px solid var(--border-color);
}

/* Первая группа идёт сразу под шапкой панели — своей черты ей не нужно. */
.rail-head + .rail-group { padding-top: 0; border-top: none; }

/* Заголовок группы — опора для взгляда, поэтому это самый заметный текст в
   панели после её собственного заголовка. */
.rail-label {
  color: var(--text-main);
  font-size: var(--fs-2);
  font-weight: var(--fw-title);
}

.rail-group-head {
  display: flex;
  align-items: center;
  gap: var(--s-2);
  width: 100%;
  padding: 0;
  border: none;
  border-radius: var(--radius-sm);
  background: none;
  font-family: inherit;
  text-align: left;
  cursor: pointer;
}

.rail-group-head:hover .rail-label { color: var(--accent-cyan); }

.rail-caret {
  flex-shrink: 0;
  width: 12px;
  height: 12px;
  color: var(--text-muted);
  transition: transform var(--dur-2) var(--ease-out);
}

/* У свёрнутой группы справа — выбранное значение. Иначе активный фильтр
   прячется вместе с группой и объяснить короткий список становится нечем. */
.rail-group-hint {
  margin-left: auto;
  overflow: hidden;
  color: var(--accent-cyan);
  font-size: var(--fs-1);
  font-weight: var(--fw-label);
  white-space: nowrap;
  text-overflow: ellipsis;
}

.rail-group.is-collapsed .rail-group-body { display: none; }
.rail-group.is-collapsed .rail-caret { transform: rotate(-90deg); }

.rail-group-body {
  display: flex;
  flex-direction: column;
  gap: var(--s-3);
}

/* Трекер статусов — он же фильтр по статусу: строка на значение, «иконка ·
   название · число». Это единственное место, где семь чисел видны целиком;
   второй, урезанный их вид — узкая полоса у спрятанной панели (.rail-stub).
   Классы .ticket-status-chip и data-status общие с прежней разметкой, поэтому
   клик и подсветка выбранного не изменились. */
.ticket-stat-tracker {
  display: flex;
  flex-direction: column;
  gap: 3px;
}

.ticket-stat-tracker .ticket-status-chip {
  min-width: 0;
  width: 100%;
  display: flex;
  align-items: center;
  gap: var(--s-4);
  /* Высота токеном, а не следствием паддинга: семь дробных строк не влезали
     в невысокое окно целиком. */
  min-height: var(--h-ctl);
  padding: 0 var(--s-4);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--text-muted);
  font: inherit;
  font-size: var(--fs-2);
  font-weight: var(--fw-label);
  line-height: 1.25;
  text-align: left;
  white-space: normal;
  cursor: pointer;
  transition: var(--transition);
}

.ticket-stat-tracker .ticket-status-chip:hover { border-color: var(--border-strong); color: var(--text-main); }

/* Выбранная строка обводится контуром, а не тенью: box-shadow тут занят
   цветной полосой .has-value (ниже). outline-offset отрицательный — контур
   садится ровно на место рамки, рамка одна. */
.ticket-stat-tracker .ticket-status-chip.active {
  outline: 2px solid var(--accent-primary);
  outline-offset: -1px;
  border-color: transparent;
  color: var(--text-main);
  font-weight: var(--fw-title);
}

.ticket-stat-tracker .ticket-status-chip:focus-visible {
  outline: 2px solid var(--accent-primary);
  outline-offset: 2px;
  box-shadow: none;
}

.ticket-status-chip-label { flex: 1; min-width: 0; }

.ticket-stat-icon {
  width: 24px;
  height: 24px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  flex: 0 0 auto;
  border-radius: var(--radius-sm);
  color: var(--accent-primary);
  background: var(--accent-primary-soft);
}

.ticket-stat-icon .ui-icon { width: 14px; height: 14px; }

.ticket-stat-count {
  flex: 0 0 auto;
  color: var(--text-main);
  font-size: var(--fs-5);
  font-weight: var(--fw-num);
  letter-spacing: -0.03em;
  /* Числа меняются при фильтрации — без табличных цифр столбец справа
     дёргается по ширине. */
  font-variant-numeric: tabular-nums;
}

/* Ненулевой счётчик у «требующих внимания» статусов красит строку цветом
   статуса, даже когда фильтр не выбран (has-value ставит setStat в
   js/tickets.js). «В работе» и «Назначено, не в работе» — одна жёлтая семья,
   разводит их форма: пунктирная рамка у второй. */
.ticket-status-chip.has-value:not(.active)[data-status="unassigned"] {
  background: var(--info-soft); border-color: var(--info-border); box-shadow: inset 4px 0 0 var(--info-solid);
}
.ticket-status-chip.has-value:not(.active)[data-status="unassigned"] .ticket-stat-icon { color: var(--accent-info); background: var(--info-wash); }
.ticket-status-chip.has-value:not(.active)[data-status="unassigned"] .ticket-stat-count { color: var(--accent-info); }
.ticket-status-chip.has-value:not(.active)[data-status="В работе"],
.ticket-status-chip.has-value:not(.active)[data-status="assigned-idle"] {
  background: var(--warning-soft); border-color: var(--warning-border); box-shadow: inset 4px 0 0 var(--warning-solid);
}
.ticket-status-chip.has-value:not(.active)[data-status="В работе"] .ticket-stat-icon,
.ticket-status-chip.has-value:not(.active)[data-status="assigned-idle"] .ticket-stat-icon { color: var(--accent-amber); background: var(--warning-wash); }
.ticket-status-chip.has-value:not(.active)[data-status="В работе"] .ticket-stat-count,
.ticket-status-chip.has-value:not(.active)[data-status="assigned-idle"] .ticket-stat-count { color: var(--accent-amber); }
.ticket-status-chip.has-value:not(.active)[data-status="assigned-idle"] { border-style: dashed; }
.ticket-status-chip.has-value:not(.active)[data-status="urgent"] {
  background: var(--danger-soft); border-color: var(--danger-border); box-shadow: inset 4px 0 0 var(--danger-solid);
}
.ticket-status-chip.has-value:not(.active)[data-status="urgent"] .ticket-stat-icon { color: var(--accent-rose); background: var(--danger-wash); }
.ticket-status-chip.has-value:not(.active)[data-status="urgent"] .ticket-stat-count { color: var(--accent-rose); }

/* Группа чипов. Живёт только внутри панели фильтров, поэтому !important здесь
   больше не нужны. */
.ticket-chip-group {
  display: flex;
  align-items: center;
  gap: 3px;
  flex-wrap: wrap;
  width: 100%;
}

.ticket-chip-group button {
  height: var(--h-ctl-sm);
  padding: 0 var(--s-4);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
  color: var(--text-muted);
  font-size: var(--fs-2);
  font-weight: var(--fw-label);
  white-space: nowrap;
  cursor: pointer;
  transition: var(--transition);
}

.ticket-chip-group button:hover { color: var(--text-main); background: var(--bg-card-hover); border-color: var(--border-strong); }
.ticket-chip-group button.active { color: var(--accent-on-primary); background: var(--accent-primary-fill); border-color: var(--accent-primary-fill); font-weight: var(--fw-title); }

/* Активный чип статуса и решения надевает цвет самого статуса: фильтр
   подсказывает цветовой словарь таблицы, а не спорит с ним. Заливка и чернила
   те же, что у плашки в строке, поэтому контраст уже проверен. Обводка 2px
   отделяет выбранный чип от невыбранных, не полагаясь на один только оттенок. */
.ticket-status-chip.active[data-status="В работе"],
.ticket-status-chip.active[data-status="assigned-idle"] {
  background: var(--warning-soft); color: var(--accent-amber); border-color: transparent;
  box-shadow: inset 0 0 0 2px var(--warning-solid);
}
.ticket-decision-chip.active[data-decision="Запрос видео"] {
  background: var(--video-soft); color: var(--video-solid); border-color: transparent;
  box-shadow: inset 0 0 0 2px var(--video-solid);
}
.ticket-decision-chip.active[data-decision="Согласование"] {
  background: var(--info-soft); color: var(--accent-info); border-color: transparent;
  box-shadow: inset 0 0 0 2px var(--info-solid);
}
/* «Без ID» — акцент (макет A): свободная заявка — то, что надо взять. */
.ticket-status-chip.active[data-status="unassigned"] {
  background: var(--accent-primary-soft); color: var(--accent-primary); border-color: transparent;
  box-shadow: inset 0 0 0 2px var(--accent-primary-fill);
}
.ticket-status-chip.active[data-status="Закрыта"],
.ticket-decision-chip.active[data-decision="Одобрили"] {
  background: var(--success-soft); color: var(--accent-green); border-color: transparent;
  box-shadow: inset 0 0 0 2px var(--success-solid);
}
.ticket-status-chip.active[data-status="urgent"],
.ticket-decision-chip.active[data-decision="Отказ"] {
  background: var(--danger-soft); color: var(--accent-rose); border-color: transparent;
  box-shadow: inset 0 0 0 2px var(--danger-solid);
}
.ticket-status-chip.active[data-status="В работе у другого модератора"] {
  background: var(--discovery-soft); color: var(--accent-purple); border-color: transparent;
  box-shadow: inset 0 0 0 2px var(--discovery-solid);
}
.ticket-status-chip.active[data-status="Закрыта ранее"],
.ticket-decision-chip.active[data-decision="Без решения"] {
  background: var(--bg-input); color: var(--text-main); border-color: transparent;
  box-shadow: inset 0 0 0 2px var(--border-strong);
}
/* Цветная строка трекера: контур выбора убираем — рамку даёт цвет статуса. */
.ticket-stat-tracker .ticket-status-chip.active[data-status]:not([data-status="all"]) { outline: none; }

/* Категории — строками во всю ширину, а не чипами. Названия приходят из
   TICKET_CATEGORIES и по длине непредсказуемы: чипами в узкой колонке они
   резались многоточием. Точка слева отличает выбранную строку не одним цветом. */
.ticket-chip-group.is-list {
  display: flex;
  flex-direction: column;
  gap: 1px;
}

.ticket-chip-group.is-list button {
  width: 100%;
  height: auto;
  min-height: var(--h-ctl-sm);
  padding: var(--s-2) var(--s-4);
  border-color: transparent;
  background: none;
  text-align: left;
  white-space: normal;
  display: flex;
  align-items: center;
  gap: var(--s-4);
}

.ticket-chip-group.is-list button::before {
  content: "";
  flex-shrink: 0;
  width: 9px;
  height: 9px;
  border: 1px solid var(--line-ctl);
  border-radius: 50%;
}

.ticket-chip-group.is-list button.active::before {
  border-color: currentColor;
  background: currentColor;
  box-shadow: inset 0 0 0 2px var(--bg-header);
}

.ticket-chip-group.is-list button.active {
  background: var(--accent-primary-soft);
  border-color: transparent;
  color: var(--accent-cyan);
}

/* Иконка забирает у подписи около 18px — в узкой колонке подпись важнее. */
.ticket-filter-rail .ticket-chip-group .ui-icon { display: none; }

/* Свой диапазон: поля во всю ширину, а не рядом друг с другом — узкому полю
   даты не хватает места на дд.мм.гггг. */
.rail-dates { display: grid; gap: 4px; }

.rail-dates input[type="date"] {
  width: 100%;
  height: var(--h-ctl-sm);
  padding: 0 var(--s-4);
  border: 1px solid var(--line-ctl);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
  color: var(--text-main);
  font-family: inherit;
  font-size: var(--fs-2);
}

.rail-dates .btn {
  height: var(--h-ctl-sm);
  justify-content: center;
  padding: 0 var(--s-4);
}

#inputTicketSearch {
  min-height: var(--h-ctl);
  color: var(--text-main) !important;
}

.ticket-search-wrap { position: relative; }
.ticket-search-wrap .ui-icon { position: absolute; left: 0.7rem; top: 50%; transform: translateY(-50%); color: var(--text-dim); }
.ticket-search-wrap input { padding-left: 2.2rem !important; }

.ticket-summary-bar {
  justify-content: space-between;
  gap: 0.8rem;
  padding: 0.48rem 0.72rem;
  border-color: var(--accent-primary-border);
  border-radius: var(--radius-md);
  background: var(--accent-primary-soft);
  color: var(--accent-primary);
  font-size: var(--fs-2);
  font-weight: var(--fw-label);
}

.ticket-summary-bar span:last-child { color: var(--text-main); }

#tab-tickets .table-card,
#ticketsTableCard {
  padding: 0 !important;
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  overflow: clip;
}

#tab-tickets .table-container {
  border: none !important;
  border-radius: 0 !important;
  overflow-x: auto;
}

#ticketsTableCard > .ticket-pager:first-of-type {
  display: none !important;
}

#ticketsTableCard > .ticket-pager {
  margin: 0 !important;
  padding: 8px 14px !important;
  border-top: 1px solid var(--border-color);
  border-bottom: 0 !important;
}

.tickets-table {
  table-layout: auto;
  width: max-content;
  min-width: 100%;
  font-size: var(--fs-2);
  border-collapse: collapse;
}

.tickets-table thead tr {
  background: var(--bg-input) !important;
  text-transform: uppercase !important;
}

.tickets-table thead th {
  padding: 8px 8px !important;
  font-size: 11px !important;
  font-weight: var(--fw-title) !important;
  letter-spacing: .05em;
  color: var(--text-dim);
  background: var(--bg-input) !important;
  white-space: nowrap;
  border-bottom: 1px solid var(--border-strong);
}

.tickets-table tbody td {
  padding: 5px 8px !important;
  font-size: var(--fs-2) !important;
  color: var(--text-main);
  white-space: nowrap;
  border-bottom: 1px solid var(--border-color);
}

.tickets-table tbody tr {
  transition: background-color var(--dur-1) var(--ease-out);
}

.tickets-table tbody tr:hover {
  background: var(--bg-card-hover) !important;
}

/* Лёгкие полупрозрачные разделители между колонками, растворяющиеся к краям строки */
.tickets-table th,
.tickets-table td {
  position: relative;
}

.tickets-table th + th::before,
.tickets-table td + td::before {
  content: "";
  position: absolute;
  left: 0;
  top: 14%;
  bottom: 14%;
  width: 1px;
  background: linear-gradient(
    to bottom,
    transparent,
    color-mix(in srgb, var(--text-main) 13%, transparent) 25%,
    color-mix(in srgb, var(--text-main) 13%, transparent) 75%,
    transparent
  );
  pointer-events: none;
}

/* Статус и решение: точка, текст и стрелка, без тяжелых рамок и плашек */
.tickets-table select.status-select {
  -webkit-appearance: none;
  appearance: none;
  background-color: transparent !important;
  border: 1px solid transparent !important;
  border-radius: var(--radius-sm) !important;
  box-shadow: none !important;
  padding: 3px 18px 3px 17px !important;
  font-weight: var(--fw-title) !important;
  font-size: var(--fs-2) !important;
  cursor: pointer;
  width: auto;
  min-width: 0;
  background-image:
    radial-gradient(circle at 7px 50%, currentColor 0 3px, transparent 3.5px),
    url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238e8e9e' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>") !important;
  background-repeat: no-repeat !important;
  background-position: 0 0, right 4px center !important;
  background-size: auto, 10px 10px !important;
  transition: background-color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out);
}

.tickets-table select.status-select:hover {
  background-color: var(--bg-card-hover) !important;
}

.tickets-table select.status-select:focus-visible {
  outline: none;
  border-color: var(--accent-primary-border) !important;
  box-shadow: var(--focus) !important;
}

.tickets-table select.status-select:disabled {
  opacity: .7;
  cursor: default;
  background-image: radial-gradient(circle at 7px 50%, currentColor 0 3px, transparent 3.5px) !important;
}

.tickets-table select.status-select option {
  background: var(--bg-card);
  color: var(--text-main);
}

/* Назначение ID, Категория, Причина: плоский аккуратный dropdown */
.tickets-table select.ticket-assign-select,
.tickets-table select.ticket-category-select,
.tickets-table select.ticket-reason-select {
  -webkit-appearance: none;
  appearance: none;
  background-color: transparent !important;
  border: 1px solid transparent !important;
  border-radius: var(--radius-sm) !important;
  box-shadow: none !important;
  padding: 3px 18px 3px 5px !important;
  font-size: var(--fs-2) !important;
  height: auto !important;
  cursor: pointer;
  background-image: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 24 24' fill='none' stroke='%238e8e9e' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'><path d='m6 9 6 6 6-6'/></svg>") !important;
  background-repeat: no-repeat !important;
  background-position: right 3px center !important;
  background-size: 10px 10px !important;
  transition: background-color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out);
}

.tickets-table select.ticket-assign-select:hover,
.tickets-table select.ticket-category-select:hover,
.tickets-table select.ticket-reason-select:hover {
  background-color: var(--bg-card-hover) !important;
}

.tickets-table select.ticket-assign-select:focus-visible,
.tickets-table select.ticket-category-select:focus-visible,
.tickets-table select.ticket-reason-select:focus-visible {
  outline: none;
  background-color: var(--bg-input) !important;
  border-color: var(--accent-primary-border) !important;
  box-shadow: var(--focus) !important;
}

.tickets-table select.ticket-assign-select option,
.tickets-table select.ticket-category-select option,
.tickets-table select.ticket-reason-select option {
  background: var(--bg-card);
  color: var(--text-main);
}

/* Поля ввода (дата, причина, комм. модератора, заметка СВ) */
.tickets-table td input.ticket-cell-truncate,
.tickets-table td input[type="date"] {
  background-color: transparent !important;
  border: 1px solid transparent !important;
  border-radius: var(--radius-sm) !important;
  box-shadow: none !important;
  color: var(--text-main) !important;
  font-size: var(--fs-2) !important;
  padding: 3px 6px !important;
  transition: background-color var(--dur-1) var(--ease-out), border-color var(--dur-1) var(--ease-out);
}

.tickets-table td input.ticket-cell-truncate::placeholder {
  color: var(--text-dim);
  opacity: 1;
}

.tickets-table td input.ticket-cell-truncate:hover,
.tickets-table td input[type="date"]:hover {
  background-color: var(--bg-card-hover) !important;
}

.tickets-table td input.ticket-cell-truncate:focus,
.tickets-table td input[type="date"]:focus {
  outline: none;
  background-color: var(--bg-input) !important;
  border-color: var(--accent-primary-border) !important;
  box-shadow: var(--focus) !important;
}

.tickets-table td input[type="date"]::-webkit-calendar-picker-indicator {
  opacity: .45;
  cursor: pointer;
}

/* Кнопки действий в строке */
.tickets-table tbody td .btn.icon-btn {
  width: 24px;
  height: 24px;
  margin: 0 2px 0 0 !important;
  padding: 0 !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm) !important;
}

.tickets-table tbody td .btn.icon-btn .ui-icon {
  width: 13px;
  height: 13px;
}

/* ФИО и ШК */
.tickets-table td.ticket-name-cell {
  font-size: var(--fs-2) !important;
  font-weight: var(--fw-title);
  color: var(--text-main);
}

.tickets-table td.ticket-shk-cell {
  font-size: var(--fs-2) !important;
  font-family: ui-monospace, SFMono-Regular, Consolas, monospace;
  font-weight: var(--fw-title);
  color: var(--accent-primary);
  cursor: copy;
}

.ticket-cell-truncate {
  display: inline-block;
  max-width: 160px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  vertical-align: bottom;
}
input.ticket-cell-truncate { max-width: 100%; }

.icon-btn {
  width: var(--h-ctl);
  height: var(--h-ctl);
  padding: 0 !important;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border-radius: var(--radius-sm) !important;
}

@media (max-width: 900px) {
  .ticket-filter-rail .search-input { max-width: 340px; }
}

/* ==========================================================================
   THEME COMPATIBILITY — legacy inline styles
   ========================================================================== */
:root {
  color-scheme: light;
}

:root[data-theme="dark"] {
  color-scheme: dark;
}

/* Было --accent-primary-soft — тот же почти-фоновый токен, что у подсветки
   строки таблицы (едва отличим от bg что в светлой, что в тёмной теме).
   Для выделения ТЕКСТА (копировать/поправить букву) нужен реальный контраст,
   не тонкий намёк — берём тот же fill+on-primary, что у активных кнопок/чипов
   (уже проверенный контраст текста поверх, см. комментарии у токенов ниже). */
::selection {
  background: var(--accent-primary-fill);
  color: var(--accent-on-primary);
}

/* Числа не должны плясать при обновлении по SSE: у пропорциональных цифр Inter
   разная ширина, и колонка «плывёт» на каждом обновлении. :where() — чтобы
   правило не перебивало ничьих частных настроек. */
:where(td, th, .kpi-value, .ticket-stat-value, .num) {
  font-variant-numeric: tabular-nums;
}

/* Кольцо фокуса объявлено через :is(), а не :where(). У :where() нулевая
   специфичность, поэтому любое позднее правило со своей box-shadow — плашка с
   планкой, активный чип, карточка с тенью — молча съедало кольцо, и обход
   табом переставал быть виден.
   `outline` прозрачный, а не `none`: в forced-colors (высокая контрастность
   Windows) box-shadow не отрисовывается вовсе, и `none` оставил бы обход табом
   без единого индикатора. Прозрачный контур там перекрашивается системой. */
:is(a, button, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid transparent;
  outline-offset: 2px;
  box-shadow: var(--focus);
}

/* Инлайновые поля, которые рисует public/js, берут волосяную границу блоков —
   1.2:1 к поверхности, то есть поля выглядят безрамочными. Поднимаем их до
   --line-ctl тем же приёмом, каким чинятся легаси-инлайны ниже: селектором по
   инлайновому стилю, без правки скриптов. */
input[style*="var(--border-color)"],
select[style*="var(--border-color)"],
textarea[style*="var(--border-color)"] {
  border-color: var(--line-ctl) !important;
}

/* color-scheme (выше) заставляет браузер рисовать раскрытый список <select>
   своей встроенной тёмной/светлой палитрой — она генерическая, не наши
   токены, и в тёмной теме давала тусклый текст, слабо отличимый от фона и
   между собой (несколько вариантов статуса читались одинаково блёкло).
   background/color на <option> Chromium поверх этого уважает — задаём явно
   нашими токенами, чтобы список читался так же, как остальной интерфейс. */
select option {
  background: var(--bg-card);
  color: var(--text-main);
}

::-webkit-scrollbar-track {
  background: var(--bg-input) !important;
}

::-webkit-scrollbar-thumb {
  background: var(--text-dim) !important;
  border-color: var(--bg-input) !important;
}

::-webkit-scrollbar-thumb:hover {
  background: var(--text-muted) !important;
}

/* Правило чинит легаси-инлайны со светлым текстом в светлой теме. Плашки
   статуса и решения из него исключены: они сами задают чернила под свою
   заливку, а !important здесь перекрашивал их обратно в --text-main, из-за
   чего цвет оставался только в фоне. */
:root:not([data-theme="dark"]) input,
:root:not([data-theme="dark"]) select:not(.status-select),
:root:not([data-theme="dark"]) textarea {
  color: var(--text-main) !important;
}

/* Keep selected filters unmistakable without relying on a bright gradient. */
.date-chip.active,
.staff-filter-chip.active {
  background: var(--accent-primary-fill) !important;
  color: var(--accent-on-primary) !important;
  border-color: transparent !important;
  box-shadow: none !important;
}

/* One primary action per toolbar; supporting actions stay neutral. */
#btnOpenImportTicketsModal,
#btnOpenAddIncomingModal,
#btnAddMyIncomingGuest,
#btnGoToSchedule,
#btnSaveImportTickets,
#btnRunAutoDistribute,
#btnRunCustomDistribute {
  background: var(--accent-primary-fill) !important;
  color: var(--accent-on-primary) !important;
  border-color: transparent !important;
  box-shadow: none !important;
}

#btnOpenAutoDistributeModal,
#btnQuickAutoDistribute {
  background: var(--bg-input) !important;
  color: var(--text-main) !important;
  border-color: var(--border-color) !important;
  box-shadow: none !important;
}

#btnBulkUrgentOn,
#btnBulkUrgentOff,
#btnBulkDelete,
#btnDeleteStaff {
  background: var(--danger-soft) !important;
  color: var(--accent-rose) !important;
  border-color: var(--danger-border) !important;
  box-shadow: none !important;
}

#liveIndicator {
  box-shadow: none !important;
}

.brand-icon,
.btn-primary,
.date-chip.active,
.staff-filter-chip.active,
button[style*="linear-gradient"],
button[style*="background: var(--accent"],
button[style*="background:var(--accent"],
span[style*="background: var(--accent-rose)"],
span[style*="background: var(--accent-green)"] {
  color: var(--accent-on-primary) !important;
}

/* Уведомления (issue #142): колокольчик, бейджи, панель, всплывашки */

.nav-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 1.2rem;
  height: 1.2rem;
  padding: 0 0.35rem;
  border-radius: 999px;
  background: var(--accent-rose);
  color: var(--bg-card);
  font-size: var(--fs-1);
  font-weight: var(--fw-title);
  line-height: 1;
}

.notif-bell-wrap {
  position: relative;
}

#btnNotifBell {
  position: relative;
}

#notifBellBadge {
  position: absolute;
  top: -0.3rem;
  right: -0.3rem;
  display: none;
  align-items: center;
  justify-content: center;
  min-width: 1.1rem;
  height: 1.1rem;
  padding: 0 0.3rem;
  border-radius: 999px;
  background: var(--accent-rose);
  color: var(--bg-card);
  font-size: var(--fs-1);
  font-weight: var(--fw-title);
  line-height: 1;
  box-shadow: 0 0 0 2px var(--bg-header);
}

#notifPanel {
  position: absolute;
  top: calc(100% + 0.5rem);
  right: 0;
  width: 360px;
  max-width: 90vw;
  max-height: 70vh;
  overflow-y: auto;
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);
  display: none;
  z-index: 200;
}

#notifPanel.open {
  display: block;
}

.notif-panel-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 0.75rem 1rem;
  border-bottom: 1px solid var(--border-color);
  font-weight: var(--fw-title);
  color: var(--text-main);
  font-size: var(--fs-4);
}

.notif-settings-btn {
  background: none;
  border: none;
  color: var(--text-muted);
  cursor: pointer;
  padding: 0.2rem;
  line-height: 0;
  border-radius: var(--radius-sm);
}

.notif-settings-btn:hover {
  color: var(--text-main);
  background: var(--bg-card-hover);
}

.notif-empty {
  padding: 1.5rem 1rem;
  text-align: center;
  color: var(--text-dim, var(--text-muted));
  font-size: var(--fs-4);
}

.notif-row {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  padding: 0.65rem 2.1rem 0.65rem 1rem;
  border-bottom: 1px solid var(--border-color);
  cursor: pointer;
  position: relative;
}

.notif-row-close {
  position: absolute;
  top: 0.5rem;
  right: 0.5rem;
  background: none;
  border: none;
  color: var(--text-dim, var(--text-muted));
  cursor: pointer;
  padding: 0.15rem;
  line-height: 0;
  border-radius: var(--radius-sm);
  opacity: 0.55;
}

.notif-row-close:hover {
  opacity: 1;
  color: var(--accent-rose);
  background: var(--bg-card-hover);
}

.notif-row:last-child {
  border-bottom: none;
}

.notif-row:hover {
  background: var(--bg-card-hover);
}

.notif-row.unread {
  background: var(--info-soft, var(--bg-card-hover));
}

.notif-row-icon {
  flex-shrink: 0;
  color: var(--accent-cyan, var(--text-muted));
  margin-top: 0.1rem;
}

.notif-row-body {
  flex: 1;
  min-width: 0;
}

.notif-row-title {
  font-size: var(--fs-4);
  font-weight: var(--fw-title);
  color: var(--text-main);
}

.notif-row-text {
  font-size: var(--fs-3);
  color: var(--text-muted);
  margin-top: 0.15rem;
}

.notif-row-time {
  font-size: var(--fs-1);
  color: var(--text-dim, var(--text-muted));
  margin-top: 0.25rem;
}

.notif-dot {
  flex-shrink: 0;
  width: 0.5rem;
  height: 0.5rem;
  border-radius: 50%;
  background: var(--accent-cyan);
  margin-top: 0.35rem;
}

#toastContainer {
  position: fixed;
  top: 1rem;
  right: 1rem;
  z-index: 999;
  display: flex;
  flex-direction: column;
  gap: 0.6rem;
  max-width: 340px;
}

.toast-card {
  display: flex;
  align-items: flex-start;
  gap: 0.6rem;
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.2);
  padding: 0.75rem 0.85rem;
  cursor: pointer;
  animation: toastIn 0.2s ease-out;
}

@keyframes toastIn {
  from { transform: translateX(16px); opacity: 0; }
  to { transform: translateX(0); opacity: 1; }
}

.toast-icon {
  flex-shrink: 0;
  color: var(--accent-cyan, var(--text-muted));
  margin-top: 0.1rem;
}

.toast-body {
  flex: 1;
  min-width: 0;
}

.toast-title {
  font-size: var(--fs-4);
  font-weight: var(--fw-title);
  color: var(--text-main);
}

.toast-text {
  font-size: var(--fs-3);
  color: var(--text-muted);
  margin-top: 0.15rem;
}

@keyframes notifFlash {
  0%, 100% { box-shadow: none; }
  25% { box-shadow: 0 0 0 3px var(--accent-cyan); }
  75% { box-shadow: 0 0 0 3px var(--accent-cyan); }
}
.notif-flash {
  animation: notifFlash 1.8s ease-in-out;
}

.toast-close {
  flex-shrink: 0;
  background: none;
  border: none;
  color: var(--text-dim, var(--text-muted));
  cursor: pointer;
  padding: 0.1rem;
  line-height: 0;
}

/* Кликабельный список результатов поиска по справочнику (замена нативного
   <datalist>, который ненадёжно выбирался в паре с ILIKE-поиском по
   произвольной строке — см. issue про поиск подменяющего в «Заменах»). */
.staff-search-results {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  z-index: 60;
  margin-top: 2px;
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  max-height: 220px;
  overflow-y: auto;
  display: none;
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.35);
}
.staff-search-results.active {
  display: block;
}
.staff-search-results .staff-search-item {
  padding: 0.5rem 0.7rem;
  cursor: pointer;
  font-size: var(--fs-4);
  color: var(--text-main);
  border-bottom: 1px solid var(--border-color);
}
.staff-search-results .staff-search-item:last-child {
  border-bottom: none;
}
.staff-search-results .staff-search-item:hover,
.staff-search-results .staff-search-item.is-active {
  background: var(--bg-card-hover);
  color: var(--accent-cyan);
}
.staff-search-results .staff-search-sub {
  display: block;
  font-size: var(--fs-2);
  color: var(--text-muted);
  margin-top: 0.1rem;
}
.staff-search-results .staff-search-empty {
  padding: 0.5rem 0.7rem;
  font-size: var(--fs-3);
  color: var(--text-muted);
}

/* Свой пикер дат/месяцев вместо нативных input[type=date]/input[type=month]
   — issue #224, public/js/dashDate.js. Кликабельность всего поля обеспечивает
   dashDate.js (перехват mousedown), здесь только визуальная подсказка. */
input[type="date"],
input[type="month"] {
  cursor: pointer;
}

.dash-date-panel {
  position: fixed;
  z-index: 200;
  width: 264px;
  background: var(--bg-card);
  border: 1px solid var(--border-color);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-md);
  padding: 0.7rem;
}
.dash-date-panel-month {
  width: 220px;
}
.dash-date-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 0.5rem;
}
.dash-date-label {
  font-weight: var(--fw-title);
  font-size: var(--fs-4);
  color: var(--text-main);
}
.dash-date-nav {
  background: transparent;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  font-size: var(--fs-5);
  line-height: 1;
  padding: 0.2rem 0.5rem;
  border-radius: var(--radius-sm);
}
.dash-date-nav:hover {
  background: var(--bg-card-hover);
  color: var(--text-main);
}
.dash-date-weekdays {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  margin-bottom: 0.15rem;
}
.dash-date-weekday {
  text-align: center;
  font-size: var(--fs-1);
  color: var(--text-dim);
  padding: 0.2rem 0;
}
.dash-date-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 2px;
}
.dash-date-day {
  background: transparent;
  border: none;
  color: var(--text-main);
  font-size: var(--fs-3);
  padding: 0.4rem 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.dash-date-day:hover {
  background: var(--bg-card-hover);
}
.dash-date-day.is-dim {
  color: var(--text-dim);
  opacity: 0.55;
}
.dash-date-day.is-today {
  box-shadow: inset 0 0 0 1px var(--accent-primary-border);
  font-weight: var(--fw-title);
}
.dash-date-day.is-selected {
  background: var(--accent-primary-fill);
  color: var(--accent-on-primary);
  font-weight: var(--fw-title);
}
.dash-date-month-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 4px;
}
.dash-date-month-cell {
  background: transparent;
  border: none;
  color: var(--text-main);
  font-size: var(--fs-3);
  padding: 0.55rem 0;
  border-radius: var(--radius-sm);
  cursor: pointer;
}
.dash-date-month-cell:hover {
  background: var(--bg-card-hover);
}
.dash-date-month-cell.is-today {
  box-shadow: inset 0 0 0 1px var(--accent-primary-border);
  font-weight: var(--fw-title);
}
.dash-date-month-cell.is-selected {
  background: var(--accent-primary-fill);
  color: var(--accent-on-primary);
  font-weight: var(--fw-title);
}
.dash-date-footer {
  display: flex;
  justify-content: space-between;
  margin-top: 0.5rem;
  padding-top: 0.5rem;
  border-top: 1px solid var(--border-color);
}
.dash-date-footer-btn {
  background: transparent;
  border: none;
  color: var(--accent-primary);
  font-size: var(--fs-3);
  cursor: pointer;
  padding: 0.2rem 0.3rem;
}
.dash-date-footer-btn:hover {
  text-decoration: underline;
}

/* «Уменьшить движение» в настройках системы (аудит 11.09): без анимаций и
   плавных переходов — сразу конечное состояние. Статичные подсказки (цвет,
   иконка, текст) остаются: движение нигде не единственный сигнал. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
    scroll-behavior: auto !important;
  }
}

/* ==========================================================================
   ЭКРАН «СМЕНА» (СВ) — этап 4, макет Adapt-1-Smena-SV. Каркас в index.html
   (#tab-shift), содержимое рисует js/shift.js. Всё на токенах выше.
   ========================================================================== */
.shift-head { display: flex; align-items: center; gap: 1rem; margin-bottom: 1rem; }
.shift-meta { font-size: var(--fs-2); color: var(--text-dim); }
.shift-head-actions { margin-left: auto; display: flex; gap: 0.5rem; }

#tab-shift .is-accent { color: var(--accent-primary); }
#tab-shift .is-ok { color: var(--accent-green); }
#tab-shift .is-warn { color: var(--accent-amber); }
#tab-shift .is-bad { color: var(--accent-rose); }
#tab-shift .is-info { color: var(--accent-info); }
#tab-shift .is-video { color: var(--video-solid); }
#tab-shift .muted { color: var(--text-dim); }
#tab-shift .num { text-align: right; font-variant-numeric: tabular-nums; }

.shift-main, .shift-aside { display: flex; flex-direction: column; gap: 1rem; min-width: 0; }
.shift-aside { padding-left: 1.25rem; border-left: 1px solid var(--border-color); }
@media (max-width: 1100px) {
  .shift-aside { padding-left: 0; border-left: none; }
}

.shift-section-head { display: flex; align-items: center; gap: 8px; }
.shift-section-head h2 { font-size: var(--fs-4); font-weight: var(--fw-title); margin: 0; }
.shift-section-head .ui-icon { width: 15px; height: 15px; color: var(--text-muted); }
.shift-section-head .shift-icon-bad { color: var(--danger-solid); }
.shift-section-head .shift-icon-warn { color: var(--warning-solid); }
.shift-section-meta { font-size: var(--fs-2); color: var(--text-dim); }
.shift-sort { margin-left: auto; display: flex; gap: 6px; flex-wrap: wrap; }
.shift-sort-btn, .shift-btn, .shift-link {
  height: var(--h-ctl-sm); padding: 0 9px; border: 1px solid var(--border-color); border-radius: var(--radius-sm);
  background: none; color: var(--text-muted); font: inherit; font-size: var(--fs-1); cursor: pointer;
}
.shift-sort-btn.active { background: var(--bg-input); border-color: var(--border-strong); color: var(--text-main); font-weight: var(--fw-title); }
.shift-btn { font-size: var(--fs-2); }
.shift-btn.is-ok { border-color: var(--success-border); background: var(--success-soft); color: var(--accent-green); font-weight: var(--fw-title); }
.shift-link { margin-left: auto; border: none; padding: 0; color: var(--accent-primary); }
.shift-pill { font-size: var(--fs-1); padding: 1px 6px; border-radius: 999px; background: var(--bg-input); border: 1px solid var(--border-color); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.shift-pill.is-bad { background: var(--danger-soft); border-color: var(--danger-soft); color: var(--accent-rose); }
.shift-pill.is-warn { background: var(--warning-soft); border-color: var(--warning-soft); color: var(--accent-amber); }
.shift-pill.is-video { background: var(--video-soft); border-color: var(--video-soft); color: var(--video-solid); }

.shift-card { border: 1px solid var(--border-color); border-radius: var(--radius-md); overflow: hidden; background: var(--bg-card); }
.shift-wl-row {
  display: grid; grid-template-columns: minmax(0, 2.5fr) minmax(90px, 1.2fr) repeat(5, minmax(44px, .5fr)) 60px;
  gap: 8px; align-items: center; padding: 10px 14px; border-bottom: 1px solid var(--border-color); font-size: var(--fs-3);
}
.shift-wl-head { padding: 9px 14px; background: var(--bg-input); font-size: 11px; font-weight: var(--fw-title); letter-spacing: .07em; text-transform: uppercase; color: var(--text-dim); }
.shift-wl-name { display: flex; align-items: center; gap: 8px; min-width: 0; }
.shift-avatar { width: 26px; height: 26px; flex: 0 0 auto; display: grid; place-items: center; border-radius: var(--radius-sm); background: var(--bg-input); color: var(--text-muted); font-size: 10px; font-weight: var(--fw-num); }
.shift-avatar.is-warn { background: var(--warning-soft); color: var(--accent-amber); }
.shift-avatar.is-bad { background: var(--danger-soft); color: var(--accent-rose); }
.shift-wl-text { min-width: 0; display: flex; flex-direction: column; }
.shift-wl-title { font-weight: var(--fw-title); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.shift-wl-note { font-size: var(--fs-1); color: var(--text-dim); }
.shift-guest { font-size: var(--fs-1); font-weight: var(--fw-label); padding: 1px 6px; border-radius: 999px; background: var(--discovery-soft); color: var(--accent-purple); }
.shift-wl-bar { display: flex; align-items: center; gap: 7px; }
.shift-wl-bar b { font-size: var(--fs-2); font-weight: var(--fw-num); font-variant-numeric: tabular-nums; }
.shift-bar { flex: 1; display: flex; height: 6px; border-radius: 3px; background: var(--bg-input); overflow: hidden; }
.shift-bar > span { display: block; height: 100%; background: var(--accent-primary-fill); }
/* Словарь реестра: в работе — жёлтый, видео — оранжевый, согласование —
   синий, назначено («Свободная») — фуксия, закрыто за сегодня — зелёный. */
.shift-bar > .seg-work { background: var(--warning-solid); }
.shift-bar > .seg-video { background: var(--video-solid); }
.shift-bar > .seg-appr { background: var(--info-solid); }
.shift-bar > .seg-idle { background: var(--accent-primary-fill); }
.shift-bar > .seg-closed { background: var(--success-solid); }
.shift-bar > .is-bad { background: var(--danger-solid); }
.shift-wl-actions { display: flex; gap: 6px; justify-content: flex-end; align-items: center; }
.shift-icon-btn { width: 26px; height: 26px; display: grid; place-items: center; border: 1px solid var(--border-color); border-radius: var(--radius-sm); background: none; color: var(--text-muted); cursor: pointer; }
.shift-icon-btn .ui-icon { width: 13px; height: 13px; }
.shift-icon-btn.is-accent { border-color: var(--accent-primary-border); background: var(--accent-primary-soft); color: var(--accent-primary); }
.shift-wl-foot { display: flex; align-items: center; gap: 10px; padding: 9px 14px; font-size: var(--fs-1); color: var(--text-dim); }
.shift-wl-foot:empty { display: none; }

.shift-banner {
  display: flex; align-items: center; gap: 10px; padding: 11px 14px;
  border: 1px solid var(--accent-primary-border); border-radius: var(--radius-md);
  background: var(--accent-primary-soft); color: var(--accent-primary); font-size: var(--fs-3);
}
.shift-banner .ui-icon { width: 16px; height: 16px; flex: 0 0 auto; }
.shift-banner > span { flex: 1; min-width: 0; }

/* Окно «Назначить заявки» */
.shift-assign-card { max-width: 440px; width: 92%; }
.shift-assign-card .modal-header h2 { font-size: var(--fs-5); font-weight: var(--fw-title); margin: 0; color: var(--text-main); }
.shift-assign-body { display: flex; flex-direction: column; gap: 16px; padding: 14px 0 6px; }
.shift-assign-who { display: flex; align-items: center; gap: 10px; }
.shift-assign-who .shift-avatar { width: 34px; height: 34px; border-radius: 10px; font-size: 12px; }
.shift-assign-who b { font-weight: var(--fw-title); color: var(--text-main); }
.shift-assign-modes { display: flex; gap: 4px; padding: 3px; border-radius: var(--radius-sm); background: var(--bg-input); }
.shift-assign-modes [role="tab"] {
  flex: 1; height: 24px; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--text-muted);
  font: inherit; font-size: var(--fs-3); font-weight: var(--fw-label); cursor: pointer;
  transition: background 0.15s, color 0.15s;
}
.shift-assign-modes [role="tab"]:hover { color: var(--text-main); }
.shift-assign-modes [role="tab"].active { background: var(--bg-card); color: var(--text-main); font-weight: var(--fw-title); box-shadow: 0 1px 3px rgba(0,0,0,0.15); }
.shift-assign-modes [role="tab"]:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--accent-primary); }
.shift-assign-pane { display: flex; flex-direction: column; gap: 16px; }
.shift-assign-pane[hidden] { display: none; }
.shift-assign-field { display: flex; flex-direction: column; gap: 8px; }
.shift-assign-label { font-size: var(--fs-2); font-weight: var(--fw-title); color: var(--text-muted); }
.shift-assign-cats { display: flex; flex-wrap: wrap; gap: 6px; }
.shift-assign-cat {
  display: inline-flex; align-items: center; gap: 8px;
  height: var(--h-ctl); padding: 0 12px;
  border: 1px solid var(--border-color); border-radius: var(--radius-sm);
  background: transparent; color: var(--text-main);
  font: inherit; font-size: var(--fs-2); cursor: pointer;
  transition: background 0.15s, border-color 0.15s;
}
.shift-assign-cat b { font-weight: var(--fw-num); color: var(--text-dim); font-variant-numeric: tabular-nums; }
.shift-assign-cat:hover:not(:disabled) { background: var(--bg-card-hover, rgba(255,255,255,0.05)); }
.shift-assign-cat.active { background: var(--accent-primary-soft); border-color: var(--accent-primary-border); color: var(--accent-primary); font-weight: var(--fw-title); }
.shift-assign-cat.active b { color: inherit; }
.shift-assign-cat:disabled { opacity: .45; cursor: not-allowed; }
.shift-assign-cat:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--accent-primary); }
.shift-assign-count { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.shift-assign-count .shift-icon-btn { width: var(--h-ctl); height: var(--h-ctl); font-size: 18px; line-height: 1; }
.shift-assign-count input {
  width: 76px; height: var(--h-ctl); text-align: center;
  border: 1px solid var(--border-color); border-radius: var(--radius-sm);
  background: var(--bg-input); color: var(--text-main);
  font: inherit; font-size: var(--fs-4); font-weight: var(--fw-title); font-variant-numeric: tabular-nums;
}
.shift-assign-count input:focus-visible { outline: none; box-shadow: 0 0 0 2px var(--accent-primary); }
.shift-assign-count input:disabled { opacity: .5; }
.shift-assign-quick { display: flex; gap: 6px; margin-left: 4px; }
.shift-assign-hint { margin: 0; font-size: var(--fs-1); color: var(--text-dim); }
.shift-assign-load-text { font-size: var(--fs-3); line-height: 1.5; color: var(--text-muted); }
.shift-assign-foot { display: flex; justify-content: flex-end; gap: 8px; padding-top: 14px; margin-top: 8px; border-top: 1px solid var(--border-color); }
.shift-assign-foot .btn:disabled { opacity: .5; cursor: not-allowed; }

.shift-block { display: flex; flex-direction: column; gap: 9px; }
.shift-block .shift-section-head h2 { font-size: var(--fs-3); }
.shift-list { display: flex; flex-direction: column; gap: 7px; }
.shift-item { padding: 9px 11px; border: 1px solid var(--border-color); border-radius: var(--radius-sm); background: var(--bg-card); font-size: var(--fs-2); }
.shift-item-head { display: flex; align-items: baseline; gap: 6px; }
.shift-item-text { display: flex; flex-direction: column; gap: 2px; min-width: 0; color: var(--text-muted); font-size: var(--fs-1); }
.shift-item-text b { color: var(--text-main); font-size: var(--fs-2); font-weight: var(--fw-title); }
.shift-item-actions { display: flex; gap: 6px; margin-top: 8px; }
.shift-item-btn, .shift-item-row { display: flex; align-items: center; gap: 9px; width: 100%; text-align: left; font: inherit; cursor: pointer; }
.shift-item-btn .shift-item-text, .shift-item-row .shift-item-text { flex: 1; }
.shift-item-btn { border-left: 3px solid var(--border-strong); }
.shift-item-btn.is-warn { border-left-color: var(--warning-solid); }
.shift-item-btn.is-bad { border-left-color: var(--danger-solid); }
.shift-item-btn .ui-icon { width: 13px; height: 13px; color: var(--text-dim); flex: 0 0 auto; }
.shift-item-row.is-dashed { border-style: dashed; border-color: var(--border-strong); background: none; cursor: default; }
.shift-item-row .num { font-size: var(--fs-2); white-space: nowrap; }
.shift-empty { padding: 0.9rem 0; text-align: center; font-size: var(--fs-2); color: var(--text-dim); }

/* ==========================================================================
   РАЗБОР ЗАЯВОК — главный экран модератора (этап 4, макет Adapt-3-Razbor).
   Вкладка занимает всю область без отступов: полоса счётчиков, ниже сетка
   «очередь | заявка». Помощник — оверлей внутри колонки заявки, не третья
   колонка (на 800 px ей нет места).
   ========================================================================== */
.rz {
  flex-direction: column;
  margin: calc(-1 * var(--content-pad));
  height: calc(100vh - 48px);
  min-width: 0;
}

.rz-stats {
  display: grid;
  grid-template-columns: repeat(6, minmax(0, 1fr));
  gap: 1px;
  background: var(--border-color);
  border-bottom: 1px solid var(--border-color);
  flex: 0 0 auto;
}

.rz-stat { padding: 12px 16px; background: var(--bg-card); display: flex; flex-direction: column; gap: 4px; min-width: 0; }
.rz-stat-label, .rz-attr-label { font-size: 11px; font-weight: var(--fw-title); letter-spacing: .06em; text-transform: uppercase; color: var(--text-dim); }
.rz-stat-value { font-size: var(--fs-7); font-weight: var(--fw-title); line-height: 1; letter-spacing: -.02em; font-variant-numeric: tabular-nums; }
.rz-stat-value.is-acc { color: var(--accent-primary); }
.rz-stat-value.is-warn { color: var(--accent-amber); }
.rz-stat-value.is-ok { color: var(--accent-green); }
.rz-stat-value.is-bad { color: var(--accent-rose); }
.rz-stat-value.is-info { color: var(--accent-info); }
.rz-stat-value.is-video { color: var(--video-solid); }
button.rz-stat { border: none; font: inherit; color: inherit; text-align: left; cursor: pointer; }
button.rz-stat:hover { background: var(--bg-card-hover); }
.rz-stat-of { font-size: var(--fs-2); color: var(--text-dim); margin-left: 6px; font-weight: var(--fw-label); }
.rz-stat-sub { font-size: 11px; color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.rz-main {
  display: grid;
  grid-template-columns: minmax(320px, 26%) minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  flex: 1;
  min-height: 0;
}

.rz-queue-col { border-right: 1px solid var(--border-color); display: flex; flex-direction: column; min-width: 0; min-height: 0; }
/* Срезы над очередью: главный выбор — сегмент «Мои | Видео | Согласование»
   (активный залит акцентом), под ним тихий ряд вкладок-подчёркиваний для
   редких срезов («Общий пул», «Закрытые»). */
.rz-queue-head { padding: 10px 12px 0; border-bottom: 1px solid var(--border-color); display: flex; flex-direction: column; gap: 6px; }
.rz-seg { display: flex; gap: 2px; padding: 2px; background: var(--bg-input); border-radius: var(--radius-sm); }
.rz-seg-btn {
  flex: 1 1 auto; height: 32px; padding: 0 6px; border: none; border-radius: 3px;
  background: transparent; color: var(--text-muted);
  font: inherit; font-size: var(--fs-3); font-weight: var(--fw-label);
  display: inline-flex; align-items: center; justify-content: center; gap: 4px;
  cursor: pointer; transition: var(--transition); white-space: nowrap;
}
.rz-seg-btn .rz-count { font-size: var(--fs-1); }
.rz-seg-btn:hover { color: var(--text-main); }
.rz-seg-btn.active { background: var(--accent-primary); color: var(--accent-on-primary); font-weight: var(--fw-title); }
.rz-seg-btn.active .rz-count { background: color-mix(in srgb, var(--accent-on-primary) 22%, transparent); color: inherit; }
.rz-subtabs { display: flex; }
.rz-subtab {
  flex: 1 1 auto; min-width: 0; height: 30px; border: none; border-bottom: 2px solid transparent;
  background: none; color: var(--text-dim);
  font: inherit; font-size: var(--fs-1);
  display: inline-flex; align-items: center; justify-content: center; gap: 5px;
  cursor: pointer; white-space: nowrap;
}
.rz-subtab:hover { color: var(--text-main); }
.rz-subtab.active { color: var(--text-main); border-bottom-color: var(--accent-primary); font-weight: var(--fw-title); }
.rz-subtab.active .rz-count { background: var(--accent-primary-soft); color: var(--accent-primary); }
.rz-seg-btn:focus-visible, .rz-subtab:focus-visible { outline: 2px solid var(--accent-primary); outline-offset: 2px; }
/* Вкладки помощника (#rzAsideTabs) — плитки с рамкой, как трекер статусов в
   реестре (.ticket-stat-tracker .ticket-status-chip): выбранная обводится контуром,
   а не заливается. */
.rz-scope { display: flex; gap: 3px; margin: 0; }
.rz-scope .ticket-scope-btn {
  flex: 1; min-width: 0;
  height: var(--h-ctl-sm); padding: 0 var(--s-4);
  border: 1px solid var(--border-color); border-radius: var(--radius-sm);
  background: var(--bg-card); color: var(--text-muted);
  font-size: var(--fs-1); font-weight: var(--fw-label); white-space: nowrap;
  cursor: pointer; transition: var(--transition);
}
.rz-scope .ticket-scope-btn:hover { border-color: var(--border-strong); color: var(--text-main); }
.rz-scope .ticket-scope-btn.active {
  outline: 2px solid var(--accent-primary); outline-offset: -1px;
  border-color: transparent; color: var(--text-main); font-weight: var(--fw-title);
}
.rz-scope .ticket-scope-btn:focus-visible { outline: 2px solid var(--accent-primary); outline-offset: 2px; }
.rz-count { font-size: 10px; padding: 0 5px; border-radius: 999px; background: var(--bg-input); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.ticket-scope-btn.active .rz-count { background: var(--accent-primary-soft); color: var(--accent-primary); }
.rz-queue { flex: 1; overflow-y: auto; display: flex; flex-direction: column; }
.rz-queue-foot { padding: 8px 12px; font-size: 11px; color: var(--text-dim); border-top: 1px solid var(--border-color); }

.rz-row {
  display: grid;
  grid-template-columns: 3px 1fr auto;
  gap: 0 10px;
  align-items: center;
  padding: 0;
  border: none;
  border-bottom: 1px solid var(--border-color);
  background: none;
  text-align: left;
  font-family: inherit;
  cursor: pointer;
  color: var(--text-main);
}
.rz-row:hover { background: var(--bg-card-hover); }
.rz-row[aria-pressed="true"] { background: var(--accent-primary-soft); box-shadow: inset 3px 0 0 var(--accent-primary); }
.rz-stripe { align-self: stretch; background: var(--border-strong); }
.rz-stripe.is-acc { background: var(--accent-primary-fill); }
.rz-stripe.is-warn { background: var(--accent-amber); }
.rz-stripe.is-ok { background: var(--accent-green); }
.rz-stripe.is-bad { background: var(--accent-rose); }
.rz-row-mid { display: flex; flex-direction: column; gap: 3px; padding: 11px 0; min-width: 0; }
.rz-row-l1 { display: flex; align-items: center; gap: 7px; flex-wrap: wrap; }
.rz-shk { font-size: 14px; font-weight: var(--fw-title); font-variant-numeric: tabular-nums; cursor: text; }
.rz-shk.is-dim { color: var(--text-dim); }
.rz-flame { width: 12px; height: 12px; color: var(--accent-rose); }
.rz-repeat {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 14px;
  height: 14px;
  color: var(--accent-info);
  flex-shrink: 0;
  vertical-align: middle;
}
.rz-repeat .ui-icon { width: 12px; height: 12px; vertical-align: 0; }
.rz-chip { font-size: 10px; font-weight: var(--fw-title); letter-spacing: .04em; text-transform: uppercase; padding: 1px 5px; border-radius: 3px; background: var(--bg-input); color: var(--text-muted); }
.rz-chip.is-ok { background: var(--success-soft); color: var(--accent-green); }
.rz-chip.is-bad { background: var(--danger-soft); color: var(--accent-rose); }
.rz-row-sub { font-size: var(--fs-1); color: var(--text-muted); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.rz-row-right { display: flex; flex-direction: column; align-items: flex-end; gap: 3px; padding: 11px 12px 11px 0; }
.rz-row-time { font-size: var(--fs-1); font-weight: var(--fw-title); font-variant-numeric: tabular-nums; color: var(--text-muted); }
.rz-row-time.is-warn { color: var(--accent-amber); }
.rz-row-time.is-ok { color: var(--accent-green); }
.rz-row-time.is-acc { color: var(--accent-primary); }
.rz-row-status { font-size: 10px; color: var(--text-dim); }
.rz-empty { padding: 24px 16px; font-size: var(--fs-2); color: var(--text-dim); text-align: center; }

.rz-work-col { min-width: 0; min-height: 0; display: flex; flex-direction: column; }
.rz-card { padding: 14px 20px; border-bottom: 1px solid var(--border-color); background: var(--bg-card); display: flex; flex-direction: column; gap: 8px; }
.rz-card-head { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; }
.rz-card-shk { font-size: 24px; font-weight: var(--fw-title); letter-spacing: -.01em; font-variant-numeric: tabular-nums; }
.rz-badge { display: inline-flex; align-items: center; gap: 5px; font-size: 11px; font-weight: var(--fw-title); padding: 3px 8px; border-radius: var(--radius-sm); background: var(--bg-input); border: 1px solid var(--line-ctl); color: var(--text-muted); }
.rz-badge.is-warn { background: var(--warning-soft); color: var(--accent-amber); border-color: transparent; }
.rz-badge.is-ok { background: var(--success-soft); color: var(--accent-green); border-color: transparent; }
.rz-badge.is-acc { background: var(--accent-primary-soft); color: var(--accent-primary); border-color: transparent; }
.rz-badge.is-bad { background: var(--danger-soft); color: var(--accent-rose); border-color: transparent; }
.rz-badge.is-info { background: var(--info-soft); color: var(--accent-info); border-color: var(--info-border); }
.rz-badge .ui-icon { width: 12px; height: 12px; }
.rz-helper-btn { margin-left: auto; }
.rz-helper-btn.active {
  border-color: var(--accent-primary-fill);
  background: var(--accent-primary-soft);
  color: var(--accent-primary);
  font-weight: var(--fw-title);
}
.rz-helper-btn.active:hover {
  border-color: var(--accent-primary);
  background: var(--accent-primary-soft);
}
/* «В работу» — на месте бейджа статуса, размером под соседние бейджи. */
.rz-card-head .rz-take { height: var(--h-ctl-sm); padding: 0 12px; font-size: var(--fs-1); }
#rzShkCopy { min-width: 140px; justify-content: center; }
.rz-card-meta { font-size: var(--fs-1); color: var(--text-muted); }
/* Дата создания в шапке: пустая обязательна — подсвечиваем, пока не проставлена. */
.rz-created { height: 24px; padding: 0 6px; border: 1px solid var(--line-ctl); border-radius: var(--radius-sm); background: var(--bg-input); color: var(--text-main); font: inherit; font-size: var(--fs-1); }
.rz-created::-webkit-calendar-picker-indicator { pointer-events: none; } /* попап — наш (dashDate.js), родной не открываем */
.rz-created:invalid { border-color: var(--danger-solid); background: var(--danger-soft); }
.rz-pill { font-size: 11px; padding: 1px 6px; border-radius: 999px; background: var(--accent-primary-soft); color: var(--accent-primary); }
.rz-attr { display: inline-flex; flex-direction: column; gap: 2px; padding: 8px 12px; border: 1px solid var(--border-color); border-radius: var(--radius-sm); background: var(--bg-page); font-size: var(--fs-2); align-self: flex-start; }

.rz-dup-wrap { display: flex; flex-direction: column; gap: 6px; }
.rz-dup-card {
  padding: 8px 12px;
  border-radius: var(--radius-sm);
  background: var(--info-wash);
  border: 1px solid var(--info-border);
  display: flex;
  flex-direction: column;
  gap: 6px;
  font-size: var(--fs-2);
}
.rz-dup-head {
  display: flex;
  align-items: center;
  gap: 6px;
  font-weight: var(--fw-title);
  color: var(--accent-info);
  font-size: 11px;
  letter-spacing: .02em;
}
.rz-dup-head .ui-icon { width: 12px; height: 12px; }
.rz-dup-list { display: flex; flex-direction: column; gap: 6px; }
.rz-dup-item { display: flex; flex-direction: column; gap: 4px; padding: 2px 0; }
.rz-dup-item:not(:last-child) { border-bottom: 1px dashed var(--border-color); padding-bottom: 6px; }
.rz-dup-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rz-dup-mod { display: inline-flex; align-items: center; gap: 6px; }
.rz-dup-id-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 4px;
  padding: 2px 7px;
  min-width: 80px;
  border: 1px solid var(--line-ctl);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--text-main);
  font-size: 11px;
  cursor: pointer;
  font-family: inherit;
  transition: border-color var(--t-fast), background var(--t-fast), color var(--t-fast);
}
.rz-dup-id-btn:hover { border-color: var(--accent-info); background: var(--info-soft); }
.rz-dup-id-btn.is-copied { border-color: var(--accent-green); background: var(--success-soft); color: var(--accent-green); }
.rz-dup-id-btn.is-copied .ui-icon { color: var(--accent-green); }
.rz-dup-id-btn .ui-icon { width: 11px; height: 11px; color: var(--accent-info); }
.rz-dup-id-btn .rz-mono { font-family: var(--font-mono, monospace); font-variant-numeric: tabular-nums; font-weight: 600; }
.rz-dup-no-id { font-size: 11px; color: var(--text-dim); }
.rz-dup-name { color: var(--text-main); font-weight: var(--fw-title); font-size: 12px; }
.rz-dup-date { font-size: var(--fs-1); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.rz-dup-comment, .rz-dup-reason {
  font-size: var(--fs-1);
  color: var(--text-muted);
  background: var(--bg-card);
  padding: 3px 8px;
  border-radius: var(--radius-sm);
  border: 1px solid var(--border-color);
  display: inline-flex;
  gap: 4px;
}
.rz-dup-label { font-weight: var(--fw-title); color: var(--text-dim); }

.rz-work-wrap { position: relative; flex: 1; min-height: 0; display: flex; flex-direction: column; overflow: hidden; }
.rz-work { flex: 1; overflow-y: auto; padding: 16px 20px; display: flex; flex-direction: column; gap: 10px; }
.rz-tpl-row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.rz-tpl-chips { display: inline-flex; align-items: center; gap: 6px; flex-wrap: wrap; flex: 1; }
.rz-tpl { height: 26px; padding: 0 10px; border: 1px solid var(--line-ctl); border-radius: var(--radius-sm); background: var(--bg-card); color: var(--text-muted); font-size: 11px; font-weight: var(--fw-label); cursor: pointer; font-family: inherit; }
.rz-tpl.active { border-color: var(--accent-primary-fill); background: var(--accent-primary-soft); color: var(--accent-primary); font-weight: var(--fw-title); }
.rz-draft-state { margin-left: auto; font-size: 11px; color: var(--accent-amber); }
.rz-builder { display: flex; gap: 6px; flex-wrap: wrap; padding: 6px 10px; border: 1px dashed var(--border-color); border-radius: var(--radius-sm); }
.rz-text {
  flex: 1;
  min-height: 200px;
  width: 100%;
  padding: 12px 14px;
  border: 1px solid var(--line-ctl);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--text-main);
  font-family: "SF Mono", Consolas, monospace;
  font-size: var(--fs-2);
  line-height: 1.55;
  resize: none;
  white-space: pre-wrap;
}
.rz-details { border: 1px solid var(--border-color); border-radius: var(--radius-sm); background: var(--bg-card); }
.rz-details summary { padding: 7px 12px; font-size: 11px; font-weight: var(--fw-title); color: var(--text-muted); cursor: pointer; }
.rz-details-body { padding: 4px 12px 10px 12px; font-size: var(--fs-1); line-height: 1.55; white-space: pre-wrap; border-left: 3px solid var(--accent-primary-fill); margin: 0 12px 10px; }
.rz-mono { font-family: "SF Mono", Consolas, monospace; font-size: var(--fs-1); }

.rz-select {
  height: var(--h-ctl);
  padding: 0 10px;
  border: 1px solid var(--line-ctl);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
  color: var(--text-main);
  font-size: var(--fs-2);
  font-family: inherit;
  min-width: 0;
}
.rz-select:disabled { opacity: .6; }
.rz-comment { flex: 1; min-width: 140px; }
.rz-decision { border-top: 1px solid var(--border-color); background: var(--bg-card); padding: 12px 20px; display: flex; flex-direction: column; gap: 10px; }
.rz-dec-row { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.rz-approve, .rz-reject, .rz-pause, .rz-reason {
  flex: 1;
  min-width: 140px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  height: var(--h-ctl-lg);
  border-radius: var(--radius-sm);
  font-size: 14px;
  font-weight: var(--fw-title);
  font-family: inherit;
  cursor: pointer;
}
.rz-approve { border: 1px solid var(--accent-green); background: var(--accent-green); color: var(--accent-on-primary); }
.rz-reject { border: 1px solid var(--accent-rose); background: var(--danger-soft); color: var(--accent-rose); }
/* Паузы «Запрос видео» / «Согласование»: вторичные, .is-on — пауза стоит,
   клик её снимает. */
.rz-pause { border: 1px solid var(--border-color); background: var(--bg-input); color: var(--text-main); }
.rz-pause.is-on { border-color: var(--info-border); background: var(--info-soft); color: var(--accent-info); }
.rz-pause.is-on[data-pause="video"] { border-color: var(--video-solid); background: var(--video-soft); color: var(--video-solid); }
/* Причины-кнопки после клика «Одобрить»/«Отказать»: рамка в цвет решения. */
.rz-reason { flex: 0 1 auto; min-width: 0; border: 1px solid var(--border-color); background: var(--bg-input); color: var(--text-main); }
.rz-reason[data-decision="Одобрили"]:hover, .rz-reason[data-decision="Одобрили"]:focus-visible { border-color: var(--accent-green); background: var(--success-soft); color: var(--accent-green); }
.rz-reason[data-decision="Отказ"]:hover, .rz-reason[data-decision="Отказ"]:focus-visible { border-color: var(--accent-rose); background: var(--danger-soft); color: var(--accent-rose); }
.rz-dec-note { font-size: 12px; color: var(--text-dim); }
/* Второй, тихий ряд: редкие исходы (Закрыта ранее / У другого / Отдать в
   пул) и «Вернуть в работу» у закрытой — не спорят с основными кнопками. */
.rz-more {
  display: inline-flex; align-items: center; gap: 6px;
  height: var(--h-ctl); padding: 0 12px; border-radius: var(--radius-sm);
  border: 1px solid transparent; background: transparent; color: var(--text-muted);
  font-size: var(--fs-2); font-family: inherit; cursor: pointer;
}
.rz-more:hover, .rz-more:focus-visible { border-color: var(--border-color); background: var(--bg-input); color: var(--text-main); }
.rz-dec-more { gap: 4px; }

.rz-aside {
  position: absolute;
  top: 0; right: 0; bottom: 0;
  width: 320px;
  max-width: 70%;
  display: flex;
  flex-direction: column;
  background: var(--bg-card);
  border-left: 1px solid var(--line-ctl);
  box-shadow: var(--shadow-md);
  z-index: 5;
}
.rz-aside-head { display: flex; align-items: center; gap: 6px; padding: 8px 10px; border-bottom: 1px solid var(--border-color); }
.rz-aside-head .icon-btn { margin-left: auto; width: 26px; height: 26px; }
.rz-aside-body { flex: 1; min-height: 0; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 8px; }
.rz-lbl { display: flex; flex-direction: column; gap: 3px; font-size: 10px; font-weight: var(--fw-title); letter-spacing: .06em; text-transform: uppercase; color: var(--text-dim); }
.rz-lbl .rz-select { height: 30px; font-size: 12px; text-transform: none; letter-spacing: 0; font-weight: var(--fw-label); }
.rz-wo-text { min-height: 96px; padding: 8px 10px; border: 1px solid var(--line-ctl); border-radius: var(--radius-sm); background: var(--bg-page); color: var(--text-main); font-family: "SF Mono", Consolas, monospace; font-size: 12px; resize: vertical; }
.rz-note { font-size: 11px; padding: 6px 9px; border-left: 3px solid var(--accent-primary-fill); background: var(--bg-page); border-radius: 0 6px 6px 0; }
.rz-list { display: flex; flex-direction: column; gap: 6px; }
.rz-list-row { display: flex; align-items: center; gap: 8px; padding: 8px 10px; border: 1px solid var(--border-color); border-radius: var(--radius-sm); font-size: 12px; }
.rz-list-title { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; }

/* ==========================================================================
   ВАРИАНТ C — «РАБОЧИЙ РЕЙЛ + ПАНЕЛЬ». ПЕРЕНОС МАКЕТА В КОД
   ==========================================================================

   Блок дописывается В КОНЕЦ public/styles.css. Он стоит последним намеренно:
   правила выше перебиваются порядком каскада, а не !important и не раздутой
   специфичностью — значит вариант C снимается удалением одного блока, без
   разбора, что он там переопределил.

   !important стоит ровно в трёх местах, и каждое подписано: там, где значение
   приходит инлайновым style из разметки (шапка таблицы) или из строкового
   шаблона в public/js (пилюля статуса, кнопки .ticket-actions). Инлайновый
   стиль каскадом не перебивается.

   Новых токенов нет. Светлая и тёмная темы получаются сами: используются те
   же роли (--bg-header, --accent-primary-soft, --border-color …), что и во
   всём файле, поэтому [data-theme="dark"] работает без второй копии правил.
   ========================================================================== */

/* --------------------------------------------------------------------------
   1. РЕЙЛ РАЗДЕЛОВ — 84px, подпись под иконкой
   Ответ на «рейл только с иконками, непонятно куда жать»: подписи всегда
   видны, títle-онли пунктов не остаётся. Подписи в разметке короткие
   («Заявки», «Согл-я»), полное имя раздела — в title.
   -------------------------------------------------------------------------- */
.sidebar {
  width: 84px;
  flex: 0 0 84px;
  align-items: stretch;
  gap: 2px;
  padding: 10px 6px;
}

#navMenuHost {
  align-items: stretch;
  gap: 2px;
}

/* Логотип перестаёт быть заливной плашкой: на рейле с подписями он читается
   как шестой пункт меню. Остаётся знак акцентным цветом. */
.sidebar .brand {
  --brand-cut: var(--bg-header);
  width: 100%;
  height: 38px;
  margin-bottom: 8px;
  border-radius: 0;
  background: none;
  color: var(--accent-primary);
}

.sidebar .brand .ui-icon { width: 20px; height: 20px; }

.nav-menu {
  align-items: stretch;
  gap: 2px;
}

.nav-item {
  width: auto;
  height: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  padding: 8px 2px;
  border: none;
  border-radius: var(--radius-sm);
  color: var(--text-muted);
}

/* Подпись возвращается в поток: правило выше в файле уводит её в
   clip-rect(0 0 0 0) для скринридера. */
.nav-item > span:not(.nav-icon):not(.nav-badge) {
  position: static;
  width: auto;
  height: auto;
  overflow: visible;
  clip: auto;
  font-size: 11.5px;
  line-height: 1.15;
  text-align: center;
  white-space: nowrap;
}

.nav-item:hover {
  background: var(--bg-input);
  color: var(--text-main);
}

/* Активный раздел — подложка акцента и планка слева, как у выбранной строки
   фильтра. Рамка (прежнее .nav-item.active) на 84px читалась как кнопка. */
.nav-item.active {
  border-color: transparent;
  background: var(--accent-primary-soft);
  color: var(--accent-primary);
  box-shadow: inset 2px 0 0 var(--accent-primary-border);
}

.nav-item.active > span:not(.nav-icon):not(.nav-badge) { font-weight: var(--fw-title); }

.nav-icon { width: 18px; height: 18px; }

.nav-item .nav-badge {
  top: 4px;
  right: 12px;
  min-width: 16px;
  height: 16px;
  border-radius: 8px;
  font-size: 10px;
  line-height: 16px;
}

/* Флайаут «Моя группа» — единственный второй уровень: внутри рейла подпунктов
   нет. Открытие по :hover/:focus-within уже описано выше в файле. */
.nav-submenu {
  left: 78px;
  top: -6px;
  width: 230px;
  padding: 8px;
}

.nav-submenu::before { left: -8px; width: 8px; }

/* Заголовок флайаута — та же метка группы, что в панели фильтров. */
.nav-submenu-title {
  padding: 5px 9px 8px;
  font-size: 11px;
  font-weight: var(--fw-title);
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.nav-subitem-count {
  margin-left: auto;
  font-size: var(--fs-1);
  font-weight: var(--fw-num);
  font-variant-numeric: tabular-nums;
  color: var(--accent-amber);
}

/* Esc закрывает флайаут: снять :hover из JS нельзя, поэтому JS ставит на
   раздел класс, который гасит правило открытия (см. js-patches.md). */
.nav-item-accordion.is-muted:hover .nav-submenu,
.nav-item-accordion.is-muted:focus-within .nav-submenu { display: none; }

/* --------------------------------------------------------------------------
   2. ПОДВАЛ РЕЙЛА — уведомления, тема, пользователь
   Переехали из шапки: шапка дублировала сайдбар, а рядом с аватаром им и
   место — это «про меня», а не «про раздел».
   -------------------------------------------------------------------------- */
.rail-foot {
  margin-top: auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  padding-top: 10px;
  border-top: 1px solid var(--border-color);
}

.rail-foot .btn,
.rail-foot .rail-user {
  width: 34px;
  height: 34px;
  min-height: 0;
  padding: 0;
  border-radius: var(--radius-sm);
}

.rail-foot .btn {
  background: none;
  border-color: var(--border-color);
  color: var(--text-muted);
}

.rail-foot .btn:hover {
  background: var(--bg-input);
  border-color: var(--border-strong);
  color: var(--text-main);
}

.rail-user {
  display: grid;
  place-items: center;
  border: 1px solid var(--border-strong);
  background: var(--bg-input);
  color: var(--text-muted);
  font-size: var(--fs-1);
  font-weight: var(--fw-num);
  cursor: pointer;
}

/* Панель уведомлений раскрывалась вниз-влево от колокола в шапке. На рейле
   тот же расчёт уводит её за левый край экрана и вверх за пределы окна:
   открываем вправо от кнопки и прижимаем к её низу. */
.sidebar #notifPanel {
  top: auto;
  right: auto;
  bottom: 0;
  left: calc(100% + 8px);
}

/* --------------------------------------------------------------------------
   3. ШАПКА — 48px, хлебные крошки вместо кикера с заголовком
   Ответ на «непонятно, где ты находишься»: путь, живой индикатор и мета
   смены; справа — только ежедневные действия текущего раздела.
   -------------------------------------------------------------------------- */
.top-bar {
  min-height: 48px;
  padding: 0 18px;
  gap: 12px;
}

/* Дата уехала в мету крошек, а «Redash Analytics» на каждом экране шапке не
   нужна — раздел называет себя сам. */
.page-kicker { display: none; }

.top-crumbs {
  display: flex;
  align-items: center;
  gap: 7px;
  min-width: 0;
  font-size: var(--fs-2);
  color: var(--text-dim);
}

.top-crumbs .ui-icon {
  width: 12px;
  height: 12px;
  flex: 0 0 auto;
  color: var(--text-dim);
}

.top-crumbs .header-title {
  font-size: var(--fs-4);
  font-weight: var(--fw-title);
  letter-spacing: 0;
  color: var(--text-main);
  white-space: nowrap;
}

.top-crumb {
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.top-meta {
  font-size: var(--fs-2);
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.top-controls { gap: 8px; }

/* Слот действий раздела: switchTab() переносит сюда панель активной вкладки
   (см. js-patches.md). Пусто — не занимает места. */
#topBarActions {
  display: flex;
  align-items: center;
  gap: 8px;
}

#topBarActions:empty { display: none; }


#topBarActions .ticket-actions,
#topBarActions .shift-head-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  flex-wrap: nowrap;
}

/* Редкие действия — за иконкой настроек: «Причины решения» и
   «Автоназначение» это не ежедневная работа. */
#topBarActions .btn.icon-btn {
  width: 30px;
  padding: 0;
}

/* --------------------------------------------------------------------------
   4. ПАНЕЛЬ ФИЛЬТРОВ — 264px, единственная панель экрана
   Порядок групп по макету: поиск · статус · период · категория · решение ·
   команда. Задан order, а не перестановкой разметки: id и data-group нужны
   обработчикам в js/tickets.js там, где они есть.
   -------------------------------------------------------------------------- */
.ticket-filter-col { --rail-w: 264px; }

.ticket-filter-rail {
  gap: 0;
  padding: 0;
}

.rail-head {
  order: 0;
  padding: 11px 14px;
  border-bottom: 1px solid var(--border-color);
  gap: 8px;
  flex-wrap: nowrap;
  min-width: 0;
}

.rail-head::before {
  /* Иконка раздела «Фильтры» — маска не нужна, хватает подписи: символ
     фильтра берётся из спрайта в разметке (см. index-fragments.html). */
  content: none;
}

.rail-count {
  font-size: var(--fs-1);
  font-weight: var(--fw-num);
  font-variant-numeric: tabular-nums;
  color: var(--accent-primary);
}

.rail-group {
  padding: 10px 14px;
  border-top: none;
  border-bottom: 1px solid var(--border-color);
  gap: 7px;
}

.rail-group[data-group="search"]   { order: 1; padding: 12px 14px; }
.rail-group[data-group="status"]   { order: 2; padding: 10px 0; }
.rail-group[data-group="period"]   { order: 3; }
.rail-group[data-group="category"] { order: 4; }
.rail-group[data-group="decision"] { order: 5; }
.rail-group[data-group="team"]     { order: 6; }

.rail-group[data-group="status"] .rail-group-head { padding: 0 14px 8px; }

.rail-label {
  font-size: 11px;
  font-weight: var(--fw-title);
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.rail-group[data-group="search"] .rail-label { display: none; }

/* Статус — он же трекер смены: строка на значение, без рамок и радиусов.
   Семь строк по 28px влезают в невысокое окно целиком. */
.ticket-stat-tracker { gap: 0; }

.ticket-stat-tracker .ticket-status-chip {
  min-height: 0;
  gap: 9px;
  padding: 6px 14px;
  border: none;
  border-radius: 0;
  background: none;
  font-size: var(--fs-3);
}

.ticket-stat-tracker .ticket-status-chip:hover { background: var(--bg-input); }

.ticket-stat-tracker .ticket-status-chip.active,
.ticket-stat-tracker .ticket-status-chip.active[data-status] {
  border: none;
  background: var(--accent-primary-fill);
  color: var(--accent-on-primary);
  box-shadow: none;
  font-weight: var(--fw-title);
}

.ticket-stat-tracker .ticket-status-chip.active .ticket-stat-count,
.ticket-stat-tracker .ticket-status-chip.active .ticket-stat-icon { color: var(--accent-on-primary); }

.ticket-stat-tracker .ticket-status-chip .ticket-stat-icon {
  width: 14px;
  height: 14px;
  background: none;
  border-radius: 0;
}

.ticket-stat-tracker .ticket-stat-count {
  font-size: var(--fs-3);
  font-weight: var(--fw-num);
  font-variant-numeric: tabular-nums;
}

/* Чипы периода и решения — 26px, радиус 4. Категории остаются строками во всю
   ширину: названия из TICKET_CATEGORIES по длине непредсказуемы. */
.ticket-filter-rail .ticket-chip-group button {
  height: 26px;
  min-height: 26px;
  padding: 0 9px;
  border-radius: var(--radius-sm);
  font-size: var(--fs-1);
}

.ticket-filter-rail .rail-group[data-group="period"] .ticket-chip-group {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 3px;
  width: 100%;
}

.ticket-filter-rail .rail-group[data-group="period"] .ticket-chip-group button {
  width: 100%;
  padding: 0 2px;
  text-align: center;
  justify-content: center;
  white-space: nowrap;
}

.ticket-filter-rail .ticket-chip-group.is-list button {
  height: 28px;
  min-height: 28px;
  width: 100%;
  justify-content: flex-start;
  border: none;
}

/* Иконки решения нужны: они и есть разница между «Одобрено» и «Отказ» на
   первом взгляде. Правило выше в файле гасит иконки во всей панели. */
.ticket-filter-rail .ticket-decision-chip .ui-icon {
  display: inline-flex;
  width: 12px;
  height: 12px;
}

.ticket-filter-rail .ticket-decision-chip[data-decision="Одобрили"] .ui-icon { color: var(--success-solid); }
.ticket-filter-rail .ticket-decision-chip[data-decision="Отказ"] .ui-icon { color: var(--danger-solid); }
.ticket-filter-rail .ticket-decision-chip[data-decision="Запрос видео"] .ui-icon { color: var(--video-solid); }
.ticket-filter-rail .ticket-decision-chip[data-decision="Согласование"] .ui-icon { color: var(--accent-info); }

/* --------------------------------------------------------------------------
   5. РАБОЧАЯ ОБЛАСТЬ РЕЕСТРА
   Блок кнопок действий и «Пульс смены» из реестра уходят: действия — в шапку,
   счётчики — в трекер статусов панели.
   -------------------------------------------------------------------------- */
.ticket-toolbar { display: none; }

/* «Найдено» и период живут в шапке панели фильтров — строка над таблицей
   повторяла их и при прокрутке всё равно не была видна. */
.ticket-summary-bar { display: none; }

.ticket-main {
  gap: 0;
  padding: 0;
}

/* #tab-tickets в селекторе — чтобы перебить рамку из «#tab-tickets .table-card»
   выше: она рисовала двойную линию у панели фильтров и под шапкой. */
#tab-tickets #ticketsTableCard {
  padding: 0 !important;
  border: none;
  border-radius: 0;
  background: none;
}

/* Полоса выделения — замена отдельного блока кнопок: появляется, когда
   выбрана хотя бы одна строка, и исчезает вместе с выделением. */
.ticket-bulk-bar {
  align-items: center;
  gap: 9px;
  flex-wrap: wrap;
  margin: 0;
  padding: 8px 18px;
  border: none;
  border-bottom: 1px solid var(--border-strong);
  border-radius: 0;
  background: var(--accent-primary-soft);
}

.ticket-bulk-bar .bulk-title {
  font-size: var(--fs-2);
  font-weight: var(--fw-title);
  color: var(--accent-primary);
}

.ticket-bulk-bar .bulk-sep {
  width: 1px;
  height: 18px;
  background: var(--border-strong);
}

.ticket-bulk-bar select,
.ticket-bulk-bar .btn {
  height: 26px;
  min-height: 26px;
  padding: 0 9px;
  border-radius: var(--radius-sm);
  font-size: var(--fs-1);
}

.ticket-bulk-bar .btn:last-child { margin-left: auto; }

/* Таблица: плотность макета. padding в шапке приходит инлайновым style из
   разметки, в ячейках — из шаблона строки в js/tickets.js; оба перебиваются
   только !important. */
.tickets-table thead th {
  padding: 8px 9px !important;
  font-size: 11px;
  font-weight: var(--fw-title);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.tickets-table tbody td {
  padding: 0 9px !important;
  height: 38px;
  font-size: var(--fs-3);
}

.tickets-table thead tr { border-bottom: 1px solid var(--border-strong); }
.tickets-table tbody tr { border-bottom: 1px solid var(--border-color); }

/* Статус остаётся живым select — это рабочий орган, а не бейдж. Пилюля с
   рамкой и заливкой снимается, остаётся точка цветом статуса и текст:
   в строке 38px девять пилюль в ряд давали пёстрый шум.
   Цвет приходит инлайном из statusStyle (js/tickets.js) — точка рисуется
   градиентом на currentColor, поэтому перекрашивается вместе с текстом. */
.tickets-table .status-select,
.tickets-table td > span[style*="border-left"] {
  padding: 0 0 0 14px !important;
  border: none !important;
  border-radius: 0 !important;
  background-color: transparent !important;
  background-image: radial-gradient(circle 3px at 4px 50%, currentColor 99%, transparent 100%) !important;
  background-repeat: no-repeat !important;
  font-size: var(--fs-2) !important;
  font-weight: var(--fw-label) !important;
}

/* Пагинация — одна, внизу, без дубля сверху (верхний блок удаляется из
   разметки, см. index-fragments.html). */
.ticket-pager {
  margin: 0 !important;
  padding: 9px 18px !important;
  border-top: 1px solid var(--border-strong);
  border-bottom: none !important;
  background: var(--bg-header);
}

.ticket-pager .btn {
  height: 26px;
  min-height: 26px;
  padding: 0 9px !important;
  border-radius: var(--radius-sm);
  font-size: var(--fs-1) !important;
}

.ticket-pager .js-ticket-page-info {
  font-variant-numeric: tabular-nums;
  font-size: var(--fs-2) !important;
}

/* --------------------------------------------------------------------------
   6. СМЕНА — планка счётчиков и правая колонка
   Счётчики из #shiftKpi — та же .rz-stats, что у модератора на «Разборе»
   (кнопки вместо div: клик ведёт в реестр с фильтром).
   -------------------------------------------------------------------------- */
#tab-shift.tab-with-rail {
  display: flex;
  align-items: stretch;
  min-width: 0;
  margin: calc(-1 * var(--content-pad));
  min-height: calc(100vh - 48px);
}

.shift-dyn {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 6px 10px;
  margin: 0;
  padding: 2px 0;
  font-size: var(--fs-2);
}

.shift-dyn dt { color: var(--text-muted); }

.shift-dyn dd {
  margin: 0;
  font-weight: var(--fw-num);
  font-variant-numeric: tabular-nums;
  color: var(--text-main);
}

.shift-work {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

/* Шапка экрана «Смена» переехала в общую .top-bar: свои мета и кнопки этому
   разделу больше не нужны. */
.shift-head { display: none; }

.shift-body {
  flex: 1;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(320px, 25vw);
  gap: 1px;
  background: var(--border-color);
}

.shift-body > .shift-main,
.shift-body > .shift-aside {
  padding: 14px 18px;
  background: var(--bg-dark);
  border-left: none;
}

/* --------------------------------------------------------------------------
   7. АДАПТИВ
   Ширина рабочей области — 1fr, средние колонки таблицы — minmax(0, …fr):
   сетка не должна выпадать за контейнер при открытой панели. Ниже ~1200px
   панель фильтров открепляется сама (matchMedia в js/ui.js).
   -------------------------------------------------------------------------- */
@media (max-width: 1280px) {
  .shift-body { grid-template-columns: minmax(0, 1fr); }
  .shift-body > .shift-aside { border-top: 1px solid var(--border-color); }
}

@media (max-width: 1100px) {
  .top-meta { display: none; }
}

/* ==========================================================================
   РАЗДЕЛ «АНАЛИТИКА» — современный дизайн в стиле экрана «Смена»
   ========================================================================== */

.analytics-kpi-card {
  padding: 12px 14px;
  background: var(--bg-card);
  display: flex;
  flex-direction: column;
  justify-content: space-between;
  gap: 4px;
  min-width: 0;
  transition: background 0.15s ease;
}

.analytics-kpi-card:hover {
  background: var(--bg-card-hover);
}

.analytics-kpi-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
}

.analytics-kpi-label {
  font-size: 11px;
  font-weight: var(--fw-title);
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.analytics-kpi-actions {
  display: flex;
  align-items: center;
  gap: 4px;
}

.analytics-kpi-info-btn {
  background: transparent;
  border: none;
  color: var(--text-dim);
  cursor: pointer;
  font-size: var(--fs-3);
  line-height: 1;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: color 0.15s ease;
}

.analytics-kpi-info-btn:hover {
  color: var(--text-main);
}

.analytics-kpi-value {
  font-size: 24px;
  font-weight: var(--fw-title);
  line-height: 1.15;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  color: var(--text-main);
  margin: 2px 0;
}

.analytics-kpi-value.is-acc { color: var(--accent-primary); }
.analytics-kpi-value.is-ok { color: var(--accent-green); }
.analytics-kpi-value.is-warn { color: var(--accent-amber); }
.analytics-kpi-value.is-bad { color: var(--accent-rose); }

.analytics-kpi-sub {
  font-size: 11px;
  color: var(--text-muted);
  line-height: 1.35;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* ==========================================================================
   ЕДИНЫЙ FLUSH-ДИЗАЙН СТРАНИЦ СВ ПО ОБРАЗЦУ ВКЛАДКИ «СМЕНА»
   1. Блоки прилегают друг к другу и краям экрана (margin: calc(-1 * var(--content-pad))).
   2. Никаких округлостей: border-radius: 0 у всех карточек, плашек, панелей и секций.
   3. Строгие 1px разделители границ вместо плавающих карточек с тенями и отступами.
   ========================================================================== */

/* Внешняя оболочка вкладок из блоков (все разделы СВ, кроме «Смены» и
   реестра со своим каркасом, и вкладки модератора «Мои …») — 100% ширины и
   высоты без отступов .content-area. Класс стоит на .tab-content в index.html. */
.tab-flush {
  margin: calc(-1 * var(--content-pad));
  min-height: calc(100vh - 48px);
  display: flex;
  flex-direction: column;
  background: var(--bg-dark);
}

/* Блоки встык — без скруглений. Контролы (кнопки, поля, чипы) сюда не входят:
   у них --radius-sm, как в шапке «Смены». */
.tab-flush .table-card,
.tab-flush .legend-bar,
.tab-flush div[style*="border-radius"],
#ticketsTableCard,
.shift-card,
.shift-banner,
.top-scroll-wrapper {
  border-radius: 0 !important;
}

/* Верхний дублирующий скроллбар не должен иметь отступов */
.top-scroll-wrapper {
  margin: 0 !important;
  line-height: 0 !important;
}

/* ==========================================================================
   ВАРИАНТ C — ОСТАЛЬНЫЕ РАЗДЕЛЫ СВ (23.09)
   «Группа» (Штат, Календарь, Перерывы, Замены, Отпуска), «Согласования»,
   «Аналитика», «Помощник» — на тех же правилах, что реестр и «Смена»:

   1. Название раздела, путь и мета — в общей шапке (.top-bar). Своих h2 с
      поясняющим абзацем у раздела больше нет.
   2. Ежедневные действия — в шапке: узел [data-topbar-actions] переносит
      switchTab(). Поэтому стили органов в шапке заданы через .vc-actions,
      а не через #tab-…: в шапке узел уже вне своей вкладки.
   3. Вторая колонка 264px (.vc-side) — там, где у раздела есть срез или
      очередь: «Согласования», «Аналитика», «Помощник» модератора.
   4. Таблицы — плотность реестра: строка 38px, шапка 11px uppercase,
      статус точкой, действия иконками (.vc-table).

   Прежние блоки «1. ШТАТ … 8. ПОМОЩНИК» flush-дизайна (журнал 55–56) заменены
   этим целиком: они правили старую разметку, которой больше нет.
   ========================================================================== */

/* --- Органы в шапке ------------------------------------------------------ */
.vc-actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-wrap: nowrap;
}

.vc-actions:empty { display: none; }

/* Сегмент: один выбор из двух-трёх. Активный — заливка акцентом, как
   выбранный статус в панели фильтров реестра. */
.vc-seg {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  height: var(--h-ctl);
  padding: 2px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
}

.vc-seg > button {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  height: 24px;
  padding: 0 10px;
  border: none;
  border-radius: 3px;
  background: transparent;
  color: var(--text-muted);
  font: inherit;
  font-size: var(--fs-2);
  font-weight: var(--fw-label);
  white-space: nowrap;
  cursor: pointer;
}

.vc-seg > button:hover { color: var(--text-main); background: var(--bg-card-hover); }

.vc-seg > button.active,
.vc-seg > button.staff-filter-chip.active {
  background: var(--accent-primary-fill) !important;
  color: var(--accent-on-primary) !important;
  font-weight: var(--fw-title);
}

.vc-seg-num {
  font-weight: var(--fw-num);
  font-variant-numeric: tabular-nums;
  opacity: .75;
}

/* Шаговик периода: ‹ месяц/день › · «Сегодня». Один орган вместо четырёх
   отдельных кнопок с разными высотами. */
.vc-step {
  display: inline-flex;
  align-items: center;
  height: var(--h-ctl);
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
}

.vc-step-btn {
  display: inline-grid;
  place-items: center;
  width: 28px;
  height: 28px;
  border: none;
  background: none;
  color: var(--text-muted);
  cursor: pointer;
}

.vc-step-btn:hover { color: var(--text-main); background: var(--bg-card-hover); }
.vc-step-btn .ui-icon { width: 14px; height: 14px; }

.vc-step-label {
  min-width: 70px;
  text-align: center;
  font-size: var(--fs-2);
  font-weight: var(--fw-title);
  font-variant-numeric: tabular-nums;
  color: var(--text-main);
}

.vc-step-date {
  height: 28px;
  width: 132px;
  padding: 0 4px;
  border: none !important;
  background: transparent !important;
  color: var(--text-main);
  font-size: var(--fs-2);
  font-weight: var(--fw-title);
  font-variant-numeric: tabular-nums;
  text-align: center;
  outline: none;
}

.vc-step-today {
  height: 28px;
  padding: 0 10px;
  border: none;
  border-left: 1px solid var(--border-strong);
  background: none;
  color: var(--accent-primary);
  font: inherit;
  font-size: var(--fs-2);
  font-weight: var(--fw-title);
  cursor: pointer;
}

.vc-step-today:hover { background: var(--accent-primary-soft); }

@media (max-width: 1360px) {
  /* Узко: у кнопок в шапке остаются иконки, подпись уходит в title. */
  #topBarActions .vc-actions .btn:has(.ui-icon) { font-size: 0; gap: 0; width: 30px; padding: 0; justify-content: center; }
  #topBarActions .vc-actions .btn:has(.ui-icon) .ui-icon { font-size: var(--fs-2); }
}

/* --- Каркас раздела ------------------------------------------------------ */
.vc-screen {
  display: flex;
  align-items: stretch;
  min-width: 0;
  min-height: calc(100vh - 48px);
}

.vc-body {
  flex: 1;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: var(--bg-dark);
}

.vc-pad { padding: 14px 18px; }
/* Последний блок вкладки тянется до низа экрана белой поверхностью. */
.vc-fill { flex: 1; background: var(--bg-card); }

/* Швы «Смены» для экранов, собранных из блоков (вкладки модератора «Мои …»,
   плитки аналитики): стопка и ряд делят шов 1px — фон контейнера цвета линии
   просвечивает в gap. У детей своих рамок, скруглений и внешних полей нет. */
.seam-stack { display: flex; flex-direction: column; gap: 1px; background: var(--border-color); }
.seam-stack > * { background: var(--bg-card); }
/* Стопка — вся вкладка: последний блок тянется белым до низа экрана. */
.tab-flush > .seam-stack { flex: 1; }
.tab-flush > .seam-stack > :last-child { flex: 1; }
.seam-row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(160px, 1fr));
  gap: 1px;
  background: var(--border-color);
  border: 1px solid var(--border-color);
}
.seam-stack > .seam-row { border: none; }

/* Заголовок блока — рецепт .shift-section-head. */
.seam-head { display: flex; align-items: center; gap: 8px; margin: 0 0 10px; font-size: var(--fs-4); font-weight: var(--fw-title); color: var(--text-main); }
.seam-head .ui-icon { width: 15px; height: 15px; color: var(--text-muted); }
.seam-head-meta { font-size: var(--fs-2); font-weight: var(--fw-text); color: var(--text-dim); }
.seam-head > .seam-head-end { margin-left: auto; }

/* Список строк во всю ширину блока — вместо стопки карточек с просветами. */
.seam-list > * { display: flex; align-items: flex-start; justify-content: space-between; gap: 12px; padding: 12px 18px; border-bottom: 1px solid var(--border-color); }
.seam-list > *:last-child { border-bottom: none; }
.seam-list > [data-clickable] { cursor: pointer; }
.seam-list > [data-clickable]:hover { background: var(--bg-card-hover); }
.seam-empty { padding: 14px 18px; font-size: var(--fs-2); color: var(--text-dim); }
/* Список внутри блока .vc-pad встаёт от края до края блока. */
.vc-pad > .seam-list { margin: 0 -18px -14px; border-top: 1px solid var(--border-color); }
.vc-pad > .seam-list > .seam-empty { border-bottom: none; }
.seam-list .seam-row-main { min-width: 0; }
.seam-list .seam-row-title { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; font-weight: var(--fw-title); color: var(--text-main); }
.seam-list .seam-row-sub { margin-top: 3px; font-size: var(--fs-2); color: var(--text-muted); }
.seam-list .seam-row-sub.is-bad { color: var(--accent-rose); }

/* «Моя карточка»: форма в две колонки. */
.my-form { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px 16px; max-width: 720px; }
.my-form .form-group { margin: 0; }
.my-ro { display: flex; align-items: center; height: var(--h-ctl); font-size: var(--fs-3); color: var(--text-main); }
.my-form-foot { display: flex; align-items: center; gap: 10px; margin-top: 14px; font-size: var(--fs-2); }

/* «Мой график»: сетка месяца швами 1px, как у .seam-row. */
.my-cal-head,
.my-cal { display: grid; grid-template-columns: repeat(7, minmax(0, 1fr)); }
.my-cal-head { margin-bottom: 4px; text-align: center; font-size: var(--fs-1); font-weight: var(--fw-label); color: var(--text-dim); text-transform: uppercase; letter-spacing: 0.04em; }
/* Швы — рамками, а не просветом gap: заливки .calendar-day-* полупрозрачные
   и с !important, фон цвета линии просвечивал бы сквозь ячейку. */
.my-cal { background: var(--bg-card); border-top: 1px solid var(--border-color); border-left: 1px solid var(--border-color); }
.my-cal > * { border-right: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color); }
@media (max-width: 560px) {
  .my-form { grid-template-columns: minmax(0, 1fr); }
  .my-form > div:empty { display: none; }
}

/* «Перерывы» модератора (renderMyBreaks): планка — .rz-stats, ниже шкала
   смены и слоты. Шкала — смена во всю ширину, блоки перерывов и отметка
   «сейчас» стоят в процентах от неё. */
.mb-budget { display: block; flex: none; margin-top: 4px; }
.mb-track { position: relative; height: 28px; background: var(--bg-input); border: 1px solid var(--border-color); overflow: hidden; }
/* Часовые риски от начала смены (--mb-hour — доля часа в ширине смены). */
.mb-track::before { content: ""; position: absolute; inset: 0; background: repeating-linear-gradient(to right, transparent 0 calc(var(--mb-hour) - 1px), var(--border-color) calc(var(--mb-hour) - 1px) var(--mb-hour)); }
.mb-block { position: absolute; top: 0; bottom: 0; min-width: 3px; background: var(--accent-primary-soft); border-left: 2px solid var(--accent-primary-fill); border-right: 2px solid var(--accent-primary-fill); }
.mb-now { position: absolute; top: -1px; bottom: -1px; width: 2px; margin-left: -1px; background: var(--warning-solid); }
.mb-scale { display: flex; justify-content: space-between; margin-top: 4px; font-size: var(--fs-1); color: var(--text-dim); font-variant-numeric: tabular-nums; }
.mb-slots { display: flex; flex-direction: column; border: 1px solid var(--border-color); }
.mb-slot { display: grid; grid-template-columns: minmax(80px, 110px) auto auto auto 1fr 26px; align-items: center; gap: 8px; padding: 8px 12px; border-bottom: 1px solid var(--border-color); }
.mb-slot:last-child { border-bottom: none; }
.mb-slot.is-now { background: var(--warning-soft); }
.mb-slot-name { font-size: var(--fs-3); font-weight: var(--fw-label); color: var(--text-main); }
.mb-slot .time-input { width: 104px; }
.mb-dash { color: var(--text-dim); }
.mb-slot-mins { font-size: var(--fs-2); color: var(--text-muted); font-variant-numeric: tabular-nums; }
.mb-msg { margin-top: 10px; font-size: var(--fs-2); color: var(--text-muted); }
.mb-msg.is-bad { color: var(--accent-rose); }
.mb-empty { display: flex; align-items: center; gap: 8px; }
@media (max-width: 560px) {
  #myBreaksStats { grid-auto-flow: row; grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .mb-slot { grid-template-columns: 1fr auto auto auto 26px; }
  .mb-slot-name { grid-column: 1 / -1; }
  .mb-slot-mins { display: none; }
  .mb-slot .time-input { width: 96px; }
}

.rz-stats.is-auto { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }

/* Карточка раздела — поверхность без рамки и полей: таблица встаёт от края
   до края, как в реестре. */
#tab-team .vc-card,
#tab-schedule-v .vc-card,
#tab-breaks .vc-card {
  margin: 0;
  padding: 0;
  gap: 0;
  border: none;
  border-radius: 0;
  background: var(--bg-card);
  flex: 1;
}

#tab-team .table-container,
#tab-schedule-v .table-container,
#tab-breaks .table-container {
  margin: 0;
  border: none;
}

/* --- Вторая колонка ------------------------------------------------------ */
.vc-side {
  flex: 0 0 264px;
  width: 264px;
  min-width: 0;
  display: flex;
  flex-direction: column;
  background: var(--bg-card);
  border-right: 1px solid var(--border-color);
}

.vc-side-head {
  display: flex;
  align-items: center;
  gap: 8px;
  padding: 11px 14px;
  border-bottom: 1px solid var(--border-color);
  font-size: var(--fs-3);
  font-weight: var(--fw-title);
  color: var(--text-main);
}

.vc-side-head .ui-icon { width: 14px; height: 14px; color: var(--text-dim); }

.vc-side-count {
  margin-left: auto;
  font-size: var(--fs-1);
  font-weight: var(--fw-num);
  font-variant-numeric: tabular-nums;
  color: var(--accent-primary);
}

.vc-side-group {
  display: flex;
  flex-direction: column;
  gap: 8px;
  padding: 12px 14px;
  border-bottom: 1px solid var(--border-color);
}

.vc-side-group.is-list { gap: 0; padding: 8px 0; }

.vc-side-label {
  font-size: 11px;
  font-weight: var(--fw-title);
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.vc-side-row {
  display: flex;
  align-items: center;
  gap: 9px;
  width: 100%;
  min-height: 32px;
  padding: 6px 14px;
  border: none;
  background: none;
  font: inherit;
  font-size: var(--fs-3);
  color: var(--text-main);
  text-align: left;
  cursor: pointer;
}

.vc-side-row .ui-icon { width: 14px; height: 14px; flex: none; color: var(--text-dim); }
.vc-side-row:hover { background: var(--bg-input); }
.vc-side-text { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.vc-side-num {
  font-weight: var(--fw-num);
  font-variant-numeric: tabular-nums;
  color: var(--text-muted);
}

.vc-side-row.active {
  background: var(--accent-primary-fill);
  color: var(--accent-on-primary);
  font-weight: var(--fw-title);
}

.vc-side-row.active .ui-icon,
.vc-side-row.active .vc-side-num { color: var(--accent-on-primary); }

.vc-side-note {
  margin: auto 0 0;
  padding: 12px 14px;
  font-size: var(--fs-1);
  line-height: var(--lh-text);
  color: var(--text-dim);
  text-wrap: pretty;
}

.vc-side-btn { width: 100%; }

/* Чипы в панели — те же 26px, что период и решение в фильтрах реестра. */
.vc-chips { display: flex; flex-wrap: wrap; gap: 5px; }

.vc-chip {
  height: 26px;
  padding: 0 9px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  color: var(--text-muted);
  font: inherit;
  font-size: var(--fs-1);
  white-space: nowrap;
  cursor: pointer;
}

.vc-chip:hover { color: var(--text-main); border-color: var(--line-ctl); }

.vc-chip.active {
  border-color: var(--accent-primary-fill);
  background: var(--accent-primary-fill);
  color: var(--accent-on-primary);
  font-weight: var(--fw-title);
}

.vc-dates { display: grid; grid-template-columns: 1fr 1fr; gap: 6px; }
.vc-dates label { display: flex; flex-direction: column; gap: 3px; font-size: var(--fs-1); color: var(--text-dim); min-width: 0; }

.vc-dates input,
.vc-select,
.vac-field input {
  width: 100%;
  min-width: 0;
  height: 30px;
  padding: 0 8px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
  color: var(--text-main);
  font: inherit;
  font-size: var(--fs-2);
  font-variant-numeric: tabular-nums;
}

.vc-dates input:focus,
.vc-select:focus,
.vac-field input:focus { outline: none; border-color: var(--accent-primary-border); }

/* --- Полоса над содержимым (подраздел помощника, журнал) ----------------- */
.vc-bar {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 46px;
  padding: 7px 18px;
  background: var(--bg-card);
  border-bottom: 1px solid var(--border-color);
  flex-wrap: wrap;
}

.vc-bar-title { margin: 0; font-size: var(--fs-3); font-weight: var(--fw-title); color: var(--text-main); }
.vc-bar-count { font-size: var(--fs-2); color: var(--text-dim); font-variant-numeric: tabular-nums; }
.vc-bar-tools { margin-left: auto; display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

.vc-bar .btn {
  height: 30px;
  min-height: 30px;
  padding: 0 10px;
  font-size: var(--fs-2);
}

.vc-bar .btn.icon-btn { width: 30px; padding: 0; }

.vc-search {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  height: 30px;
  width: 240px;
  padding: 0 9px;
  border: 1px solid var(--border-strong);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
  color: var(--text-dim);
}

.vc-search .ui-icon { width: 13px; height: 13px; flex: none; }

.vc-search input {
  flex: 1;
  min-width: 0;
  height: 100%;
  border: none !important;
  background: transparent !important;
  color: var(--text-main);
  font: inherit;
  font-size: var(--fs-2);
  outline: none;
}

.vc-search:focus-within { border-color: var(--accent-primary-border); }

.vc-filterbar {
  align-items: center;
  gap: 10px;
  padding: 7px 18px;
  background: var(--accent-primary-soft);
  border-bottom: 1px solid var(--border-strong);
  font-size: var(--fs-2);
  font-weight: var(--fw-title);
  color: var(--accent-primary);
}

.vc-filterbar .btn { height: var(--h-ctl-sm); min-height: var(--h-ctl-sm); padding: 0 9px; font-size: var(--fs-1); margin-left: auto; }
.vc-filterbar .ui-icon { width: 13px; height: 13px; }

/* --- Таблица раздела ----------------------------------------------------- */
.vc-table { width: 100%; }

.vc-table thead th {
  padding: 8px 10px;
  background: var(--bg-input);
  border: none;
  border-bottom: 1px solid var(--border-strong);
  font-size: 11px;
  font-weight: var(--fw-title);
  letter-spacing: .07em;
  text-transform: uppercase;
  text-align: left;
  color: var(--text-dim);
  white-space: nowrap;
}

.vc-table tbody td {
  height: 38px;
  padding: 0 10px;
  border: none;
  border-bottom: 1px solid var(--border-color);
  font-size: var(--fs-3);
  text-align: left;
  vertical-align: middle;
  color: var(--text-main);
}

.vc-table thead th:first-child,
.vc-table tbody td:first-child { padding-left: 18px; }

.vc-table thead th:last-child,
.vc-table tbody td:last-child { padding-right: 18px; }

/* Зебры в разделах нет: строки делит линия, как в реестре. */
.vc-table tbody tr:nth-child(even) { background: none; }
.vc-table tbody tr.is-static { cursor: default; }
.vc-table tbody tr.is-static:hover { background: none !important; }

.vc-th-sort { cursor: pointer; user-select: none; }
.vc-th-sort:hover { color: var(--text-main); }
.vc-th-actions { width: 1%; }

.vc-mono { font-variant-numeric: tabular-nums; color: var(--text-muted); white-space: nowrap; }
.vc-muted { color: var(--text-muted); }
.vc-empty { color: var(--text-dim); }
.vc-name { font-weight: var(--fw-label); color: var(--text-main); white-space: nowrap; cursor: pointer; }
.vc-ellipsis { max-width: 260px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

.vc-two-line { padding-top: 7px !important; padding-bottom: 7px !important; white-space: normal !important; }

.vc-sub {
  display: flex;
  flex-wrap: wrap;
  gap: 2px 12px;
  margin-top: 2px;
  font-size: var(--fs-1);
  color: var(--text-dim);
}

.vc-sub-item { display: inline-flex; align-items: center; gap: 4px; }
.vc-sub-item .ui-icon { width: 12px; height: 12px; }

.vc-empty-row td {
  height: 64px !important;
  text-align: center !important;
  color: var(--text-dim) !important;
}

.vc-empty-row:hover { background: none !important; cursor: default; }

.vc-group-row td {
  height: 30px !important;
  background: var(--bg-input);
  font-size: var(--fs-1) !important;
  font-weight: var(--fw-title);
  letter-spacing: .04em;
  text-transform: uppercase;
}

.vc-group-row td .ui-icon { width: 12px; height: 12px; margin-right: 6px; vertical-align: -2px; }
.vc-group-row:hover { background: none !important; cursor: default; }
.vc-group-row.is-warn td { color: var(--warning-solid); background: var(--warning-soft); }
.vc-group-row.is-in td { color: var(--replacement-in); }
.vc-group-row.is-out td { color: var(--replacement-out); }

/* Подсветка строки — планка слева и тихий слой, а не плотная заливка:
   на 20 строках плотная заливка кричала громче данных. */
.vc-table tr.vc-row-bad  { background: var(--danger-wash); box-shadow: inset 2px 0 0 var(--danger-solid); }
.vc-table tr.vc-row-acc  { background: var(--info-wash); box-shadow: inset 2px 0 0 var(--info-solid); }
.vc-table tr.vc-row-warn { background: var(--warning-wash); box-shadow: inset 2px 0 0 var(--warning-solid); }

/* Статус точкой — как в реестре; кликабелен там, где открывает подробности. */
.vc-dot {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  padding: 0;
  border: none;
  background: none;
  font: inherit;
  font-size: var(--fs-2);
  font-weight: var(--fw-label);
  color: var(--text-main);
  white-space: nowrap;
}

button.vc-dot { cursor: pointer; }
button.vc-dot:hover { text-decoration: underline; text-underline-offset: 3px; }

.vc-dot::before {
  content: "";
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: currentColor;
  flex: none;
}

.vc-dot.is-ok   { color: var(--accent-green); }
.vc-dot.is-bad  { color: var(--accent-rose); }
.vc-dot.is-warn { color: var(--accent-amber); }
.vc-dot.is-acc  { color: var(--accent-info); }
.vc-dot.is-mute { color: var(--text-dim); }

.vc-tag {
  display: inline-flex;
  align-items: center;
  gap: 4px;
  height: 20px;
  padding: 0 6px;
  border-radius: 3px;
  font-size: var(--fs-1);
  font-weight: var(--fw-label);
  white-space: nowrap;
  vertical-align: 1px;
}

.vc-tag .ui-icon { width: 12px; height: 12px; }
.vc-tag.is-warn { background: var(--warning-soft); color: var(--warning-solid); }
.vc-tag.is-in   { background: var(--discovery-soft); color: var(--replacement-in); }
.vc-tag.is-ok   { background: var(--success-soft); color: var(--accent-green); }
.vc-tag.is-bad  { background: var(--danger-soft); color: var(--accent-rose); }

/* Действия строки — иконки 26px, текст в title. «Уволить» и «Перевести»
   были двумя цветными кнопками с подписью в каждой строке — шум на 20 строк. */
.vc-actions-cell { white-space: nowrap; text-align: right !important; }
.vc-actions-cell .vc-icon-btn + .vc-icon-btn { margin-left: 2px; }

.vc-icon-btn {
  display: inline-grid;
  place-items: center;
  width: 26px;
  height: 26px;
  padding: 0;
  border: 1px solid transparent;
  border-radius: var(--radius-sm);
  background: none;
  color: var(--text-dim);
  cursor: pointer;
  vertical-align: middle;
}

.vc-icon-btn .ui-icon { width: 14px; height: 14px; }
.vc-icon-btn:hover { background: var(--bg-input); border-color: var(--border-color); color: var(--text-main); }
.vc-icon-btn.is-danger:hover { color: var(--accent-rose); background: var(--danger-wash); }
.vc-icon-btn.is-info:hover { color: var(--accent-info); background: var(--info-wash); }

.vc-link {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  color: var(--accent-primary);
  font-size: var(--fs-2);
  text-decoration: none;
}

.vc-link .ui-icon { width: 13px; height: 13px; flex: none; }
.vc-link:hover { text-decoration: underline; text-underline-offset: 3px; }

.vc-empty-state {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  padding: 56px 18px;
  text-align: center;
  font-size: var(--fs-3);
  color: var(--text-dim);
}

/* --- Календарные сетки (Календарь смен, Отпуска) ------------------------ */
.vc-cal { border-collapse: collapse; margin: 0; }

.vc-cal thead th,
.vc-cal tbody td { border: none; min-width: 0; }

.vc-cal thead th { padding: 8px 4px; }
.vc-cal tbody td { height: 36px; padding: 0 2px; }

.vc-cal .vc-cal-name {
  position: sticky;
  left: 0;
  z-index: 2;
  min-width: 190px;
  padding-left: 18px;
  padding-right: 10px;
  background: var(--bg-card);
  text-align: left;
  box-shadow: inset -1px 0 0 var(--border-color);
}

.vc-cal thead .vc-cal-name { z-index: 3; background: var(--bg-input); }
.vc-cal tr.vc-row-bad .vc-cal-name { background: var(--danger-wash); }
.vc-cal tr.vc-row-acc .vc-cal-name { background: var(--info-wash); }

.vc-cal-fio {
  display: block;
  max-width: 220px;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-weight: var(--fw-label);
}

.vc-cal-until {
  display: inline-flex;
  align-items: center;
  gap: 3px;
  font-size: var(--fs-1);
  font-weight: var(--fw-label);
}

.vc-cal-until .ui-icon { width: 11px; height: 11px; }
.vc-cal-until.is-bad { color: var(--accent-rose); }
.vc-cal-until.is-acc { color: var(--accent-info); }

.vc-cal-meta {
  padding: 0 8px !important;
  text-align: center !important;
  font-size: var(--fs-2) !important;
  color: var(--text-muted) !important;
  white-space: nowrap;
}

.vc-cal-meta.is-acc { color: var(--accent-primary) !important; font-weight: var(--fw-title); }
.vc-cal-toggle { cursor: pointer; color: var(--accent-primary) !important; }
.vc-cal-toggle .ui-icon { width: 11px; height: 11px; vertical-align: -1px; }

.vc-cal-dayhead {
  min-width: 30px !important;
  text-align: center !important;
  letter-spacing: 0 !important;
  font-variant-numeric: tabular-nums;
}

.vc-cal-dayhead.is-weekend { color: var(--text-muted) !important; background: var(--bg-card-hover) !important; }
.vc-cal-dayhead.is-today { color: var(--accent-on-primary) !important; background: var(--accent-primary-fill) !important; }

/* Клетка дня — плашка в ячейке с просветом 1px: сетка читается по плашкам,
   а не по рамкам таблицы. Цвет — прежние .calendar-day-* (тихий слой). */
.vc-cal-day {
  text-align: center !important;
  font-size: var(--fs-2) !important;
  font-weight: var(--fw-title);
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  user-select: none;
  box-shadow: inset 0 0 0 1px var(--bg-card);
}

.vc-cal-day:hover { outline: 1px solid var(--accent-primary-border); outline-offset: -2px; }
.vc-cal-day.is-empty { color: var(--border-strong); font-weight: var(--fw-text); }

.vc-cal-gone {
  text-align: center !important;
  font-size: var(--fs-2) !important;
  font-weight: var(--fw-label);
  cursor: not-allowed;
  user-select: none;
}

.vc-cal-gone .ui-icon { width: 12px; height: 12px; vertical-align: -2px; margin-right: 4px; }
.vc-cal-gone.is-bad  { color: var(--danger-solid); background: repeating-linear-gradient(135deg, var(--danger-wash) 0 6px, transparent 6px 12px); }
.vc-cal-gone.is-info { color: var(--info-solid); background: repeating-linear-gradient(135deg, var(--info-wash) 0 6px, transparent 6px 12px); }

.vc-cal-sum {
  min-width: 64px !important;
  padding: 0 8px !important;
  text-align: center !important;
  font-weight: var(--fw-title);
  font-variant-numeric: tabular-nums;
  color: var(--text-main);
}

.vc-cal-sum.is-first { box-shadow: inset 1px 0 0 var(--border-strong); }
.vc-cal-sum.is-warn { color: var(--warning-solid); }
thead .vc-cal-sum { color: var(--text-dim) !important; font-weight: var(--fw-title); }

.vc-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 6px 16px;
  margin: 0;
  padding: 8px 18px;
  background: var(--bg-card);
  border: none;
  border-bottom: 1px solid var(--border-color);
  border-radius: 0;
  font-size: var(--fs-2);
  color: var(--text-muted);
}

.vc-legend-item { display: inline-flex; align-items: center; gap: 6px; }

.vc-legend .schedule-legend-code {
  min-width: 20px;
  height: 20px;
  padding: 0 4px;
  align-items: center;
  border-radius: 3px;
  font-size: var(--fs-1);
}

.vc-legend-hint { margin-left: auto; font-size: var(--fs-1); color: var(--text-dim); }

/* --- Перерывы ------------------------------------------------------------ */
.vc-breaks thead th { text-align: center; }
.vc-breaks thead .vc-th-name { text-align: left; }
.vc-breaks thead .vc-th-group { box-shadow: inset 1px 0 0 var(--border-color); }
.vc-breaks thead .vc-th-sub { padding-top: 0; font-size: 10.5px; letter-spacing: .04em; }
.vc-breaks thead tr:first-child th[rowspan] { vertical-align: bottom; }
.vc-breaks thead tr:first-child th[colspan] { border-bottom: none; padding-bottom: 2px; }
.vc-breaks tbody td { text-align: center; padding: 0 4px; }
.vc-breaks tbody td:first-child { text-align: left; }
.vc-breaks .vc-td-group { box-shadow: inset 1px 0 0 var(--border-color); }
.vc-breaks .vc-td-total { text-align: left !important; white-space: nowrap; font-weight: var(--fw-title); color: var(--accent-green); padding-left: 12px !important; }
.vc-breaks .time-input { width: 82px; height: 28px; background: transparent; border-color: transparent; }
.vc-breaks .time-input:hover { border-color: var(--border-strong); }
.vc-breaks .time-input:focus { background: var(--bg-input); border-color: var(--accent-primary-border); }
.vc-breaks tbody tr.vc-row-warn .vc-name { color: var(--warning-solid); }

/* --- Замены -------------------------------------------------------------- */
.vc-split {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 1px;
  align-items: stretch;
  min-height: calc(100vh - 48px);
  background: var(--border-color);
}

@media (max-width: 1180px) { .vc-split { grid-template-columns: minmax(0, 1fr); } }

.vc-col { min-width: 0; display: flex; flex-direction: column; background: var(--bg-card); }

.vc-col-head {
  display: flex;
  align-items: center;
  gap: 8px;
  min-height: 46px;
  padding: 7px 18px;
  border-bottom: 1px solid var(--border-color);
}

.vc-col-head h2 { margin: 0; font-size: var(--fs-3); font-weight: var(--fw-title); color: var(--text-main); white-space: nowrap; }

.vc-col-icon { display: inline-grid; place-items: center; }
.vc-col-icon .ui-icon { width: 14px; height: 14px; }
.vc-col-icon.is-out { color: var(--replacement-out); }
.vc-col-icon.is-in  { color: var(--replacement-in); }

.vc-col-count {
  font-size: var(--fs-2);
  font-weight: var(--fw-num);
  font-variant-numeric: tabular-nums;
  color: var(--text-dim);
}

.vc-col-note {
  margin-left: auto;
  font-size: var(--fs-1);
  color: var(--text-dim);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  min-width: 0;
}

#replacementsCalendarGrid { padding: 0; background: var(--bg-card); min-height: calc(100vh - 48px); }

/* --- Отпуска ------------------------------------------------------------- */
.vac-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 280px;
  min-height: calc(100vh - 48px);
  background: var(--bg-card);
}

.vac-main { min-width: 0; }

.vac-aside {
  display: flex;
  flex-direction: column;
  gap: 10px;
  padding: 14px 16px;
  border-left: 1px solid var(--border-color);
  background: var(--bg-card);
}

.vac-field { display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-2); color: var(--text-muted); }
.vac-field input { width: 100%; }
.vac-limit-ro { margin: 0; font-size: var(--fs-2); color: var(--text-main); }

.vac-sum {
  display: flex;
  flex-direction: column;
  margin: 4px 0;
  border-top: 1px solid var(--border-color);
}

.vac-sum > div {
  display: flex;
  justify-content: space-between;
  gap: 8px;
  padding: 7px 0;
  border-bottom: 1px solid var(--border-color);
  font-size: var(--fs-2);
  color: var(--text-muted);
}

.vac-sum b { font-weight: var(--fw-num); font-variant-numeric: tabular-nums; color: var(--text-main); }
.vac-sum b.is-warn { color: var(--warning-solid); }
.vac-sum b.is-bad { color: var(--accent-rose); }

.vac-legend { display: flex; flex-direction: column; gap: 6px; font-size: var(--fs-2); color: var(--text-muted); }
.vac-legend span { display: flex; align-items: center; gap: 8px; }
.vac-note { margin: auto 0 0; font-size: var(--fs-1); color: var(--text-dim); text-wrap: pretty; }

.vac-cell { text-align: center !important; padding: 0 !important; }

.vac-mark {
  display: inline-grid;
  place-items: center;
  width: 20px;
  height: 20px;
  border-radius: 3px;
  font-style: normal;
  font-size: var(--fs-1);
  font-weight: var(--fw-title);
}

.vac-mark.is-ok   { background: var(--success-soft); color: var(--accent-green); }
.vac-mark.is-warn { background: var(--warning-soft); color: var(--warning-solid); }
.vac-mark.is-bad  { background: var(--danger-soft); color: var(--accent-rose); }
.vac-mark.is-click { cursor: pointer; }
.vac-mark.is-click:hover { box-shadow: 0 0 0 1px currentColor; }

.vac-sum-row td { height: 30px !important; background: var(--bg-input); }
.vac-sum-row .vc-cal-name { background: var(--bg-input) !important; font-size: var(--fs-1); font-weight: var(--fw-title); letter-spacing: .04em; text-transform: uppercase; color: var(--text-dim); }
.vac-sum-row:hover { background: none !important; }

.vac-sum-cell { text-align: center !important; font-size: var(--fs-1) !important; font-weight: var(--fw-title); font-variant-numeric: tabular-nums; }
.vac-sum-cell.is-ok   { color: var(--accent-green) !important; }
.vac-sum-cell.is-warn { color: var(--warning-solid) !important; }
.vac-sum-cell.is-bad  { color: var(--accent-rose) !important; background: var(--danger-wash); }

@media (max-width: 1180px) {
  .vac-layout { grid-template-columns: minmax(0, 1fr); }
  .vac-aside { border-left: none; border-top: 1px solid var(--border-color); }
}

/* --- Согласования -------------------------------------------------------- */
.ap-selbar {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 46px;
  padding: 7px 18px;
  background: var(--bg-card);
  border-bottom: 1px solid var(--border-color);
}

.ap-selbar.is-on { background: var(--accent-primary-soft); border-bottom-color: var(--border-strong); }
.ap-selbar .btn { height: var(--h-ctl-sm); min-height: var(--h-ctl-sm); padding: 0 10px; font-size: var(--fs-1); }

.ap-selall {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: var(--fs-2);
  font-weight: var(--fw-label);
  color: var(--text-muted);
  cursor: pointer;
}

.ap-selbar.is-on .ap-selall { color: var(--accent-primary); font-weight: var(--fw-title); }

.ap-list { display: flex; flex-direction: column; background: var(--bg-card); }

.ap-row {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 58px;
  padding: 9px 18px;
  border-bottom: 1px solid var(--border-color);
  cursor: pointer;
}

.ap-row:hover { background: var(--bg-card-hover); }
.ap-row.is-static { cursor: default; }
.ap-row.is-static:hover { background: none; }
.ap-row.is-selected { background: var(--accent-primary-soft); box-shadow: inset 2px 0 0 var(--accent-primary-border); }
.ap-row > input[type="checkbox"] { flex: none; cursor: pointer; accent-color: var(--accent-primary-fill); }

.ap-type {
  flex: none;
  display: grid;
  place-items: center;
  width: 30px;
  height: 30px;
  border-radius: var(--radius-sm);
}

.ap-type .ui-icon { width: 15px; height: 15px; }
.ap-type.is-replace  { background: var(--info-soft); color: var(--accent-info); }
.ap-type.is-vacation { background: var(--success-soft); color: var(--accent-green); }
.ap-type.is-dayoff   { background: var(--warning-soft); color: var(--warning-solid); }

.ap-row-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.ap-row-top { display: flex; align-items: center; gap: 8px; min-width: 0; flex-wrap: wrap; }

.ap-row-kind {
  font-size: 11px;
  font-weight: var(--fw-title);
  letter-spacing: .07em;
  text-transform: uppercase;
  color: var(--text-dim);
}

.ap-row-name { font-size: var(--fs-3); font-weight: var(--fw-title); color: var(--text-main); }
.ap-row-id { font-size: var(--fs-1); color: var(--text-dim); font-variant-numeric: tabular-nums; }
.ap-row-details { font-size: var(--fs-2); color: var(--text-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ap-row-details b { color: var(--text-main); font-weight: var(--fw-label); }
.ap-row-reason { font-size: var(--fs-2); color: var(--accent-rose); }

.ap-row-age {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 5px;
  margin-left: auto;
  font-size: var(--fs-2);
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

.ap-row-age .ui-icon { width: 12px; height: 12px; }
.ap-row-top .ap-row-age { margin-left: auto; }
.ap-row-open { flex: none; color: var(--text-dim); display: grid; place-items: center; }
.ap-row-open .ui-icon { width: 14px; height: 14px; }
.ap-row:hover .ap-row-open { color: var(--accent-primary); }
.ap-empty-sub { font-size: var(--fs-2); }

/* --- Аналитика ----------------------------------------------------------- */
#analyticsContainer { padding: 0; }

/* Аналитика (СВ и модератор), вариант 3a: одна лента, цвет — только по смыслу. */
.ana { font-size: var(--fs-3); line-height: 1.45; font-variant-numeric: tabular-nums; color: var(--text-main); }
.ana-head { height: 52px; padding: 0 18px; display: flex; align-items: center; gap: 16px; border-bottom: 1px solid var(--border-color); background: var(--bg-card); }
.ana-title { font-size: var(--fs-5); font-weight: var(--fw-title); }
.ana-seg { display: flex; align-items: center; gap: 2px; height: var(--h-ctl); padding: 2px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm); background: var(--bg-input); }
.ana-seg-btn { height: 24px; padding: 0 10px; border: none; border-radius: 3px; background: transparent; color: var(--text-muted); font: inherit; font-size: var(--fs-2); cursor: pointer; white-space: nowrap; }
.ana-seg-btn:hover { color: var(--text-main); }
.ana-seg-btn.is-active { background: var(--bg-card-hover); color: var(--text-main); }
.ana-range { border: none; background: none; padding: 0; font: inherit; font-size: var(--fs-2); color: var(--text-dim); cursor: pointer; white-space: nowrap; }
.ana-range:hover, .ana-range.is-active { color: var(--text-main); }
.ana-spacer { flex: 1; }
.ana-icon-btn { width: var(--h-ctl); height: var(--h-ctl); display: grid; place-items: center; border: 1px solid var(--border-color); border-radius: var(--radius-sm); background: transparent; color: var(--text-muted); cursor: pointer; }
.ana-icon-btn:hover { color: var(--text-main); background: var(--bg-card-hover); }
.ana-icon-btn .ui-icon { width: 15px; height: 15px; }
.ana-custom { display: flex; align-items: center; gap: 12px; padding: 10px 18px; border-bottom: 1px solid var(--border-color); background: var(--bg-card); font-size: var(--fs-2); color: var(--text-muted); }
.ana-custom[hidden] { display: none; }
.ana-custom input { height: var(--h-ctl); padding: 0 8px; border: 1px solid var(--border-color); border-radius: var(--radius-sm); background: var(--bg-input); color: var(--text-main); font: inherit; font-size: var(--fs-2); }
.ana-btn { display: inline-flex; align-items: center; gap: 6px; height: var(--h-ctl); padding: 0 10px; border: 1px solid var(--border-color); border-radius: var(--radius-sm); background: transparent; color: var(--text-muted); font: inherit; font-size: var(--fs-2); cursor: pointer; white-space: nowrap; }
.ana-btn:hover { color: var(--text-main); background: var(--bg-card-hover); }
.ana-btn .ui-icon { width: 12px; height: 12px; }
.ana-btn.is-primary { color: var(--accent-primary); border-color: var(--accent-primary); }
.ana-btn.is-danger { color: var(--danger-solid); }
.ana-btn-right { margin-left: auto; }

/* Лента встык, как «Смена»: блоки делит шов 1px — фон ленты цвета линии
   просвечивает в gap. Своих рамок и скруглений у карточек нет. */
.ana-feed { padding: 0; display: flex; flex-direction: column; gap: 1px; background: var(--border-color); }
.ana-row { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 1px; }
.ana-row-wide { grid-template-columns: minmax(0, 2.2fr) minmax(0, 1fr); }
.ana-card { background: var(--bg-card); padding: 14px 18px; display: flex; flex-direction: column; gap: 16px; min-width: 0; }
.ana-card-flush { padding: 14px 0 8px; gap: 12px; }
.ana-card-flush > .ana-card-head { padding: 0 18px; }
.ana-card-head { display: flex; align-items: center; gap: 10px 14px; flex-wrap: wrap; }
.ana-card-head h3 { margin: 0; font-size: var(--fs-4); font-weight: var(--fw-title); }
.ana-note, .ana-dim { font-size: var(--fs-2); color: var(--text-dim); }
.ana-muted { color: var(--text-muted); }
.ana-card-head > .ana-info { margin-left: auto; }
.ana-card-head > .ana-btn-right + .ana-info { margin-left: 0; }
.ana-info { border: none; background: none; padding: 0; display: inline-grid; place-items: center; color: var(--border-strong); cursor: pointer; }
.ana-info:hover { color: var(--text-muted); }
.ana-info .ui-icon { width: 14px; height: 14px; }
.ana-empty { padding: 24px 0; text-align: center; font-size: var(--fs-2); color: var(--text-dim); }
.ana-foot { font-size: var(--fs-1); color: var(--text-dim); }
.ana-ellipsis { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ana-num { text-align: right; }

/* Смысловые цвета: квадраты легенды, сегменты, столбцы. */
.ana .is-ok { --c: var(--success-solid); }
.ana .is-bad { --c: var(--danger-solid); }
.ana .is-warn { --c: var(--warning-solid); }
/* KPI-полоса */
.ana-kpis { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); background: var(--bg-card); }
@media (min-width: 1201px) { .ana-kpis.is-3 { grid-template-columns: repeat(3, minmax(0, 1fr)); } }
.ana-kpi { padding: 16px 18px; display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.ana-kpi + .ana-kpi { border-left: 1px solid var(--border-color); }
.ana-kpi-label { display: flex; align-items: center; gap: 6px; font-size: var(--fs-2); color: var(--text-muted); }
.ana-kpi-label .ui-icon { width: 13px; height: 13px; }
.ana-kpi-value { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap; font-size: var(--fs-7); font-weight: var(--fw-num); letter-spacing: -.01em; line-height: 1.1; }
.ana-kpi-unit { font-size: var(--fs-3); font-weight: 400; color: var(--text-dim); letter-spacing: 0; }
.ana-kpi-bar { height: 4px; border-radius: 2px; background: var(--bg-input); overflow: hidden; }
.ana-kpi-bar span { display: block; height: 100%; }
.ana-kpi-sub { font-size: var(--fs-1); color: var(--text-dim); text-wrap: pretty; }

/* Общее для графиков (хендофф «1c · 1d · 1g · 1j»): карточка, легенда, тултип. */
.ana-card-chart { padding: 20px 22px 18px; gap: 14px; }
.ana-card-dec { padding: 18px 20px 20px; gap: 18px; }
.ana-card-bars { padding: 18px 20px; gap: 14px; }
.ana-card-head > .ana-push { margin-left: auto; }
.ana-card-head > .ana-push ~ .ana-info { margin-left: 0; }
.ana-legend { display: inline-flex; align-items: center; gap: 14px; font-size: 12px; color: var(--text-muted); }
.ana-legend > span { display: inline-flex; align-items: center; gap: 6px; }
.ana-legend i { width: 8px; height: 8px; border-radius: 2px; background: var(--c); }
.ana-tip { position: absolute; z-index: 5; top: 0; width: 190px; padding: 10px 12px; display: flex; flex-direction: column; gap: 8px; background: var(--bg-card-hover); border: 1px solid var(--border-strong); border-radius: 8px; box-shadow: var(--shadow-md); pointer-events: none; font-size: 12px; }
.ana-tip[hidden] { display: none; }
.ana-tip.is-wide { width: 210px; }
.ana-tip-total { display: flex; align-items: baseline; gap: 6px; }
.ana-tip-total b { font-size: 18px; font-weight: var(--fw-title); }
.ana-tip-rows { display: flex; flex-direction: column; gap: 4px; padding-top: 8px; border-top: 1px solid var(--border-color); }
.ana-tip-row { display: flex; align-items: center; gap: 8px; }
.ana-tip-row i { flex: none; width: 7px; height: 7px; border-radius: 2px; background: var(--c); }
.ana-tip-val { margin-left: auto; }
.ana-tip-val.is-strong { font-weight: var(--fw-title); }
.ana-tip-extra { width: 34px; text-align: right; color: var(--text-dim); white-space: nowrap; }
.ana-tip.is-wide .ana-tip-extra { width: 52px; }
.ana-dc-col, .ana-cm-group { transition: opacity .12s; }
.ana-dc-field.is-hover .ana-dc-col:not(.is-hot),
.ana-cm-field.is-hover .ana-cm-group:not(.is-hot) { opacity: .4; }

/* 1c «Закрыто по дням»: стопка решений, итог над столбцом */
.ana-dc-field { position: relative; height: 240px; border-bottom: 1px solid var(--border-strong); }
.ana-dc-cols { position: absolute; inset: 0; display: flex; gap: 4px; }
.ana-dc-col { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; justify-content: flex-end; gap: 5px; }
.ana-dc-total { font-size: 11px; color: var(--text-muted); white-space: nowrap; }
.ana-dc-total.is-best, .ana-dc-col.is-hot .ana-dc-total { font-weight: var(--fw-title); color: var(--text-main); }
.ana-dc-field.is-hover .ana-dc-col:not(.is-hot) .ana-dc-total.is-best { font-weight: 400; color: var(--text-muted); }
.ana-dc-bar { width: 80%; display: flex; flex-direction: column; gap: 1px; border-radius: 4px 4px 0 0; overflow: hidden; }
.ana-dc-bar span { flex: none; background: var(--c); }
.ana-dc-bar .is-ok { flex: 1; display: flex; justify-content: center; padding-top: 4px; font-size: 10px; font-weight: var(--fw-title); line-height: 1; color: var(--bg-dark); overflow: hidden; }
.ana-dc-labels { display: flex; gap: 4px; margin-top: -6px; font-size: 11px; color: var(--text-muted); }
.ana-dc-labels span { flex: 1; min-width: 0; text-align: center; white-space: nowrap; }
.ana-dc-labels span.is-weekend { color: var(--text-dim); }
.ana-dc-field.is-dense .ana-dc-cols, .ana-dc-labels.is-dense { gap: 1px; }
.ana-dc-field.is-dense .ana-dc-bar { width: 100%; }

/* 1d «Решения»: полоса долей, риска прошлого периода, три крупные доли */
.ana-dec-bar { position: relative; padding-top: 18px; }
.ana-dec-segs { display: flex; gap: 3px; height: 14px; }
.ana-dec-segs span { border-radius: 3px; background: var(--c); }
.ana-dec-mark { position: absolute; top: 12px; bottom: -4px; width: 2px; margin-left: -1px; border-radius: 1px; background: var(--text-main); }
.ana-dec-mark-label { position: absolute; top: -2px; font-size: 11px; color: var(--text-muted); white-space: nowrap; }
.ana-dec-grid { display: grid; grid-template-columns: repeat(3, minmax(0, 1fr)); gap: 14px; }
.ana-dec-cell { display: flex; flex-direction: column; gap: 4px; min-width: 0; font-size: 12.5px; }
.ana-dec-name { display: inline-flex; align-items: center; gap: 6px; color: var(--text-muted); white-space: nowrap; }
.ana-dec-name i { flex: none; width: 8px; height: 8px; border-radius: 2px; background: var(--c); }
.ana-dec-share { font-size: 24px; font-weight: var(--fw-title); letter-spacing: -.01em; line-height: 1.2; }
.ana-warn-link { margin-top: auto; display: flex; align-items: center; gap: 6px; border: none; background: none; padding: 0; font: inherit; font-size: var(--fs-2); color: var(--warning-solid); cursor: pointer; text-align: left; }
.ana-warn-link:hover { text-decoration: underline; }
.ana-warn-link .ui-icon { width: 14px; height: 14px; flex: none; }
.ana-warn-link .ui-icon:last-child { width: 12px; height: 12px; }

/* 1g: полоса как фон строки — категории и причины */
.ana-bar-list { display: flex; flex-direction: column; gap: 6px; }
.ana-bar-list.is-reason { gap: 4px; }
.ana-bar-row { display: grid; grid-template-columns: minmax(0, 1fr) 60px 40px; gap: 12px; align-items: center; }
.ana-bar-row b { font-weight: var(--fw-title); }
.ana-bar-cell { position: relative; height: 34px; display: flex; align-items: center; min-width: 0; }
.is-reason .ana-bar-cell { height: 28px; }
.ana-bar-bg { position: absolute; left: 0; top: 0; bottom: 0; border-radius: 5px; background: var(--bg-input); overflow: hidden; }
.is-reason .ana-bar-bg { border-radius: 4px; }
.ana-bar-bg.is-ok { background: var(--success-soft); }
.ana-bar-bg.is-bad { background: var(--danger-soft); }
/* Модератор: своя строка в «Команде сегодня» и «Вы vs команда». */
.ana-bar-row.is-me .ana-bar-bg { background: var(--accent-primary-soft); }
.ana-bar-row.is-me .ana-bar-label { font-weight: var(--fw-title); }
.ana-bar-mix { position: absolute; left: 0; right: 0; bottom: 0; height: 3px; display: flex; }
.ana-bar-mix span { background: var(--c); }
.ana-bar-label { position: relative; min-width: 0; padding-left: 12px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.is-reason .ana-bar-label { padding-left: 10px; }
.ana-bar-label .ana-dim { font-size: 12px; }

/* Трек в таблице «Модераторы» */
.ana-track { height: 10px; border-radius: 3px; background: var(--bg-input); overflow: hidden; }
.ana-track > span { display: block; height: 100%; border-radius: 3px; background: var(--line-ctl); }
.ana-track.is-mini { height: 4px; border-radius: 2px; flex: 1; }

/* «Модераторы» */
.ana-mod-head, .ana-mod-row { display: grid; grid-template-columns: minmax(0, 1.3fr) minmax(0, 1.2fr) 84px 84px 84px 84px 52px; gap: 16px; padding: 0 20px; align-items: center; }
.ana-mod-head { padding-top: 9px; padding-bottom: 9px; border-top: 1px solid var(--border-color); border-bottom: 1px solid var(--border-color); }
.ana-mod-head button { border: none; background: none; padding: 0; font: inherit; font-size: var(--fs-1); color: var(--text-dim); text-align: left; cursor: pointer; white-space: nowrap; }
.ana-mod-head button.is-num { text-align: right; }
.ana-mod-head button.is-active, .ana-mod-head button:hover { color: var(--text-main); }
.ana-mod-row { height: 44px; border-bottom: 1px solid var(--border-color); cursor: pointer; }
.ana-mod-row:hover, .ana-mod-row:focus-visible { background: var(--bg-card-hover); outline: none; }
.ana-mod-row .is-num { text-align: right; white-space: nowrap; }
.ana-mod-name { display: flex; align-items: center; gap: 10px; min-width: 0; }
.ana-avatar { flex: none; width: 26px; height: 26px; border-radius: 50%; display: grid; place-items: center; background: var(--bg-input); font-size: 11px; font-weight: var(--fw-title); color: var(--text-muted); }
.ana-mod-closed { display: flex; align-items: center; gap: 10px; }
.ana-mod-closed b { width: 40px; flex: none; text-align: right; font-weight: var(--fw-title); }
.ana-mod-closed .ana-track > span { border-radius: 2px; }

/* 1j «Сравнение месяцев»: N месяцев столбиками на человека, одна шкала.
   Текущий месяц — акцент; прошлые — шкала от --border-strong (старый) к
   --text-dim (новый), --t задаёт JS. В светлой теме старые выходят светлее. */
.ana-stepper { display: inline-flex; align-items: center; height: 28px; border: 1px solid var(--border-strong); border-radius: 7px; overflow: hidden; }
.ana-stepper button { width: 28px; height: 100%; border: none; background: transparent; color: var(--text-main); font: inherit; font-size: 15px; cursor: pointer; }
.ana-stepper button:first-child { border-right: 1px solid var(--border-strong); }
.ana-stepper button:last-child { border-left: 1px solid var(--border-strong); }
.ana-stepper button:hover:not(:disabled) { background: var(--bg-card-hover); }
.ana-stepper button:disabled { opacity: .3; cursor: default; }
.ana-stepper > span { min-width: 74px; padding: 0 10px; text-align: center; font-size: 12.5px; }
.ana-cm-sum { font-size: 13px; color: var(--text-muted); white-space: nowrap; }
.ana-cm-sum b { font-weight: var(--fw-title); }
.ana-cm-c { --c: color-mix(in oklab, var(--border-strong), var(--text-dim) var(--t, 50%)); background: var(--c); }
.ana-cm-c.is-cur { --c: var(--accent-primary); }
.ana-cm { --cm-gap: 14px; --cm-bar-gap: 3px; display: flex; flex-direction: column; gap: 14px; }
.ana-cm.is-sm { --cm-gap: 10px; }
.ana-cm.is-lg { --cm-gap: 18px; --cm-bar-gap: 1px; }
.ana-cm-legend { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: 12px; color: var(--text-muted); }
.ana-cm-legend span { display: inline-flex; align-items: center; gap: 6px; }
.ana-cm-legend span.is-cur { color: var(--text-main); }
.ana-cm-legend i { width: 10px; height: 10px; border-radius: 2px; }
.ana-cm-field { position: relative; height: 260px; display: flex; gap: var(--cm-gap); border-bottom: 1px solid var(--border-strong); }
.ana-cm-group { position: relative; flex: 1; min-width: 0; display: flex; align-items: flex-end; justify-content: center; gap: var(--cm-bar-gap); }
.ana-cm-slot { flex: 1; max-width: 30px; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 4px; }
.ana-cm-bar { display: block; width: 100%; border-radius: 3px 3px 0 0; overflow: hidden; }
.ana-cm-bar i { display: block; height: 100%; }
.ana-cm-v { font-size: 11px; color: var(--text-dim); white-space: nowrap; }
.ana-cm-v.is-cur { font-weight: var(--fw-title); color: var(--text-main); }
.ana-cm-top { position: absolute; left: 0; right: 0; text-align: center; font-size: 11.5px; font-weight: var(--fw-title); white-space: nowrap; }
.ana-cm-names { display: flex; gap: var(--cm-gap); margin-top: -4px; }
.ana-cm-name { flex: 1; min-width: 0; display: flex; flex-direction: column; align-items: center; gap: 1px; font-size: 12px; }
.ana-cm-name .ana-ellipsis { max-width: 100%; color: var(--text-muted); }
.ana-cm-name b { font-weight: var(--fw-title); white-space: nowrap; }
.ana-skel { height: 330px; border-radius: 6px; background: var(--bg-input); }

@media (max-width: 1200px) {
  .ana-row, .ana-row-wide { grid-template-columns: minmax(0, 1fr); }
  .ana-kpis { grid-template-columns: repeat(3, minmax(0, 1fr)); }
  .ana-kpi:nth-child(4) { border-left: none; }
  .ana-kpi:nth-child(n+4) { border-top: 1px solid var(--border-color); }
  .ana-head { height: auto; min-height: 52px; flex-wrap: wrap; padding: 10px 18px; }
}

@media (max-width: 560px) {
  /* Телефон: сегменты периода и категории листаются внутри себя, а не
     раздвигают страницу. */
  .ana-seg { max-width: 100%; overflow-x: auto; }
  .ana-seg-btn { flex: none; }
  .ana-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ana-kpi:nth-child(n) { border-left: none; border-top: 1px solid var(--border-color); }
  .ana-kpi:nth-child(even) { border-left: 1px solid var(--border-color); }
}

/* --- Помощник ------------------------------------------------------------ */
#tab-helper .vc-body > div { background: var(--bg-card); min-height: calc(100vh - 48px); }
#helperTemplatesList { background: var(--bg-dark); }

@media (max-width: 1100px) {
  .vc-side { flex-basis: 220px; width: 220px; }
}

/* ---------- Репорты (журнал 117) ---------- */
.rail-user.is-admin { border-color: var(--accent-rose); color: var(--accent-rose); }

.report-severity-group { display: flex; gap: 0.5rem; margin-top: 0.35rem; }
.report-severity-group .report-sev { flex: 1; cursor: pointer; }
.report-sev {
  padding: 0.35rem 0.5rem;
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-input);
  color: var(--text-muted);
  font: inherit;
  font-size: var(--fs-3);
  font-weight: var(--fw-title);
  white-space: nowrap;
}
.report-sev.active[data-severity="critical"] { background: var(--danger-soft); border-color: var(--danger-border); color: var(--accent-rose); }
.report-sev.active[data-severity="important"] { background: var(--warning-soft); border-color: var(--warning-border); color: var(--accent-amber); }
.report-sev.active[data-severity="minor"] { background: var(--success-soft); border-color: var(--success-border); color: var(--accent-green); }

.report-photos { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-top: 0.5rem; }
.report-photo { position: relative; width: 72px; height: 72px; }
.report-photo img { width: 100%; height: 100%; object-fit: cover; border-radius: var(--radius-sm); border: 1px solid var(--border-color); background: var(--bg-input); }
.report-photo button {
  position: absolute; top: -6px; right: -6px; width: 18px; height: 18px;
  border: none; border-radius: 50%; background: var(--accent-rose); color: #fff; line-height: 1; cursor: pointer;
}

.reports-screen { max-width: 860px; padding: 16px; }
.reports-toolbar { display: flex; justify-content: space-between; align-items: center; gap: 0.5rem; margin-bottom: 12px; }
.report-card {
  border: 1px solid var(--border-color);
  border-radius: var(--radius-sm);
  background: var(--bg-card);
  padding: 12px 14px;
  margin-bottom: 10px;
}
.report-card.is-done { opacity: 0.6; }
.report-card header { display: flex; align-items: center; gap: 0.6rem; flex-wrap: wrap; }
.report-card header .btn { margin-left: auto; }
.report-card .report-meta { color: var(--text-muted); font-size: var(--fs-2); }
.report-card p { margin: 0.5rem 0 0; white-space: pre-wrap; overflow-wrap: anywhere; }

/* «Что нового» (журнал 130): точка непрочитанного на кнопке рейла и список. */
#btnChangelog { position: relative; }
.changelog-dot {
  position: absolute;
  top: -0.2rem;
  right: -0.2rem;
  width: 0.55rem;
  height: 0.55rem;
  border-radius: 50%;
  background: var(--accent-rose);
  box-shadow: 0 0 0 2px var(--bg-header);
}
.changelog-dot[hidden] { display: none; }
.changelog-list { padding: 0.5rem 0 1rem; max-height: 65vh; overflow-y: auto; }
.changelog-day + .changelog-day { margin-top: 1rem; }
.changelog-day h3 { margin: 0 0 0.35rem; font-size: var(--fs-3); font-weight: var(--fw-title); color: var(--text-muted); }
.changelog-day ul { margin: 0; padding-left: 1.2rem; }
.changelog-day li { margin: 0.25rem 0; line-height: 1.45; }
