/* Фирменный стиль ИКПК. Зелёный — действие и успех, бирюза — сведения и фокус,
   графит — текст; на одном элементе зелёный с бирюзой не встречаются.
   Замысел: docs/superpowers/specs/2026-09-27-firmennyj-stil-ikpk-design.md */

/* Фирменный шрифт пульта. Файл лежит в vendor: пульт обязан подниматься без
   интернета, внешних CDN здесь не бывает. Если woff2 не загрузится, текст
   молча остаётся на системном стеке — он в хвосте font-family у body. */
@font-face {
  font-family: 'Inter';
  src: url('/vendor/fonts/InterVariable.woff2') format('woff2');
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  /* Бренд: зелёный ИКПК */
  --brand: #338035;
  --brand-hover: #3D9440;
  --brand-active: #29662A;
  --brand-soft: #E6F2E6;
  --brand-line: #ABD6AC;
  --brand-rgb: 51, 128, 53;
  /* Второй акцент: бирюза — сведения и кольцо фокуса */
  --teal: #02AEC4;
  --teal-ink: #0A7D8E;
  --teal-soft: #E3F6F8;
  --teal-rgb: 2, 174, 196;
  /* Графит: текст трёх весов */
  --ink: #263238;
  --ink-soft: #455A64;
  --ink-muted: #5C7D90;
  --ink-rgb: 38, 50, 56;
  /* Поверхности и линии */
  --bg: #F6F8F9;
  --bg-sunken: #EEF2F4;
  --surface: #FFFFFF;
  --surface-rgb: 255, 255, 255;
  --line: #E1E7EB;
  --line-strong: #C5D0D8;
  /* Статусы: цвет, чернила для текста по светлому, тройка для rgba() */
  --ok: #53A655;      --ok-ink: #2E7337;      --ok-rgb: 83, 166, 85;
  --warn: #F59E0B;    --warn-ink: #8A5B08;    --warn-rgb: 245, 158, 11;
  --danger: #E54545;  --danger-ink: #992E2E;  --danger-rgb: 229, 69, 69;
  --info: #468EF5;    --info-ink: #2F6099;    --info-rgb: 70, 142, 245;
  --past: #A3A3A3;
  /* Ряды семинаров на графике выручки: восемь цветов в постоянном порядке,
     проверены на различимость при дальтонизме на белом фоне. Жёлто-оранжевый
     предупреждений (--warn) среди них нет: он значит «внимание», а не «ряд». */
  --ser-1: #338035;
  --ser-2: #7E57C2;
  --ser-3: #D45500;
  --ser-4: #2B6CC4;
  --ser-5: #C2185B;
  --ser-6: #0A8F9E;
  --ser-7: #A0522D;
  --ser-8: #3949AB;
  --gold: #C9A227;
  /* Лиды: своя, фиолетовая семья — лид не читается ни как заявка, ни как сведения */
  --lead: #7E57C2;
  --lead-ink: #5E35B1;
  --lead-soft: #F1ECFA;
  --lead-rgb: 126, 87, 194;
  --accent-grad: linear-gradient(90deg, var(--brand), var(--teal));
  /* Форма и тени */
  --radius-sm: 6px;
  --radius: 10px;
  --radius-lg: 14px;
  --shadow-1: 0 1px 2px rgba(var(--ink-rgb), .06);
  --shadow-2: 0 2px 4px rgba(var(--ink-rgb), .05), 0 12px 28px rgba(var(--ink-rgb), .08);
  --shadow-3: 0 4px 10px rgba(var(--ink-rgb), .07), 0 24px 48px rgba(var(--ink-rgb), .14);
  /* Исторические имена --b24-*: их читают тысячи строк ниже, переименовывать
     дороже, чем оставить. Значения — только ссылки на токены выше. */
  --b24-blue: var(--brand);
  --b24-blue-dark: var(--brand-active);
  --b24-primary: var(--brand);
  --b24-primary-soft: var(--brand-soft);
  --b24-green: var(--ok);
  --b24-success: var(--ok-ink);
  --b24-red: var(--danger);
  --b24-danger: var(--danger);
  --b24-danger-ink: var(--danger-ink);
  --b24-warning: var(--warn);
  --b24-warning-ink: var(--warn-ink);
  --b24-gray: var(--past);
  --b24-bg: var(--bg);
  --b24-white: var(--surface);
  --b24-card: var(--surface);
  --b24-text: var(--ink);
  --b24-text-light: var(--ink-soft);
  --text-muted: var(--ink-muted);
  --b24-border: var(--line);
  --b24-border-strong: var(--line-strong);
  --b24-hover: rgba(var(--brand-rgb), .08);
  --b24-shadow: var(--shadow-1);
}

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

body {
  font-family: 'Inter', -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Arial, sans-serif;
  background: var(--b24-bg);
  color: var(--b24-text);
  font-size: 14px;
  line-height: 1.5;
}

/* Кольцо фокуса — одно на весь пульт и только для клавиатуры: :focus-visible
   не рисует кольцо по щелчку мыши. :where() держит специфичность нулевой,
   любое точечное правило перебьёт его без !important. Бирюза — второй акцент:
   зелёный занят действием, и фокус на зелёной кнопке был бы невидим. */
:where(button, a, input, select, textarea, [tabindex]):focus-visible {
  outline: 2px solid var(--teal);
  outline-offset: 2px;
}

/* Табличные цифры там, где числа стоят колонками или сменяются на месте:
   пропорциональные «11» и «48» разной ширины дёргают соседей при каждом
   обновлении. Часы уже моноширинные — им правило не нужно. */
.stat__value, .card__stats, .seats-input {
  font-feature-settings: 'tnum' 1;
}

/* Тихая «аура» фона: статичный градиент, без анимации и перерисовок —
   глубина бесплатно. pointer-events: none — клики проходят насквозь. */
body::before {
  content: '';
  position: fixed;
  inset: 0;
  pointer-events: none;
  z-index: -1;
  background:
    radial-gradient(900px 500px at 12% -10%, rgba(var(--brand-rgb), 0.05), transparent 60%),
    radial-gradient(700px 400px at 95% 0%, rgba(var(--teal-rgb), 0.04), transparent 60%);
}

/* HEADER */
.header {
  /* Стекло: при прокрутке контент просвечивает и размывается — шапка живёт
     над страницей, а не лежит на ней. Откат для старых браузеров — ниже. */
  background: rgba(var(--surface-rgb), 0.82);
  -webkit-backdrop-filter: blur(12px) saturate(1.4);
  backdrop-filter: blur(12px) saturate(1.4);
  border-bottom: 1px solid var(--b24-border);
  padding: 14px 24px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* Шапка переносит ряды, а не сплющивает их. Без переноса кнопки на узком
     экране сжимаются до ширины слова, подписи ломаются на две-три строки — и
     ряд «съезжает», потому что кнопки становятся вдвое выше соседей. */
  flex-wrap: wrap;
  row-gap: 10px;
  column-gap: 16px;
  position: sticky;
  top: 0;
  z-index: 10;
}

/* Тонкая градиентная линия — фирменный акцент вместо голубой полосы Б24. */
.header::before {
  content: '';
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  height: 2px;
  background: var(--accent-grad);
}

@supports not (backdrop-filter: blur(1px)) {
  .header { background: var(--b24-white); }
}

.header__inner { display: flex; align-items: center; gap: 12px; min-width: 0; }

/* Логотип. Картинка круглая с прозрачными углами, поэтому подложка не нужна —
   она бы только обвела эмблему лишним квадратом. */
.header__icon {
  width: 36px;
  height: 36px;
  object-fit: contain;
  flex-shrink: 0;
}

.header__title {
  font-size: 18px;
  font-weight: 700;
  color: var(--b24-text);
}

.header__subtitle {
  font-size: 12px;
  color: var(--b24-text-light);
  margin-top: 1px;
}

.header__controls {
  display: flex;
  align-items: center;
  /* Переносим вправо: перенесённый ряд обязан остаться под кнопками, а не
     уехать к логотипу — иначе шапка читается как два разных блока. */
  flex-wrap: wrap;
  justify-content: flex-end;
  row-gap: 8px;
  column-gap: 12px;
}

/* ─── Часы в шапке ─────────────────────────────────────────────────────────
   Дата и время рядом с логотипом: половина решений в пульте — про сроки, и
   «сейчас» обязано быть на экране. Движение живёт в motion.css, здесь только
   вид и раскладка.

   Блок стартует прозрачным и проявляется, когда js/clock.js нарисовал первый
   кадр (.clock--live). Иначе при загрузке на долю секунды мигали бы прочерки
   разметки, а если скрипт не поднялся — висели бы навсегда. */
.clock {
  position: relative;
  display: flex;
  align-items: center;
  gap: 8px;
  margin-left: 4px;
  padding-left: 12px;
  border-left: 1px solid var(--b24-border);
  /* Часы не сжимаются: усохнув, они переносят «16:42» на две строки и
     растягивают шапку. Место уступают кнопки — они переносятся сами. */
  flex-shrink: 0;
  opacity: 0;
}

.clock__col { display: flex; flex-direction: column; }

/* Моноширинные цифры обязательны: у пропорциональных «11:11» уже 4 см, а
   «08:38» — 4,3 см, и часы дёргались бы каждую минуту, двигая соседей. */
.clock__time {
  display: flex;
  align-items: baseline;
  font-size: 20px;
  font-weight: 700;
  line-height: 1.15;
  color: var(--b24-text);
  font-variant-numeric: tabular-nums;
  letter-spacing: .4px;
}
.clock__flap { display: inline-block; }
.clock__sep { margin: 0 1px; color: var(--b24-primary); }

.clock__date {
  font-size: 11px;
  line-height: 1.3;
  color: var(--text-muted);
  white-space: nowrap;
}

/* Приписка появляется только у тех, чей пояс отличается от московского:
   москвичу подпись «МСК» ничего не сообщает, а место занимает. */
.clock__msk {
  align-self: flex-start;
  margin-top: 2px;
  padding: 2px 6px;
  border-radius: 8px;
  background: var(--b24-primary-soft);
  color: var(--ink-muted);
  font-size: 10px;
  font-weight: 700;
  white-space: nowrap;
}

/* Секунды волоском, а не цифрами: цифра секунд в шапке дёргает глаз каждую
   секунду, а показать, что часы идут, надо. */
.clock__minute {
  position: absolute;
  left: 12px;
  right: 0;
  bottom: -5px;
  height: 2px;
  border-radius: 2px;
  background: var(--b24-border);
  overflow: hidden;
}
.clock__minute i {
  display: block;
  height: 100%;
  background: linear-gradient(90deg, var(--b24-blue), var(--b24-primary));
  transform: scaleX(0);
  transform-origin: left center;
}

.toggle-label {
  display: flex;
  align-items: center;
  gap: 6px;
  white-space: nowrap;
  font-size: 13px;
  color: var(--b24-text-light);
  cursor: pointer;
  user-select: none;
}

.toggle-label input { cursor: pointer; }

/* Фильтр «Только мои активности» стоит третьим в ряду одинаковых галочек, а
   меняет список сильнее прочих — поэтому он в рамке даже в покое. Включённый
   заливаем синим тем же языком, что и выбранный вид («☰ Список»): включённый
   фильтр прячет часть заявок, и неполный список обязан объяснять себя сам. */
.toggle-label--framed {
  padding: 4px 10px;
  border: 1px solid var(--b24-border);
  border-radius: var(--radius);
  color: var(--b24-text);
}
.toggle-label--framed:hover:not(.toggle-label--on) { background: var(--b24-hover); border-color: var(--brand-line); }
.toggle-label--on {
  background: var(--b24-blue);
  border-color: var(--b24-blue);
  color: var(--surface);
  font-weight: 600;
}

/* BUTTONS */
.btn {
  padding: 8px 16px;
  border-radius: var(--radius);
  border: none;
  font-size: 13px;
  font-weight: 600;
  line-height: 1.2;
  /* Подпись кнопки не переносится: «Обновить данные» в две строки делает
     кнопку вдвое выше соседних и роняет выравнивание всего ряда. */
  white-space: nowrap;
  cursor: pointer;
}
/* Отключённая кнопка одинакова у всех семейств: блёкнет, не поднимается, не
   светится и курсором говорит, что нажимать нечего. Семейства ниже своих
   :disabled не объявляют — второго места для этого состояния нет. */
.btn:disabled { opacity: .55; cursor: not-allowed; transform: none; box-shadow: none; }

/* Иконки спрайта (index.html, <symbol id="i-…">). Обводка currentColor: на заливной
   кнопке белая, на мягкой зелёная, в подписи серая — без отдельных правил цвета.
   1em и опущенная базовая линия — иконка стоит в строке как буква, не как эмодзи. */
.ico {
  width: 1em;
  height: 1em;
  vertical-align: -.15em;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
}
.btn .ico {
  margin-right: 6px;
  opacity: .85;
  transition: opacity var(--dur-quick) var(--ease-out), transform var(--dur-quick) var(--ease-out);
}
.btn:hover:not(:disabled) .ico { opacity: 1; }
/* «Отправить», «Скачать»: иконка чуть подаётся в сторону действия. */
.btn:hover:not(:disabled) .ico--go { transform: translateX(1px); }
.ico--xl { width: 48px; height: 48px; color: var(--ink-muted); }
.error__icon .ico { width: 32px; height: 32px; color: var(--danger); }
.card__hide-btn .ico { width: 13px; height: 13px; }
.modal__close .ico { width: 16px; height: 16px; display: block; }

/* Заливные кнопки — одно семейство: фирменный зелёный, сверху вниз чуть темнее,
   цветная тень вместо серой (кнопка «светится» своим цветом), подъём на 1px под
   курсором — transform, раскладку не трогает. На нажатии темнее и тень короче:
   кнопку продавили. Различаются семейства только размером. */
.btn--primary, .btn--refresh, .btn--save, .btn--report {
  background: linear-gradient(180deg, var(--brand-hover), var(--brand));
  color: var(--surface);
  border: 0;
  box-shadow: 0 2px 8px rgba(var(--brand-rgb), .35);
}
.btn--primary:hover:not(:disabled), .btn--refresh:hover:not(:disabled),
.btn--save:hover:not(:disabled), .btn--report:hover:not(:disabled) {
  background: var(--brand-hover);
  transform: translateY(-1px);
  box-shadow: 0 6px 16px rgba(var(--brand-rgb), .35);
}
.btn--primary:active:not(:disabled), .btn--refresh:active:not(:disabled),
.btn--save:active:not(:disabled), .btn--report:active:not(:disabled) {
  background: var(--brand-active);
  box-shadow: 0 1px 4px rgba(var(--brand-rgb), .3);
}

.btn--save { padding: 4px 12px; font-size: 12px; }

.btn--report { padding: 4px 12px; font-size: 12px; }

/* Выгрузка заявки в Excel: плашка семинара, шапка модалки, «Экспорт CSV».
   Одно правило на все места. Правил было два — это и второе, на 1750 строк
   ниже, — с равной специфичностью и разными значениями: фон побеждал из нижнего
   (белый), а подсветка из верхнего (тёмно-зелёная), и подпись при наведении
   пропадала на тёмном фоне. Дубль убран, значения оставлены те, что и так
   действовали; новые состояния кнопки добавлять сюда, второго места больше нет. */
.btn--export {
  background: var(--brand-soft);
  color: var(--ok-ink);
  border: 1px solid transparent;
  padding: 6px 14px;
  border-radius: 6px;
  font-size: 13px;
  cursor: pointer;
  white-space: nowrap;
}
/* Мягкое семейство: светло-зелёная подложка с тёмно-зелёной подписью (контраст
   ≈5:1, выше порога AA 4.5:1); под курсором подложка густеет до цвета линии
   бренда, кнопка приподнимается с лёгкой зелёной тенью. */
.btn--export:hover:not(:disabled) {
  background: var(--brand-line);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(var(--brand-rgb), .18);
}

/* LOADING */
.loading {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 16px;
  padding: 80px 24px;
  color: var(--b24-text-light);
}

.loading__spinner {
  width: 36px;
  height: 36px;
  border: 3px solid var(--b24-border);
  border-top-color: var(--b24-blue);
  border-radius: 50%;
  animation: spin 0.8s linear infinite;
}

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

@keyframes fadeInUp {
  from { opacity: 0; transform: translateY(12px); }
  to   { opacity: 1; transform: translateY(0); }
}

/* Каскад ограничен пятью шагами: на семинарах с тридцатью карточками честная
   лесенка заставила бы ждать последнюю почти полторы секунды.

   Каскад заперт на модификатор .seminars--fresh: его ставит render() только
   там, где человек ждал загрузку (первый заход, «Обновить», смена периода —
   всё, что прошло через скелетон), и снимает на рутинной перерисовке. render()
   пересобирает список целиком на каждое действие — сортировку, «Скрытые»,
   перетаскивание, тихое автообновление раз в 15 минут, — и без запора весь
   список заново выцветал бы и выезжал на каждый клик по чекбоксу. */
.seminars--fresh .card { animation: fadeInUp var(--dur-slow) var(--ease-out) both; }
.seminars--fresh .card:nth-child(2)      { animation-delay: 40ms; }
.seminars--fresh .card:nth-child(3)      { animation-delay: 80ms; }
.seminars--fresh .card:nth-child(4)      { animation-delay: 120ms; }
.seminars--fresh .card:nth-child(5)      { animation-delay: 160ms; }
.seminars--fresh .card:nth-child(n+6)    { animation-delay: 200ms; }

/* Календарь: та же лесенка для месяцев и тот же запор — .cal-grid--fresh ставит
   renderCalendar() только когда человек ждал загрузку; перелистывание периода
   и тихое автообновление перерисовывают сетку без анимации. Шаги равны шагам
   карточек, равенство стережёт tests/motion-css.test.mjs. */
.cal-grid--fresh .cal-month { animation: fadeInUp var(--dur-slow) var(--ease-out) both; }
.cal-grid--fresh .cal-month:nth-child(2)   { animation-delay: 40ms; }
.cal-grid--fresh .cal-month:nth-child(3)   { animation-delay: 80ms; }
.cal-grid--fresh .cal-month:nth-child(4)   { animation-delay: 120ms; }
.cal-grid--fresh .cal-month:nth-child(5)   { animation-delay: 160ms; }
.cal-grid--fresh .cal-month:nth-child(n+6) { animation-delay: 200ms; }

/* ERROR */
.error {
  text-align: center;
  padding: 60px 24px;
  color: var(--b24-red);
}
.error__icon { font-size: 32px; margin-bottom: 12px; }

/* GRID */
.seminars {
  padding: 24px;
  display: grid;
  grid-template-columns: repeat(4, 1fr);   /* 4 крупные плашки в ширину страницы */
  gap: 18px;
  align-items: stretch;     /* карточки одной строки одинаковой высоты */
  grid-auto-rows: 1fr;
}
@media (max-width: 1280px) { .seminars { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 980px)  { .seminars { grid-template-columns: repeat(2, 1fr); } }

/* CARD */
.card {
  background: var(--b24-white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-2);
  overflow: hidden;
  transition: box-shadow var(--dur-quick) var(--ease-out),
              transform var(--dur-quick) var(--ease-out);
  display: flex;
  flex-direction: column;
  height: 100%;             /* заполняет ячейку grid → единая высота */
}

.card { cursor: pointer; }
.card:hover { box-shadow: var(--shadow-3); transform: translateY(-2px); }

.card--past { opacity: 0.6; }

/* Цветная полоска сверху карточки. Свечение — тень полоски вниз своим цветом:
   статус читается издалека, не крича заливкой. Под курсором свечение густеет,
   но не тенью самой полоски (box-shadow перерисовывается каждый кадр), а
   прозрачностью псевдоэлемента с той же тенью: opacity — из разрешённых
   свойств. Цвет свечения модификатор передаёт через --accent-glow. */
.card__accent {
  position: relative;
  height: 3px;
  background: var(--line);
}
.card__accent::after {
  content: '';
  position: absolute;
  inset: 0;
  box-shadow: 0 4px 14px var(--accent-glow, transparent);
  opacity: 0;
  transition: opacity var(--dur-base) var(--ease-out);
}
.card:hover .card__accent::after { opacity: 1; }
.card__accent--green  { background: linear-gradient(90deg, var(--ok), var(--ok-ink));         box-shadow: 0 2px 8px rgba(var(--ok-rgb), .35);     --accent-glow: rgba(var(--ok-rgb), .45); }
.card__accent--orange { background: linear-gradient(90deg, var(--warn), var(--warn-ink));     box-shadow: 0 2px 8px rgba(var(--warn-rgb), .35);   --accent-glow: rgba(var(--warn-rgb), .45); }
.card__accent--red    { background: linear-gradient(90deg, var(--danger), var(--danger-ink)); box-shadow: 0 2px 8px rgba(var(--danger-rgb), .35); --accent-glow: rgba(var(--danger-rgb), .45); }

.card--urgent {
  border: 2px solid var(--danger);
  box-shadow: 0 0 0 3px rgba(var(--danger-rgb), 0.12), var(--b24-shadow);
}

.card--urgent:hover {
  box-shadow: 0 0 0 3px rgba(var(--danger-rgb), .18), var(--shadow-3);
}

/* Подпись стоит по верху плашки и ровно по её середине. Прижатая влево (так
   было раньше) она упиралась в ручку перетаскивания «⣿» вплотную, зазор
   ноль: два красных пятна в одном углу читались как одно, и глаз искал
   приоритет там, где его нет. Ширину берём по содержимому, центруем полями —
   flex с auto-полями, потому что inline-элемент auto-поля игнорирует. */
.card__priority {
  display: flex;
  align-items: center;
  justify-content: center;
  width: fit-content;
  gap: 4px;
  font-size: 11px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--b24-danger);
  background: rgba(var(--danger-rgb), 0.1);
  border-radius: 4px;
  padding: 3px 8px;
  /* Верх минус десять: кнопки в углах плашки («⣿» и «✕») стоят на 8 px от
     верха и высотой 24 px, подпись ниже их на десяток — без этой поправки
     верхняя строка «ручка — подпись — крестик» идёт уступом. Содержимое
     шапки поднимается вслед за подписью на те же десять — и хорошо: на
     плашке без приоритета заголовок стоит выше, разнобой становится меньше.
     Нижний отступ прежние 8 px, воздух до заголовка не съедаем. */
  margin: -10px auto 8px;
}

.card__header {
  padding: 16px 16px 12px;
  border-bottom: 1px solid var(--b24-border);
}

.card__name {
  font-size: 16px;
  font-weight: 700;
  color: var(--b24-text);
  margin-bottom: 4px;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;          /* ровно 2 строки, длинное — с многоточием */
  -webkit-box-orient: vertical;
  overflow: hidden;
  min-height: 2.6em;              /* фиксируем высоту заголовка под 2 строки */
}

.card__date-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.card__date {
  font-size: 13px;
  color: var(--b24-text-light);
}

.badge {
  padding: 3px 8px;
  border-radius: 20px;
  font-size: 11px;
  font-weight: 700;
  white-space: nowrap;
}

/* Тональные бейджи: цветной текст на своём же цвете 12–14% прозрачности.
   Плотная заливка кричала; тон даёт тот же смысл тише. Контраст пар ≥4.5:1. */
.badge--soon    { background: rgba(var(--warn-rgb), 0.14); color: var(--warn-ink); }
.badge--today   { background: rgba(var(--ok-rgb), 0.14);  color: var(--ok-ink); }
.badge--past    { background: rgba(var(--ink-rgb), .08); color: var(--b24-text-light); }
.badge--days    { background: rgba(var(--info-rgb), .12);  color: var(--info-ink); }

/* STATS — сетка 3 в ряд, чтобы счётчики не накладывались */
.card__stats {
  padding: 14px 12px;
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 10px 6px;
  margin-top: auto;          /* прижимаем блок статов к низу — единое выравнивание */
}

.stat {
  min-width: 0;
  text-align: center;
  padding: 4px 2px;
}

.stat__value {
  font-size: 24px;
  font-weight: 700;
  line-height: 1;
  margin-bottom: 3px;
}

.stat__label {
  font-size: 11px;
  color: var(--ink-muted);
  text-transform: uppercase;
  letter-spacing: 0.2px;
  /* Подпись счётчика пишет настройщик, и она бывает в два-три слова. Раньше
     здесь стоял white-space: nowrap — надписи были зашиты в разметке и всегда
     умещались в слово. С настраиваемыми подписями замер в браузере показал 3
     обрезанные подписи на 1280px и 2 на 400px (например «Отказались после
     звонка» — 176px в ячейке 116px): текст вылезал на соседний счётчик.
     Перенос по словам с разрывом слишком длинного слова держит её в ячейке. */
  line-height: 1.2;
  overflow-wrap: anywhere;
}

/* Код счётчика — из настроек: у заводского «Заявки» он apps (раньше класс был
   зашит в разметке карточки и назывался total). Счётчику, которого здесь нет,
   цвет не назначен — он берёт цвет текста карточки, и это нормально. */
.stat--apps   .stat__value { color: var(--b24-text); }
.stat--paid   .stat__value { color: var(--ok-ink); }
.stat--seats  .stat__value { color: var(--teal-ink); }
.stat--free   .stat__value { color: var(--b24-danger); }

/* PROGRESS */
.card__progress {
  padding: 0 16px 14px;
}

.progress-bar {
  height: 8px;
  background: var(--bg-sunken);
  border-radius: 4px;
  overflow: hidden;
  margin-bottom: 4px;
}

.progress-bar__fill {
  height: 100%;
  border-radius: 4px;
}

/* Заполнение от нуля в такт появлению своей карточки.
   Прописанный тут прежде transition: width при первой отрисовке не срабатывал —
   ширина проставлялась вместе с элементом, и переходу не от чего было
   оттолкнуться; убран как мёртвый, потому что ширину полоске задают ровно один
   раз, в разметке карточки (app.js), и больше никогда не меняют — карточка
   пересобирается целиком.
   Ширину анимируем осознанно: движение ширины и есть смысл прогресс-бара.
   Правило живёт здесь, а не в motion.css: там анимаций раскладки быть не должно,
   и за этим следит сторож из tests/motion-css.test.mjs.
   Запор на .seminars--fresh — тот же, что у каскада карточек выше: полоска
   заполняется вместе со своей карточкой и молчит на рутинной перерисовке. */
.seminars--fresh .progress-bar__fill {
  animation: bar-fill var(--dur-slow) var(--ease-out) both;
}

@keyframes bar-fill {
  from { width: 0; }
  to   { width: var(--fill, 0%); }
}

/* Задержки продублированы с лесенки .card выше — селектор в селектор, значение
   в значение. Без этого полоска стартует в момент вставки карточки в DOM, а не
   вместе с её собственным появлением: у карточек из шестой и далее (задержка
   200ms) заполнение к тому моменту, когда карточка только проявляется, уже
   почти отыграно. Сторож в tests/motion-css.test.mjs сверяет обе лесенки. */
.seminars--fresh .card:nth-child(2)      .progress-bar__fill { animation-delay: 40ms; }
.seminars--fresh .card:nth-child(3)      .progress-bar__fill { animation-delay: 80ms; }
.seminars--fresh .card:nth-child(4)      .progress-bar__fill { animation-delay: 120ms; }
.seminars--fresh .card:nth-child(5)      .progress-bar__fill { animation-delay: 160ms; }
.seminars--fresh .card:nth-child(n+6)    .progress-bar__fill { animation-delay: 200ms; }

.progress-label {
  font-size: 11px;
  color: var(--b24-text-light);
  text-align: right;
}

/* Причина вместо полосы, когда зал не вписан: та же приглушённая подпись, что
   у счётчиков, и по левому краю — это фраза, а не число у полосы. Цвета
   предупреждения здесь нет намеренно: незаполненный зал это не поломка, а
   несделанная настройка, и поле для неё в карточке сразу ниже. */
.card__progress--unknown {
  font-size: 11px;
  color: var(--ink-muted);
  line-height: 1.3;
}

/* SEATS EDITOR */
.card__seats {
  padding: 10px 16px 14px;
  border-top: 1px solid var(--b24-border);
  display: flex;
  align-items: center;
  gap: 8px;
  /* Кнопок в строке четыре — на узкой плашке они переносятся, а не выдавливают поле ввода. */
  flex-wrap: wrap;
}

.seats-label {
  font-size: 12px;
  color: var(--b24-text-light);
  flex: 1;
}

.seats-input {
  width: 64px;
  padding: 4px 8px;
  border: 1px solid var(--b24-border);
  border-radius: 4px;
  font-size: 13px;
  text-align: center;
}

.seats-input:focus { border-color: var(--teal); }
.seats-input { cursor: text; }

/* EMPTY */
.empty {
  grid-column: 1 / -1;
  text-align: center;
  padding: 60px;
  color: var(--b24-text-light);
}

.rs-select {
  width: 100%;
  padding: 8px 12px;
  border: 1px solid var(--b24-border);
  border-radius: var(--radius);
  font-size: 14px;
  color: var(--b24-text);
  background: var(--b24-white);
  cursor: pointer;
}

.rs-select:focus { border-color: var(--teal); }
.rs-select:disabled { opacity: 0.5; cursor: not-allowed; }

.rs-table {
  width: 100%;
  border-collapse: collapse;
  background: var(--b24-white);
  border-radius: var(--radius);
  box-shadow: var(--b24-shadow);
  overflow: hidden;
  font-size: 13px;
}

.rs-table thead tr {
  background: var(--b24-bg);
  border-bottom: 2px solid var(--b24-border);
}

.rs-table th {
  padding: 10px 14px;
  text-align: left;
  font-weight: 700;
  color: var(--b24-text-light);
  font-size: 11px;
  text-transform: uppercase;
  letter-spacing: 0.4px;
  white-space: nowrap;
}

.rs-table td {
  padding: 10px 14px;
  border-bottom: 1px solid var(--b24-border);
  color: var(--b24-text);
  vertical-align: middle;
}

.rs-table tbody tr:last-child td { border-bottom: none; }
.rs-table tbody tr:hover { background: var(--b24-hover); }

/* МОДАЛЬНОЕ ОКНО */
.modal-overlay {
  position: fixed;
  inset: 0;
  /* Стекло: страница под окном размывается — взгляд остаётся в окне,
     а контекст просвечивает. Откат для старых браузеров — ниже. */
  background: rgba(var(--ink-rgb), 0.45);
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  z-index: 100;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 24px;
}

@supports not (backdrop-filter: blur(1px)) {
  /* Без размытия подложка темнее — иначе контент под ней слишком читается. */
  .modal-overlay { background: rgba(var(--ink-rgb), 0.6); }
}

.modal {
  background: var(--b24-white);
  border-radius: var(--radius-lg);
  box-shadow: var(--shadow-3);
  width: 100%;
  max-width: 640px;
  max-height: 86vh;
  display: flex;
  flex-direction: column;
  overflow: hidden;
}

.modal__header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  padding: 20px 24px;
  border-bottom: 1px solid var(--b24-border);
  flex-shrink: 0;
}

.modal__title {
  font-size: 19px;
  font-weight: 700;
  color: var(--b24-text);
}

.modal__close {
  background: none;
  border: none;
  font-size: 18px;
  color: var(--b24-text-light);
  cursor: pointer;
  padding: 4px 8px;
  border-radius: 4px;
  line-height: 1;
}
.modal__close:hover { background: var(--b24-hover); color: var(--ink); }

.modal__body {
  padding: 24px;
  overflow-y: auto;
  flex: 1;
  font-size: 15px;
}

.btn--primary {
  padding: 8px 18px;
  border-radius: var(--radius);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
}

.btn--ghost {
  background: transparent;
  color: var(--b24-text-light);
  border: 1px solid var(--b24-border);
  padding: 7px 14px;
  border-radius: var(--radius);
  font-size: 13px;
  cursor: pointer;
}
/* Подсветка фоном обязательна: правило красило подпись в белый, оставляя фон
   прозрачным, а все четыре кнопки этого класса стоят на белом (панель выбора,
   модалка дублей, архив и пересборка в подвале отчёта) — под курсором текст
   попросту исчезал. Цвет заливки берём тот же, что уже стоял у рамки.
   :not(:disabled) — чтобы выключенная кнопка архива (оплативших нет либо сборка
   идёт) не отзывалась на наведение и не выглядела нажимаемой. */
.btn--ghost:hover:not(:disabled) {
  background: var(--ink-soft);
  color: var(--surface);
  border-color: var(--ink-soft);
  transform: translateY(-1px);
  box-shadow: 0 4px 12px rgba(var(--ink-rgb), .18);
}

/* SORTABLE TABLE HEADERS */
.rs-table th.sortable {
  cursor: pointer;
  user-select: none;
}
.rs-table th.sortable:hover { background: var(--b24-hover); }

.sort-icon {
  display: inline-block;
  margin-left: 4px;
  font-size: 12px;
  color: var(--b24-text-light);
  transition: color var(--dur-quick) var(--ease-out);
}
.rs-table th.sortable:hover .sort-icon { color: var(--b24-blue); }

/* ─── МОДАЛКА СДЕЛОК СЕМИНАРА ─────────────────────────────────────────────── */

.modal--deals {
  max-width: 900px;
  max-height: 85vh;
}

.modal__meta {
  font-size: 12px;
  color: var(--b24-text-light);
  margin-top: 2px;
}

.deals-filter-bar {
  padding: 10px 16px;
  border-bottom: 1px solid var(--b24-border);
  flex-shrink: 0;
}

.deals-search {
  width: 100%;
  padding: 7px 14px;
  border: 1px solid var(--b24-border);
  border-radius: 20px;
  font-size: 13px;
  color: var(--b24-text);
  transition: border-color var(--dur-quick) var(--ease-out);
}
.deals-search:focus { border-color: var(--teal); }

.deals-list {
  list-style: none;
  padding: 0;
  margin: 0;
}

.deal-item {
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 11px 20px;
  border-bottom: 1px solid var(--b24-border);
  cursor: pointer;
  text-decoration: none;
  color: inherit;
  transition: background var(--dur-quick) var(--ease-out);
}
.deal-item:last-child { border-bottom: none; }
.deal-item:hover { background: var(--b24-primary-soft); }

.deal-item__avatar {
  width: 38px;
  height: 38px;
  border-radius: 50%;
  background: linear-gradient(135deg, var(--b24-blue) 0%, var(--b24-blue-dark) 100%);
  color: var(--surface);
  font-size: 14px;
  font-weight: 700;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  text-transform: uppercase;
}

.deal-item__info {
  flex: 1;
  min-width: 0;
}

.deal-item__name {
  font-size: 15px;
  font-weight: 600;
  color: var(--b24-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.deal-item__sub {
  font-size: 12px;
  color: var(--b24-text-light);
  margin-top: 2px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.deal-item--done { opacity: 0.7; }
.deal-item--done:hover { opacity: 1; }

.deal-item__avatar--done {
  background: linear-gradient(135deg, var(--b24-gray) 0%, var(--ink-muted) 100%);
}

.deal-item__stage {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: var(--radius);
  white-space: nowrap;
}
.deal-item__stage--active { background: rgba(var(--info-rgb), .12); color: var(--info-ink); }
.deal-item__stage--won    { background: rgba(var(--ok-rgb), .12); color: var(--b24-success); }
.deal-item__stage--lost   { background: rgba(var(--danger-rgb), .10); color: var(--b24-danger); }

.deal-item__paid {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: var(--radius);
}
.deal-item__paid--yes { background: rgba(var(--ok-rgb), .12); color: var(--b24-success); }
.deal-item__paid--no  { background: var(--b24-bg); color: var(--b24-text-light); }

.deals-empty {
  padding: 40px 20px;
  text-align: center;
  color: var(--b24-text-light);
  font-size: 14px;
}

.deals-stats {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 10px 16px;
  background: var(--b24-bg);
  border-bottom: 1px solid var(--b24-border);
  font-size: 13px;
  flex-shrink: 0;
}

.deals-stat { display: flex; align-items: center; gap: 6px; }
.deals-stat__num { font-weight: 700; font-size: 19px; }
.deals-stat__num--green { color: var(--b24-green); }
.deals-stat__num--blue  { color: var(--teal-ink); }
.deals-stat__label { color: var(--ink-muted); font-size: 13px; }

/* Чипы-фильтры: клик по счётчику фильтрует список. Активный подсвечен. */
.deals-stat--btn {
  border: 1px solid transparent;
  background: transparent;
  padding: 5px 11px;
  border-radius: 9px;
  cursor: pointer;
  font: inherit;
  line-height: 1;
}
.deals-stat--btn:hover { background: var(--b24-hover); }
.deals-stat--btn.deals-stat--active {
  background: var(--surface);
  border-color: var(--brand-line);
  box-shadow: 0 1px 3px rgba(var(--ink-rgb), .1);
}
.deals-stat--btn .deals-stat__label { cursor: pointer; }

/* ══════════════════════════════════════════════════════════════
   Переключатель вида (список / календарь)
   ══════════════════════════════════════════════════════════════ */

.view-toggle {
  display: flex;
  border: 1px solid var(--b24-border);
  border-radius: var(--radius);
  overflow: hidden;
  flex-shrink: 0;
}

.view-btn {
  padding: 5px 14px;
  border: none;
  background: var(--b24-white);
  color: var(--b24-text-light);
  font-size: 12px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.view-btn + .view-btn { border-left: 1px solid var(--b24-border); }
.view-btn:hover { background: var(--b24-hover); color: var(--ink); }
.view-btn--active { background: var(--b24-blue) !important; color: var(--surface) !important; }

/* ══════════════════════════════════════════════════════════════
   Сортировка и скрытие карточек
   ══════════════════════════════════════════════════════════════ */

.sort-group {
  display: flex;
  align-items: center;
  gap: 6px;
}

/* Список семинаров в шапке. Размером — как выбор года в календаре, но названия
   программ длинные: ширину ограничиваем, обрезку делает сам список. */
.seminar-select { width: auto; max-width: 220px; padding: 5px 8px; font-size: 13px; }

/* Счётчик рядом с кнопками отбора: «плашек: 2 из 4, из них вид угадан у 1».
   Отфильтрованный список обязан сам сказать, какую часть он показывает, иначе
   «мало плашек» читается как потеря данных. Тон приглушённый — это подпись к
   кнопкам, а не их часть. */
.plate-count {
  white-space: nowrap;
  font-size: 12px;
  color: var(--b24-text-light);
}

.btn--sort {
  background: var(--b24-white);
  color: var(--b24-text);
  border: 1px solid var(--b24-border);
  padding: 5px 12px;
  font-size: 12px;
  font-weight: 600;
  border-radius: var(--radius);
  cursor: pointer;
  white-space: nowrap;
}
.btn--sort:hover { background: var(--b24-hover); border-color: var(--brand-line); color: var(--brand-active); }

.btn--sort-reset {
  background: none;
  border: 1px solid var(--b24-border);
  color: var(--b24-text-light);
  padding: 5px 10px;
  font-size: 14px;
  border-radius: var(--radius);
  cursor: pointer;
}
.btn--sort-reset:hover { background: var(--b24-hover); color: var(--brand-active); border-color: var(--brand-line); }

/* Бейдж количества скрытых */
.hidden-badge {
  display: inline-block;
  background: var(--b24-gray);
  color: var(--surface);
  font-size: 11px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: var(--radius);
  margin-left: 2px;
}

/* ── Кнопка скрытия на карточке ── */

.card { position: relative; }

.card__hide-btn {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 24px;
  height: 24px;
  border-radius: 50%;
  border: none;
  background: rgba(var(--ink-rgb),0.08);
  color: var(--b24-text-light);
  cursor: pointer;
  font-size: 11px;
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.7;              /* видна всегда, чтобы было понятно — можно скрыть */
  z-index: 3;
  line-height: 1;
}
.card:hover .card__hide-btn { opacity: 1; }
.card__hide-btn:hover { background: rgba(var(--ink-rgb),0.18); color: var(--b24-text); }

/* ── Drag handle ── */

.card__drag-handle {
  position: absolute;
  top: 8px;
  left: 8px;
  font-size: 14px;
  color: var(--b24-gray);
  cursor: grab;
  opacity: 0.7;              /* видна всегда — подсказка, что плашку можно перетащить */
  transition: opacity var(--dur-quick) var(--ease-out),
              color var(--dur-quick) var(--ease-out);
  z-index: 3;
  user-select: none;
  line-height: 1;
}
.card:hover .card__drag-handle { opacity: 1; }
.card__drag-handle:hover { color: var(--b24-text); }

/* ── Drag состояния ── */

.card[draggable="true"] { cursor: default; }

.card--dragging {
  opacity: 0.4;
  transform: scale(0.98);
}

.card--drag-over {
  outline: 2px solid var(--brand);
  outline-offset: 2px;
  transform: scale(1.02);
}

/* ── Скрытые карточки ── */

.card--hidden {
  opacity: 0.45;
  filter: grayscale(40%);
}
.card--hidden .card__hide-btn {
  opacity: 1;
  color: var(--teal-ink);
  background: rgba(var(--teal-rgb), 0.12);
}

/* ══════════════════════════════════════════════════════════════
   Календарный вид
   ══════════════════════════════════════════════════════════════ */

.calendar-wrap {
  padding: 16px 16px 40px;
}

/* ── Сетка месяцев ── */
.cal-grid {
  display: grid;
  gap: 12px;
  align-items: start;
}
/* Колонок столько, сколько месяцев в виде: 6 месяцев — по два в ряд, год и два
   года — по три. Без этих двух строк grid остаётся с одной колонкой, и все три
   периода выглядят одинаковым столбиком: переключение «Год → 2 года» уезжает
   на тринадцать тысяч пикселей вниз и с экрана не видно вовсе.

   Имя класса в коде не написано: app.js собирает его склейкой
   'cal-grid cal-grid--' + (calMonths <= 6 ? '2col' : '3col'). Поиск по
   «cal-grid--3col» даёт ноль совпадений и в стилях, и в скриптах — правило
   однажды сочли мёртвым и вырезали. Шов сторожит tests/front-css-modifiers. */
.cal-grid--2col { grid-template-columns: repeat(2, 1fr); }
.cal-grid--3col { grid-template-columns: repeat(3, 1fr); }

/* ── Блок одного месяца ── */
.cal-month {
  background: var(--b24-white);
  border-radius: var(--radius);
  box-shadow: var(--b24-shadow);
  overflow: hidden;
  min-width: 0; /* не распирать колонку */
}

.cal-month__header {
  background: var(--b24-blue);
  color: var(--surface);
  font-size: 13px;
  font-weight: 700;
  padding: 8px 12px;
  letter-spacing: 0.3px;
}

/* ── Сетка дней ── */
.cal-days-grid {
  display: grid;
  grid-template-columns: repeat(7, 1fr);
  gap: 1px;
  background: var(--b24-border);
  border-top: 1px solid var(--b24-border);
}

.cal-weekday {
  background: var(--b24-bg);
  text-align: center;
  font-size: 9px;
  font-weight: 700;
  color: var(--b24-text-light);
  padding: 4px 0;
  text-transform: uppercase;
  letter-spacing: 0;
  aspect-ratio: auto; /* заголовки не квадратные */
}

.cal-day {
  background: var(--b24-white);
  aspect-ratio: 1;
  overflow: hidden;
  padding: 4px;
  position: relative;
  box-sizing: border-box;
}
.cal-day--empty {
  background: var(--bg);
  aspect-ratio: 1;
}
.cal-day--past   { background: var(--bg-sunken); }
.cal-day--today  { background: var(--teal-soft); }

.cal-day--today .cal-day__num {
  background: var(--teal);
  color: var(--surface);
  border-radius: 50%;
  width: 18px;
  height: 18px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-weight: 700;
}

.cal-day--has-seminar { background: rgba(var(--ok-rgb), .08); }

.cal-day__num {
  display: block;
  font-size: 10px;
  color: var(--b24-text-light);
  font-weight: 500;
  line-height: 18px;
  padding: 0 1px;
}

/* ── Виджет семинара ── */
.cal-widget {
  background: var(--b24-white);
  border-left: 3px solid var(--b24-green);
  border-radius: 3px;
  padding: 2px 4px;
  margin-top: 2px;
  cursor: pointer;
  transition: box-shadow var(--dur-quick) var(--ease-out);
  box-shadow: 0 1px 2px rgba(var(--ink-rgb),0.07);
  overflow: hidden;
}
.cal-widget:hover { box-shadow: 0 2px 6px rgba(var(--ink-rgb),0.14); }
.cal-widget--past { opacity: 0.5; }

.cal-widget__name {
  font-size: 10px;
  font-weight: 600;
  color: var(--b24-text);
  line-height: 1.2;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.cal-widget__stats {
  display: flex;
  align-items: center;
  gap: 4px;
  margin-top: 1px;
}

.cal-widget__stat {
  font-size: 9px;
  color: var(--b24-text-light);
  white-space: nowrap;
}

.cal-widget__paid {
  font-size: 9px;
  color: var(--b24-green);
  font-weight: 700;
  white-space: nowrap;
}

/* ── Навигация календаря ── */

.cal-nav {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 0 0 12px;
}

.cal-nav-title {
  flex: 1;
  text-align: center;
  font-size: 15px;
  font-weight: 700;
  color: var(--b24-text);
}

.cal-nav-btn {
  padding: 6px 14px;
  border: 1px solid var(--b24-border);
  border-radius: var(--radius);
  background: var(--b24-white);
  color: var(--b24-text);
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
  white-space: nowrap;
}
.cal-nav-btn:hover { background: var(--b24-hover); border-color: var(--brand-line); color: var(--brand-active); }
.cal-nav-btn--today {
  background: var(--b24-blue);
  color: var(--surface);
  border-color: var(--b24-blue);
}
.cal-nav-btn--today:hover { background: var(--b24-blue-dark); border-color: var(--b24-blue-dark); color: var(--surface); }

/* ── Легенда ── */

.cal-legend {
  display: flex;
  gap: 16px;
  padding: 0 0 14px;
  flex-wrap: wrap;
}

.cal-legend-item {
  display: flex;
  align-items: center;
  gap: 5px;
  font-size: 12px;
  color: var(--b24-text-light);
}

.cal-legend-dot {
  width: 10px;
  height: 10px;
  border-radius: 50%;
  flex-shrink: 0;
}

/* Цвет точки задаёт класс, а не inline-стиль из app.js: скрипты фронта цветов не знают. */
.cal-legend-dot--ok     { background: var(--ok); }
.cal-legend-dot--warn   { background: var(--warn); }
.cal-legend-dot--danger { background: var(--danger); }
.cal-legend-dot--past   { background: var(--past); }

/* ── Плашки-чипы (режим год) ── */

.cal-chip {
  display: block;
  border-left: 2px solid var(--ok);
  border-radius: 2px;
  padding: 1px 3px;
  font-size: 9px;
  font-weight: 600;
  color: var(--b24-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  cursor: pointer;
  margin-top: 1px;
  line-height: 1.4;
  transition: transform var(--dur-quick) var(--ease-out), box-shadow var(--dur-quick) var(--ease-out);
}
.cal-chip:hover { transform: translateY(-1px); box-shadow: 0 2px 6px rgba(var(--ink-rgb), .18); }
.cal-chip--past { opacity: 0.55; }

/* ── Popover ── */

.cal-popover {
  position: absolute;
  z-index: 9999;
  background: var(--b24-white);
  border: 1px solid var(--b24-border);
  border-radius: var(--radius);
  box-shadow: 0 6px 24px rgba(var(--ink-rgb),0.15);
  padding: 14px 16px;
  width: 240px;
  pointer-events: none;
}

.cal-pop__name {
  font-size: 13px;
  font-weight: 700;
  color: var(--b24-text);
  margin-bottom: 4px;
  line-height: 1.3;
}

.cal-pop__date {
  font-size: 12px;
  color: var(--b24-text-light);
  margin-bottom: 10px;
}

.cal-pop__row {
  display: flex;
  gap: 12px;
  margin-bottom: 8px;
}

.cal-pop__stat {
  font-size: 13px;
  color: var(--b24-text-light);
}
.cal-pop__stat b { color: var(--b24-text); font-size: 15px; }
.cal-pop__stat--green b { color: var(--b24-green); }

.cal-pop__bar-wrap {
  height: 6px;
  background: var(--b24-border);
  border-radius: 3px;
  overflow: hidden;
  margin-bottom: 4px;
}

.cal-pop__bar-fill {
  height: 100%;
  border-radius: 3px;
  transition: width var(--dur-slow) var(--ease-out);
}

.cal-pop__pct {
  font-size: 11px;
  color: var(--b24-text-light);
  text-align: right;
  margin-bottom: 8px;
}

.cal-pop__hint {
  font-size: 11px;
  color: var(--b24-text-light);
  border-top: 1px solid var(--b24-border);
  padding-top: 6px;
  margin-top: 2px;
  font-style: italic;
}

/* ─── Кнопка "Задача" в шапке модалки сделок ─────────────────────────────── */
.modal__header-actions {
  display: flex;
  align-items: center;
  gap: 8px;
}

/* ─── Модалка создания задачи ─────────────────────────────────────────────── */
.modal--task { max-width: 580px; width: 100%; }

/* ─── Список семинаров в заголовке месяца календаря ──────────────────────── */
.cal-month__semlist {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 6px 10px 8px;
  border-bottom: 1px solid var(--b24-border);
  background: var(--b24-bg);
  height: 88px; /* ~4 строки — одинаково для всех месяцев */
  overflow-y: auto;
  overflow-x: hidden;
}
.cal-semlist__empty {
  font-size: 12px;
  color: var(--b24-text-light);
  padding: 4px 6px;
  font-style: italic;
}
.cal-semlist__item {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 3px 6px;
  border-radius: 5px;
  cursor: pointer;
  transition: background var(--dur-quick) var(--ease-out);
  min-width: 0;
}
.cal-semlist__item:hover { background: var(--b24-hover); }
.cal-semlist__item--past { opacity: 0.55; }
.cal-semlist__item--past:hover { opacity: 0.85; }
.cal-semlist__dot {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  flex-shrink: 0;
}
.cal-semlist__day {
  font-size: 11px;
  font-weight: 700;
  color: var(--b24-text-light);
  min-width: 16px;
  text-align: right;
  flex-shrink: 0;
}
.cal-semlist__name {
  font-size: 12px;
  color: var(--b24-text);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  flex: 1;
  min-width: 0;
}
.cal-semlist__count {
  font-size: 11px;
  font-weight: 600;
  color: var(--b24-text-light);
  background: var(--b24-border);
  border-radius: var(--radius);
  padding: 1px 6px;
  flex-shrink: 0;
}

/* ════════════════════════════════════════════════════════════════
   АДАПТИВНОСТЬ (мобильные / планшеты)
   ════════════════════════════════════════════════════════════════ */

/* ─── A1: Шапка, вкладки, контейнер ─── */
@media (max-width: 768px) {
  .header { flex-direction: column; align-items: stretch; gap: 10px; padding: 12px 14px; }
  .header__controls { flex-wrap: wrap; gap: 8px; }
  .app { padding-left: 12px; padding-right: 12px; }
}
@media (max-width: 480px) {
  .header__title { font-size: 18px; }
  .header__controls .btn, .header__controls .view-btn { font-size: 12px; padding: 6px 10px; }
}

/* ─── A2: Таблицы ─── */
@media (max-width: 768px) {
  .rs-table{ min-width: 560px; }
  .rs-table th, .rs-table td{
    padding: 8px 10px; font-size: 13px;
  }
}

/* ─── A3: Модалки ─── */
@media (max-width: 768px) {
  .modal-overlay { padding: 10px; align-items: flex-start; }
  .modal{ max-width: 100%; width: 100%; max-height: 92vh; }
  .modal__body { padding: 16px; }
  .modal__header { padding: 12px 16px; }
}

.sem-cal { font-size: 13px; }

/* Многодневный семинар — непрерывная полоса на фиксированной дорожке (абсолютная) */
.cal-bar {
  position: absolute;
  height: 18px;
  line-height: 18px;
  padding: 0 5px;
  font-size: 11px;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
  border-top: 1px solid;
  border-bottom: 1px solid;
  color: var(--ink);
  cursor: pointer;
  box-sizing: border-box;
  z-index: 2;
  transition: box-shadow var(--dur-quick) var(--ease-out);
}
.cal-bar--start {
  border-left: 1px solid;
  border-top-left-radius: 9px;
  border-bottom-left-radius: 9px;
  font-weight: 600;
}
.cal-bar--end {
  border-right: 1px solid;
  border-top-right-radius: 9px;
  border-bottom-right-radius: 9px;
}
.cal-bar--past { opacity: 0.5; }
/* 100px — больше любой высоты полосы: внутренняя тень заливает сегмент целиком.
   Тень, а не фон, потому что фон полосы ставит app.js инлайном через color-mix,
   и CSS-фон проиграл бы инлайну. */
.cal-bar:hover { box-shadow: inset 0 0 0 100px rgba(var(--ink-rgb), .06); }

/* ─── Хаб действий над семинаром ─── */
.modal--hub { max-width: 520px; }
.hub-meta { margin-bottom: 18px; }
.hub-dates { font-size: 15px; font-weight: 600; color: var(--b24-text); margin-bottom: 6px; }
.hub-stats { color: var(--text-muted); font-size: 14px; }
.hub-actions { display: flex; flex-direction: column; gap: 10px; }
.btn--danger { background: var(--danger); color: var(--surface); border-color: var(--danger); box-shadow: 0 2px 8px rgba(var(--danger-rgb), .35); }
.btn--danger:hover:not(:disabled) { background: var(--danger-ink); border-color: var(--danger-ink); transform: translateY(-1px); box-shadow: 0 6px 16px rgba(var(--danger-rgb), .35); }

.sem-form-row { display: flex; gap: 12px; margin-bottom: 14px; flex-wrap: wrap; }
.sem-form-row label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; flex: 1; min-width: 140px; }
.sem-form-row input, .sem-form-row select { padding: 7px 9px; border: 1px solid var(--b24-border); border-radius: 6px; font-size: 14px; }
.sem-form-err { color: var(--b24-danger); font-size: 13px; margin-bottom: 10px; }
#semFormSubmit { width: 100%; }

/* Место проведения семинара */
.card__venue { font-size: 12px; color: var(--text-muted); margin-top: 4px; }
.hub-venue { font-size: 14px; color: var(--b24-text); margin: 4px 0; }

/* События из заявок */
.modal--cand { max-width: 720px; }
.cand-hint { color: var(--text-muted); font-size: 13px; margin-bottom: 12px; line-height: 1.5; }
.cand-toolbar { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; font-size: 13px; }
.cand-list { max-height: 50vh; overflow-y: auto; border: 1px solid var(--b24-border); border-radius: 8px; }
.cand-item { display: flex; align-items: center; gap: 10px; padding: 8px 12px; border-bottom: 1px solid var(--b24-border); cursor: pointer; }
.cand-item:last-child { border-bottom: none; }
.cand-item:hover { background: var(--b24-hover); }
.cand-name { flex: 1; font-size: 13px; font-weight: 600; }
.cand-meta { font-size: 12px; color: var(--text-muted); white-space: nowrap; }
.cand-empty { padding: 24px; text-align: center; color: var(--text-muted); }
#candSubmit { width: 100%; margin-top: 12px; }

/* Воронка/стадия сделки в списке участников */
.deal-item__funnel { font-size: 11px; color: var(--text-muted); margin-top: 3px; }
.deal-item__funnel-name { font-weight: 600; color: var(--b24-primary); }

/* Строка клиента — кликабельна (открывает сделку в Б24) */
.deal-item--clickable { cursor: pointer; }
.deal-item--clickable:hover { background: var(--b24-hover); }

/* Небольшое окно строго по центру экрана: подтверждение действия. Имя класса
   осталось от PIN-окна исходного пульта, где так же стоял запрос общего
   кода. */
.pin-center-overlay {
  position: fixed;
  inset: 0;
  display: none;
  align-items: center;
  justify-content: center;
  background: rgba(var(--ink-rgb),0.45);
  z-index: 10000;
}
.modal--pin-center {
  max-width: 340px;
  width: 90%;
  margin: 0;
}

/* Выбор года в календаре */
.calyear-select { padding: 5px 8px; font-size: 13px; border-radius: var(--radius); border: 1px solid var(--b24-border); background: var(--b24-white); cursor: pointer; }

/* Ячейка дня кликабельна — создать семинар. Обычный день берёт зелёную кайму:
   добавление — действие. Сегодняшний день уже стоит на бирюзовой подложке, и
   зелёная кайма на ней смешала бы две семьи — ему кайма из семьи бирюзы. */
.cal-day--add { cursor: pointer; }
.cal-day--add:hover { box-shadow: inset 0 0 0 2px var(--b24-primary); }
.cal-day--today.cal-day--add:hover { box-shadow: inset 0 0 0 2px var(--teal); }

/* Пройденная плашка с проблемными сделками — требует внимания.
   Название, подсказку и цвет полосы задаёт сработавшее правило подсветки из
   настроек: цвет — один из пяти разрешённых (rule-settings.js COLORS), и для
   каждого здесь своя пара «подложка полосы + кайма карточки». Заводской —
   оранжевый; --attn-color держит оба цвета в одном месте. */
.card--attention { --attn-color: var(--b24-danger); box-shadow: 0 0 0 2px var(--attn-color), var(--b24-shadow); }
.card--attention--red    { --attn-color: var(--b24-danger); }
.card--attention--orange { --attn-color: var(--warn); }
.card--attention--yellow { --attn-color: var(--gold); }
.card--attention--blue   { --attn-color: var(--teal-ink); }
.card--attention--green  { --attn-color: var(--b24-success); }

.card__attention {
  display: inline-block;
  max-width: 100%;
  background: var(--b24-danger);
  color: var(--surface);
  font-size: 11px;
  font-weight: 700;
  line-height: 1.35;
  padding: 2px 8px;
  border-radius: 6px;
  margin-bottom: 6px;
}
/* Полоса берёт цвет карточки, если он задан правилом, и свой — если полоса
   стоит сама по себе (цвет правила меняется независимо от каймы). */
.card__attention--red    { background: var(--b24-danger); }
.card__attention--orange { background: var(--warn); }
.card__attention--yellow { background: var(--gold); }
.card__attention--blue   { background: var(--teal-ink); }
.card__attention--green  { background: var(--b24-success); }

/* Модалка подтверждения (дубликат семинара) */
.confirm-text { font-size: 14px; line-height: 1.5; color: var(--b24-text); margin-bottom: 18px; text-align: center; }
.confirm-actions { display: flex; gap: 10px; }
.confirm-actions .btn { flex: 1; }

/* Бездатная сделка в списке участников — подсветка красным */
.deal-item--undated { background: rgba(var(--danger-rgb), .10); }
.deal-item--undated:hover { background: rgba(var(--danger-rgb), .18); }
.deal-item__undated {
  display: inline-block;
  margin-left: 8px;
  background: var(--b24-danger);
  color: var(--surface);
  font-size: 10px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 5px;
  vertical-align: middle;
}

/* Стат «В резерве» (донабор) */
.stat--reserve .stat__value { color: var(--b24-success); }

/* Статус «В резерве» (бездатные кандидаты) — красный */
.deal-item__stage--reserve { background: var(--b24-danger); color: var(--surface); }

/* ════════════════════════════════════════════════════════════════
   МОБИЛЬНАЯ АДАПТАЦИЯ (телефоны) — добавлено отдельным слоем,
   только переопределения, существующие десктоп-стили не трогаем.
   ════════════════════════════════════════════════════════════════ */

@media (max-width: 640px) {

  /* ─── Шапка ─── */
  .header__inner { flex-wrap: wrap; gap: 8px; }
  .header__title { font-size: 18px; }
  .header__subtitle { font-size: 11px; }
  /* Часы на телефоне: остаются число и время — то, ради чего они и стоят.
     Подпись дня недели и приписка про Москву переносили бы шапку на третью
     строку, а число всё равно написано на плашке календаря. */
  .clock { gap: 8px; margin-left: 0; padding-left: 10px; }
  .clock__time { font-size: 18px; }
  .clock__date, .clock__msk { display: none; }
  .clock__minute { left: 10px; }
  .header__controls { flex-wrap: wrap; gap: 6px; align-items: stretch; }
  .toggle-label { font-size: 12px; }

  /* Кнопки шапки/сортировки/вида — компактнее, текст целиком */
  .header__controls .btn,
  .header__controls .btn--sort,
  .header__controls .view-btn {
    font-size: 12px;
    padding: 7px 10px;
    white-space: nowrap;
  }
  /* Важные кнопки с текстом не обрезаем */
  #newSeminarBtn, #fillFromDealsBtn { font-size: 12px; padding: 7px 10px; white-space: nowrap; }
  .view-toggle { flex-wrap: wrap; }
  .sort-group { flex-wrap: wrap; gap: 6px; }
  .calyear-select { font-size: 12px; padding: 5px 6px; }
  .seminar-select { font-size: 12px; padding: 5px 6px; max-width: 160px; }

  

  /* ─── Набор семинаров: одна колонка ─── */
  .seminars { grid-template-columns: 1fr; padding: 12px; gap: 12px; }

  /* Статы: 5 в ряд тесно — разрешаем перенос по 3 и уменьшаем шрифт */
  .card__stats { flex-wrap: wrap; padding: 12px 8px; }
  .stat { flex: 1 1 33%; padding: 4px 2px; border-right: none; }
  .stat__value { font-size: 16px; }
  .stat__label { font-size: 9px; }

  /* На телефоне месяц занимает всю ширину при любом периоде. */
  .cal-grid--2col, .cal-grid--3col { grid-template-columns: 1fr; }
  .cal-nav { flex-wrap: wrap; gap: 8px; padding-bottom: 10px; }
  .cal-nav-title { flex: 1 1 100%; order: -1; font-size: 14px; }
  .cal-nav-btn { padding: 6px 10px; font-size: 12px; }
  .cal-month__header { font-size: 12px; padding: 7px 10px; }
  .cal-day { padding: 2px; }
  .cal-day__num { font-size: 9px; line-height: 16px; }
  .cal-widget { padding: 1px 3px; }
  .cal-widget__name { font-size: 9px; }
  .cal-widget__stat, .cal-widget__paid { font-size: 8px; }
  .cal-bar { font-size: 10px; padding: 0 3px; }
  .cal-chip { font-size: 8px; }
  .cal-legend { gap: 10px; }
  .cal-legend-item { font-size: 11px; }

  /* ─── Модалки (универсально) ─── */
  .modal-overlay { padding: 12px; }
  .modal,
  .modal--hub, .modal--cand, .modal--deals, .modal--task{
    width: 100%;
    max-width: 100%;
    max-height: 90vh;
    overflow-y: auto;
  }
  .modal--pin-center { width: 100%; max-width: 100%; }

  /* Сделки в модалке */
  .deals-stats { flex-wrap: wrap; gap: 10px 16px; }
  .deal-item { padding: 10px 12px; gap: 10px; }
  .deal-item__info { min-width: 0; }
  .deal-item__name, .deal-item__sub { overflow: hidden; text-overflow: ellipsis; }
  .modal__header-actions { flex-wrap: wrap; gap: 6px; }

  /* Форма семинара */
  .sem-form-row { flex-direction: column; gap: 10px; }
  .sem-form-row label { min-width: 0; width: 100%; }

  /* Кандидаты */
  .cand-item { flex-wrap: wrap; }
  .cand-meta { white-space: normal; }
  .cand-toolbar { flex-wrap: wrap; gap: 6px; }

  

  

  
  .rs-select { width: 100%; }

  

  

  
}

@media (max-width: 400px) {

  .header__title { font-size: 17px; }
  .header__controls .btn,
  .header__controls .btn--sort,
  .header__controls .view-btn,
  #newSeminarBtn, #fillFromDealsBtn { font-size: 11px; padding: 6px 8px; }

  /* Статы ещё мельче, чтобы цифры не наезжали */
  .stat__value { font-size: 15px; }
  .stat__label { font-size: 8px; }

  /* Календарь — самые узкие экраны */
  .cal-day__num { font-size: 8px; }
  .cal-widget__name { font-size: 8px; }
  .cal-weekday { font-size: 8px; }
}

/* Лиды: счётчик на плашке, строка и тег в списке */
.stat--leads .stat__value { color: var(--lead-ink); }
.deals-stat__num--lead { color: var(--lead-ink); }
.deal-item--lead { background: var(--lead-soft); }
.deal-item--lead:hover { background: rgba(var(--lead-rgb), .16); }
.deal-item__lead {
  display: inline-block;
  margin-left: 8px;
  background: var(--lead);
  color: var(--surface);
  font-size: 10px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 5px;
  vertical-align: middle;
}

/* Донабор: счётчик на плашке, тег в списке (тёплая база с прошлых запусков) */
.stat--refill .stat__value { color: var(--warn-ink); }
.deals-stat__num--refill { color: var(--warn-ink); }
.deal-item--refill { background: rgba(var(--warn-rgb), .12); }
.deal-item--refill:hover { background: rgba(var(--warn-rgb), .24); }
.deal-item__stage--refill { background: var(--warn); color: var(--surface); }
.deal-item__refill {
  display: inline-block;
  margin-left: 8px;
  background: var(--warn);
  color: var(--surface);
  font-size: 10px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 5px;
  vertical-align: middle;
}

/* Подсказка под чипами: во время поиска список шире выбранной категории. */
.deals-hint {
  margin: -4px 0 10px;
  padding: 0 4px;
  font-size: 12px;
  color: var(--ink-muted);
}

/* Другая дата: заявка того же семинара, но в сделке стоит другой день. В счёт
   плашки не идёт (иначе цифра соврёт) — лежит под своим чипом, с датой в строке. */
.deals-stat__num--other { color: var(--warn-ink); }
.deal-item--other { background: rgba(var(--warn-rgb), .08); }
.deal-item--other:hover { background: rgba(var(--warn-rgb), .18); }
.deal-item__other {
  display: inline-block;
  margin-left: 8px;
  background: rgba(var(--warn-rgb), .18);
  color: var(--warn-ink);
  border: 1px solid rgba(var(--warn-rgb), .35);
  font-size: 10px;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 5px;
  vertical-align: middle;
}

/* Кнопка «дата плашки»: ставит в самой сделке дату этого запуска. Стоит только на
   строках с разошедшейся датой, поэтому цвет тот же тревожный, что и у метки рядом. */
.deal-item__fix {
  flex-shrink: 0;
  margin-right: 10px;
  background: var(--surface);
  color: var(--warn-ink);
  border: 1px solid rgba(var(--warn-rgb), .45);
  font-size: 11px;
  font-weight: 600;
  padding: 4px 10px;
  border-radius: 6px;
  cursor: pointer;
  white-space: nowrap;
  transition: background var(--dur-quick) var(--ease-out),
              border-color var(--dur-quick) var(--ease-out);
}
.deal-item__fix:hover:not(:disabled) { background: rgba(var(--warn-rgb), .18); border-color: rgba(var(--warn-rgb), .45); }
.deal-item__fix:disabled { opacity: .6; cursor: default; }

/* ─── Плашка «Загрузить данные» (Набор на семинары) ─────────────────────── */
.seminars-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 16px;
  padding: 80px 24px;
  color: var(--b24-text-light);
}
.seminars-placeholder__icon { font-size: 48px; line-height: 1; }
.seminars-placeholder__text { font-size: 16px; font-weight: 500; }
.seminars-placeholder__btn  { font-size: 15px; padding: 12px 32px; }

/* ─── Модалка отчёта (заявка во внешнюю организацию) ────────────────────── */
/* Открывается поверх списка клиентов, поэтому слой выше общего модального. */
#exportModalOverlay { z-index: 110; }

.modal--export { max-width: 760px; max-height: 88vh; }

/* Пока сохраняется состав ассистентов — окно не принимает клики: два быстрых
   нажатия «убрать» подряд отправили бы второй список, собранный из устаревшего. */
.exp-body--busy { opacity: 0.55; pointer-events: none; }

.exp-summary {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 6px 14px;
  padding: 14px 16px;
  background: var(--b24-primary-soft);
  border-radius: var(--radius);
  margin-bottom: 14px;
}
.exp-summary__people { font-size: 20px; font-weight: 700; color: var(--b24-text); }
.exp-summary__break  { font-size: 13px; color: var(--b24-text-light); }
.exp-summary__ready  { font-size: 13px; color: var(--b24-success); margin-left: auto; font-weight: 600; }
.exp-summary__ready--warn { color: var(--b24-warning); }

.exp-money {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
  gap: 8px;
  margin-bottom: 14px;
}
.exp-money__item {
  display: flex;
  flex-direction: column;
  gap: 2px;
  padding: 8px 12px;
  border: 1px solid var(--b24-border);
  border-radius: var(--radius);
}
.exp-money__item span { font-size: 11px; color: var(--b24-text-light); text-transform: uppercase; letter-spacing: 0.02em; }
.exp-money__item b    { font-size: 16px; font-weight: 700; color: var(--b24-text); }

.exp-warn {
  padding: 8px 12px;
  margin-bottom: 14px;
  border-radius: var(--radius);
  background: rgba(var(--warn-rgb), .12);
  color: var(--warn-ink);
  font-size: 13px;
}

.exp-section { margin-bottom: 18px; }
.exp-section:last-child { margin-bottom: 0; }
.exp-section__title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 13px;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.03em;
  color: var(--b24-text-light);
  margin-bottom: 8px;
}
.exp-section__count {
  background: var(--b24-bg);
  border-radius: 10px;
  padding: 1px 8px;
  font-size: 12px;
  color: var(--b24-text);
}
/* Пояснение к заголовку блока: «оплатили 29 · не оплатили 13». Обычным
   регистром и потоньше — заголовок остаётся заголовком, а не строкой цифр.
   Длинное пояснение обрезается многоточием, а не ломает шапку блока. */
.exp-section__sub {
  font-size: 11px;
  font-weight: 400;
  text-transform: none;
  letter-spacing: 0;
  color: var(--b24-text-light);
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* Подпись перед общим списком. Выше — то, что уйдёт в заявку, ниже — рабочий
   лист целиком. Без разделителя оплатившие читались бы как показанные дважды. */
.exp-sheet {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px 8px;
  margin: 20px 0 12px;
  padding-top: 14px;
  border-top: 1px solid var(--b24-border);
  font-size: 13px;
  color: var(--b24-text-light);
}
.exp-sheet b { color: var(--b24-text); font-weight: 700; }

.exp-list {
  list-style: none;
  margin: 0;
  padding: 0;
  border: 1px solid var(--b24-border);
  border-radius: var(--radius);
  overflow: hidden;
}
.exp-row {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--b24-border);
  font-size: 14px;
}
.exp-row:last-child { border-bottom: none; }
.exp-row:hover { background: var(--b24-hover); }
.exp-row--gap  { background: rgba(var(--warn-rgb), .08); }
.exp-row--gap:hover { background: rgba(var(--warn-rgb), .12); }
.exp-row__mark { flex-shrink: 0; line-height: 1.5; }
.exp-row__body { display: flex; flex-direction: column; gap: 2px; flex: 1; min-width: 0; }
.exp-row__name { color: var(--b24-text); }
.exp-row__gap  { font-size: 12px; color: var(--b24-text-light); }
.exp-row__link {
  flex-shrink: 0;
  color: var(--info);
  text-decoration: none;
  padding: 0 4px;
  font-size: 15px;
}
/* Убрать ассистента — действие обратимое (вернуть можно тем же поиском), но одной
   иконкой ✕ его не находят: кнопка подписана словом и видна как кнопка. */
.exp-row__remove {
  flex-shrink: 0;
  align-self: center;
  background: var(--surface);
  border: 1px solid var(--b24-border);
  color: var(--b24-text-light);
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
  white-space: nowrap;
  padding: 6px 10px;
  border-radius: 4px;
}
.exp-row__remove:hover { background: rgba(var(--danger-rgb), .10); border-color: var(--b24-danger); color: var(--b24-danger); }

/* «Убрать всех» — справа в заголовке блока, чтобы не путалась с построчной кнопкой. */
.exp-section__action {
  margin-left: auto;
  background: none;
  border: 1px solid var(--b24-border);
  border-radius: 4px;
  padding: 4px 10px;
  font: inherit;
  font-size: 11px;
  font-weight: 600;
  text-transform: none;
  letter-spacing: 0.02em;
  color: var(--b24-text-light);
  cursor: pointer;
}
.exp-section__action:hover { background: rgba(var(--danger-rgb), .10); border-color: var(--b24-danger); color: var(--b24-danger); }

.exp-tag {
  display: inline-block;
  font-size: 11px;
  padding: 1px 6px;
  border-radius: 10px;
  background: var(--b24-bg);
  color: var(--b24-text-light);
  vertical-align: middle;
}
.exp-tag--warn { background: rgba(var(--danger-rgb), .10); color: var(--b24-danger); }

.exp-empty {
  padding: 12px;
  text-align: center;
  color: var(--b24-text-light);
  font-size: 13px;
}

.exp-search { position: relative; margin-top: 8px; }
.exp-search .deals-search { width: 100%; }

.exp-hits {
  list-style: none;
  margin: 6px 0 0;
  padding: 0;
  border: 1px solid var(--b24-border);
  border-radius: var(--radius);
  max-height: 220px;
  overflow-y: auto;
  box-shadow: var(--b24-shadow);
}
.exp-hits--empty {
  padding: 10px 12px;
  color: var(--b24-text-light);
  font-size: 13px;
  box-shadow: none;
}
.exp-hit {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 8px 12px;
  border-bottom: 1px solid var(--b24-border);
  cursor: pointer;
}
.exp-hit:last-child { border-bottom: none; }
.exp-hit:hover { background: var(--b24-primary-soft); }
.exp-hit__name { font-size: 14px; color: var(--b24-text); }
.exp-hit__sub  { font-size: 12px; color: var(--b24-text-light); }
.exp-hits__more {
  padding: 6px 12px;
  font-size: 12px;
  color: var(--b24-text-light);
  background: var(--b24-bg);
}

.export-footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 14px 24px;
  border-top: 1px solid var(--b24-border);
  flex-shrink: 0;
  /* Перенос нужен полосе прогресса: она заявляет flex-basis: 100%, чтобы встать
     отдельной строкой под кнопками. Без переноса она бы осталась в одном ряду и
     сплющила заметку и кнопки. Заметке с кнопками переносить нечего — они и так
     помещаются в строку. */
  flex-wrap: wrap;
}
.export-footer__note { font-size: 12px; color: var(--b24-text-light); }

/* Кнопки в подвале отчёта: Excel, архив с документами и пересборка архива. */
.export-footer__actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }

/* Пересборка — второстепенное действие рядом с основной кнопкой архива.
   Отдельного размера кнопок в проекте нет (btn--small не существует), поэтому
   уменьшаем здесь. */
.btn--rebuild { padding: 6px 10px; font-size: 12px; }

/* Сборка архива идёт около минуты — без полосы прогресса это выглядит зависанием.
   Полоса ростом с кнопку архива: сборка занимает минуту, и всё это время она —
   единственное, что в окне происходит. Шестипиксельная ниточка под кнопками
   терялась, а её подпись сбоку читалась как случайная строка. */
.export-progress { flex-basis: 100%; display: flex; align-items: center; gap: 10px; }
.export-progress__track {
  position: relative;               /* система координат для подписи поверх заливки */
  flex: 1;
  /* 32px = высота .btn--ghost: 13px шрифта × 1.2 + 7px padding сверху и снизу + рамка. */
  height: 32px;
  /* Тёмная дорожка, а не светлая: подпись внутри белая и одного цвета, и читаться
     она должна и на заполненной части, и на пустой. Светлый фон потребовал бы
     красить текст по-разному слева и справа от границы заливки. */
  background: var(--ink-soft);
  border-radius: var(--radius);
  overflow: hidden;
}
.export-progress__bar {
  height: 100%;
  width: 0;
  background: var(--brand);
  transition: width var(--dur-slow) var(--ease-out);
}
.export-progress__text {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 0 10px;
  font-size: 13px;
  font-weight: 600;
  color: var(--surface);
  white-space: nowrap;
  text-shadow: 0 1px 2px rgba(var(--ink-rgb), 0.35);
  pointer-events: none;             /* подпись не должна перехватывать курсор у окна */
}

/* ─── Сверка с Битрикс24 ─────────────────────────────────────────────────────
   Плашка показывает заявки только при точном совпадении даты семинара со
   свободной датой в календаре. Всё, что не совпало, раньше пропадало молча —
   эта полоса и приписка на плашке говорят об этом вслух. */
.recon-wrap { margin: 0 0 16px; }
.recon {
  background: var(--b24-white);
  border: 1px solid var(--b24-border);
  border-left: 4px solid var(--b24-success);
  border-radius: var(--radius);
  padding: 10px 14px;
  box-shadow: var(--b24-shadow);
  font-size: 14px;
}
.recon--warn { border-left-color: var(--b24-warning); }
.recon__row { display: flex; flex-wrap: wrap; align-items: center; gap: 6px 18px; }
.recon__title { font-weight: 700; color: var(--b24-text); }
.recon__item { color: var(--text-muted); }
.recon__item b { color: var(--b24-text); font-weight: 700; }
.recon__item--warn b { color: var(--b24-warning); }
.recon__item--ok { color: var(--b24-success); font-weight: 600; }
.recon__time { margin-left: auto; color: var(--text-muted); font-size: 13px; white-space: nowrap; }
.recon__why { margin-top: 6px; color: var(--text-muted); font-size: 13px; }
.recon__why b { color: var(--b24-text); }
.recon__details { margin-top: 8px; }
.recon__details summary { cursor: pointer; color: var(--b24-primary); font-size: 14px; }

/* Список расхождений. Строка тут — не строка, а блок из трёх ярусов: что и
   когда, в чём расхождение, кто именно. Буллит рядом с таким блоком выглядит
   мусором, поэтому маркеров нет, а соседей разделяет линия. */
.recon__list { margin: 8px 0 0; padding-left: 0; list-style: none; }
.recon__orphan { color: var(--b24-text); padding: 10px 0; }
.recon__orphan + .recon__orphan { border-top: 1px solid var(--b24-border); }
/* Шапка строки: дата и семинар слева, кнопки действий справа.

   Flex, а не строка текста: кнопки «Обновить даты» и «Пингануть» стояли вплотную
   к названию семинара, а длинное название закрывали собой. Теперь название
   занимает всё свободное место и переносится само, кнопки не сжимаются и при
   нехватке ширины уходят на строку ниже — но никогда не налезают на текст. */
.recon__orphan-head {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 10px;
  font-size: 15px; line-height: 1.4;
}
.recon__orphan-title { flex: 1 1 240px; min-width: 0; overflow-wrap: anywhere; }
.recon__orphan-head > .recon__fix, .recon__orphan-head > .recon__ping { flex-shrink: 0; }
.recon__orphan-why { margin-top: 3px; font-size: 13px; color: var(--text-muted); line-height: 1.5; }
.recon__orphan-deals { display: flex; flex-wrap: wrap; gap: 6px; margin-top: 7px; }

/* Настоящая причина и выход из неё — одной строкой под расхождением.

   Раньше здесь было только «события в календаре нет», и это уводило править дату
   в сделке: после правки заявка оставалась в списке. Подсказка называет причину,
   кнопка рядом даёт единственное действие, которое её снимает. */
.recon__orphan-hint {
  margin-top: 5px; font-size: 13px; line-height: 1.5; color: var(--text-muted);
}
.recon__orphan-hint b { color: var(--b24-text); }
/* «Создать плашку» — красная нарочно: она добавляет событие в календарь, а это
   уже видно всему порталу. Синей она читалась как обычная ссылка и нажималась
   раньше, чем человек убеждался, что семинар в сделке выбран верно. */
.recon__make {
  display: inline-flex; align-items: center; gap: 4px;
  margin-left: 4px; padding: 3px 8px;
  border: 1px solid var(--b24-danger); border-radius: 12px;
  background: rgba(var(--danger-rgb), .10); color: var(--danger-ink);
  font-size: 12px; line-height: 1.2; cursor: pointer; white-space: nowrap;
}
.recon__make:hover { background: rgba(var(--danger-rgb), .18); }

/* «Обновить даты» — зелёная и мерцающая (сама анимация в motion.css): главное
   действие строки, оно чинит заявки, а не заводит новое событие. */
.recon__fix {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 10px;
  border: 1px solid var(--b24-success); border-radius: 12px;
  background: rgba(var(--ok-rgb), .12); color: var(--ok-ink);
  font-size: 12px; line-height: 1.2; cursor: pointer; white-space: nowrap;
}
.recon__fix:hover { background: rgba(var(--ok-rgb), .22); }

/* ── Окно «Обновить даты» ─────────────────────────────────────────────────── */

/* Что стоит в заявках сейчас — первой строкой: правка чужих сделок начинается с
   того, чтобы человек увидел исходное и убедился, что это та самая группа. */
.fix-now {
  padding: 8px 10px; margin-bottom: 12px;
  border-radius: 8px; background: var(--b24-bg);
  font-size: 14px; color: var(--b24-text);
  /* Названия семинаров бывают длинными и без пробелов («Нейро-профильные»):
     переносим где придётся, лишь бы не расширять окно. */
  overflow-wrap: anywhere;
}
.fix-fields { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 12px; }
/* min-width: 0 обязателен. У элемента flex ширина по умолчанию не меньше своего
   содержимого (min-width: auto), а содержимое выпадающего списка — САМОЕ ДЛИННОЕ
   название семинара из справочника, а их там под сотню. Без этой строки поле
   растягивалось на всю длину такого названия и вылезало за края окна. */
.fix-field { display: flex; flex-direction: column; gap: 4px; flex: 1 1 140px; min-width: 0; }
.fix-field--wide { flex: 1 1 100%; }
.fix-field > span { font-size: 12px; color: var(--text-muted); }
.fix-field select, .fix-field input {
  width: 100%; max-width: 100%;
  padding: 7px 9px; border: 1px solid var(--b24-border); border-radius: 8px;
  font-size: 14px; background: var(--surface); color: var(--b24-text);
}
/* Название не помещается — обрываем многоточием, а не окном. Целиком его видно
   в раскрытом списке и в подсказке при наведении (title ставит js/deal-fix.js). */
.fix-field select { text-overflow: ellipsis; }
.fix-lead { font-size: 13px; color: var(--text-muted); margin-bottom: 6px; }
.fix-list { list-style: none; margin: 0 0 12px; padding: 0; max-height: 260px; overflow-y: auto; }
.fix-item { border-bottom: 1px solid var(--b24-border); }
.fix-item:last-child { border-bottom: none; }
.fix-item__label { display: flex; align-items: center; gap: 8px; padding: 7px 2px; cursor: pointer; }
.fix-item__name { font-size: 14px; color: var(--b24-text); min-width: 0; overflow-wrap: anywhere; }
.fix-item__paid { color: var(--b24-success); font-size: 13px; }
.fix-note { font-size: 12px; line-height: 1.5; color: var(--text-muted); margin-bottom: 12px; }
.fix-empty { font-size: 14px; color: var(--text-muted); padding: 8px 0; }
.fix-actions { display: flex; flex-wrap: wrap; gap: 8px; }
.fix-result { font-size: 15px; color: var(--b24-text); margin-bottom: 8px; }
/* Отказ и предупреждение — одним видом: человеку важно не «класс сообщения», а
   что именно не сделано. */
.fix-warn {
  padding: 8px 10px; margin-bottom: 10px;
  border-radius: 8px; background: rgba(var(--warn-rgb), .12); color: var(--warn-ink); font-size: 13px; line-height: 1.5;
}
.fix-skipped { margin: 0; padding-left: 18px; font-size: 13px; line-height: 1.6; color: var(--text-muted); }

/* Заявка — ссылка в карточку CRM. Синяя «таблетка» сама сообщает, что сюда можно
   нажать: подчёркивания и стрелки у девяти заявок в ряд дали бы рябь. Стрелка
   всё же есть, но проявляется при наведении — место под неё занято всегда,
   иначе ряд дёргался бы под курсором. */
.recon__deal {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 3px 10px;
  border: 1px solid transparent;
  border-radius: 12px;
  background: var(--b24-primary-soft);
  color: var(--b24-primary);
  font-size: 14px;
  text-decoration: none;
  white-space: nowrap;
}
.recon__deal:hover { border-color: var(--b24-primary); }
.recon__deal::after { content: '↗'; font-size: 11px; opacity: 0; transition: opacity var(--dur-quick) var(--ease-out); }
.recon__deal:hover::after { opacity: 1; }
.recon__paid { color: var(--b24-success); font-weight: 700; }

.recon__past { margin-top: 8px; font-size: 13px; color: var(--text-muted); }

/* Письмо ответственному прямо из строки сверки.

   Кнопка стоит РЯДОМ со ссылкой на карточку, а не внутри неё: вложенная в ссылку
   кнопка утаскивала бы клик в новую вкладку. Общая обводка на паре «заявка +
   колокольчик» показывает, что колокольчик относится именно к этой заявке. */
.recon__deal-wrap { display: inline-flex; align-items: center; gap: 2px; }

/* Кто отвечает за заявку — подписью между таблеткой клиента и колокольчиком.
   Приглушённой и мелкой: имя менеджера здесь справочное, кликают по клиенту. */
.recon__owner {
  font-size: 12px; color: var(--text-muted); white-space: nowrap; padding: 0 2px 0 4px;
}
.recon__owner--none { font-style: italic; }

.recon__ping {
  display: inline-flex; align-items: center; gap: 4px;
  padding: 3px 8px;
  border: 1px solid rgba(var(--warn-rgb), .45); border-radius: 12px;
  background: rgba(var(--warn-rgb), .12); color: var(--warn-ink);
  font-size: 12px; line-height: 1.2; cursor: pointer; white-space: nowrap;
}
.recon__ping:hover { background: rgba(var(--warn-rgb), .18); }
.recon__ping--all  { vertical-align: middle; }
/* Уже писали и писать некому — не кнопки: их вид обязан отличаться от нажимаемого,
   иначе неактивная кнопка читается как поломка интерфейса. */
.recon__ping--done {
  border-style: dashed; background: transparent; color: var(--text-muted); cursor: default;
}
.recon__ping--none {
  border: none; background: transparent; color: var(--text-muted); cursor: default;
  padding: 3px 4px;
}

/* Приписка на плашке: заявки того же семинара на другой дате */
.card__nearby {
  margin: 0 14px 10px;
  padding: 6px 10px;
  background: rgba(var(--warn-rgb), .12);
  border: 1px solid var(--b24-warning);
  border-radius: 6px;
  font-size: 12px;
  color: var(--warn-ink);
  line-height: 1.4;
}

@media (max-width: 720px) {
  .recon__time { margin-left: 0; }
}

/* ── Экран отказа ────────────────────────────────────────────────────────── */
/* Спрятан по умолчанию: показывает его auth.js и только когда войти не вышло. */
.auth { display: none; position: fixed; inset: 0; z-index: 9000;
        align-items: center; justify-content: center; background: rgba(var(--ink-rgb), .92); }
.auth__box { display: flex; flex-direction: column; gap: 12px; width: 320px; max-width: 90vw;
             padding: 28px; border-radius: var(--radius-lg); background: var(--b24-white);
             box-shadow: var(--shadow-3); text-align: center; }
.auth__title { font-size: 18px; font-weight: 600; }
.auth__hint { font-size: 13px; color: var(--b24-text-light); line-height: 1.4; }

/* Ввод личного кода на экране отказа. Показывается только вне рамки Битрикс24. */
.auth-pin { display: flex; flex-direction: column; gap: 8px; align-items: center; margin-top: 16px; }
.auth-pin__label { font-size: 13px; color: var(--text-muted); }
.auth-pin__input {
  width: 170px; padding: 10px 12px; font-size: 20px; letter-spacing: 6px; text-align: center;
  border: 1px solid var(--b24-border); border-radius: var(--radius); background: var(--b24-white);
  color: var(--b24-text);
}
.auth-pin__note { min-height: 18px; font-size: 13px; color: var(--b24-danger); }

/* ─── Активности: бублик на плашке и карточка при наведении ──────────────── */

.card__date-tags {
  display: flex;
  align-items: center;
  gap: 6px;
}

.act-badge {
  display: inline-flex;
  align-items: baseline;
  gap: 2px;
  padding: 2px 8px;
  border-radius: 10px;
  background: var(--b24-bg);
  border: 1px solid var(--b24-border);
  font-size: 12px;
  line-height: 16px;
  color: var(--b24-text-light);
  white-space: nowrap;
  cursor: default;
}

.act-badge--hot {
  background: rgba(var(--danger-rgb), 0.08);
  border-color: rgba(var(--danger-rgb), 0.25);
}

.act-badge__hot   { color: var(--b24-red); font-weight: 700; }
.act-badge__slash { opacity: .5; }
.act-badge__total { color: var(--b24-text-light); }

.cal-popover--act { width: 260px; }

.act-pop__title {
  font-size: 13px;
  font-weight: 700;
  color: var(--b24-text);
  margin-bottom: 4px;
}

.act-pop__kinds {
  font-size: 12px;
  color: var(--b24-text-light);
  margin-bottom: 8px;
  padding-bottom: 8px;
  border-bottom: 1px solid var(--b24-border);
}

.act-pop__users { list-style: none; margin: 0; padding: 0; }

.act-pop__row {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 12px;
  padding: 2px 0;
}

.act-pop__who {
  flex: 1;
  color: var(--b24-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.act-pop__n   { font-weight: 700; color: var(--b24-text); }
.act-pop__hot { color: var(--b24-red); }

/* ─── Активности в списке заявок ─────────────────────────────────────────── */

.deals-stat__num--hot { color: var(--b24-red); }
/* «Не горит» — спокойная половина той же категории, поэтому и цвет спокойный.
   Но не бледный: числом в 19px по светлому фону серый цвет подписи уже плохо читается. */
.deals-stat__num--calm { color: var(--ink-soft); }

/* Ряд «Дела»: те же по размеру чипы, что и у заявок, — числа на плашке стоят
   рядом, и мельче их держать нельзя. Два ряда читаются как одна панель: у верхнего
   снимаем границу, нижний её и держит. Подписи слева выровнены по одной колонке,
   чтобы сразу было видно, где считаются заявки, а где дела. */
.deals-stats__cap {
  flex-shrink: 0;
  min-width: 54px;
  font-size: 11px;
  font-weight: 700;
  letter-spacing: .04em;
  text-transform: uppercase;
  color: var(--b24-text-light);
  user-select: none;
}

.deals-stats--split { border-bottom: 0; padding-bottom: 2px; }
.deals-stats--acts  { padding-top: 2px; }

/* Чип дел двухэтажный: сверху — сколько ДЕЛ (как на плашке), снизу мелко — в
   скольких ЗАЯВКАХ они лежат. Обе величины на виду, потому что клик открывает
   заявки, и «8» над списком из семи строк без второй строки читается как ошибка. */
.deals-stat--two .deals-stat__label {
  display: flex;
  flex-direction: column;
  line-height: 1.15;
  text-align: left;
}
.deals-stat__sub { font-size: 11px; color: var(--b24-gray); white-space: nowrap; }
.deals-stat--btn.deals-stat--active .deals-stat__sub { color: var(--b24-text-light); }

.deal-item__act {
  display: flex;
  align-items: baseline;
  gap: 6px;
  margin-top: 3px;
  font-size: 12px;
  color: var(--b24-text-light);
}

.deal-item__act-subj {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  max-width: 260px;
}

.deal-item__act-due--hot { color: var(--b24-red); font-weight: 600; }

.deal-item__act-who { margin-left: auto; opacity: .8; }
/* ─── Напоминания об активностях ──────────────────────────────────────────── */

/* Кнопка нарочно не похожа на чип-фильтр: клик «отфильтровать» и клик «написать
   людям» рядом друг с другом, и путать их нельзя. */
.deals-ping {
  display: inline-flex; align-items: center; gap: 4px;
  margin-left: 6px; padding: 4px 10px;
  border: 1px solid rgba(var(--warn-rgb), .45); border-radius: 14px;
  background: rgba(var(--warn-rgb), .12); color: var(--warn-ink);
  font-size: 12px; line-height: 1.2; cursor: pointer; white-space: nowrap;
}
.deals-ping:hover { background: rgba(var(--warn-rgb), .18); }
.deals-ping--row  { margin-left: 0; padding: 4px 8px; align-self: center; }
.deals-ping--done {
  border-style: dashed; background: transparent; color: var(--b24-text-light); cursor: default;
}

.ping-lead    { margin-bottom: 12px; color: var(--b24-text); }
.ping-empty   { padding: 16px 0; color: var(--b24-text-light); }
.ping-list    { list-style: none; margin: 0 0 12px; padding: 0; }
.ping-item__label {
  display: flex; align-items: center; gap: 8px;
  padding: 8px 4px; border-bottom: 1px solid var(--b24-border); cursor: pointer;
}
.ping-item__name  { flex: 1; }
.ping-item__count { color: var(--b24-text-light); font-size: 13px; }
.ping-warn    { margin: 8px 0; padding: 8px 10px; border-radius: 6px; background: rgba(var(--warn-rgb), .12); color: var(--warn-ink); font-size: 13px; }
.ping-skipped { margin: 8px 0; color: var(--b24-text-light); font-size: 13px; }
.ping-note    { display: block; margin: 12px 0; }
.ping-note__input {
  width: 100%; margin-top: 4px; padding: 8px; box-sizing: border-box;
  border: 1px solid var(--b24-border); border-radius: 6px; font: inherit; resize: vertical;
}
.ping-actions { display: flex; gap: 8px; margin-top: 12px; }
.ping-result  { font-size: 15px; }
.ping-failed  { margin: 8px 0 0; padding-left: 18px; color: var(--b24-red); font-size: 13px; }

/* ── Ход массового создания событий ─────────────────────────────────────────
   Раскладка и цвета окна прогресса. Движение живёт в motion.css: и появление
   строк, и пульс работающей строки, и свечение кольца. Здесь только один
   переход — заполнение кольца: как и ширина обычного прогресс-бара, это не
   украшение, а сам смысл элемента. */

.modal--bulkp { max-width: 760px; width: 94%; }

.bulkp__top {
  display: flex;
  align-items: center;
  gap: 22px;
  padding-bottom: 16px;
  border-bottom: 1px solid var(--b24-border);
}

.bulkp__ring {
  position: relative;
  flex: 0 0 132px;
  width: 132px;
  height: 132px;
}
.bulkp__ringSvg {
  width: 132px;
  height: 132px;
  /* Начало дуги — сверху, а не справа: круг заполняется по часовой от 12 часов. */
  transform: rotate(-90deg);
}
.bulkp__ringBg {
  fill: none;
  stroke: var(--b24-border);
  stroke-width: 9;
}
.bulkp__ringFg {
  fill: none;
  stroke: url(#bulkpGrad);
  stroke-width: 9;
  stroke-linecap: round;
  transition: stroke-dashoffset var(--dur-slow) var(--ease-out);
}
/* Цвета градиента кольца — здесь, а не атрибутами stop-color в разметке:
   иначе кольцо осталось бы единственным местом, которое смена палитры в :root
   обходит стороной. Создание событий — действие, значит зелёная пара. */
#bulkpGrad stop:first-child { stop-color: var(--brand-hover); }
#bulkpGrad stop:last-child  { stop-color: var(--brand); }
.bulkp__ringText {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 2px;
}
.bulkp__pct {
  font-size: 28px;
  font-weight: 700;
  line-height: 1;
  color: var(--b24-text);
  font-variant-numeric: tabular-nums;
}
.bulkp__count {
  font-size: 12px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}

.bulkp__side {
  flex: 1 1 auto;
  min-width: 0;
}
.bulkp__phase {
  font-size: 15px;
  font-weight: 600;
  color: var(--b24-text);
  margin-bottom: 10px;
}
.bulkp__chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
}
.bulkp__chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 4px 10px;
  border-radius: 999px;
  font-size: 12px;
  background: var(--b24-bg);
  color: var(--text-muted);
}
.bulkp__chip b {
  font-size: 14px;
  font-variant-numeric: tabular-nums;
}
.bulkp__chip--ok   { background: rgba(var(--ok-rgb),.12);  color: var(--b24-success); }
.bulkp__chip--dup  { background: rgba(var(--warn-rgb),.14); color: var(--warn-ink); }
.bulkp__chip--fail { background: rgba(var(--danger-rgb),.12);  color: var(--b24-danger); }
.bulkp__hint {
  font-size: 12px;
  color: var(--text-muted);
}

.bulkp__list {
  max-height: 340px;
  overflow-y: auto;
  margin: 12px 0 4px;
}
.bulkp__row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  border-radius: var(--radius);
  transition: background-color var(--dur-base) var(--ease-out);
}
.bulkp__row + .bulkp__row { box-shadow: inset 0 1px 0 var(--b24-border); }

/* Кружок состояния. Знак внутри рисует ::before — по одному правилу на состояние,
   чтобы скрипт менял ровно один атрибут и ничего больше. */
.bulkp__ic {
  flex: 0 0 20px;
  width: 20px;
  height: 20px;
  border-radius: 50%;
  background: var(--b24-border);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  font-size: 12px;
  line-height: 1;
  color: var(--b24-white);
}
.bulkp__row[data-state="run"]  .bulkp__ic { background: var(--b24-primary); }
.bulkp__row[data-state="ok"]   .bulkp__ic { background: var(--b24-success); }
.bulkp__row[data-state="ok"]   .bulkp__ic::before { content: "\2713"; }
.bulkp__row[data-state="dup"]  .bulkp__ic { background: var(--b24-warning); }
.bulkp__row[data-state="dup"]  .bulkp__ic::before { content: "\2261"; }
.bulkp__row[data-state="fail"] .bulkp__ic { background: var(--b24-danger); }
.bulkp__row[data-state="fail"] .bulkp__ic::before { content: "\2715"; }
.bulkp__row[data-state="skip"] .bulkp__ic::before { content: "\2013"; color: var(--text-muted); }

.bulkp__body {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}
.bulkp__name {
  font-size: 13px;
  color: var(--b24-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.bulkp__dates {
  font-size: 11px;
  color: var(--text-muted);
  font-variant-numeric: tabular-nums;
}
.bulkp__st {
  flex: 0 0 auto;
  font-size: 12px;
  color: var(--text-muted);
}
/* Полоса хода у КАЖДОГО семинара, прямо в его строке. Заливка тянется через
   transform: scaleX, а не width — ширина заставляет браузер пересчитывать
   раскладку списка на каждом кадре, а строк здесь полсотни. Долю по одному
   событию сервер не сообщает (запись в календарь либо прошла, либо нет),
   поэтому полоса показывает состояние: пусто → бегущий отрезок (motion.css)
   → залито целиком цветом исхода. */
.bulkp__bar {
  position: relative;
  height: 3px;
  margin-top: 5px;
  border-radius: 2px;
  background: var(--b24-border);
  overflow: hidden;
}
.bulkp__fill {
  position: absolute;
  inset: 0;
  border-radius: inherit;
  background: var(--b24-primary);
  transform: scaleX(0);
  transform-origin: left center;
  transition: transform var(--dur-slow) var(--ease-out),
              background-color var(--dur-base) var(--ease-out);
}
.bulkp__row[data-state="run"]  .bulkp__fill { transform: scaleX(.35); }
.bulkp__row[data-state="ok"]   .bulkp__fill { transform: scaleX(1); background: var(--b24-success); }
.bulkp__row[data-state="dup"]  .bulkp__fill { transform: scaleX(1); background: var(--b24-warning); }
.bulkp__row[data-state="fail"] .bulkp__fill { transform: scaleX(1); background: var(--b24-danger); }
.bulkp__row[data-state="skip"] .bulkp__fill { transform: scaleX(1); background: var(--text-muted); }
.bulkp__row[data-state="run"]  { background: var(--b24-primary-soft); }
.bulkp__row[data-state="run"]  .bulkp__st { color: var(--b24-primary); font-weight: 600; }
.bulkp__row[data-state="ok"]   .bulkp__st { color: var(--b24-success); }
.bulkp__row[data-state="fail"] { background: rgba(var(--danger-rgb),.07); }
.bulkp__row[data-state="fail"] .bulkp__st { color: var(--b24-danger); font-weight: 600; }

.bulkp__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-top: 12px;
  border-top: 1px solid var(--b24-border);
}
.bulkp__note {
  font-size: 13px;
  font-weight: 600;
  color: var(--b24-text);
}

@media (max-width: 640px) {
  .bulkp__top { flex-direction: column; align-items: stretch; gap: 14px; }
  .bulkp__ring { align-self: center; }
}

/* ── Дашборд статистики по запуску семинара ────────────────────────────────
   Раскладка и цвета; всё движение — в motion.css.
   Окно шире обычного: внизу график на всю ширину, сжимать его нельзя — кривая
   набора только тогда и читается, когда видно расстояние между точками. */
.modal--stats { max-width: 860px; width: 100%; }

.stats__head {
  display: grid;
  gap: 10px;
  margin-bottom: 16px;
}
/* Колонок ровно столько, сколько карточек: без «Собрано» их три, и растягивать
   оставшиеся на пустую четвёртую ячейку нельзя — числа разъедутся по ширине.
   Число в имени подставляет seminar-stats.js ('stats__head--' + cards.length),
   поэтому буквального «stats__head--4» в коде нет. */
.stats__head--3 { grid-template-columns: repeat(3, 1fr); }
.stats__head--4 { grid-template-columns: repeat(4, 1fr); }

.stnum {
  padding: 12px 14px;
  border: 1px solid var(--b24-border);
  border-left-width: 3px;
  border-radius: var(--radius);
  background: var(--b24-card);
  min-width: 0;
}
/* Полоса слева и есть весь сигнал тревоги: ширину задаёт .stnum выше, цвет —
   эти четыре строки. Уровень подставляет seminar-stats.js ('stnum--' + risk),
   в коде он не написан; без правил полоса оставалась серой при любом риске, и
   «Заполнение», «Темп» и «Прогноз» выглядели одинаково спокойно. */
.stnum--ok   { border-left-color: var(--b24-success); }
.stnum--warn { border-left-color: var(--b24-warning); }
.stnum--bad  { border-left-color: var(--b24-danger); }
.stnum--none { border-left-color: var(--b24-border); }
/* Полоса зала под шапкой: дефицит мест, чем он закрывается и какой темп нужен.
   Видна на всех вкладках — это и есть ответ на вопрос «успеваем или нет», и
   прятать его за вкладку значит прятать повод открыть окно. Уровень
   подставляет seminar-stats.js ('sthall--' + risk), буквального имени в коде
   нет; без этих правил полоса оставалась бы серой при любом дефиците. */
.sthall {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: 2px 10px;
  margin: -4px 0 14px;
  padding: 10px 14px;
  border: 1px solid var(--b24-border);
  border-left-width: 3px;
  border-radius: var(--radius);
  background: var(--b24-bg);
  font-size: 13px;
  line-height: 1.5;
  color: var(--text-muted);
}
.sthall--ok   { border-left-color: var(--b24-success); }
.sthall--warn { border-left-color: var(--b24-warning); }
.sthall--bad  { border-left-color: var(--b24-danger); }
.sthall--none { border-left-color: var(--b24-border); }
.sthall b { color: var(--b24-text); font-weight: 700; }
.sthall__main { font-weight: 600; color: var(--b24-text); }
/* Разделитель между оговорками — точка, а не рамка: при переносе на вторую
   строку рамка повисла бы в её начале, а точка уезжает вместе со словами. */
.sthall__part + .sthall__part::before { content: '·'; margin-right: 8px; color: var(--b24-gray); }

.stnum__label {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-muted); margin-bottom: 6px;
}
.stnum__value { font-size: 26px; font-weight: 700; color: var(--b24-text); line-height: 1.1; }
.stnum__sub { margin-top: 6px; font-size: 12px; color: var(--text-muted); line-height: 1.45; }
.stnum__sub b { color: var(--b24-text); }
.stnum__other { display: block; margin-top: 3px; color: var(--b24-gray); }

.stats__tabs {
  /* Вкладок шесть: на узком экране они переносятся строкой, а не сжимаются в
     полосу из обрывков слов. */
  display: flex; flex-wrap: wrap; gap: 4px; padding: 3px;
  background: var(--b24-bg); border-radius: var(--radius);
  margin-bottom: 14px;
}
.stats__tab {
  flex: 1 1 96px; white-space: nowrap; padding: 8px 10px; border: 0; border-radius: 6px;
  background: transparent; cursor: pointer;
  font-size: 14px; font-weight: 600; color: var(--text-muted);
  font-family: inherit;
  transition: background-color var(--dur-quick) var(--ease-out),
              color var(--dur-quick) var(--ease-out);
}
.stats__tab:hover { color: var(--b24-text); }
.stats__tab.is-active { background: var(--b24-card); color: var(--b24-primary); box-shadow: var(--b24-shadow); }

.stats__panel { min-height: 240px; }
.stats__sec { margin-bottom: 18px; }
.stats__sec-t {
  font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-muted); margin-bottom: 8px;
}
.stats__empty, .stats__note {
  font-size: 13px; color: var(--text-muted); line-height: 1.5;
}
.stats__empty { padding: 28px 0; text-align: center; }
.stats__note { margin-top: 8px; }

/* Скелет: окно открывается мгновенно, а цифры приезжают следом. Серый
   прямоугольник честнее вертушки — он занимает ровно то место, куда встанут числа. */
.stats__skeleton {
  height: 240px; border-radius: var(--radius);
  background: var(--b24-bg);
}

/* height:auto — svg держит пропорцию сам по viewBox, иначе кривая сплющится. */
.stchart { display: block; width: 100%; height: auto; }
.stchart__grid { stroke: var(--b24-border); stroke-width: 1; }
.stchart__tick { fill: var(--text-muted); font-size: 10px; }
.stchart__cur  { stroke: var(--b24-primary); stroke-width: 2.5; stroke-linejoin: round; stroke-linecap: round; }
.stchart__prev { stroke: var(--b24-gray); stroke-width: 1.5; stroke-dasharray: 4 3; }
.stchart__area { fill: var(--b24-primary); opacity: .10; }
.stchart__fc   { stroke: var(--b24-primary); stroke-width: 2; stroke-dasharray: 5 4; opacity: .55; }
.stchart__dot  { fill: var(--b24-primary); }
/* Коридор прошлых запусков: полоса серединной половины и линия их середины. */
.stchart__band { fill: var(--b24-gray); opacity: .14; }
.stchart__med  { stroke: var(--b24-gray); stroke-width: 1.5; opacity: .75; }

.stlegend { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 10px; font-size: 12px; color: var(--text-muted); }
.stlegend__i { display: inline-flex; align-items: center; gap: 6px; }
.stlegend__i::before { content: ''; width: 14px; height: 2px; border-radius: 1px; background: currentColor; }
.stlegend__i--cur  { color: var(--b24-primary); }
.stlegend__i--prev { color: var(--b24-gray); }
.stlegend__i--fc   { color: var(--b24-primary); opacity: .7; }
.stlegend__i--band { color: var(--b24-gray); }
.stlegend__i b { color: var(--b24-text); }

.strow { display: flex; align-items: center; gap: 10px; padding: 5px 0; font-size: 13px; }
.strow__name { flex: 0 0 190px; color: var(--b24-text); }
.strow__val { flex: 0 0 auto; margin-left: auto; font-weight: 600; color: var(--b24-text); white-space: nowrap; }
.strow__val i { font-style: normal; font-weight: 400; color: var(--text-muted); }
.stbar {
  position: relative; flex: 1 1 auto; height: 8px; min-width: 40px;
  border-radius: 4px; background: var(--b24-bg); overflow: hidden;
}
.stbar__fill {
  position: absolute; left: 0; top: 0; bottom: 0;
  border-radius: inherit; transform-origin: left center;
}
.stbar__fill--stage { background: var(--b24-primary); }
.stbar__fill--paid  { background: var(--b24-success); }
.stbar__fill--wait  { background: var(--b24-warning); }
.stbar__fill--lost  { background: var(--b24-danger); }

/* Строка разреза по ответственным: полоса сверху, числа подписью под ней. */
.ststaff { padding: 4px 0 8px; }
.ststaff__sub {
  font-size: 12px; color: var(--text-muted); line-height: 1.5;
  padding-left: 190px;
}
@media (max-width: 700px) { .ststaff__sub { padding-left: 0; } }

.stcards { display: flex; flex-wrap: wrap; gap: 10px; }
.stcard {
  flex: 1 1 140px; padding: 10px 12px; border-radius: var(--radius);
  background: var(--b24-bg); border: 1px solid transparent;
}
.stcard b { display: block; font-size: 20px; font-weight: 700; color: var(--b24-text); }
.stcard span { font-size: 12px; color: var(--text-muted); }
/* Вторая строка карточки сценария: ещё одно число, но подписью, а не заголовком. */
.stplan__sub { display: block; margin-top: 3px; }
.stcard--ok   { background: rgba(var(--ok-rgb), .12); border-color: var(--b24-success); }
.stcard--warn { background: rgba(var(--warn-rgb), .12); border-color: var(--b24-warning); }
.stcard--bad  { background: rgba(var(--danger-rgb), .10); border-color: var(--b24-danger); }

.stpills { display: flex; flex-wrap: wrap; gap: 8px; }
.stpill {
  padding: 5px 10px; border-radius: 14px; font-size: 12px;
  background: var(--b24-primary-soft); color: var(--b24-text);
}
.stpill b { font-weight: 700; }

@media (max-width: 720px) {
  .stats__head--3,
  .stats__head--4 { grid-template-columns: repeat(2, 1fr); }
  .strow__name { flex-basis: 120px; }
}

/* ── Заполненность анкеты (C1) ─────────────────────────────────────── */
/* Бейдж в строке заявки: «Анкета 11/13». Цвет — по числу пустых полей. */
.form-badge {
  flex-shrink: 0;
  font-size: 11px;
  font-weight: 700;
  padding: 3px 8px;
  border-radius: var(--radius);
  white-space: nowrap;
}
/* Уровень ставит form-view.js ('form-badge--' + lvl), буквального имени в коде
   нет. Без этих правил значок «Анкета 11/13» шёл без фона и цвета — полная и
   пустая анкета выглядели одинаково. */
.form-badge--ok   { background: rgba(var(--ok-rgb), 0.10);  color: var(--b24-success); }
.form-badge--warn { background: rgba(var(--warn-rgb), 0.12); color: var(--b24-warning-ink); }
.form-badge--bad  { background: rgba(var(--danger-rgb), 0.10);  color: var(--b24-danger-ink); }
/* Подпись под строкой: чего именно нет. */
.deal-item__form-missing {
  margin-top: 2px;
  font-size: 12px;
  color: var(--b24-text-light);
}
.deals-stat__num--form { color: var(--b24-warning-ink); }
.deals-stats--forms { padding-top: 2px; }
/* Метка на плашке: «📋 4» рядом с датой и бубликом дел. */
.card__form {
  display: inline-flex;
  align-items: center;
  gap: 2px;
  padding: 2px 8px;
  border-radius: 10px;
  background: rgba(var(--warn-rgb), 0.10);
  border: 1px solid rgba(var(--warn-rgb), 0.35);
  font-size: 12px;
  line-height: 16px;
  color: var(--b24-warning-ink);
  white-space: nowrap;
}

/* Вкладка «Настройки»: ряд вкладок, разделы, таблица доступа. */
.tabs { display: flex; gap: 8px; padding: 0 20px; border-bottom: 1px solid var(--b24-border); }
.tab {
  padding: 10px 16px; border: 0; background: transparent; cursor: pointer; font-size: 14px;
  color: var(--text-muted); border-bottom: 2px solid transparent;
}
.tab--active { color: var(--b24-text); border-bottom-color: var(--b24-primary); }
.tab:hover:not(.tab--active) { color: var(--ink); background: var(--b24-hover); border-bottom-color: var(--brand-line); }
.set-nav { display: flex; gap: 8px; margin-bottom: 16px; flex-wrap: wrap; }
.set-nav__btn {
  padding: 6px 14px; border: 1px solid var(--b24-border); border-radius: var(--radius);
  background: var(--b24-card); color: var(--b24-text); cursor: pointer;
}
.set-nav__btn--active { background: var(--b24-primary); color: var(--b24-white); border-color: transparent; }
.set-nav__btn:hover:not(.set-nav__btn--active) { background: var(--b24-hover); color: var(--brand-active); border-color: var(--brand-line); }
#tab-settings { padding: 20px; }
.set-table { width: 100%; border-collapse: collapse; background: var(--b24-card);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-1); }
.set-row td { padding: 12px 10px; border-bottom: 1px solid var(--b24-border); vertical-align: top; }
.set-row--off { opacity: .55; }
.set-row__sub { font-size: 12px; color: var(--text-muted); margin-top: 2px; }
/* Ряд кнопок держит внутренний блок, а ячейка остаётся ячейкой. display:flex на
   самой <td> выбивает её из таблицы: высота ячейки (57 px) переставала совпадать
   с высотой строки (66 px), и линия-разделитель под кнопками шла на 9 px ниже,
   чем под именем и PIN, — ступенька на каждой строке списка доступа. */
.set-row__acts { display: flex; flex-wrap: wrap; gap: 6px; }
.set-tag { font-size: 11px; padding: 1px 7px; border-radius: var(--radius-sm); background: var(--b24-border); }
.set-tag--admin { background: var(--b24-primary-soft); color: var(--b24-primary); }
.set-warn { padding: 12px 14px; margin-bottom: 12px; border-radius: var(--radius);
  background: rgba(var(--warn-rgb), .18); color: var(--b24-warning-ink); }
.set-fresh { padding: 12px 14px; margin-bottom: 12px; border-radius: var(--radius);
  background: var(--b24-primary-soft); color: var(--b24-text); }
.set-fresh b { font-size: 22px; letter-spacing: 4px; }
/* Код в строке сотрудника: разрядка, чтобы шесть цифр списывались без ошибки, и
   размер меньше, чем у только что выданного в плашке. Цвета нет: код это
   сведение, а не действие и не предупреждение.
   Имя класса по строке (.set-row__name, .set-row__pin рядом), а не по смыслу:
   коротким «.set-pin» уже названа накладка окна подтверждения ниже в этом
   файле, и цифры в строке получали от неё position:fixed на весь экран. */
.set-row__code { font-size: 17px; letter-spacing: 3px; }
.set-hint { font-size: 12px; color: var(--text-muted); }
/* Виды семинаров: ряд одной программы и кнопки выбора вида. Цвета тут нет
   вовсе — решение человека и догадка пульта различаются начертанием рамки.
   Цвет в пульте уже занят смыслом (зелёный — действие, бирюзовый — сведения),
   и третий смысл на тех же красках не прочитался бы. */
.kind-row { padding: 10px 0; border-bottom: 1px solid var(--line); }
.kind-row__name { font-size: 14px; font-weight: 600; color: var(--b24-text); margin-bottom: 6px; }
.kind-row__picks { display: flex; flex-wrap: wrap; gap: 6px; }
.kind-row__sub { font-size: 12px; color: var(--text-muted); margin-top: 6px; }
.kind-pick--guess { border-style: dashed; border-color: var(--line-strong); color: var(--text-muted); }
.set-add { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.set-h3 { margin: 22px 0 10px; font-size: 15px; color: var(--b24-text); }
/* Окно подтверждения личным кодом, по центру: пока код не введён или не отменён,
   за окном ничего нажимать не нужно. Слой 60 этого не давал — он лежал НИЖЕ и
   окон пульта (.modal-overlay 100, #exportModalOverlay 110), и поповера календаря
   (9999). Стоим выше них, но НИЖЕ экрана отказа (.auth 9000): если сессию
   оборвали прямо во время подтверждения, сперва вход — вводить код в мёртвую
   сессию незачем. */
.set-pin { position: fixed; inset: 0; background: rgba(var(--ink-rgb),.45); z-index: 120;
  display: flex; align-items: center; justify-content: center; }
.set-pin__card { background: var(--b24-card); border-radius: var(--radius-lg); padding: 24px;
  display: flex; flex-direction: column; gap: 14px; align-items: center; min-width: 280px;
  box-shadow: var(--shadow-3); }
.set-form { display: flex; flex-direction: column; gap: 12px; max-width: 560px; }
.set-field { display: flex; gap: 8px; align-items: center; }
/* Поля денег раздела «Экономика»: подпись отмеренной ширины, иначе поля
   каналов и людей встают лестницей и в какое из них пишешь — не видно.
   Собственных цветов у правила нет: только токены. */
.econ-field > span { flex: 0 0 220px; font-size: 13px; color: var(--text-muted); }
.econ-field .rs-input { width: 160px; }
.set-days { display: flex; gap: 12px; flex-wrap: wrap; }
/* Список «что уйдёт»: коробка с прокруткой, а не молча обрезанный текст.
   Высота отмерена ровно на десять строк (LIST_ROWS в js/settings.js) — обрыв
   приходится между строками, а не на полуслове десятой, как было; рамка и
   всегда отведённое место под полосу прокрутки показывают, что у списка есть
   край и он едет. Сколько строк видно из скольких семинаров — подписано под
   списком: полосу прокрутки браузер иногда рисует только при наведении. */
.set-list {
  margin: 0 0 4px; padding: 8px 8px 8px 30px;
  /* Десять строк по 24px плюс свои поля и рамка: box-sizing здесь border-box. */
  line-height: 24px; max-height: calc(24px * 10 + 16px + 2px);
  overflow-y: auto; scrollbar-gutter: stable;
  border: 1px solid var(--b24-border); border-radius: var(--radius);
  background: var(--b24-card);
}
/* Список получателей личной сводки: коробка с прокруткой по тому же приёму, что
   .set-list — сотрудников портала бывает несколько десятков, и без края они
   выдавили бы «Сохранить» за экран. Одна галочка в строке, а не в ряд: имена
   разной длины, и ряд читался бы как таблица без столбцов. */
.set-people {
  display: flex; flex-direction: column; gap: 6px;
  max-height: calc(26px * 8); overflow-y: auto; scrollbar-gutter: stable;
  padding: 8px 10px; border: 1px solid var(--b24-border); border-radius: var(--radius);
  background: var(--b24-card);
}

/* Полоска согласия отправителя сводки на вкладке набора. Не .set-warn: это не
   предупреждение, а просьба, и цветом она не кричит. Пустая — скрыта самим
   скриптом (display:none в разметке). */
.sender-ask {
  padding: 12px 14px; margin-bottom: 14px; border-radius: var(--radius);
  background: var(--b24-primary-soft); color: var(--b24-text); font-size: 14px;
}
.sender-ask__acts { display: flex; gap: 8px; flex-wrap: wrap; margin-top: 10px; }
.sender-ask__note { margin-top: 8px; font-size: 12px; color: var(--text-muted); }
.sender-ask__note--bad { color: var(--b24-warning-ink); }

/* Поля формы сводки. Отдельно от .rs-select: тот растянут на всю ширину, а
   время и число дней стоят в строке рядом с подписью. */
.rs-input {
  padding: 8px 12px; border: 1px solid var(--b24-border); border-radius: var(--radius);
  font-size: 14px; color: var(--b24-text); background: var(--b24-white);
}
.rs-input:focus { border-color: var(--teal); }

/* Раздел «Филиалы»: таблица правил, список значений галочками, журнал. */
.br-field > span { flex: 0 0 120px; font-size: 13px; color: var(--text-muted); }
.br-field .rs-input { min-width: 260px; }
.br-block { margin-top: 4px; }
.br-table th { text-align: left; padding: 10px; font-size: 12px; color: var(--text-muted); border-bottom: 1px solid var(--b24-border); }
.br-table .rs-input { min-width: 200px; max-width: 100%; }
.br-no { width: 48px; font-weight: 600; color: var(--text-muted); }
.br-values { display: flex; flex-wrap: wrap; gap: 6px 14px; max-height: 160px; overflow: auto; }
.br-check { margin-top: 6px; }
.br-ok { color: var(--ok-ink); font-weight: 600; }
.br-err { color: var(--danger-ink); font-weight: 600; }
.br-row-err td { background: rgba(var(--danger-rgb), .05); }
.br-changed { margin: 6px 0 0; padding: 6px 10px; }
/* Итог «Отправить заново» — под кнопкой своей строки, а не только наверху вкладки. */
.br-row-note { margin-top: 6px; font-size: 12px; max-width: 260px; }
.br-row-note--ok { color: var(--ok-ink); }
.br-row-note--err { color: var(--danger-ink); }
.br-cities { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 10px; margin-top: 8px; }
.br-city {
  display: flex; flex-direction: column; gap: 4px; align-items: flex-start; text-align: left;
  padding: 12px 14px; border: 1px solid var(--b24-border); border-radius: var(--radius-lg);
  background: var(--b24-white); color: var(--b24-text); cursor: pointer; font: inherit;
}
.br-city:hover { background: var(--b24-hover); }
.br-city--ready { border-left: 4px solid var(--ok-ink); }
.br-city--off { opacity: .7; }
.br-city__name { font-weight: 600; }
.br-city__state { font-size: 12px; color: var(--text-muted); }
.br-city__badge { font-size: 12px; color: var(--danger-ink); background: rgba(var(--danger-rgb), .08); padding: 2px 8px; border-radius: 999px; }
.modal--city { max-width: 640px; width: 94%; }
.br-rule { padding: 10px 12px; border-radius: var(--radius); background: var(--b24-primary-soft); }
.br-rule__text { font-size: 14px; color: var(--b24-text); }
.br-modal-actions { display: flex; gap: 8px; margin-top: 14px; }

/* ─── Настройки приложения: счётчики, анкета, подсветка, эталон ─────────────

   Вёрстка компактная: подпись слева, контрол справа, ширина контролов
   ограничена, счётчики — списком слева и одной карточкой справа. Раскладка
   повторяет раздел «Приложение» пульта prodaju (спека того проекта от
   24.09.2026): там замер показал экран в 6 700 px, где не помещался даже один
   счётчик, и лечится он ровно этим — сеткой строк, подсказками по требованию
   и мастер-детейлом.

   Раздел шире 1120 px не растёт: подпись в 200 px и контрол в 520 px
   читаются одним взглядом, а поле во всю ширину монитора — нет.

   Подраздел свой, .set-subnav — не .set-nav: тот листает Доступ/Сводку/
   Очистку, этот — страницы внутри «Настроек приложения», и разные
   уровни навигации совпадать не должны. */

/* Ряд страниц раздела — сегментный переключатель на подложке: тоньше верхнего
   ряда вкладок, чтобы два ряда кнопок подряд не читались как один. */
.set-subnav {
  display: inline-flex; align-self: flex-start; gap: 2px; padding: 3px;
  margin: 0 0 12px; background: var(--bg-sunken); border-radius: var(--radius-sm);
}
.set-subnav__btn {
  padding: 5px 14px; font-size: 13px; font-weight: 600; color: var(--text-muted);
  background: none; border: none; border-radius: var(--radius-sm); cursor: pointer;
}
.set-subnav__btn:hover { color: var(--b24-text); }
.set-subnav__btn--active {
  background: var(--b24-white); color: var(--b24-text); box-shadow: var(--shadow-1);
}

/* Объяснение страницы — свёрнутое: его читают один раз, а три строки над
   каждым экраном сдвигали первое поле на 120–300 px вниз. */
.set-about { margin: 0 0 12px; font-size: 13px; color: var(--text-muted); }
.set-about > summary {
  width: max-content; cursor: pointer; color: var(--teal-ink);
  list-style: none; display: inline-flex; align-items: center; gap: 6px;
}
.set-about > summary::-webkit-details-marker { display: none; }
.set-about > summary::before { content: '▸'; font-size: 10px; line-height: 1; }
.set-about[open] > summary::before { content: '▾'; }
.set-about > summary:hover { text-decoration: underline; }
.set-help-intro { margin: 6px 0 0; max-width: 760px; line-height: 1.45; }

.set-body { display: flex; flex-direction: column; max-width: 1120px; }

/* ── Счётчики: список слева, карточка раскрытого — справа ──────────────────
   Пять карточек подряд давали экран в несколько тысяч точек: списком видно
   все счётчики сразу, а правят всегда один. Список липнет к верху окна,
   чтобы переключаться между счётчиками, не листая карточку до конца. */
.set-md {
  display: grid; grid-template-columns: 250px minmax(0, 1fr);
  gap: 16px; align-items: start;
}
.set-md__side {
  position: sticky; top: 12px; display: flex; flex-direction: column; gap: 2px;
  padding: 8px; background: var(--b24-card); border: 1px solid var(--b24-border);
  border-radius: var(--radius);
}
.set-md__pane { min-width: 0; }
.set-md__group {
  display: flex; align-items: center; gap: 6px; margin: 10px 8px 4px;
  font-size: 11px; font-weight: 700; letter-spacing: .05em;
  text-transform: uppercase; color: var(--text-muted);
}
.set-md__group:first-child { margin-top: 4px; }
.set-md__group .set-i { margin-left: 0; }
.set-md__count {
  margin-left: auto; font-weight: 500; letter-spacing: 0; text-transform: none;
}
.set-md__item {
  display: flex; flex-direction: column; gap: 1px; padding: 7px 10px;
  text-align: left; background: none; border: 1px solid transparent;
  border-radius: var(--radius-sm); cursor: pointer;
}
.set-md__item b { font-size: 14px; font-weight: 600; color: var(--b24-text); }
.set-md__item small { font-size: 12px; color: var(--text-muted); }
.set-md__item em { font-size: 11px; font-style: normal; }
.set-md__note { color: var(--text-muted); }
/* Жалобы сверщика названы числом: карточка невыбранного счётчика не
   нарисована, и его замечания иначе не увидеть, не раскрыв каждый. */
.set-md__issue { color: var(--b24-warning-ink); }
.set-md__issue--bad { color: var(--b24-danger-ink); }
.set-md__item:hover { background: var(--b24-bg); }
.set-md__item--on { background: var(--b24-primary-soft); border-color: var(--brand-line); }
.set-md__empty { padding: 2px 10px 6px; font-size: 13px; color: var(--b24-gray); }
.set-md__side .set-app-add { margin: 4px 8px; }
.set-md__side .set-app-hint { margin: 2px 8px 6px; }

/* Счётчик, набор анкеты и правило подсветки — карточки: настройки одной вещи
   не должны перетекать в соседнюю. Расстояние между строками задают сами
   строки (padding), не gap. */
.set-counter {
  display: flex; flex-direction: column; gap: 0;
  padding: 16px 20px 18px; background: var(--b24-card);
  border: 1px solid var(--b24-border); border-radius: var(--radius);
}
.set-counter + .set-counter { margin-top: 12px; }
.set-counter__head {
  display: flex; flex-wrap: wrap; gap: 12px; align-items: center;
  padding-bottom: 12px; border-bottom: 1px solid var(--b24-border);
}
.set-title {
  flex: 0 1 320px; min-width: 200px; padding: 7px 9px;
  font-size: 15px; font-weight: 600; color: var(--b24-text);
  background: var(--b24-white); border: 1px solid var(--b24-border-strong);
  border-radius: var(--radius-sm);
}
.set-title:focus { border-color: var(--teal); }
/* Удаление и его вопрос уходят вправо: это выход из карточки, а не её поле. */
.set-counter__head .set-x, .set-counter__head .set-ask { margin-left: auto; }
.set-check {
  display: inline-flex; gap: 6px; align-items: center;
  font-size: 14px; color: var(--b24-text);
}

/* Заголовок группы строк внутри карточки; у исключений — свой цвет: условия
   в них выглядят ровно так же, как условия счёта, и перепутать наборы стоило
   бы счётчику всех записей разом. */
.set-g {
  margin: 18px 0 2px; font-size: 11px; font-weight: 700; letter-spacing: .06em;
  text-transform: uppercase; color: var(--text-muted);
}
.set-g--veto { color: var(--warn-ink); }
.set-g__hint {
  margin: 0 0 4px; max-width: 640px; font-size: 12px;
  color: var(--text-muted); line-height: 1.45;
}

/* Строка настройки: подпись слева, контрол справа. Ширина контрола
   ограничена — список во всю ширину карточки читался хуже, чем в 520 px. */
.set-term-field {
  display: grid; grid-template-columns: 200px minmax(0, 520px);
  gap: 4px 16px; align-items: center; min-width: 0;
  padding: 5px 0; font-size: 13px; color: var(--ink-soft);
}
.set-term-field > span:first-child { grid-column: 1; grid-row: 1; }
.set-term-field > :not(span:first-child) { grid-column: 2; }
/* У многострочного списка подпись встаёт к его верху: по центру шестистрочного
   выбора она оказывалась напротив середины списка и теряла свою строку. */
.set-term-field:has(select[multiple]) > span:first-child {
  align-self: start; padding-top: 8px;
}
.set-term-field select, .set-term-field input {
  padding: 6px 8px; font-size: 14px; color: var(--b24-text);
  background: var(--b24-white); border: 1px solid var(--b24-border-strong);
  border-radius: var(--radius-sm);
}
.set-term-field select:focus, .set-term-field input:focus {
  border-color: var(--teal);
}
.set-term-field select[multiple] { min-height: 0; height: auto; padding: 2px; }
.set-term-field input[type="number"] { width: 88px; }

/* Слова вместо контрола: выбора здесь нет, и сказано, почему. */
.set-static { font-size: 13px; color: var(--ink-soft); }
.set-static--warn { color: var(--b24-warning-ink); }

/* Пояснение под контролом занимает всю ширину колонки: иначе оно вклинивается
   между полями и разрывает их ряд. */
.set-app-hint {
  grid-column: 2; font-size: 12px; color: var(--text-muted); line-height: 1.45;
}
.set-sub { display: block; font-size: 12px; color: var(--text-muted); margin-top: 4px; }

/* Значок «?» с подсказкой: пузырь по наведению, фокусу и щелчку (на планшете
   наведения нет). Заглавные буквы и разрядка заголовка группы в пузырь не
   наследуются — иначе подсказка кричала бы капслоком. */
.set-i {
  position: relative; display: inline-flex; align-items: center;
  justify-content: center; width: 15px; height: 15px; margin-left: 6px;
  font-size: 10px; font-style: normal; font-weight: 700; color: var(--text-muted);
  border: 1px solid var(--b24-border-strong); border-radius: 50%;
  cursor: help; vertical-align: middle; text-transform: none; letter-spacing: 0;
}
/* pre-line — не украшение: в пузыре четыре части пояснения, разделённые в
   data-hint пустой строкой, и без него они склеились бы в один абзац. */
.set-i::after {
  content: attr(data-hint); position: absolute; left: 0; top: calc(100% + 6px);
  z-index: 20; display: none; width: max-content; max-width: 380px;
  padding: 10px 12px; font-size: 12px; font-weight: 400; line-height: 1.45;
  color: var(--b24-white); text-align: left; white-space: pre-line;
  background: var(--b24-text); border-radius: var(--radius-sm);
  box-shadow: var(--shadow-2);
}
.set-i:hover::after, .set-i:focus::after { display: block; }

/* ── Условия отбора ───────────────────────────────────────────────────── */
.set-term { display: flex; flex-direction: column; }
.set-term__issues { display: flex; flex-wrap: wrap; gap: 6px; }
.set-terms { display: contents; }
.set-veto { display: flex; flex-direction: column; }
.set-conds {
  display: grid; grid-template-columns: 200px minmax(0, 640px);
  gap: 6px 16px; align-items: start; padding: 5px 0;
}
.set-conds__title {
  grid-column: 1; padding-top: 7px; font-size: 13px; font-weight: 500;
  color: var(--ink-soft);
}
.set-conds > :not(.set-conds__title) { grid-column: 2; }
.set-conds > .set-app-hint { grid-column: 2; }

/* Одно условие — своя строка с фоном: без неё поля соседних условий читаются
   как одно длинное перечисление. Подписи полей — только у первой строки: ниже
   те же две колонки, и повторять их подписи незачем. У строк со значениями
   списка колонок три — там подписи остаются. */
.set-cond {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) auto;
  gap: 8px 12px; align-items: end; padding: 6px 10px;
  background: var(--b24-bg); border-radius: var(--radius-sm);
}
.set-cond--3 {
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) auto;
  align-items: start;
}
.set-cond__part {
  display: flex; flex-direction: column; align-items: stretch; gap: 3px;
  min-width: 0; padding: 0; font-size: 13px; color: var(--ink-soft);
}
.set-cond__part > span:first-child { font-size: 12px; }
.set-cond__part select, .set-cond__part input {
  padding: 6px 8px; font-size: 14px; color: var(--b24-text);
  background: var(--b24-white); border: 1px solid var(--b24-border-strong);
  border-radius: var(--radius-sm);
}
.set-cond__part select[multiple] { min-height: 0; height: auto; padding: 2px; }
.set-cond ~ .set-cond:not(.set-cond--3) .set-cond__part > span:first-child {
  display: none;
}
.set-cond .set-x {
  grid-column: -2 / -1; grid-row: 1; justify-self: end; align-self: end;
  height: 32px; padding: 0; white-space: nowrap;
}
/* В строке со списком «убрать» стоит вровень с контролами: подпись над ними
   (12 px × 1.5) плюс зазор в 3 px. */
.set-cond--3 .set-x { align-self: start; margin-top: 21px; }
/* Приписки под строкой — во всю её ширину: и предупреждение о невозможном
   условии, и строка пробы про отсев объясняют строку целиком. */
.set-cond__warn, .set-cond__note, .set-cond__cut { grid-column: 1 / -1; }
.set-cond__note, .set-cond__cut {
  font-size: 12px; color: var(--text-muted); line-height: 1.45;
}
.set-cond__cut--all { color: var(--b24-danger-ink); }
.set-cond__cut--idle { color: var(--b24-warning-ink); }
.set-cond .set-app-hint { grid-column: 1 / -1; }
.set-conds .set-app-add { justify-self: start; padding: 5px 10px; font-size: 12px; }
.set-conds .set-pill { justify-self: start; }

/* Поля анкеты — таблицей: у каждой строки одни и те же колонки, и подписи
   стоят один раз в шапке. */
.set-app-lists { display: block; padding: 6px 0; }
.set-app-lists__title {
  display: block; margin-bottom: 4px; font-size: 13px; color: var(--ink-soft);
}
.set-app-field {
  display: grid; gap: 8px 12px; align-items: center;
  grid-template-columns: minmax(0, 260px) minmax(0, 230px) auto;
  padding: 6px 10px; background: var(--b24-bg); border-radius: var(--radius-sm);
}
.set-app-field + .set-app-field { margin-top: 4px; }
.set-app-field__name { font-size: 13px; color: var(--b24-text); }

/* Плашка-ярлык: роль счётчика, жалоба сверщика, число пробы. */
.set-pill {
  display: inline-block; padding: 2px 8px; font-size: 12px; line-height: 1.6;
  color: var(--ink-soft); background: var(--bg-sunken); border-radius: 999px;
}
.set-pill--role { color: var(--teal-ink); background: var(--teal-soft); }
.set-pill--warn { color: var(--b24-warning-ink); background: rgba(var(--warn-rgb), .18); }
.set-pill--bad { color: var(--b24-danger-ink); background: rgba(var(--danger-rgb), .10); }

/* Жалобы, которым не нашлось места на экране: показываем их наверху, а не
   прячем — правило, которое не считается, важнее аккуратности списка. */
.set-issues {
  padding: 10px 12px; margin: 0 0 12px; border: 1px solid rgba(var(--warn-rgb), .4);
  border-radius: var(--radius); background: rgba(var(--warn-rgb), .08);
}
.set-issues__title {
  margin-bottom: 6px; font-size: 13px; font-weight: 600;
  color: var(--b24-warning-ink);
}
.set-alert {
  padding: 10px 14px; margin: 0 0 12px; border-radius: var(--radius);
  background: var(--b24-primary-soft); color: var(--b24-text);
}
.set-alert--bad { background: rgba(var(--danger-rgb), .10); color: var(--b24-danger-ink); }

/* «Добавить» — пунктиром: кнопка заводит новое, а не подтверждает набранное. */
.set-app-add {
  align-self: flex-start; padding: 7px 12px; font-size: 13px; color: var(--ink);
  background: var(--b24-white); border: 1px dashed var(--b24-gray);
  border-radius: var(--radius-sm); cursor: pointer;
}
.set-app-add:hover { background: var(--b24-hover); color: var(--brand-active); border-color: var(--brand-line); }
.set-app-add--big { padding: 8px 16px; }

/* «Убрать» — ссылкой, а не кнопкой: рядом с полями настроек полноценная
   кнопка спорит за внимание с самими настройками. */
.set-x {
  padding: 4px 2px; font-size: 13px; color: var(--text-muted);
  background: none; border: none; cursor: pointer; text-decoration: underline;
}
.set-x:hover { color: var(--b24-text); }
.set-x--bad { color: var(--b24-danger-ink); }
.set-x--bad:hover { color: var(--danger-ink); }

/* Вопрос подтверждения встаёт на место самой кнопки — ответ там же, где был
   вопрос, и уводить взгляд не нужно. */
.set-ask {
  display: inline-flex; flex-wrap: wrap; gap: 8px; align-items: center;
  padding: 4px 10px; background: rgba(var(--danger-rgb), .06); border: 1px solid rgba(var(--danger-rgb), .35);
  border-radius: 999px;
}
.set-ask__q { font-size: 13px; color: var(--b24-danger-ink); }

.set-body--wait { color: var(--text-muted); padding: 16px 0; }

/* ── Подвал раздела ────────────────────────────────────────────────────────
   Прилипает к низу окна: раздел длиной в несколько экранов, и кнопка
   «Сохранить» в его конце стояла на тысячи точек ниже того места, где правят.
   Фон — фон страницы: подвал плывёт поверх карточек и не должен в них
   сливаться. */
.set-foot {
  position: sticky; bottom: 0; z-index: 5; display: flex; flex-direction: column;
  gap: 8px; max-width: 1120px; margin-top: 16px;
  padding: 10px 0 12px; background: var(--b24-bg);
  border-top: 1px solid var(--b24-border);
  box-shadow: 0 -8px 16px -12px rgba(var(--ink-rgb), .35);
}
/* Исход действия — над кнопками, в самом подвале: «Настройки сохранены» и
   отказ сервера обязаны встать там, где нажали, а не над разделом высотой в
   несколько экранов. */
.set-foot__msg { display: flex; flex-direction: column; gap: 6px; }
.set-foot__msg .set-alert { margin: 0; padding: 8px 12px; font-size: 13px; }
.set-foot__row { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.set-save {
  padding: 8px 18px; font-size: 14px; border-radius: var(--radius);
  border: 1px solid var(--b24-border); background: var(--b24-card);
  color: var(--text-muted); cursor: default;
}
.set-save--on {
  background: var(--b24-primary); border-color: var(--b24-primary);
  color: var(--b24-white); cursor: pointer;
}
.set-try {
  padding: 8px 16px; font-size: 14px; border-radius: var(--radius);
  border: 1px solid var(--b24-border-strong); background: var(--b24-card);
  color: var(--b24-text); cursor: pointer;
}
.set-try:hover { background: var(--b24-hover); color: var(--brand-active); border-color: var(--brand-line); }
.set-foot .set-app-hint { grid-column: auto; }
/* Строка пробы: кнопка и приписка о том, что она посчитает, — над самим
   итогом пробы, а не в подвале с настоящими действиями. */
.set-try-row {
  display: flex; flex-wrap: wrap; gap: 8px; align-items: center;
  max-width: 1120px; margin-top: 12px;
}

/* Строка свежести справочника: кнопки и перечень того, что портал изменил с
   прошлого раза. Стоит под переключателем страниц раздела. */
.set-watch { max-width: 1120px; margin-bottom: 12px; }
.set-watch .set-try-row { margin-top: 0; }
.set-try:disabled { opacity: .55; cursor: not-allowed; }
.set-watch__list {
  display: flex; flex-direction: column; gap: 6px; margin-top: 10px;
  padding: 10px 14px; border-radius: var(--radius);
  background: var(--b24-bg); border: 1px solid var(--b24-border);
}
.set-watch__item { font-size: 13px; color: var(--text-muted); }
/* Изменение, которое касается настроек, читается первым и не серым: его надо
   не заметить, а разобрать. */
.set-watch__item--use { color: var(--b24-text); font-weight: 500; }
.set-watch__used { display: block; font-size: 12px; color: var(--text-muted); font-weight: 400; }

/* ── Проба ─────────────────────────────────────────────────────────────── */
.set-preview {
  border: 1px solid var(--b24-primary); border-radius: var(--radius);
  background: var(--b24-primary-soft); padding: 12px 14px; margin: 12px 0 0;
  max-width: 1120px;
}
.set-preview__head { font-size: 13px; color: var(--b24-text); margin-bottom: 8px; }
/* Строка под числами счётчика: причины отказа и круг, по которому счётчик
   считал. Одно правило на оба вида приписки — вид у них один, и разойтись они
   не должны. */
.set-preview__why, .set-preview__pool {
  font-size: 12px; color: var(--text-muted); padding: 2px 0 6px;
}
.set-preview__why-one { display: inline-block; margin-right: 12px; }
.set-preview__why-one::before { content: '• '; }
/* Три колонки, а не три слова в строку: числа разных счётчиков обязаны стоять
   друг под другом, иначе «было 12 / станет 3» соседних строк не сравнить
   глазом. auto по краям — колонки шириной по самому длинному числу. */
.set-preview__row {
  display: grid; grid-template-columns: 1fr auto auto; gap: 12px;
  padding: 4px 0; font-size: 14px; color: var(--b24-text);
  border-top: 1px solid var(--b24-border);
}

/* Предпросмотр сводки: сообщения чата и письма по людям, каждое — своим
   блоком, как придёт в чат Битрикса. pre-wrap — переносы строк из текста
   сообщения, а не из разметки; anywhere — длинная ссылка не выталкивает блок
   за край. Коробка со всеми сообщениями прокручивается сама: серия на десять
   семинаров и двадцать человек длиннее экрана, а под ней стоят кнопки. */
.set-preview__head--row {
  display: flex; align-items: center; justify-content: space-between; gap: 12px; flex-wrap: wrap;
}
.set-preview__msgs { max-height: 70vh; overflow-y: auto; scrollbar-gutter: stable; margin-top: 8px; }
.set-preview__who { font-size: 13px; font-weight: 600; color: var(--b24-text); margin: 12px 0 6px; }
.set-preview__who:first-child { margin-top: 0; }
.set-msg {
  white-space: pre-wrap; overflow-wrap: anywhere;
  font-size: 13px; line-height: 1.45; color: var(--b24-text);
  background: var(--b24-white); border: 1px solid var(--b24-border); border-radius: var(--radius);
  padding: 10px 12px; margin: 0 0 8px;
}
.set-msg a { color: var(--b24-primary); }

/* Журнал сохранений: коробка с прокруткой по тому же приёму, что .set-list —
   обрыв между строками, а не на полуслове. Записей со временем становится
   много, а под ними стоит подвал с «Сохранить». */
.set-log {
  max-height: calc(28px * 8); overflow-y: auto; scrollbar-gutter: stable;
  border: 1px solid var(--b24-border); border-radius: var(--radius);
  background: var(--b24-white); padding: 4px 10px;
}
.set-log__row {
  display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
  min-height: 28px; font-size: 13px; color: var(--b24-text);
}
/* Пол журнала — строка заводских настроек. Она стоит ВНЕ прокручиваемого
   списка (settings-view.js, baselineMarkup), и отступ выравнивает её со
   строками внутри: рамка списка плюс его внутренний отступ. */
.set-log__row--floor { padding: 0 11px; }

/* Узкий экран: раздел открывают и с телефона внутри рамки Битрикса. Две
   колонки там не помещаются — и список счётчиков, и строки настроек
   складываются в столбик, а липкий список счётчиков отлипает: на телефоне он
   съел бы пол-экрана. */
@media (max-width: 860px) {
  .set-md { grid-template-columns: minmax(0, 1fr); }
  .set-md__side { position: static; }
}
@media (max-width: 560px) {
  .set-term-field, .set-conds { grid-template-columns: minmax(0, 1fr); }
  .set-term-field > :not(span:first-child), .set-conds > :not(.set-conds__title),
  .set-app-hint { grid-column: 1; }
  .set-conds__title { padding-top: 0; }
  .set-cond, .set-cond--3 { grid-template-columns: minmax(0, 1fr) auto; }
  .set-cond ~ .set-cond .set-cond__part > span:first-child { display: block; }
  .set-preview__row { grid-template-columns: 1fr; gap: 2px; }
  .set-counter { padding: 12px; }
  .set-foot { padding: 10px 0; }
}

/* ═══ ПОВТОРНЫЕ ПРОДАЖИ (задача 2ec081) ═══════════════════════════════════
   Только существующие токены (design-contract §2). Таблица — .rs-table,
   поверх неё липкая шапка и внутренняя прокрутка. */
.rsx-top { display: flex; gap: 16px; align-items: stretch; flex-wrap: wrap; margin-bottom: 12px; }
.rsx-pick {
  flex: 1 1 320px; background: var(--surface); border-radius: var(--radius);
  box-shadow: var(--shadow-1); padding: 16px; display: flex; flex-direction: column; gap: 8px; min-width: 0;
}
.rsx-pick__title { font-size: 15px; font-weight: 700; color: var(--ink); margin: 0; }
.rsx-pick__foot { display: flex; align-items: center; justify-content: space-between; gap: 8px; margin-top: auto; }
.rsx-field { display: flex; flex-direction: column; gap: 4px; font-size: 12px; color: var(--ink-soft); min-width: 0; }
.rsx-field--inline { flex-direction: row; align-items: center; gap: 6px; }
.rsx-field .rs-select { text-overflow: ellipsis; }
.rsx-fresh { display: flex; flex-direction: column; align-items: flex-end; justify-content: center; gap: 6px; font-size: 13px; color: var(--ink-soft); }
.rsx-hint { font-size: 12px; color: var(--ink-muted); }
.rsx-hint--bad { color: var(--danger-ink); }
.rsx-muted { color: var(--ink-muted); }

.rsx-diag { background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow-1); padding: 10px 16px; margin-bottom: 12px; font-size: 13px; }
.rsx-diag summary { cursor: pointer; color: var(--warn-ink); font-weight: 600; }
.rsx-diag__body { display: flex; gap: 24px; flex-wrap: wrap; margin-top: 8px; }
.rsx-diag__col { flex: 1 1 280px; min-width: 0; }
.rsx-diag__col h3 { font-size: 12px; font-weight: 600; color: var(--ink-soft); margin: 0 0 6px; }
.rsx-diag__col ul { margin: 0; padding-left: 18px; }

.rsx-switch { display: flex; gap: 4px; margin-bottom: 8px; border-bottom: 1px solid var(--line); }
.rsx-switch__btn {
  background: none; border: none; border-bottom: 2px solid transparent; padding: 8px 14px;
  font-size: 14px; color: var(--ink-soft); cursor: pointer;
}
.rsx-switch__btn:hover { background: var(--b24-hover); }
.rsx-switch__btn--on { color: var(--brand); border-bottom-color: var(--brand); font-weight: 600; }

.rsx-empty { padding: 32px 16px; text-align: center; color: var(--ink-muted); font-size: 14px; }
.rsx-loading-sec { text-align: center; color: var(--ink-muted); font-size: 13px; font-variant-numeric: tabular-nums; }
.rsx-list-title { font-size: 15px; font-weight: 700; color: var(--ink); margin: 4px 0 6px; overflow-wrap: anywhere; }
.rsx-stats { display: flex; flex-wrap: wrap; gap: 6px 16px; font-size: 13px; color: var(--ink-soft); margin-bottom: 8px; }
.rsx-filters { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; margin-bottom: 8px; }
.rsx-filters__csv { margin-left: auto; }
.rsx-search {
  padding: 7px 10px; border: 1px solid var(--b24-border); border-radius: var(--radius);
  font-size: 13px; color: var(--ink); background: var(--surface); min-width: 220px;
}
.rsx-search:focus { border-color: var(--teal); }

.rsx-table-wrap { max-height: calc(100vh - 320px); min-height: 240px; overflow: auto; border-radius: var(--radius); max-width: 1600px; }
.rsx-table { table-layout: fixed; }
.rsx-table thead th { position: sticky; top: 0; z-index: 2; background: var(--b24-bg); }
.rsx-col-check { width: 40px; }
.rsx-table th:nth-child(2) { width: 28%; }
.rsx-table th:nth-child(3) { width: 18%; }
.rsx-table th:nth-child(4) { width: 20%; }
.rsx-table th:nth-child(5) { width: 16%; }
.rsx-sort { background: none; border: none; padding: 0; font: inherit; color: inherit; text-transform: inherit; letter-spacing: inherit; cursor: pointer; }
.rsx-table th[aria-sort="ascending"] .rsx-sort::after { content: ' ▲'; }
.rsx-table th[aria-sort="descending"] .rsx-sort::after { content: ' ▼'; }
.rsx-cell { white-space: nowrap; overflow: hidden; }
.rsx-cell > .ico { width: 14px; height: 14px; color: var(--ink-muted); vertical-align: middle; margin-right: 4px; }
.rsx-ellipsis { display: inline-block; max-width: calc(100% - 44px); overflow: hidden; text-overflow: ellipsis; vertical-align: middle; }
.rsx-name { background: none; border: none; padding: 0; font: inherit; color: var(--brand); cursor: pointer; text-align: left; max-width: 100%; }
.rsx-name:hover { text-decoration: underline; }
.rsx-copy { background: none; border: none; padding: 2px; margin-left: 4px; color: var(--ink-muted); cursor: pointer; border-radius: var(--radius-sm); vertical-align: middle; }
.rsx-copy:hover { background: var(--b24-hover); color: var(--ink); }
.rsx-copy .ico { width: 14px; height: 14px; display: block; }
.rsx-row--done td { background: rgba(var(--ok-rgb), .06); }
.rsx-more { display: block; margin: 8px auto; }

.rsx-badge { display: inline-block; margin-left: 6px; padding: 1px 6px; border-radius: var(--radius-sm); font-size: 11px; font-weight: 600; white-space: nowrap; }
.rsx-badge--warn { color: var(--warn-ink); background: rgba(var(--warn-rgb), .15); }
.rsx-badge--danger { color: var(--danger-ink); background: rgba(var(--danger-rgb), .12); }
.rsx-badge--severe { color: var(--b24-white); background: var(--danger-ink); }
.rsx-badge--ok { color: var(--ok-ink); background: rgba(var(--ok-rgb), .12); }

.rsx-progress { display: flex; align-items: center; gap: 8px; }
.rsx-progress__track { flex: 1; height: 6px; background: var(--bg-sunken); border-radius: var(--radius-sm); overflow: hidden; min-width: 40px; }
.rsx-progress__fill { height: 100%; background: var(--brand); }
.rsx-progress__text { font-size: 12px; color: var(--ink-soft); white-space: nowrap; }

.rsx-card__head { display: flex; align-items: center; gap: 16px; margin-bottom: 12px; font-size: 14px; }
.rsx-card__h { font-size: 13px; font-weight: 700; color: var(--ink); margin: 12px 0 6px; }
.rsx-card__list { margin: 0; padding-left: 18px; font-size: 13px; }
.rsx-card__list li { margin-bottom: 4px; overflow-wrap: anywhere; }
.rsx-ring { width: 80px; height: 80px; flex: none; transform: rotate(-90deg); }
.rsx-ring__track, .rsx-ring__fill { fill: none; stroke-width: 8; }
.rsx-ring__track { stroke: var(--line); }
.rsx-ring__fill { stroke: var(--brand); stroke-linecap: round; }
.rsx-ring__text { transform: rotate(90deg); transform-origin: 40px 40px; font-size: 16px; font-weight: 700; fill: var(--ink); }

.rsx-actions { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 12px; }
.rsx-run__line { font-size: 15px; font-weight: 600; color: var(--ink); margin-bottom: 8px; }

.rsx-bar {
  position: sticky; bottom: 0; z-index: 50; display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px;
  background: var(--surface); box-shadow: var(--shadow-3); border-radius: var(--radius); padding: 10px 16px; margin-top: 12px;
}
.rsx-bar .rs-select { width: auto; max-width: 260px; }
.rsx-bar .rsx-search { min-width: 120px; width: 140px; }

.rsx-tpl {
  width: 100%; padding: 8px 10px; border: 1px solid var(--b24-border); border-radius: var(--radius);
  font: inherit; font-size: 13px; color: var(--ink); resize: vertical; box-sizing: border-box;
}
.rsx-tpl:focus { border-color: var(--teal); }
.rsx-preview { max-height: 260px; overflow: auto; padding-left: 20px; font-size: 13px; }
.rsx-preview li { margin-bottom: 8px; }
.rsx-preview__text { white-space: pre-wrap; overflow-wrap: anywhere; color: var(--ink); }
.rsx-pause { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; font-size: 13px; margin-top: 12px; }
.rsx-pause input { width: 64px; padding: 4px 6px; border: 1px solid var(--b24-border); border-radius: var(--radius-sm); }

.rsx-widget {
  position: fixed; right: 16px; bottom: 16px; width: 320px; z-index: 90;
  background: var(--surface); box-shadow: var(--shadow-3); border-radius: var(--radius); padding: 12px 16px;
}
.rsx-widget__text { font-size: 13px; color: var(--ink); margin-bottom: 8px; }
.rsx-widget__actions { display: flex; gap: 8px; }
.rsx-widget--folded { width: auto; max-width: 320px; padding: 8px 12px; }
.rsx-widget--folded .rsx-widget__text { margin-bottom: 4px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }

.rsx-live { position: absolute; width: 1px; height: 1px; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; }

@media (max-width: 1279px) {
  .rsx-top { flex-direction: column; }
  .rsx-fresh { align-items: flex-start; }
}

/* ── Вкладка «Аналитика» ───────────────────────────────────────────── */
/* У вкладки свой набор правил с приставкой an-: панель управления, подвкладки
   с пиктограммами, разделы-карточки, числа, графики трёх стилей и сортируемые
   таблицы. От дашборда плашки взят только скелет загрузки. Цвета — только
   токенами; зелёный и бирюза в одном правиле не встречаются: ряды и ключи
   получают цвет через свою переменную в отдельных правилах. */

/* Панель управления: период, стиль графиков, свежесть данных и «Обновить». */
.an-toolbar {
  position: relative; display: flex; flex-wrap: wrap; align-items: center;
  gap: 12px 20px; padding: 16px 18px 14px; margin-bottom: 14px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-1); overflow: hidden;
}
.an-toolbar::before {
  content: ''; position: absolute; left: 0; right: 0; top: 0; height: 3px;
  background: var(--accent-grad);
}
.an-toolbar__side {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 14px; margin-left: auto;
}
.an-ctl { display: flex; align-items: center; gap: 10px; }
.an-ctl__label {
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .07em;
  color: var(--ink-muted);
}
.an-seg {
  display: inline-flex; flex-wrap: wrap; gap: 2px; padding: 3px;
  background: var(--bg-sunken); border-radius: var(--radius);
}
.an-seg__btn {
  border: 0; padding: 6px 12px; border-radius: var(--radius-sm);
  background: transparent; color: var(--ink-soft); cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 600; white-space: nowrap;
  transition: background-color var(--dur-quick) var(--ease-out),
              color var(--dur-quick) var(--ease-out),
              box-shadow var(--dur-quick) var(--ease-out),
              transform var(--dur-quick) var(--ease-out);
}
.an-seg__btn:hover { color: var(--ink); }
.an-seg__btn:active { transform: scale(.97); }
.an-seg__btn.is-active {
  background: var(--surface); color: var(--brand); box-shadow: var(--shadow-1);
  animation: chip-pick var(--dur-quick) var(--ease-out) both;
}
.an-fresh {
  display: flex; flex-wrap: wrap; align-items: center; font-size: 12px;
  color: var(--ink-muted); font-variant-numeric: tabular-nums;
}
.an-fresh__i + .an-fresh__i::before { content: '·'; margin: 0 8px; color: var(--line-strong); }
.an-refresh {
  display: inline-flex; align-items: center; gap: 7px; padding: 6px 12px;
  border: 1px solid var(--line); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--ink-soft); cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 600;
  transition: color var(--dur-quick) var(--ease-out),
              border-color var(--dur-quick) var(--ease-out),
              box-shadow var(--dur-quick) var(--ease-out),
              transform var(--dur-quick) var(--ease-out);
}
.an-refresh:hover { color: var(--brand); border-color: var(--brand-line); box-shadow: var(--shadow-1); }
.an-refresh:active { transform: scale(.97); }
.an-refresh__ic { width: 15px; height: 15px; flex: none; }
.an-refresh.is-busy { color: var(--ink-muted); cursor: progress; }
.an-refresh.is-busy .an-refresh__ic { animation: an-spin var(--dur-pulse) linear infinite; }

/* Подвкладки: выбранная залита фирменным цветом с тенью, остальные — текстом
   на утопленной полосе. На узком экране переносятся строкой. */
.an-tabs {
  display: flex; flex-wrap: wrap; gap: 4px; padding: 4px; margin-bottom: 16px;
  background: var(--bg-sunken); border-radius: var(--radius);
}
.an-tab {
  display: inline-flex; align-items: center; justify-content: center; gap: 8px;
  flex: 1 1 128px; padding: 9px 14px; border: 0; border-radius: var(--radius-sm);
  background: transparent; color: var(--ink-soft); cursor: pointer;
  font-family: inherit; font-size: 14px; font-weight: 600; white-space: nowrap;
  transition: background-color var(--dur-quick) var(--ease-out),
              color var(--dur-quick) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              transform var(--dur-quick) var(--ease-out);
}
.an-tab:hover { color: var(--ink); background: rgba(var(--ink-rgb), .05); }
.an-tab:active { transform: scale(.98); }
.an-tab__ic { width: 16px; height: 16px; flex: none; opacity: .7; transition: opacity var(--dur-quick) var(--ease-out); }
.an-tab:hover .an-tab__ic { opacity: 1; }
.an-tab.is-active {
  background: var(--brand); color: var(--surface);
  box-shadow: 0 6px 16px rgba(var(--brand-rgb), .28);
  animation: chip-pick var(--dur-quick) var(--ease-out) both;
}
.an-tab.is-active:hover { background: var(--brand-hover); color: var(--surface); }
.an-tab.is-active .an-tab__ic { opacity: 1; }

/* Тело: при перезапросе прежние числа гаснут наполовину, но остаются. */
.an-body { transition: opacity var(--dur-base) var(--ease-out); }
.an-body.is-busy { opacity: .55; pointer-events: none; }
.an-panel { min-height: 240px; }
.an-panel > * { animation: an-panel-in var(--dur-slow) var(--ease-out) both; }
.an-panel > :nth-child(2) { animation-delay: calc(var(--dur-stagger) * 2); }
.an-panel > :nth-child(3) { animation-delay: calc(var(--dur-stagger) * 4); }
.an-panel > :nth-child(4) { animation-delay: calc(var(--dur-stagger) * 6); }
.an-panel > :nth-child(n+5) { animation-delay: calc(var(--dur-stagger) * 8); }
/* Пересортировка строк — не новый экран: ничему не выезжать и не отрастать. */
.an-panel.is-still, .an-panel.is-still * { animation: none; }

/* Скелет: плашки встают туда, куда приедут подвкладки, график и карточки. */
.an-skeleton { display: grid; gap: 14px; }
.an-skeleton__bar { border-radius: var(--radius); }
.an-skeleton__bar--tabs { height: 46px; }
.an-skeleton__bar--chart { height: 260px; }
.an-skeleton__row { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; }
.an-skeleton__bar--card { height: 92px; }

/* Раздел — карточка с заголовком; полоска у заголовка — фирменный градиент. */
.an-sec {
  margin-bottom: 16px; padding: 16px 18px 18px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-1);
}
.an-sec__t {
  display: flex; align-items: center; gap: 10px; margin: 0 0 12px;
  font-size: 12px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-soft);
}
.an-sec__t::before { content: ''; width: 4px; height: 14px; border-radius: 2px; flex: none; background: var(--accent-grad); }

/* Карточки чисел: число крупно, единица в нём же, пояснение мелко. */
.an-kpis { display: grid; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); gap: 12px; }
.an-kpi {
  position: relative; padding: 14px 16px 14px 18px; overflow: hidden;
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);
  transition: transform var(--dur-base) var(--ease-out),
              box-shadow var(--dur-base) var(--ease-out),
              border-color var(--dur-base) var(--ease-out);
}
.an-kpi::before { content: ''; position: absolute; left: 0; top: 0; bottom: 0; width: 4px; background: var(--line-strong); }
.an-kpi:hover { transform: translateY(-2px); box-shadow: var(--shadow-2); border-color: var(--line-strong); }
.an-kpi__label { margin-bottom: 6px; font-size: 12px; color: var(--ink-muted); }
.an-kpi__value {
  font-size: 24px; font-weight: 700; line-height: 1.15; letter-spacing: -.01em;
  color: var(--ink); font-variant-numeric: tabular-nums;
}
.an-kpi__sub { margin-top: 6px; font-size: 12px; line-height: 1.4; color: var(--ink-muted); }
.an-kpi--lead::before { background: var(--lead); }
.an-kpi--deal::before { background: var(--brand); }
.an-kpi--money::before { background: var(--teal); }
.an-kpi--plan::before { background: var(--ink-muted); }

/* Раздел «Отчёт»: карточка файла с кнопкой и перечень листов. Кнопка — общая
   .btn--primary, своего цвета у раздела нет; пунктирная рамка — «здесь ещё
   не файл, а его имя». */
.an-report__lead { margin: 0 0 14px; font-size: 14px; line-height: 1.5; color: var(--ink-soft); }
.an-report__file {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px;
  margin-top: 14px; padding: 16px 18px;
  background: var(--bg); border: 1px dashed var(--line-strong); border-radius: var(--radius);
}
.an-report__name {
  flex: 1 1 320px; font-size: 15px; font-weight: 600; color: var(--ink);
  word-break: break-word; font-variant-numeric: tabular-nums;
}
.an-report__btn { display: inline-flex; align-items: center; gap: 8px; white-space: nowrap; }
.an-report__ic { width: 16px; height: 16px; flex: none; }
.an-report__btn.is-busy { cursor: progress; }
.an-report__btn.is-busy .an-report__ic { animation: an-spin var(--dur-pulse) linear infinite; }
.an-report__hint { flex: 1 1 100%; font-size: 12px; line-height: 1.4; color: var(--ink-muted); }
.an-report__file .an-warn { flex: 1 1 100%; margin: 0; }
.an-report__sheets { margin: 0; padding: 0 0 0 22px; }
.an-report__sheet { padding: 7px 0; border-bottom: 1px solid var(--line); font-size: 14px; line-height: 1.45; }
.an-report__sheet:last-child { border-bottom: 0; }
.an-report__sheet-name { font-weight: 600; color: var(--ink); }
.an-report__sheet-name::after { content: ' — '; font-weight: 400; color: var(--ink-muted); }
.an-report__sheet-about { color: var(--ink-soft); }
.an-report__sheet.is-off .an-report__sheet-name,
.an-report__sheet.is-off .an-report__sheet-about { color: var(--ink-muted); }
.an-report__sheet.is-off .an-report__sheet-name { text-decoration: line-through; text-decoration-color: var(--line-strong); }

/* Чеклист «Что введено руками» на подвкладке «Экономика»: три строки с
   состоянием и кнопка в раздел настроек. Введённое помечено заливкой кружка,
   невведённое — пустым кружком; цвет здесь не единственный признак, рядом
   слова «введено за…» / «не введено». Кнопка — общая .btn--primary. */
.an-check { list-style: none; margin: 0; padding: 0; display: grid; gap: 8px; }
.an-check__item {
  display: grid; grid-template-columns: 12px auto 1fr; gap: 2px 12px; align-items: center;
  padding: 10px 14px; background: var(--bg); border: 1px solid var(--line); border-radius: var(--radius);
}
.an-check__mark {
  width: 12px; height: 12px; box-sizing: border-box; border-radius: 50%;
  border: 2px solid var(--line-strong);
}
.an-check__item.is-on .an-check__mark { border-color: var(--ok-ink); background: var(--ok-ink); }
.an-check__label { font-size: 14px; font-weight: 600; color: var(--ink); }
.an-check__state { justify-self: end; font-size: 13px; color: var(--ink-muted); font-variant-numeric: tabular-nums; }
.an-check__item.is-on .an-check__state { color: var(--ok-ink); }
.an-check__role { grid-column: 2 / -1; font-size: 12px; line-height: 1.4; color: var(--ink-soft); }
.an-check__foot { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px; margin-top: 12px; }
.an-check__btn { white-space: nowrap; }
.an-check__hint { flex: 1 1 280px; font-size: 12px; line-height: 1.4; color: var(--ink-muted); }

/* График. height:auto — svg держит пропорцию сам по viewBox. Стиль задаёт
   analytics-lib.js классом an-chart--столбики/линии/области; от стиля зависит
   лишь сила подсветки полосы под курсором: у линий есть свои точки-мишени. */
/* Полотно svg рисуется в пикселях экрана (AnalyticsLib.setCanvas), поэтому
   размеры шрифтов ниже — настоящие: подписи сетки 11px, названия строк 12,5px. */
.an-chart { display: block; width: 100%; height: auto; margin-top: 6px; }
.an-chart--bars { --an-band: .05; }
.an-chart--lines { --an-band: .035; }
.an-chart--area { --an-band: .03; }
.an-grid { stroke: var(--line); stroke-width: 1; }
.an-grid--base { stroke: var(--line-strong); }
.an-tick { fill: var(--ink-muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.an-band { fill: transparent; transition: fill var(--dur-quick) var(--ease-out); }
.an-band:hover { fill: rgba(var(--ink-rgb), var(--an-band, .05)); }

/* Цвет ряда — переменной в отдельных правилах: лид сиреневый, заявка зелёная,
   деньги бирюзовые, план серый — это цель, а не факт. Одна переменная кормит
   столбик, линию, область, точку и ключ. */
.an-bar--lead { --an-c: var(--lead); }
.an-bar--deal { --an-c: var(--brand); }
.an-bar--money { --an-c: var(--teal); }
.an-bar--plan { --an-c: var(--ink-muted); }
.an-bar {
  --i: 0;
  fill: var(--an-c, var(--past));
  transform-box: fill-box; transform-origin: center bottom;
  animation: an-bar-in var(--dur-slow) var(--ease-out) both;
  animation-delay: calc(var(--i) * var(--dur-stagger));
  transition: opacity var(--dur-quick) var(--ease-out);
}
.an-bar:hover { opacity: .75; }
.an-line {
  fill: none; stroke: var(--an-c, var(--past)); stroke-width: 2.5;
  stroke-linejoin: round; stroke-linecap: round; stroke-dasharray: 1;
  animation: stats-draw var(--dur-count) var(--ease-out) both;
}
.an-area { fill: var(--an-c, var(--past)); opacity: .14; animation: stats-fade var(--dur-slow) var(--ease-out) both; }
.an-dot {
  fill: var(--an-c, var(--past)); stroke: var(--surface); stroke-width: 2;
  animation: stats-fade var(--dur-slow) var(--ease-out) both; animation-delay: var(--dur-slow);
}
.an-hit { fill: transparent; transition: fill var(--dur-quick) var(--ease-out); }
.an-hit:hover { fill: rgba(var(--ink-rgb), .08); }

.an-keys {
  display: flex; flex-wrap: wrap; gap: 8px 16px; margin-top: 10px;
  font-size: 12px; color: var(--ink-soft); font-variant-numeric: tabular-nums;
}
.an-key { display: inline-flex; align-items: center; gap: 7px; }
.an-key::before { content: ''; width: 10px; height: 10px; border-radius: 3px; background: var(--an-c, var(--past)); }
.an-key--lead { --an-c: var(--lead); }
.an-key--deal { --an-c: var(--brand); }
.an-key--money { --an-c: var(--teal); }
.an-key--plan { --an-c: var(--ink-muted); }

/* Ряды семинаров («Деньги» → «Выручка по месяцам»). Цвет закреплён за
   семинаром, а не за местом в списке: снятый ряд не перекрашивает остальные.
   «Прочие семинары» — серым: это остаток, а не программа. */
.an-ser--1 { --an-c: var(--ser-1); }
.an-ser--2 { --an-c: var(--ser-2); }
.an-ser--3 { --an-c: var(--ser-3); }
.an-ser--4 { --an-c: var(--ser-4); }
.an-ser--5 { --an-c: var(--ser-5); }
.an-ser--6 { --an-c: var(--ser-6); }
.an-ser--7 { --an-c: var(--ser-7); }
.an-ser--8 { --an-c: var(--ser-8); }
.an-ser--other { --an-c: var(--past); }
/* Фон «Итого»: серая область без анимации линии — он подложка, а не ряд. */
.an-ghost { --an-c: var(--past); }
.an-area.an-ghost { opacity: .16; }
.an-line.an-ghost { stroke-width: 1.5; stroke-dasharray: none; animation: none; opacity: .7; }
.an-key--ghost::before { opacity: .45; }
.an-ser { transition: opacity var(--dur-quick) var(--ease-out); }
/* Мишень вдоль линии: невидима, но ловит курсор полосой в 14px — по тонкой
   линии в 2,5px мышью не попасть, а пальцем тем более. */
.an-line-hit { fill: none; stroke: transparent; stroke-width: 14; pointer-events: stroke; cursor: pointer; }
.an-chart--rich .an-hit { cursor: pointer; }
.an-chart--rich .an-ser .an-line { transition: stroke-width var(--dur-quick) var(--ease-out); }
.an-chart[data-focus] .an-ser:not(.is-hot),
.an-chart[data-focus] .an-bar:not(.is-hot) { opacity: .18; }
.an-chart[data-focus] .an-ser.is-hot .an-line { stroke-width: 4; }
.an-chart--rich .an-bar.is-hot { opacity: 1; }
.an-chart--rich .an-bar:hover { opacity: 1; }

.an-plot { position: relative; }
.an-tip {
  position: absolute; z-index: 5; pointer-events: none;
  max-width: 280px; padding: 8px 10px; border-radius: 8px;
  background: var(--surface); box-shadow: var(--shadow-2); border: 1px solid var(--line);
  font-size: 12px; line-height: 1.45; color: var(--ink-soft); font-variant-numeric: tabular-nums;
}
.an-tip[hidden] { display: none; }
.an-tip__h { font-weight: 600; color: var(--ink); overflow-wrap: anywhere; }
.an-tip__l { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.an-key[data-ser] { cursor: pointer; padding: 2px 4px; margin: -2px -4px; border-radius: 4px; }
.an-key[data-ser].is-hot { background: rgba(var(--ink-rgb), .06); color: var(--ink); }
.an-key__v { color: var(--ink-muted); }

/* Переключатели ряда и бенчмарков над графиком выручки. */
.an-money__ctl { display: flex; flex-wrap: wrap; align-items: flex-end; gap: 10px 16px; margin: 4px 0 8px; }
.an-money__chips { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 6px; }
.an-chip--ser { display: inline-flex; align-items: center; gap: 6px; }
.an-chip--ser::before { content: ''; width: 8px; height: 8px; border-radius: 2px; background: var(--an-c, var(--past)); }
.an-pick__item.is-full { opacity: .5; }
.an-table__total td { font-weight: 600; color: var(--ink); }
.an-table__sub td:first-child { padding-left: 22px; color: var(--ink-soft); }
@media (max-width: 640px) {
  .an-money__ctl { flex-direction: column; align-items: stretch; }
  .an-tip { max-width: 220px; }
}

/* Таблица: липкая шапка, чётные строки чуть темнее, строка под курсором
   подсвечена. Сортируемый столбец помечен стрелкой и фирменным цветом. */
.an-table-wrap {
  overflow-x: auto; background: var(--surface);
  border: 1px solid var(--line); border-radius: var(--radius);
}
.an-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: 13px; }
.an-table th {
  position: sticky; top: 0; z-index: 1; text-align: right; padding: 9px 12px;
  font-size: 11px; font-weight: 700; text-transform: uppercase; letter-spacing: .05em;
  color: var(--ink-muted); background: var(--bg-sunken);
  border-bottom: 1px solid var(--line); white-space: nowrap;
}
.an-table td {
  text-align: right; padding: 9px 12px; color: var(--ink);
  border-bottom: 1px solid var(--line); white-space: nowrap;
  font-variant-numeric: tabular-nums;
  transition: background-color var(--dur-quick) var(--ease-out);
}
.an-table tbody tr:last-child td { border-bottom: 0; }
.an-table tbody tr:nth-child(even) td { background: rgba(var(--ink-rgb), .02); }
.an-table tbody tr:hover td { background: rgba(var(--brand-rgb), .06); }
.an-table th[data-an-sort] {
  cursor: pointer; user-select: none;
  transition: color var(--dur-quick) var(--ease-out), background-color var(--dur-quick) var(--ease-out);
}
.an-table th[data-an-sort]:hover { color: var(--ink); background: rgba(var(--ink-rgb), .05); }
.an-table th[data-an-sort]::after {
  content: '↕'; display: inline-block; margin-left: 5px; font-size: 11px; opacity: .45;
  transition: opacity var(--dur-quick) var(--ease-out);
}
.an-table th.is-sorted { color: var(--brand); }
.an-table th.is-sorted::after { opacity: 1; }
.an-table th.is-asc::after { content: '↑'; }
.an-table th.is-desc::after { content: '↓'; }
/* Первый столбец — имя: левый и переносится. Селектор с td нужен, иначе
   правило `.an-table td` выше по специфичности и прижимает имена вправо. */
.an-table th:first-child,
.an-table td.an-table__name { text-align: left; white-space: normal; font-weight: 500; min-width: 180px; }
/* «Не указан» и месяц без расхода — не строки ряда, а пустое поле: приглушены. */
.an-table__row--unknown td { color: var(--ink-muted); font-style: italic; }
/* Прошедший запуск в таблице плана: приглушён, но не курсивом — он известен, просто позади. */
.an-table__row--past td { color: var(--ink-muted); }
.an-cover { margin-top: 10px; font-size: 12px; color: var(--ink-muted); }

/* Пустой экран, оговорки и предупреждение сервера. */
.an-empty {
  padding: 28px 16px; text-align: center; font-size: 13px; line-height: 1.5;
  color: var(--ink-muted); background: var(--bg-sunken);
  border: 1px dashed var(--line-strong); border-radius: var(--radius);
}
.an-sec .an-empty { padding: 18px 12px; }
.an-empty--error {
  color: var(--danger-ink); background: rgba(var(--danger-rgb), .06);
  border-color: var(--danger); border-style: solid;
}
.an-notes {
  margin: 12px 0 0; padding: 10px 14px 10px 30px; list-style: disc;
  font-size: 12.5px; line-height: 1.55; color: var(--ink-muted);
  background: var(--bg-sunken); border-left: 3px solid var(--line-strong);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.an-notes li + li { margin-top: 5px; }
.an-panel > .an-notes { margin-top: 0; margin-bottom: 16px; }
.an-note {
  margin: 0 0 14px; padding: 10px 14px; font-size: 13px; line-height: 1.5;
  color: var(--ink-soft); background: var(--bg-sunken);
  border-left: 3px solid var(--line-strong); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
/* Предупреждение сервера («названия каналов показаны кодами») — оговоркой
   жёлтого тона, а не алой плашкой: числа от этого верными быть не перестали. */
.an-warn { color: var(--warn-ink); background: rgba(var(--warn-rgb), .08); border-left-color: var(--warn); }

/* ─── Раздел «План продаж по запускам» ─────────────────────────────────────
   Органы управления разделом — тем же языком, что шапка вкладки (.an-ctl и
   .an-seg), плюс список выбора семинаров и чипсы. Цвета — только токенами. */
.an-plan__ctl {
  display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px;
  margin: 2px 0 10px;
}
.an-plan__chips { display: flex; flex-wrap: wrap; gap: 6px; margin: -4px 0 10px; }
.an-chip {
  display: inline-flex; align-items: center; gap: 6px;
  border: 1px solid var(--line-strong); padding: 5px 11px; border-radius: 999px;
  background: var(--surface); color: var(--ink-soft); cursor: pointer;
  font-family: inherit; font-size: 12.5px; font-weight: 600; white-space: nowrap;
  transition: background-color var(--dur-quick) var(--ease-out),
              color var(--dur-quick) var(--ease-out),
              border-color var(--dur-quick) var(--ease-out),
              transform var(--dur-quick) var(--ease-out);
}
.an-chip:hover { color: var(--ink); border-color: var(--ink-muted); }
.an-chip:active { transform: scale(.97); }
.an-chip.is-on {
  background: var(--brand-soft); color: var(--brand); border-color: var(--brand-line);
}

/* Выбор семинаров: кнопка-сводка, под ней панель со списком. Список — весь
   справочник поля «Выбор направления»; программы без запусков приглушены,
   но остаются, их тоже можно выбрать. */
.an-pick { position: relative; }
.an-pick__btn {
  display: inline-flex; align-items: center; gap: 8px;
  border: 1px solid var(--line-strong); padding: 7px 34px 7px 12px; border-radius: var(--radius);
  background: var(--surface); color: var(--ink); cursor: pointer;
  font-family: inherit; font-size: 13px; font-weight: 600; max-width: 100%;
  position: relative; text-align: left;
  transition: border-color var(--dur-quick) var(--ease-out), box-shadow var(--dur-quick) var(--ease-out);
}
.an-pick__btn::after {
  content: ''; position: absolute; right: 13px; top: 50%; width: 7px; height: 7px;
  border-right: 2px solid var(--ink-muted); border-bottom: 2px solid var(--ink-muted);
  transform: translateY(-70%) rotate(45deg);
  transition: transform var(--dur-quick) var(--ease-out);
}
.an-pick__btn:hover { border-color: var(--ink-muted); }
.an-pick.is-open .an-pick__btn { border-color: var(--brand); box-shadow: 0 0 0 3px var(--brand-soft); }
.an-pick.is-open .an-pick__btn::after { transform: translateY(-20%) rotate(225deg); }
.an-pick__panel {
  position: absolute; z-index: 20; left: 0; top: calc(100% + 6px);
  width: min(520px, 92vw); padding: 12px;
  background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-lg); box-shadow: var(--shadow-3);
  animation: stats-fade var(--dur-quick) var(--ease-out) both;
}
.an-pick__q {
  display: block; width: 100%; box-sizing: border-box;
  border: 1px solid var(--line-strong); border-radius: var(--radius);
  padding: 8px 12px; font-family: inherit; font-size: 13px; color: var(--ink);
  background: var(--bg-sunken);
  transition: border-color var(--dur-quick) var(--ease-out), background-color var(--dur-quick) var(--ease-out);
}
.an-pick__q:focus { border-color: var(--brand); background: var(--surface); }
.an-pick__tools { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0; }
.an-pick__list {
  max-height: 320px; overflow: auto; margin: 0 -4px; padding: 0 4px;
  border-top: 1px solid var(--line); border-bottom: 1px solid var(--line);
}
.an-pick__item {
  display: grid; grid-template-columns: auto 1fr; grid-template-rows: auto auto;
  column-gap: 10px; align-items: center; padding: 8px 6px; cursor: pointer;
  border-radius: var(--radius-sm);
  transition: background-color var(--dur-quick) var(--ease-out);
}
.an-pick__item:hover { background: var(--bg-sunken); }
.an-pick__item.is-on { background: var(--brand-soft); }
.an-pick__item input { grid-row: 1 / span 2; margin: 0; accent-color: var(--brand); }
.an-pick__name { font-size: 13px; font-weight: 600; color: var(--ink); }
.an-pick__meta { font-size: 11.5px; color: var(--ink-muted); }
.an-pick__item.is-idle .an-pick__name { color: var(--ink-muted); font-weight: 500; }
.an-pick__none { padding: 18px 8px; text-align: center; font-size: 13px; color: var(--ink-muted); }
.an-pick__foot { margin-top: 10px; font-size: 11.5px; line-height: 1.45; color: var(--ink-muted); }

/* Подпись под органами управления: что именно нарисовано, по частям —
   «Семинары», «Срок», «Разрез»… Это ответ на вопрос «график какого семинара»,
   и она стоит до графика, а не в оговорках после. */
.an-caption {
  display: flex; flex-wrap: wrap; gap: 6px 22px; margin: 0 0 14px; padding: 9px 14px;
  color: var(--ink-soft); background: var(--bg-sunken);
  border-left: 3px solid var(--brand-line); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.an-caption__i { display: flex; flex-direction: column; gap: 1px; margin: 0; min-width: 0; }
.an-caption__k {
  font-size: 10.5px; font-weight: 700; text-transform: uppercase; letter-spacing: .06em;
  color: var(--ink-muted);
}
.an-caption__v { margin: 0; font-size: 13px; line-height: 1.4; color: var(--ink); font-variant-numeric: tabular-nums; }

/* Опорные линии графика: цель (100 %) — фирменным цветом, среднее — серым;
   обе пунктиром, чтобы не спутать с рядом. */
.an-mark { stroke: var(--ink-muted); stroke-width: 1.5; stroke-dasharray: 5 4; }
.an-mark--goal { stroke: var(--brand); }
.an-mark--avg { stroke: var(--ink-muted); }
.an-mark__t { fill: var(--ink-soft); font-size: 11px; font-weight: 600; }
.an-key--goal { --an-c: var(--brand); }
.an-key--goal::before { background: transparent; border-top: 2px dashed var(--an-c); height: 0; border-radius: 0; }
.an-key--avg { --an-c: var(--ink-muted); }
.an-key--avg::before { background: transparent; border-top: 2px dashed var(--an-c); height: 0; border-radius: 0; }
.an-bar--miss { --an-c: var(--warn); }
.an-key--miss { --an-c: var(--warn); }

/* Горизонтальные полосы: строка на запуск или семинар, подпись слева, число
   справа. Полоса растёт слева, а не снизу. */
.an-chart--hbars { --an-band: .04; }
.an-bar--h { transform-origin: left center; animation-name: an-hbar-in; }
.an-hbar__label { fill: var(--ink); font-size: 12.5px; font-weight: 600; }
.an-hbar__sub { fill: var(--ink-muted); font-size: 11px; font-variant-numeric: tabular-nums; }
.an-hbar__val { fill: var(--ink-soft); font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums; }
.an-hbar__label.is-past, .an-hbar__val.is-past { fill: var(--ink-muted); font-weight: 500; }
.an-hbar__label.is-bare, .an-hbar__sub.is-bare, .an-hbar__val.is-bare { fill: var(--ink-muted); font-style: italic; }
/* Запуск без плана в таблице: оплаты есть, плана нет — курсивом, как «не введено». */
.an-table__row--bare td { color: var(--ink-muted); font-style: italic; }

@media (max-width: 720px) {
  .an-toolbar { padding: 12px 12px 10px; gap: 10px 12px; }
  .an-toolbar__side { margin-left: 0; width: 100%; justify-content: space-between; }
  /* Подпись органа управления — над кнопками, кнопки переносятся: в строку
     «Показатель» с тремя кнопками на телефоне не влезает. */
  .an-ctl { flex-direction: column; align-items: flex-start; gap: 5px; width: 100%; }
  .an-seg { display: flex; }
  .an-seg__btn { flex: 1 1 auto; padding: 7px 10px; font-size: 12.5px; white-space: normal; }
  .an-plan__ctl { gap: 10px 12px; }
  .an-plan__ctl > .an-pick { width: 100%; }
  .an-pick__btn { width: 100%; box-sizing: border-box; }
  .an-pick__panel { position: static; width: 100%; box-sizing: border-box; margin-top: 8px; }
  .an-caption { gap: 8px 16px; padding: 10px 12px; }
  .an-caption__i { flex: 1 1 40%; }
  .an-tab { flex: 1 1 44%; padding: 8px 10px; font-size: 13px; }
  .an-sec { padding: 12px 12px 14px; }
  /* Карточки чисел — по две в ряд: столбик из шести карточек на всю ширину
     оставлял половину экрана пустой. */
  .an-kpis { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
  .an-kpi { padding: 10px 12px 10px 14px; }
  .an-kpi__value { font-size: 20px; }
  .an-kpi__label, .an-kpi__sub { font-size: 11.5px; }
}

/* ─── Расчёт ЗП сотрудников ─────────────────────────────────────────────────

   Ведомость широкая (17 колонок), поэтому прокручивается по горизонтали
   внутри своей рамки, а не всей страницей. Клетки ввода отличаются от
   расчётных фоном и рамкой: человек должен с одного взгляда видеть, что он
   может поправить, а что посчитано. Цвет уровня KPI — фоном клетки, текст
   остаётся чернилами: цвет не единственный носитель смысла, число рядом. */
.pr { display: flex; flex-direction: column; gap: 14px; }
/* Один ритм на все три подвкладки: блоки идут колонкой с общим промежутком,
   своих внешних отступов у них нет — иначе рамка вкладок, карточки и подсказки
   стояли бы кто на 16px, кто на 0. Длинная подсказка не тянется на всю
   ширину экрана: строка в 1100px ещё читается, в 1900 — уже нет. */
.pr .an-tabs { margin-bottom: 0; }
.pr-body { display: flex; flex-direction: column; gap: 14px; }
.pr-body > .an-sec, .pr-body > .set-hint, .pr-body > p, .pr-body > .an-note, .pr-body > .an-warn { margin: 0; }
.pr-body > .set-hint, .pr-crm__hint, .pr-staff-note { line-height: 1.45; max-width: 1100px; }
.pr-head { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 18px; }
.pr-title { margin: 0; font-size: 20px; font-weight: 700; color: var(--ink); }
.pr-period { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; }
.pr-select { width: auto; min-width: 0; padding: 6px 8px; font-size: 13px; }
.pr-link {
  padding: 0; border: 0; background: none; font: inherit; color: var(--brand);
  text-decoration: underline; cursor: pointer;
}
.pr-link.is-active { color: var(--ink); font-weight: 700; text-decoration: none; }
.pr-saveline { margin-left: auto; font-size: 13px; }
.pr-save { color: var(--ink-muted); }
.pr-save--ok { color: var(--ok-ink); }
.pr-save--bad { color: var(--danger-ink); }
.pr-toolbar, .pr-actions, .pr-crm, .pr-legend { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px; }
.pr-toolbar .pr-in, .pr-actions .pr-in { height: 32px; box-sizing: border-box; }
/* Блок «Чистота CRM»: кнопка, под ней пояснение, под ним итог чтения. */
.pr-crm { flex-direction: column; align-items: flex-start; gap: 8px; }
.pr-crm__hint, .pr-crm__note { margin: 0; }
.pr-crm__note { align-self: stretch; }
.pr-legend { gap: 6px 10px; }
/* Карточки сводки: подпись прижата к низу, чтобы в ряду карточек подписи
   стояли на одной линии и при переносе числа. */
.pr-cards { margin: 0; }
.pr-cards .an-kpi { display: flex; flex-direction: column; }
.pr-cards .an-kpi__sub { margin-top: auto; padding-top: 6px; }
.pr-chip {
  display: inline-block; padding: 2px 8px; border-radius: var(--radius-sm); font-size: 12px;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink-soft);
}
.pr-chip--in { background: rgba(var(--teal-rgb), .08); border-color: var(--teal); }

/* Ведомость. Шапка в два яруса: группы — капителью по центру, колонки под
   ними — обычным начертанием, иначе 25 заголовков капителью сливаются в
   одну полосу. Линия между группами (.pr-gend) идёт сверху донизу. Клетка
   ввода всегда несёт строку источника, пусть и пустую: так у всех строк
   одна высота и поля стоят на одной линии. */
.pr-table th, .pr-table td { padding: 6px 8px; vertical-align: middle; }
.pr-table .pr-thead-group th {
  text-align: center; padding: 8px 8px 4px; border-bottom: 0; border-right: 1px solid var(--line);
  color: var(--ink-soft);
}
.pr-table .pr-thead-group th:last-child { border-right: 0; }
.pr-table .pr-thead-cols th {
  padding: 2px 8px 7px; text-transform: none; letter-spacing: 0; font-size: 11.5px; font-weight: 600;
  color: var(--ink-muted); line-height: 1.25;
}
.pr-table .pr-thead-cols th:nth-child(2) { text-align: left; }
.pr-table th.pr-gend, .pr-table td.pr-gend { border-right: 1px solid var(--line); }
.pr-col--fio { width: 200px; }
.pr-col--sch { width: 150px; }
.pr-table .pr-name { text-align: left; min-width: 160px; }
.pr-table .pr-scheme { text-align: left; color: var(--ink-muted); font-size: 12px; }
.pr-table .pr-in { height: 28px; box-sizing: border-box; }
.pr-src { display: block; min-height: 14px; margin-top: 2px; font-size: 11px; line-height: 14px; color: var(--ink-muted); white-space: nowrap; }
.pr-miss { font-size: 11px; color: var(--ink-muted); white-space: normal; }
.pr-out { color: var(--ink-soft); }
.pr-out--team { font-style: italic; }
.pr-table .pr-total { font-weight: 700; color: var(--ink); cursor: help; }
.pr-table .pr-totals td { font-weight: 700; background: var(--bg-sunken); }
.pr-sep td { text-align: left; font-size: 12px; color: var(--ink-muted); background: var(--bg-sunken); }
.pr-table td.pr-lvl--0 { background: rgba(var(--danger-rgb), .10); }
.pr-table td.pr-lvl--1 { background: rgba(var(--warn-rgb), .14); }
.pr-table td.pr-lvl--2 { background: rgba(var(--ok-rgb), .14); }
.pr-chip.pr-lvl--0 { background: rgba(var(--danger-rgb), .10); }
.pr-chip.pr-lvl--1 { background: rgba(var(--warn-rgb), .14); }
.pr-chip.pr-lvl--2 { background: rgba(var(--ok-rgb), .14); }

.pr-in {
  width: 72px; padding: 4px 6px; text-align: right; font: inherit; font-variant-numeric: tabular-nums;
  color: var(--ink); background: rgba(var(--teal-rgb), .06);
  border: 1px solid var(--line-strong); border-radius: var(--radius-sm);
}
.pr-in--wide { width: 104px; }
.pr-in:focus { border-color: var(--teal); }
.pr-in--bad { border-color: var(--danger); background: rgba(var(--danger-rgb), .08); }
.pr-paste { width: 100%; box-sizing: border-box; font-family: inherit; }
.pr-file { cursor: pointer; }
.pr-imp--bad td { color: var(--danger-ink); }
.pr-confirm { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ink); }

/* «Настройки»: карточка схемы. Поля сетки одной высоты и одной ширины, чтобы
   их края в ряду совпадали; вычисленное число (KPI-фонд, ставка) стоит в
   строке той же высоты, что и поле рядом. Заголовки разделов — мелкие и
   жирные, в один тон с метками карточек. */
.pr-scheme-card { display: flex; flex-direction: column; gap: 12px; }
.pr-scheme-head { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 12px; }
.pr-scheme-name { min-width: 260px; height: 36px; box-sizing: border-box; font-weight: 700; }
.pr-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(200px, 1fr)); gap: 12px 16px; align-items: start; }
.pr-f { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--ink); }
.pr-f__l { font-size: 12px; line-height: 1.3; color: var(--ink-muted); }
.pr-f .pr-in, .pr-f .pr-select { display: block; width: 100%; max-width: 220px; height: 32px; box-sizing: border-box; }
.pr-f .pr-in { text-align: left; }
.pr-f > b { display: block; height: 32px; line-height: 32px; font-size: 14px; font-variant-numeric: tabular-nums; }
.pr-f .set-hint { line-height: 1.3; }
.pr-f--check { flex-direction: row; align-items: center; gap: 6px; min-height: 32px; }
.pr-scheme-card .set-h3 { margin: 6px 0 0; font-size: 13px; font-weight: 700; color: var(--ink); }
.pr-scheme-card .an-table-wrap { margin: 0; }
.pr-bonus th, .pr-bonus td { padding: 6px 8px; vertical-align: middle; }
.pr-bonus td:first-child { text-align: left; }
.pr-bonus .pr-in, .pr-bonus .pr-select { height: 30px; box-sizing: border-box; }
.pr-err { color: var(--danger-ink); }
.pr-questions { margin: 0; padding-left: 20px; font-size: 13px; color: var(--ink); }
/* «Сотрудники»: колонки постоянной ширины, шапка выровнена так же, как
   клетки под ней. Клетка с подсказкой выше соседних, поэтому всё прижато к
   верху — поля одной строки стоят на одной линии. Поля занимают колонку
   целиком: края списков в столбце совпадают. */
.pr-staff { table-layout: fixed; }
.pr-col--name { width: 280px; }
.pr-col--pos { width: 262px; }
.pr-col--pay { width: 196px; }
.pr-col--scheme { width: 270px; }
.pr-col--num { width: 104px; }
.pr-col--mid { width: 88px; }
.pr-col--lead { width: 220px; }
.pr-col--del { width: 56px; }
.pr-staff th, .pr-staff td { padding: 10px 10px; vertical-align: top; text-align: left; }
.pr-staff td { white-space: normal; }
.pr-staff .pr-c--num { text-align: right; }
.pr-staff .pr-c--mid, .pr-staff .pr-c--del { text-align: center; }
.pr-staff th.pr-c { line-height: 1.3; white-space: normal; }
.pr-staff .pr-select, .pr-staff .pr-name-in { display: block; width: 100%; box-sizing: border-box; height: 32px; }
.pr-staff .pr-name-in { margin-top: 6px; font-size: 13px; }
.pr-staff .pr-name-in:first-child { margin-top: 0; }
.pr-staff .pr-in--wide { width: 100%; box-sizing: border-box; height: 32px; }
.pr-staff .pr-in { height: 32px; box-sizing: border-box; }
.pr-staff td > .set-hint { display: inline-block; padding-top: 7px; }
.pr-staff .pr-who-hint { margin-top: 4px; line-height: 1.35; }
.pr-staff input[type="checkbox"] { margin: 8px 0 0; }
.pr-name-in { width: 220px; padding: 6px 8px; }
.pr-order { display: inline-flex; gap: 4px; }
.pr-print-title { display: none; }

/* Зарплатный фонд: решение ГД, сводка, подпись месяца. */
.pr-lock { border: 0; margin: 0; padding: 0; min-width: 0; }
.pr-locked { margin-bottom: 12px; }
.pr-fund-inputs { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 12px 16px; align-items: start; }
.pr-fund-note { margin-top: 12px; }
.pr-fund-note textarea { width: 100%; max-width: 720px; box-sizing: border-box; resize: vertical; }
.pr-fund-bad .an-kpi__value { color: var(--danger-ink); }
.pr-fund-bad { box-shadow: inset 3px 0 0 var(--danger); }
.pr-fund-warn { display: flex; flex-direction: column; gap: 8px; margin: 12px 0; }
.pr-fund-table th, .pr-fund-table td { padding: 8px 10px; }
.pr-fund-table .pr-c--num { text-align: right; font-variant-numeric: tabular-nums; white-space: nowrap; }
.pr-fund-status { margin: 0 0 8px; font-weight: 600; }
.pr-fund-approve .pr-actions { align-items: flex-end; }
.pr-pin { max-width: 120px; letter-spacing: .2em; }

/* Печать и PDF: только ведомость, без органов управления. Класс на body
   ставится лишь на время window.print() из вкладки, поэтому печать других
   вкладок остаётся прежней. */
@media print {
  body.pr-printing * { visibility: hidden; }
  body.pr-printing #tab-payroll, body.pr-printing #tab-payroll * { visibility: visible; }
  body.pr-printing #tab-payroll { position: absolute; left: 0; top: 0; width: 100%; }
  body.pr-printing .pr-noprint, body.pr-printing .pr-head { display: none; }
  body.pr-printing .pr-print-title { display: block; margin-bottom: 10px; font-size: 16px; font-weight: 700; }
  body.pr-printing .an-table-wrap { overflow: visible; border: 0; }
  body.pr-printing .pr-in { border: 0; background: none; padding: 0; width: auto; }
  body.pr-printing .pr-table { font-size: 10px; }
}

/* ── Окно «Сменить ответственного» (js/reassign.js) ─────────────────────────
   Строится на классах окна «Обновить даты» (.fix-*): примечание, итог и
   предупреждения выглядят одинаково. Своё здесь — фишки «кто сейчас отвечает»,
   список с колонками, блок «Передаём → кому» и экран хода передачи, устроенный
   как у массового создания событий (.bulkp-*): этапы, полоса, строки с кружком. */
.modal--reassign { max-width: 780px; width: 94%; }

/* Фишки: имя и число заявок. Включённая — зелёная: отмечены все её заявки. */
.ra-who { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; margin-bottom: 12px; }
.ra-who__label { font-size: 12px; color: var(--text-muted); margin-right: 4px; }
.ra-chip {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 10px 5px 12px; border-radius: 999px;
  border: 1px solid var(--b24-border); background: var(--surface); color: var(--b24-text);
  font-size: 13px; cursor: pointer;
  transition: border-color var(--dur-base) var(--ease-out), background-color var(--dur-base) var(--ease-out),
              color var(--dur-base) var(--ease-out);
}
.ra-chip:hover { border-color: var(--b24-primary); }
.ra-chip__n {
  padding: 1px 7px; border-radius: 999px;
  background: var(--b24-bg); color: var(--text-muted); font-size: 11px; font-variant-numeric: tabular-nums;
}
.ra-chip--on { border-color: var(--b24-primary); background: var(--b24-primary-soft); }
.ra-chip--on .ra-chip__n { background: var(--b24-primary); color: var(--b24-white); }

.ra-tools { display: flex; flex-wrap: wrap; align-items: center; gap: 10px; margin-bottom: 8px; }
.ra-all { display: flex; align-items: center; gap: 6px; font-size: 13px; cursor: pointer; white-space: nowrap; }
.ra-search {
  flex: 1 1 180px; min-width: 0;
  padding: 7px 10px; border: 1px solid var(--b24-border); border-radius: 8px;
  font-size: 13px; background: var(--surface); color: var(--b24-text);
}
.ra-search:focus { border-color: var(--teal); }
.ra-count { font-size: 13px; color: var(--text-muted); white-space: nowrap; font-variant-numeric: tabular-nums; }

/* Список — сетка: галочка, клиент, тип, ответственный, дела, чат. Шапка и
   строки делят один шаблон колонок, чтобы заголовки стояли ровно над числами. */
.ra-head, .ra-row__label {
  display: grid;
  grid-template-columns: 22px minmax(0, 1fr) 60px 128px 56px 18px;
  align-items: center; gap: 8px;
}
.ra-head {
  padding: 4px 8px 6px; font-size: 11px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-muted); border-bottom: 1px solid var(--b24-border);
}
.ra-head__r { text-align: right; }
.ra-list {
  list-style: none; margin: 0 0 14px; padding: 0; max-height: 300px; overflow-y: auto;
  border: 1px solid var(--b24-border); border-top: 0; border-radius: 0 0 var(--radius) var(--radius);
}
.ra-row + .ra-row { box-shadow: inset 0 1px 0 var(--b24-border); }
.ra-row__label {
  padding: 7px 8px; cursor: pointer; font-size: 14px;
  transition: background-color var(--dur-base) var(--ease-out);
}
.ra-row__label:hover { background: var(--b24-bg); }
.ra-row--on .ra-row__label { background: rgba(var(--brand-rgb), .07); }
.ra-row--same { opacity: .45; }
.ra-row--same .ra-row__label { cursor: default; }
.ra-box { margin: 0; accent-color: var(--b24-primary); }
.ra-row__name { min-width: 0; overflow-wrap: anywhere; color: var(--b24-text); }
.ra-type, .ra-tag {
  display: inline-block; padding: 1px 7px; border-radius: 999px;
  font-size: 11px; line-height: 16px; white-space: nowrap;
  background: var(--b24-bg); color: var(--text-muted);
}
.ra-type--lead { background: rgba(var(--brand-rgb), .10); color: var(--b24-primary); }
.ra-tag { background: rgba(var(--warn-rgb), .12); color: var(--warn-ink); vertical-align: 1px; }
.ra-row__resp { font-size: 13px; color: var(--b24-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ra-row__acts { font-size: 12px; color: var(--text-muted); text-align: right; white-space: nowrap; font-variant-numeric: tabular-nums; }
.ra-row__chat { color: var(--warn-ink); line-height: 0; }
.ra-empty { padding: 12px 8px; font-size: 14px; color: var(--text-muted); }

/* «Передаём N → кому»: одна плашка, стрелка посередине. */
.ra-target {
  display: grid; grid-template-columns: minmax(0, 1fr) auto minmax(0, 1fr); align-items: center; gap: 12px;
  padding: 12px 14px; margin-bottom: 12px;
  border-radius: var(--radius); background: var(--b24-bg); border: 1px solid var(--b24-border);
}
.ra-target__from { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.ra-target__label { font-size: 11px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); }
.ra-target__n { font-size: 15px; color: var(--b24-text); font-variant-numeric: tabular-nums; }
.ra-target__sub { font-size: 12px; color: var(--text-muted); overflow-wrap: anywhere; }
.ra-target__arrow { font-size: 22px; color: var(--b24-primary); line-height: 1; }
.ra-target__to { display: flex; flex-direction: column; gap: 4px; min-width: 0; }
/* min-width: 0 — иначе список растянется под самое длинное имя (см. .fix-field). */
.ra-select {
  width: 100%; max-width: 100%; min-width: 0;
  padding: 8px 10px; border: 1px solid var(--b24-border); border-radius: 8px;
  font-size: 14px; background: var(--surface); color: var(--b24-text); text-overflow: ellipsis;
}
.ra-select:focus { border-color: var(--teal); }
@media (max-width: 560px) {
  .ra-target { grid-template-columns: 1fr; }
  .ra-target__arrow { transform: rotate(90deg); justify-self: center; }
  .ra-head, .ra-row__label { grid-template-columns: 22px minmax(0, 1fr) 56px 90px; }
  .ra-head__r, .ra-head span:last-child, .ra-row__acts, .ra-row__chat { display: none; }
}

.ra-actions { align-items: center; }
.ra-actions__hint { font-size: 12px; color: var(--text-muted); margin-left: auto; }
.ra-confirm {
  width: 100%; padding: 12px 14px; border-radius: var(--radius);
  background: rgba(var(--warn-rgb), .10); border: 1px solid rgba(var(--warn-rgb), .35);
  font-size: 14px; line-height: 1.5; color: var(--b24-text);
}
.ra-confirm__title { font-weight: 600; margin-bottom: 6px; }
.ra-confirm p { margin: 0 0 6px; }
.ra-confirm .fix-actions { margin-top: 10px; }

/* ── Ход передачи ── */
.ra-prog__head { display: flex; align-items: baseline; justify-content: space-between; gap: 12px; flex-wrap: wrap; }
.ra-prog__phase { font-size: 15px; font-weight: 600; color: var(--b24-text); }
.ra-prog__meta { display: flex; align-items: baseline; gap: 12px; font-size: 12px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.ra-prog__to b { color: var(--b24-text); font-weight: 600; }

/* Этапы — цепочка подписей: пройденные зелёные, текущий пульсирует (motion.css). */
.ra-steps { display: flex; flex-wrap: wrap; gap: 6px; margin: 10px 0 8px; }
.ra-step {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 3px 10px 3px 8px; border-radius: 999px; font-size: 12px;
  background: var(--b24-bg); color: var(--text-muted);
  transition: background-color var(--dur-base) var(--ease-out), color var(--dur-base) var(--ease-out);
}
.ra-step::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%; background: var(--b24-border);
  transition: background-color var(--dur-base) var(--ease-out);
}
.ra-step[data-st="run"]  { background: var(--b24-primary-soft); color: var(--b24-primary); }
.ra-step[data-st="run"]::before  { background: var(--b24-primary); }
.ra-step[data-st="done"] { color: var(--b24-success); }
.ra-step[data-st="done"]::before { background: var(--b24-success); }
.ra-step[data-st="fail"] { background: rgba(var(--danger-rgb), .10); color: var(--b24-danger); }
.ra-step[data-st="fail"]::before { background: var(--b24-danger); }

/* Полоса общего хода: заливка через transform, раскладку не трогает. */
.ra-bar { position: relative; height: 4px; border-radius: 2px; background: var(--b24-border); overflow: hidden; margin-bottom: 10px; }
.ra-bar__fill {
  position: absolute; inset: 0; border-radius: inherit; background: var(--accent-grad, var(--b24-primary));
  transform: scaleX(0); transform-origin: left center;
  transition: transform var(--dur-slow) var(--ease-out);
}

/* Строки хода: кружок состояния, клиент и номер, подпись справа. Знак в кружке
   рисует ::before — по одному правилу на состояние, скрипт меняет один атрибут. */
.ra-prows { max-height: 300px; overflow-y: auto; border-radius: var(--radius); border: 1px solid var(--b24-border); }
.ra-prow {
  display: flex; align-items: center; gap: 10px; padding: 8px 10px;
  transition: background-color var(--dur-base) var(--ease-out);
}
.ra-prow + .ra-prow { box-shadow: inset 0 1px 0 var(--b24-border); }
.ra-prow[data-state="run"] { background: rgba(var(--brand-rgb), .05); }
.ra-prow__ic {
  flex: 0 0 20px; width: 20px; height: 20px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--b24-border); color: var(--b24-white); font-size: 12px; line-height: 1;
  transition: background-color var(--dur-base) var(--ease-out);
}
.ra-prow[data-state="run"]  .ra-prow__ic { background: var(--b24-primary); }
.ra-prow[data-state="ok"]   .ra-prow__ic { background: var(--b24-success); }
.ra-prow[data-state="ok"]   .ra-prow__ic::before { content: "\2713"; }
.ra-prow[data-state="fail"] .ra-prow__ic { background: var(--b24-danger); }
.ra-prow[data-state="fail"] .ra-prow__ic::before { content: "\2715"; }
.ra-prow[data-state="skip"] .ra-prow__ic::before { content: "\2013"; color: var(--text-muted); }
.ra-prow__body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }
.ra-prow__name { font-size: 13px; color: var(--b24-text); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ra-prow__sub { font-size: 11px; color: var(--text-muted); font-variant-numeric: tabular-nums; }
.ra-prow__st { flex: 0 0 auto; max-width: 46%; font-size: 12px; color: var(--text-muted); text-align: right; overflow-wrap: anywhere; }
.ra-prow[data-state="ok"]   .ra-prow__st { color: var(--b24-success); }
.ra-prow[data-state="fail"] .ra-prow__st { color: var(--b24-danger); }
.ra-prog__hint { font-size: 12px; line-height: 1.5; color: var(--text-muted); margin: 10px 0 12px; }

/* Итог: три карточки с числами и единицей под каждым. */
.ra-sum { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 10px; margin-bottom: 12px; }
.ra-sum__card {
  display: flex; flex-direction: column; gap: 2px; padding: 12px 14px;
  border-radius: var(--radius); background: var(--b24-bg); border: 1px solid var(--b24-border);
}
.ra-sum__card b { font-size: 24px; line-height: 1.1; color: var(--b24-text); font-variant-numeric: tabular-nums; }
.ra-sum__card span { font-size: 12px; color: var(--text-muted); }
.ra-sum__card--ok { background: var(--b24-primary-soft); border-color: var(--brand-line); }
.ra-sum__card--ok b { color: var(--b24-primary); }
.ra-bad__title { font-size: 12px; text-transform: uppercase; letter-spacing: .04em; color: var(--text-muted); margin: 4px 0 4px; }
