/* Панель Buying Support (форк DWH Messaging) — тёмная тема в тонах ночного Telegram: сине-серые поверхности, фиолетовый акцент.
   Правила системы:
   - цвета только из переменных ниже; акцент один (фиолетовый), красный — только для разрушающих
     действий и ошибок, зелёный и жёлтый — только для статусов;
   - контраст: основной текст ≥ 12:1, вторичный ≥ 6:1, белый на фиолетовой кнопке ≈ 6,5:1;
   - шаг отступов 4/8, поля и кнопки 36 px (маленькие 30), скругления 8 / 12 / 16;
   - один шрифт (Inter), размеры 12 / 13 / 14 / 16 / 20, без капса.
   Ширина окна — одни точки перехода на всю панель (масштаб браузера — та же ширина в CSS px):
   ≤640 телефон, ≤900 планшет вертикально (инбокс — список или чат), ≤1180 ноутбук и планшет
   горизонтально (карточка клиента поверх чата); по высоте — (max-height: 700px). Сенсорный экран —
   по устройству ввода, а не по ширине: (pointer: coarse) и (hover: none). */

:root {
  color-scheme: dark;
  --bg: #0E1621;
  --surface: #17212B;
  --surface-2: #1E2C3A;
  --surface-3: #26394C;
  --border: #243241;
  --border-strong: #33475C;
  --text: #E9EEF3;
  --text-2: #93A4B5;
  --text-3: #6B7F92;

  --accent: #A99BFF;        /* ссылки, иконки, фокус, активное */
  --accent-fill: #5B4BC4;   /* заливка основных кнопок */
  --accent-hover: #6757D3;
  --accent-soft: rgba(169, 155, 255, .14);

  --ok: #5CC28E;   --ok-bg: rgba(92, 194, 142, .13);
  --warn: #E3B24F; --warn-bg: rgba(227, 178, 79, .13);
  --bad: #F07272;  --bad-bg: rgba(240, 114, 114, .13);
  --wait-fill: #4E6378; /* «Ждут итога» в полосках «Отчётов» */

  /* выделение тегов — три оттенка, проверены валидатором палитры на surface-2/3 (все пары) */
  --tag-1: #3987E5; --tag-2: #D95926; --tag-3: #199E70;

  /* инбокс — цвета Telegram Desktop (ночная тема) */
  --chat-bg: #0E1621;
  --bubble-in: #182533;
  --bubble-out: #2B5278;
  --selected: #2B5278;

  --font: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --h-control: 36px;
  --h-control-sm: 30px;
  --r-control: 8px;
  --r-card: 12px;
  --r-modal: 16px;
  --shadow: 0 16px 48px rgba(0, 0, 0, .45);
  /* Высота окна без панелей браузера телефона (100vh там выше видимого). */
  --app-h: 100vh;
}
@supports (height: 100dvh) { :root { --app-h: 100dvh; } }
/* Пальцем в 30px не попасть: на сенсорном экране поля и кнопки выше. Строки остаются ровными —
   у всех высота из этих переменных. */
@media (pointer: coarse) {
  :root { --h-control: 40px; --h-control-sm: 36px; }
}

* { box-sizing: border-box; }
/* Полосы прокрутки — широкая дорожка, по которой легко попасть мышью, и ползунок-капсула внутри
   (как у GitHub и YouTube), без стрелок. Стандартные scrollbar-width/-color — только для Firefox:
   Chrome и Edge, увидев их, отключают ::-webkit-scrollbar и рисуют свою тонкую полосу. */
@supports not selector(::-webkit-scrollbar) {
  * { scrollbar-width: auto; scrollbar-color: #3E5266 transparent; }
}
::-webkit-scrollbar { width: 14px; height: 14px; }
::-webkit-scrollbar-track, ::-webkit-scrollbar-corner { background: transparent; }
::-webkit-scrollbar-thumb { background: #3E5266; border-radius: 7px; border: 3px solid transparent; background-clip: padding-box; }
::-webkit-scrollbar-thumb:vertical { min-height: 40px; }
::-webkit-scrollbar-thumb:horizontal { min-width: 40px; }
::-webkit-scrollbar-thumb:hover { background-color: #56708A; }
::-webkit-scrollbar-thumb:active { background-color: var(--text-3); }
::-webkit-scrollbar-button { display: none; height: 0; width: 0; }
/* Место под полосу прокрутки — всегда: иначе на длинных страницах всё сдвигается на её ширину.
   Переход к элементу (scrollIntoView, якорь) не прячет его под закреплённое меню. */
html { height: 100%; scrollbar-gutter: stable; scroll-padding-top: calc(var(--topbar-h, 56px) + 16px); }
/* Не height: закреплённое меню держится только в пределах body — с высотой в экран оно уезжало
   вместе с ним после первого экрана прокрутки. */
body {
  min-height: 100%; margin: 0; background: var(--bg); color: var(--text);
  font: 400 14px/1.5 var(--font); font-feature-settings: "cv11", "ss01";
  -webkit-font-smoothing: antialiased; -webkit-text-size-adjust: 100%; -webkit-tap-highlight-color: transparent;
}
h1 { margin: 0; font-size: 20px; line-height: 1.3; font-weight: 600; letter-spacing: -0.2px; }
h2 { margin: 0; font-size: 16px; line-height: 1.35; font-weight: 600; }
h3 { margin: 0; font-size: 14px; font-weight: 600; }
p { margin: 0; }
a { color: var(--accent); text-decoration: none; }
a:hover { text-decoration: underline; }
.hidden { display: none !important; }
/* Невидимо, но место занимает: то, что появляется по ходу, не сдвигает соседей. */
.muted { color: var(--text-2); }
.faint { color: var(--text-3); }
.small { font-size: 12px; }
.num { font-variant-numeric: tabular-nums; }
/* Количества в колонке — друг под другом (решение владельца 2026-10-24): вправо, цифры одной
   ширины; доля — своей колонкой постоянной ширины, точки и проценты тоже в линию. */
.qty { text-align: right; font-variant-numeric: tabular-nums; }
th.qty .sort-mark { margin: 0 4px 0 0; }
.nowrap { white-space: nowrap; }
.stack { display: flex; flex-direction: column; gap: 16px; }
.stack-sm { display: flex; flex-direction: column; gap: 4px; }
.row { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.grow { flex: 1 1 auto; min-width: 0; }
.spacer { flex: 1 1 auto; }

/* ---------- каркас ---------- */
.topbar {
  position: sticky; top: 0; z-index: 10;
  display: flex; align-items: center; gap: 16px;
  height: 56px; padding: 0 24px;
  background: var(--surface); border-bottom: 1px solid var(--border);
}
.brand { display: flex; align-items: center; gap: 10px; flex: 0 0 auto; color: var(--text-2); }
.brand:hover { text-decoration: none; }
.brand img { height: 20px; width: auto; }
.brand span { font-size: 12px; font-weight: 500; padding-left: 10px; border-left: 1px solid var(--border-strong); }
.topbar nav { display: flex; gap: 2px; flex: 1 1 auto; min-width: 0; overflow-x: auto; scrollbar-width: none; }
.topbar nav a {
  display: inline-flex; align-items: center; gap: 6px;
  height: 34px; padding: 0 11px; border-radius: var(--r-control);
  color: var(--text-2); font-weight: 500; white-space: nowrap;
  transition: background-color .12s, color .12s;
}
.topbar nav a:hover { color: var(--text); background: var(--surface-2); text-decoration: none; }
.topbar nav a.active { color: var(--text); background: var(--surface-3); }
.me { display: flex; align-items: center; gap: 8px; flex: 0 0 auto; color: var(--text-2); font-size: 13px; white-space: nowrap; }
/* Переключатель направлений: сегменты на утопленной подложке, как вкладки, но крупнее по смыслу. */
/* С переключателем подпись «Messaging» лишняя: место нужно меню. */
.brand:has(+ .ws-switch:not(.hidden)) span { display: none; }
.ws-switch { display: flex; flex: 0 0 auto; gap: 2px; padding: 3px; background: var(--bg); border: 1px solid var(--border); border-radius: 10px; }
.ws-switch a {
  display: inline-flex; align-items: center; gap: 6px; height: 28px; padding: 0 12px; border-radius: 7px;
  color: var(--text-2); font-size: 13px; font-weight: 500; white-space: nowrap; transition: background-color .12s, color .12s;
}
.ws-switch a:hover { color: var(--text); text-decoration: none; }
.ws-switch a.active { background: var(--surface-3); color: var(--text); }
/* Меню и «Выйти» стоят в шапке как есть, пока помещаются; не помещаются (узкий экран, много
   пунктов, крупный масштаб — меряет fitTopbar в app.js) — шапка .compact: кнопка «☰» с
   выезжающей слева панелью, в шапке — название раздела. */
.nav-panel { display: contents; }
.topbar.measuring .nav-panel, .topbar.measuring .nav-back { transition: none !important; }
/* Значок, который бывает в другом направлении, — место под него учитывается только при замере. */
nav .badge.spare { display: none; }
.topbar.measuring nav .badge.spare { display: inline-flex; }
.topbar .nav-toggle, .nav-title, .nav-back { display: none; }
.topbar.compact { gap: 8px; padding: 0 12px 0 6px; }
.topbar.compact .brand span { display: none; }
.topbar.compact .nav-toggle { display: inline-flex; position: relative; color: var(--text); }
.nav-toggle .badge { position: absolute; top: 0; right: -4px; min-width: 18px; height: 18px; padding: 0 5px; font-size: 11px; box-shadow: 0 0 0 2px var(--surface); }
.topbar.compact .nav-title { display: block; flex: 1 1 auto; min-width: 0; padding-left: 4px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.topbar.compact .nav-panel {
  position: fixed; top: 0; left: 0; z-index: 2; display: flex; flex-direction: column; gap: 12px;
  width: min(300px, 86vw); height: var(--app-h); padding: 12px; overflow-y: auto; overscroll-behavior: contain;
  background: var(--surface); border-right: 1px solid var(--border); box-shadow: var(--shadow);
  transform: translateX(-102%); visibility: hidden; transition: transform .18s ease-out, visibility .18s;
}
.topbar.compact.nav-open .nav-panel { transform: none; visibility: visible; }
.topbar.compact .nav-back { display: block; position: fixed; inset: 0; z-index: 1; background: rgba(6, 10, 15, .6); opacity: 0; pointer-events: none; transition: opacity .18s; }
.topbar.compact.nav-open .nav-back { opacity: 1; pointer-events: auto; }
.topbar.compact nav { flex-direction: column; flex: 1 1 auto; gap: 2px; overflow: visible; }
.topbar.compact nav a { height: 44px; padding: 0 12px; font-size: 15px; }
.topbar.compact nav a .badge { margin-left: auto; }
.topbar.compact .me { justify-content: space-between; padding: 12px 0 0 12px; border-top: 1px solid var(--border); }

.banner { padding: 8px 24px; background: var(--warn-bg); color: var(--warn); border-bottom: 1px solid var(--border); font-size: 13px; line-height: 20px; text-align: center; }
/* Панель обновилась (app.js renderChrome): вся строка — кнопка «Обновить». */
.banner.clickable { cursor: pointer; }
.banner.clickable:hover .banner-act { text-decoration: underline; }
.banner-act { color: var(--accent); font-weight: 500; }

/* Инбокс тоже в колонке, а не во всю ширину: чаты слева и карточка клиента справа должны
   оставаться в поле зрения, когда смотришь в переписку (решение владельца 2026-10-23). */
main { position: relative; max-width: 1440px; margin: 0 auto; padding: 28px 24px 56px; }
/* Страница, на которую идёт переход: рисуется невидимой поверх прежней, пока не готова (route).
   Высота 0 — пока собирается, не удлиняет документ: иначе заранее меняется полоса прокрутки. */
.page-next { position: absolute; top: 0; left: 0; right: 0; height: 0; overflow: hidden; padding: inherit; opacity: 0; pointer-events: none; }
/* Загрузка панели: скрыта, пока первая страница и шрифт не готовы (appReady). Если скрипт не
   дошёл до конца, через 10 с панель показывается сама — без JS, анимацией. */
html.boot { background: var(--bg); }
html.boot body { visibility: hidden; animation: boot-fallback 0s 10s forwards; }
@keyframes boot-fallback { to { visibility: visible; } }

.page-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; min-height: 36px; margin-bottom: 20px; }
.page-head h1 { flex: 1 1 auto; }
.page-head .actions { display: flex; gap: 8px; flex-wrap: wrap; }
.page-head .actions select { width: auto; min-width: 200px; }
.lead { max-width: 760px; margin: -8px 0 20px; color: var(--text-2); }

/* ---------- вкладки ---------- */
/* Переключатель внутри вкладки («Тексты и настройки | Очередь») — своей строкой под вкладками. */
.tabs + .segmented { margin-bottom: 16px; }
.tabs { display: flex; gap: 4px; margin-bottom: 20px; border-bottom: 1px solid var(--border); overflow-x: auto; scrollbar-width: none; }
.tab {
  height: 40px; padding: 0 14px; margin-bottom: -1px; flex: 0 0 auto;
  background: none; border: 0; border-bottom: 2px solid transparent;
  color: var(--text-2); font-weight: 500; cursor: pointer; white-space: nowrap;
}
.tab:hover { color: var(--text); }
.tab.active { color: var(--text); border-bottom-color: var(--accent); }
/* Непрочитанные на подвкладке «Переписки» раздела. */
.tab .badge { margin-left: 6px; }

/* ---------- карточки ---------- */
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-card); }
.card + .card, .notice + .card, .card + .notice { margin-top: 16px; }
.card-head { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; min-height: 60px; padding: 12px 20px; border-bottom: 1px solid var(--border); }
.card-head .title { display: flex; flex-direction: column; gap: 2px; flex: 1 1 260px; min-width: 0; }
.card-head .meta { color: var(--text-2); font-size: 13px; }
.card-head .meta .seg { white-space: nowrap; }
.card-head .actions { display: flex; gap: 8px; flex-wrap: wrap; align-items: center; min-width: 0; max-width: 100%; }
.card-head .actions select { width: auto; height: var(--h-control-sm); }
.card-body { padding: 20px; }
.card-body.flush { padding: 0; }
.card-foot { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 12px 20px; border-top: 1px solid var(--border); }
.section-title { margin: 32px 0 12px; }

.cards { display: grid; grid-template-columns: repeat(auto-fit, minmax(150px, 1fr)); gap: 12px; margin-top: 16px; }
.cards > .card { margin-top: 0; }
/* Плитка с крупным числом и карточка аккаунта — как в DWH: плитки, ниже блоки с подписью. */
.stat { padding: 12px 16px; text-align: center; }
.stat .value { font-size: 24px; line-height: 1.2; font-weight: 600; font-variant-numeric: tabular-nums; }
.stat .value .aside { margin-left: 8px; color: var(--text-2); font-size: 13px; font-weight: 400; }
.stat .label { margin-top: 4px; color: var(--text-2); font-size: 13px; }
.acc-stats { grid-template-columns: repeat(3, minmax(0, 1fr)); margin-top: 0; }
@media (max-width: 640px) { .acc-stats > .stat { padding: 12px 6px; } }
.acc-sec { display: flex; flex-direction: column; gap: 12px; padding-top: 16px; border-top: 1px solid var(--border); }
.modal-pane > .acc-sec:first-child { padding-top: 0; border-top: 0; }
/* Доли времени: полоса и подписи под ней; цвета — как у плашек статусов. */
.share-bar { display: flex; gap: 2px; height: 8px; border-radius: 4px; overflow: hidden; background: var(--surface-2); }
.share-bar .seg { min-width: 3px; background: var(--text-3); }
.share-legend { display: flex; flex-wrap: wrap; gap: 6px 16px; color: var(--text-2); font-size: 13px; }
.share-legend .key { display: inline-flex; align-items: center; gap: 6px; }
.share-legend .sw { width: 10px; height: 10px; border-radius: 3px; background: var(--text-3); }
.share-legend b { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
:is(.share-bar .seg, .share-legend .sw).ok { background: var(--ok); }
:is(.share-bar .seg, .share-legend .sw).warn { background: var(--warn); }
:is(.share-bar .seg, .share-legend .sw).bad { background: var(--bad); }
:is(.share-bar .seg, .share-legend .sw).info { background: var(--accent); }
/* «Нет связи» — красной штриховкой: тревожно, но не путается с красными статусами («Ограничен»). */
:is(.share-bar .seg, .share-legend .sw).off { background: repeating-linear-gradient(135deg, var(--bad) 0 2px, transparent 2px 4px); box-shadow: inset 0 0 0 1px var(--bad); }
/* Пара чисел «3 · 2,5» в колонке количеств: правая часть постоянной ширины — точка во всех строках
   на одном месте; правая часть — под словом «медиана» заголовка. */
.pair { display: inline-grid; grid-template-columns: auto 18px minmax(39px, max-content); font-variant-numeric: tabular-nums; white-space: nowrap; overflow-wrap: normal; }
.pair > :first-child { text-align: right; }
.pair > :last-child { text-align: left; }
.pair-sep { text-align: center; color: var(--text-3); }
.pair.median { grid-template-columns: auto 18px minmax(48px, max-content); }
/* «Обзор»: рассылка одной строкой — без тела карточки. */
.mailing-bar .card-head { border-bottom: 0; }
.mailing-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.mailing-line h2 { margin-right: 4px; }

/* ---------- таблицы ---------- */
.table-wrap { overflow-x: auto; }
table { width: 100%; border-collapse: collapse; }
th, td { padding: 11px 16px; text-align: left; vertical-align: middle; border-bottom: 1px solid var(--border); }
th { color: var(--text-2); font-size: 12px; font-weight: 500; white-space: nowrap; }
/* Крайние ячейки — с тем же отступом, что шапка карточки и строка фильтров (20px): край текста
   таблицы совпадает со всем, что над ней. */
th:first-child, td:first-child { padding-left: 20px; }
th:last-child, td:last-child { padding-right: 20px; }
tbody tr:last-child td { border-bottom: 0; }
tbody tr:hover td { background: rgba(255, 255, 255, .015); }
tr.clickable { cursor: pointer; }
tr.clickable:hover td { background: var(--surface-2); }
td.check, th.check { width: 48px; padding-right: 0; }
td.check input, th.check input { display: block; }
td.actions, th.actions { text-align: right; white-space: nowrap; }
td.actions .row { justify-content: flex-end; flex-wrap: nowrap; }
.cell-sub { margin-top: 2px; color: var(--text-2); font-size: 12px; }
.empty { padding: 40px 20px; color: var(--text-2); text-align: center; }
.empty p { margin: 0 auto; max-width: 560px; }
.empty .form-actions { justify-content: center; margin-top: 16px; }
/* Длинные списки (feed в app.js): заголовок дня и «Загрузка…» под последней строкой. День —
   полосой своего цвета: он не сливается ни со строками, ни с шапкой таблицы. */
tr.feed-day td { padding: 8px 20px; background: var(--surface-2); color: var(--text); font-size: 13px; font-weight: 600; }
tbody tr.feed-day:hover td { background: var(--surface-2); }
.feed-more { padding: 12px 20px; border-top: 1px solid var(--border); color: var(--text-2); font-size: 13px; text-align: center; }
.feed-more:empty { display: none; }

/* ---------- формы ---------- */
input, select, textarea, button { font: inherit; color: inherit; }
input:not([type=checkbox]):not([type=radio]):not([type=file]), select, textarea {
  width: 100%; min-width: 0;
  background: var(--surface-2); color: var(--text);
  border: 1px solid var(--border-strong); border-radius: var(--r-control);
  outline: none; transition: border-color .12s, box-shadow .12s;
}
input:not([type=checkbox]):not([type=radio]):not([type=file]), select { height: var(--h-control); padding: 0 12px; }
/* Поле растёт по тексту — ручка в углу не нужна (где браузер не справился, растит fitArea в app.js).
   Текст переносится по словам, листать вбок нечего: полоса снизу была в поле ответа. */
textarea { padding: 10px 12px; min-height: 120px; max-height: 520px; field-sizing: content; resize: none; line-height: 1.5; overflow-x: hidden; }
input::placeholder, textarea::placeholder { color: var(--text-3); }
/* Подсказки подобраны по ширине полей (/ui-check меряет); не влезла на необычной ширине — многоточие, а не срез по букве. */
input:placeholder-shown { text-overflow: ellipsis; }
input:hover, select:hover, textarea:hover { border-color: #41586F; }
input:focus, select:focus, textarea:focus { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
input:disabled, select:disabled, textarea:disabled, input[readonly], textarea[readonly] { opacity: .6; cursor: default; }
/* Стрелка списка — SVG (data:), как у системных списков. */
select {
  -webkit-appearance: none; appearance: none; padding-right: 34px !important; cursor: pointer; text-overflow: ellipsis;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 6l4 4 4-4' fill='none' stroke='%2393A4B5' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat; background-position: right 10px center; background-size: 16px 16px;
}
select option { background: var(--surface-2); color: var(--text); }
input[type=checkbox], input[type=radio] { width: 16px; height: 16px; margin: 0; accent-color: var(--accent-fill); cursor: pointer; flex: 0 0 auto; }
/* Галочка в цветах панели: системная — серый квадрат, выбивается из тёмной темы. */
input[type=checkbox] {
  -webkit-appearance: none; appearance: none; outline: none;
  border: 1px solid var(--border-strong); border-radius: 4px;
  background: var(--surface-2) center / 12px 12px no-repeat;
  transition: background-color .12s, border-color .12s, box-shadow .12s;
}
input[type=checkbox]:hover { border-color: #41586F; }
input[type=checkbox]:focus { border-color: var(--border-strong); box-shadow: none; }
input[type=checkbox]:focus-visible { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
input[type=checkbox]:checked {
  border-color: var(--accent-fill); background-color: var(--accent-fill);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 12 12'%3E%3Cpath d='M2.5 6.2l2.3 2.3 4.7-4.9' fill='none' stroke='%23fff' stroke-width='1.8' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
input[type=checkbox]:checked:hover { border-color: var(--accent-hover); background-color: var(--accent-hover); }
input[type=checkbox]:disabled { opacity: .5; cursor: default; }
input[type=search]::-webkit-search-cancel-button { filter: invert(.7); cursor: pointer; }
/* Без стрелок ±1: случайный щелчок или прокрутка меняли лимиты. Колесо гасится в app.js. */
input[type=number] { -moz-appearance: textfield; appearance: textfield; }
input[type=number]::-webkit-inner-spin-button, input[type=number]::-webkit-outer-spin-button { -webkit-appearance: none; margin: 0; }

.field { display: flex; flex-direction: column; gap: 6px; min-width: 0; }
.field > span { font-size: 13px; font-weight: 500; color: var(--text-2); }
.field .hint { font-size: 12px; font-weight: 400; color: var(--text-3); }
.form-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: 16px; }
.form-grid.two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.form-actions { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
/* В окнах действия справа — как в подвале окна. */
.modal-body .form-actions { justify-content: flex-end; }
.check-line { display: inline-flex; align-items: flex-start; gap: 10px; cursor: pointer; line-height: 1.4; }
/* Квадрат — по середине первой строки текста. */
.check-line input { margin-top: 2px; margin-top: calc((1lh - 16px) / 2); }
/* Пояснение под галочкой — вровень с текстом, его можно выделить и скопировать. */
.check-field { display: flex; flex-direction: column; gap: 2px; }
.check-hint { padding-left: 26px; font-size: 13px; line-height: 1.4; color: var(--text-3); }
.days { display: flex; gap: 6px; flex-wrap: wrap; }
.day {
  display: inline-flex; align-items: center; gap: 8px;
  height: var(--h-control); padding: 0 12px; border: 1px solid var(--border-strong); border-radius: var(--r-control);
  background: var(--surface-2); cursor: pointer; user-select: none; font-weight: 500;
}
.day:hover { border-color: #41586F; }
.day:has(input:checked) { border-color: var(--accent); background: var(--accent-soft); }
.search { position: relative; }
.search svg { position: absolute; left: 11px; top: 50%; transform: translateY(-50%); color: var(--text-3); pointer-events: none; }
.search input { padding-left: 34px !important; }
.toolbar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 12px 20px; border-bottom: 1px solid var(--border); }
.toolbar .search { flex: 1 1 240px; }
.toolbar select { width: auto; min-width: 170px; }
.selection-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; padding: 10px 20px; background: var(--accent-soft); border-bottom: 1px solid var(--border); }

/* ---------- кнопки ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 6px;
  height: var(--h-control); padding: 0 14px; flex: 0 0 auto;
  border: 1px solid transparent; border-radius: var(--r-control);
  font-size: 14px; font-weight: 500; white-space: nowrap; cursor: pointer; text-decoration: none; user-select: none;
  transition: background-color .12s, border-color .12s, color .12s;
}
.btn:hover { text-decoration: none; }
/* Значок рядом с текстом — на полпикселя ниже середины строки: у строки снизу запас под хвостики
   букв («д», «у»), и заглавные сидят ниже её середины — по пикселям значок был выше букв на 0,5–0,7px.
   На обычном экране сдвиг округляется до 1px, на плотном (телефон, масштаб 150%) — ровно по буквам.
   Значок без текста (.btn.icon, «Отправить») не сдвигается. */
:is(.btn:not(.icon, .send), .menu button, .folder.add, .kcol-add) > svg { position: relative; top: .5px; }
.btn.primary { background: var(--accent-fill); color: #fff; }
.btn.primary:hover { background: var(--accent-hover); }
.btn.secondary { background: var(--surface-2); color: var(--text); border-color: var(--border-strong); }
.btn.secondary:hover { background: var(--surface-3); border-color: #41586F; }
.btn.danger { background: transparent; color: var(--bad); border-color: rgba(240, 114, 114, .45); }
.btn.danger:hover { background: var(--bad-bg); border-color: var(--bad); }
.btn.danger.solid { background: #C24848; color: #fff; border-color: #C24848; }
.btn.danger.solid:hover { background: #D05252; }
.btn.ghost { background: transparent; color: var(--text-2); }
.btn.ghost:hover { background: var(--surface-2); color: var(--text); }
.btn.sm { height: var(--h-control-sm); padding: 0 10px; }
.btn.icon { width: var(--h-control); padding: 0; }
.btn.icon.sm { width: var(--h-control-sm); }
.btn:disabled { opacity: .45; cursor: default; pointer-events: none; }
.link { padding: 0; border: 0; background: none; color: var(--accent); cursor: pointer; font-weight: 500; }
.link:hover { text-decoration: underline; }
:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
input:focus-visible, select:focus-visible, textarea:focus-visible { outline: none; }

/* ---------- метки, уведомления ---------- */
.pill {
  display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: 6px;
  font-size: 12px; font-weight: 500; white-space: nowrap;
  background: var(--surface-3); color: var(--text-2);
}
.pill.ok { background: var(--ok-bg); color: var(--ok); }
.pill.warn { background: var(--warn-bg); color: var(--warn); }
.pill.bad { background: var(--bad-bg); color: var(--bad); }
.pill.info { background: var(--accent-soft); color: var(--accent); }
.pills { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; }
.badge {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; padding: 0 6px; border-radius: 10px;
  background: var(--accent-fill); color: #fff; font-size: 12px; font-weight: 600; font-variant-numeric: tabular-nums;
}
.badge.muted { background: var(--surface-3); color: var(--text-2); }
.notice { padding: 10px 14px; border-radius: var(--r-control); background: var(--warn-bg); color: var(--warn); line-height: 1.45; }
.notice.bad { background: var(--bad-bg); color: var(--bad); }
.notice.info { background: var(--accent-soft); color: var(--accent); }
.notice.ok { background: var(--ok-bg); color: var(--ok); }
.notice + .notice { margin-top: 12px; }
.err-text { color: var(--bad); font-size: 12px; line-height: 1.4; }
td.err-cell { min-width: 260px; }
.mono { font-family: ui-monospace, Consolas, monospace; font-size: 12px; }
.inline-form { display: flex; gap: 8px; align-items: center; }
.inline-form input { width: 150px; }
.inline-form + .err-text, .inline-form ~ .notice { margin-top: 6px; }

/* Сворачиваемая подсказка «Как заполнять». */
details.help { border: 1px solid var(--border); border-radius: var(--r-control); background: var(--surface-2); }
details.help > summary { display: flex; align-items: center; gap: 8px; padding: 10px 14px; cursor: pointer; color: var(--text-2); font-weight: 500; list-style: none; }
details.help > summary::-webkit-details-marker { display: none; }
details.help > summary::before { content: "▸"; color: var(--text-3); }
details.help[open] > summary::before { content: "▾"; }
details.help .help-body { padding: 0 14px 14px; font-size: 13px; line-height: 1.55; color: var(--text-2); }
details.help .help-body p { margin: 8px 0 0; }
details.help .help-body ol { margin: 6px 0 0; padding-left: 22px; }
details.help .help-body li + li { margin-top: 3px; }
details.help .help-body b { color: var(--text); font-weight: 600; }
details.help .help-grid { display: grid; grid-template-columns: max-content 1fr; gap: 5px 16px; margin-top: 8px; }
details.help .help-grid > b { font-weight: 500; }
/* Пример — целиком: «socks5://логин:пароль@хост:порт», разорванный посередине, читается плохо. */
details.help code { font-family: ui-monospace, Consolas, monospace; font-size: 12px; padding: 1px 5px; border-radius: 4px; background: var(--surface-3); white-space: nowrap; }

/* ---------- окна, меню, тосты ---------- */
.modal-back {
  position: fixed; inset: 0; z-index: 30; overflow-y: auto; scrollbar-gutter: stable; overscroll-behavior: contain;
  display: flex; align-items: flex-start; justify-content: center; padding: 48px 16px;
  background: rgba(6, 10, 15, .72);
}
/* Окно не выше экрана: шапка и кнопки внизу всегда на виду, прокручивается содержимое. */
.modal { display: flex; flex-direction: column; width: 100%; max-width: 680px; max-height: calc(var(--app-h) - 96px); background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-modal); box-shadow: var(--shadow); }
.modal > .modal-head, .modal > .modal-foot { flex: none; }
.modal.narrow { max-width: 440px; }
.modal.wide { max-width: 980px; }
/* Выбор причины — кнопки в две колонки: окно шире подтверждения, чтобы причины помещались в строку. */
.modal.narrow:has(.reason-list) { max-width: 560px; }
/* Боковая панель: справа на всю высоту, доска за ней видна. */
.modal-back.drawer-back { align-items: stretch; justify-content: flex-end; padding: 0; background: rgba(6, 10, 15, .45); }
.modal.drawer { display: flex; flex-direction: column; max-width: 460px; height: var(--app-h); max-height: none; border-radius: 0; border-width: 0 0 0 1px; }
.modal.drawer .modal-body { flex: 1 1 auto; overflow-y: auto; }
.modal-head { display: flex; align-items: center; gap: 12px; padding: 16px 20px; border-bottom: 1px solid var(--border); }
.modal-head h2 { flex: 1 1 auto; font-size: 17px; }
.modal-body { flex: 1 1 auto; min-height: 0; overflow-y: auto; overscroll-behavior: contain; padding: 20px; display: flex; flex-direction: column; gap: 16px; }
/* Непрозрачный фон, нарисованный в самой прокрутке (local), — только так Chrome листает окно
   целиком одним слоем. Без него окно листается перерисовкой, а пузыри сообщений (position:
   relative) и кнопки итога (своя прокрутка вбок) рисуются отдельными слоями и при прокрутке
   плавают отдельно от остального. Углы — как у окна, когда кнопок внизу нет. */
.modal-body { background: var(--surface); background-attachment: local; }
.modal > .modal-body:last-child { border-bottom-left-radius: inherit; border-bottom-right-radius: inherit; }
/* Окно с вкладками или группами: полоса прокрутки появляется и пропадает со сменой группы —
   место под неё есть всегда, чтобы содержимое не становилось то шире, то уже. */
.modal.steady > .modal-body { scrollbar-gutter: stable; }
/* Телефон: окно — на весь экран, с шапкой и кнопками на виду; подтверждение (narrow) —
   карточкой по середине, как на компьютере. */
@media (max-width: 640px) {
  .modal-back { padding: 0; scrollbar-gutter: auto; }
  .modal-back:has(> .modal.narrow) { align-items: center; padding: 16px; }
  .modal:not(.narrow) { max-width: none; height: var(--app-h); max-height: none; border-width: 0; border-radius: 0; box-shadow: none; }
  .modal.narrow { max-height: calc(var(--app-h) - 32px); }
  .modal-head { padding: 10px 12px 10px 20px; }
  .modal-foot { flex-wrap: wrap; }
}
.modal-body h3 { margin-top: 8px; }
.modal-foot { display: flex; justify-content: flex-end; gap: 8px; padding: 14px 20px; border-top: 1px solid var(--border); }

.menu {
  position: fixed; z-index: 40; min-width: 180px; max-height: calc(var(--app-h) - 16px); overflow-y: auto; overscroll-behavior: contain; padding: 6px;
  background: var(--surface-2); border: 1px solid var(--border-strong); border-radius: 10px; box-shadow: var(--shadow);
}
.menu button {
  display: flex; align-items: center; gap: 10px; width: 100%; height: 34px; padding: 0 10px;
  background: none; border: 0; border-radius: 6px; color: var(--text); cursor: pointer; text-align: left;
}
.menu button:hover, .menu button:focus-visible { background: var(--surface-3); outline: none; }
.menu button.danger { color: var(--bad); }
.menu button svg { color: var(--text-2); }
.menu button.danger svg { color: var(--bad); }
.menu button svg, .menu-ico { flex: 0 0 16px; width: 16px; }
.menu-sep { height: 1px; margin: 5px 4px; background: var(--border); }

/* Свой раскрывающийся список у <select> (openPick в app.js). Колонки подписи, подсказки и
   цены — общие для всех пунктов (subgrid): цифры стоят ровно одна под другой. */
select.open { border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft); }
.menu.pick { display: flex; flex-direction: column; gap: 6px; }
.menu.pick:focus-visible { outline: none; }
.menu.pick input.pick-search { flex: 0 0 auto; height: var(--h-control-sm); background: var(--surface); }
.pick-list {
  display: grid; grid-template-columns: minmax(0, 1fr) auto auto auto; align-content: start;
  min-height: 0; overflow-y: auto; overscroll-behavior: contain;
}
.pick-opt {
  grid-column: 1 / -1; display: grid; grid-template-columns: subgrid; align-items: center;
  min-height: 34px; padding: 0 10px; border-radius: 6px; cursor: pointer;
}
.pick-opt.active { background: var(--surface-3); }
.pick-opt.selected .pick-label { color: var(--accent); }
.pick-opt.disabled { opacity: .45; cursor: default; }
.pick-label { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pick-hint, .pick-meta { white-space: nowrap; font-variant-numeric: tabular-nums; }
.pick-hint { font-size: 13px; color: var(--text-3); }
.pick-meta { text-align: right; }
.pick-hint:not(:empty), .pick-meta:not(:empty) { padding-left: 16px; }
.pick-check { display: flex; width: 16px; margin-left: 10px; color: var(--accent); }
.pick-group { grid-column: 1 / -1; padding: 10px 10px 4px; font-size: 12px; font-weight: 600; color: var(--text-3); }
.pick-group:first-child { padding-top: 4px; }
.pick-group:not(:first-child) { margin-top: 6px; border-top: 1px solid var(--border); }
.pick-empty { grid-column: 1 / -1; padding: 8px 10px; color: var(--text-3); }
/* Пальцем пункты выше; на телефоне список — панелью снизу во всю ширину, с названием поля. */
@media (pointer: coarse) { .pick-opt { min-height: 40px; } }
.pick-back { position: fixed; inset: 0; z-index: 40; background: rgba(6, 10, 15, .6); touch-action: none; animation: pick-fade .15s ease-out; }
.menu.pick.sheet {
  left: 0; right: 0; bottom: 0; width: auto; min-width: 0; max-width: none;
  padding: 8px 8px calc(8px + env(safe-area-inset-bottom)); border-width: 1px 0 0; border-radius: 14px 14px 0 0;
  animation: pick-up .18s ease-out;
}
.sheet .pick-title { flex: none; padding: 8px 10px 4px; font-weight: 600; }
.sheet .pick-opt { min-height: 44px; }
@keyframes pick-fade { from { opacity: 0; } }
@keyframes pick-up { from { transform: translateY(32px); opacity: 0; } }

.toast {
  position: fixed; right: 24px; bottom: 24px; z-index: 50; max-width: 420px;
  padding: 12px 16px; border-radius: 10px;
  background: var(--surface-3); color: var(--text); border: 1px solid var(--border-strong); box-shadow: var(--shadow);
}
.toast.bad { border-color: rgba(240, 114, 114, .55); color: var(--bad); }
@media (max-width: 640px) { .toast { left: 12px; right: 12px; bottom: 12px; max-width: none; } }

.login { max-width: 380px; margin: 12vh auto 0; }
.login .card-body { display: flex; flex-direction: column; gap: 16px; padding: 32px 28px; }
.login .logo { display: flex; justify-content: center; }
.login .logo img { height: 28px; }
.login h1 { text-align: center; font-size: 18px; }
.login .btn { width: 100%; height: 40px; }

pre.raw {
  margin: 0; padding: 12px 14px; white-space: pre-wrap; word-wrap: break-word;
  background: var(--surface-2); border: 1px solid var(--border); border-radius: var(--r-control);
  font: inherit; font-size: 13.5px; line-height: 1.55; color: var(--text);
}

/* Под закреплённым меню — с отступом 16px. */
.folder {
  display: flex; align-items: center; gap: 8px; width: 100%; min-height: 36px; padding: 0 10px;
  background: none; border: 0; border-radius: 8px; color: var(--text-2); text-align: left; cursor: pointer; font-weight: 500;
}
.folder:hover { background: var(--surface-2); color: var(--text); }
.folder.active { background: var(--surface-3); color: var(--text); }
.folder .name { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.folder .count { color: var(--text-3); font-size: 12px; font-variant-numeric: tabular-nums; }
.folder.drop-before { box-shadow: inset 0 2px 0 var(--accent); }
.folder.drop-after { box-shadow: inset 0 -2px 0 var(--accent); }
.folder[draggable] { cursor: grab; }

/* ---------- каналы ---------- */
.folder.add { color: var(--accent); }
.folder.add svg { flex: 0 0 auto; }
@keyframes pulse { 50% { opacity: .35; } }

/* ---------- шаблоны ---------- */
.tpl { display: grid; grid-template-columns: minmax(0, 1fr) 300px; gap: 24px; padding: 18px 20px; border-bottom: 1px solid var(--border); }
.tpl:last-child { border-bottom: 0; }
.tpl.off .tpl-title, .tpl.off pre.raw { color: var(--text-2); }
.tpl-title { display: flex; align-items: center; gap: 8px; margin-bottom: 10px; font-weight: 600; }
.tpl-stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 4px; align-content: start; }
.tpl-stats > div { padding: 10px 4px; border-radius: var(--r-control); background: var(--surface-2); text-align: center; }
.tpl-stats b { display: block; font-size: 17px; font-weight: 600; font-variant-numeric: tabular-nums; }
.tpl-stats span { font-size: 11.5px; color: var(--text-2); }
details.archive > summary { display: flex; align-items: center; gap: 8px; padding: 16px 20px; cursor: pointer; color: var(--text-2); font-weight: 500; list-style: none; }
details.archive > summary::-webkit-details-marker { display: none; }
details.archive > summary::before { content: "▸"; color: var(--text-3); }
details.archive[open] > summary::before { content: "▾"; }
details.archive[open] > summary { border-bottom: 1px solid var(--border); }

/* ---------- время ---------- */
.time-field { display: flex; align-items: center; gap: 6px; }
.time-field select { width: auto; min-width: 76px; }
.time-field span { color: var(--text-2); font-weight: 600; }

/* ---------- сортировка таблиц ---------- */
th.sortable { cursor: pointer; user-select: none; }
th.sortable:hover { color: var(--text); }
th.sorted { color: var(--text); }
.sort-mark { display: inline-block; width: 12px; margin-left: 4px; color: var(--accent); }

/* ---------- обзор ---------- */
.attention { list-style: none; margin: 0; padding: 0; }
.attention li { display: flex; align-items: flex-start; gap: 10px; padding: 12px 20px; border-bottom: 1px solid var(--border); }
.attention li:last-child { border-bottom: 0; }
.attention .dot { flex: 0 0 8px; height: 8px; margin-top: 7px; border-radius: 50%; background: var(--warn); }
.attention .dot.bad { background: var(--bad); }
.attention .dot.info { background: var(--accent); }
.attention .dot.ok { background: var(--ok); }
.attention a { color: var(--text); }
.attention .sub { color: var(--text-2); font-size: 13px; }
/* Строка «Итого» под таблицей с сортировкой — последней при любой сортировке. */
tfoot tr.total-row td { border-top: 1px solid var(--border-strong); border-bottom: 0; font-weight: 600; }
/* «Запас и автоматика»: подпись слева, число справа. */
.reserve { list-style: none; margin: 0; padding: 0; }
.reserve li { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 12px 20px; border-bottom: 1px solid var(--border); }
.reserve li:last-child { border-bottom: 0; }
.reserve a { color: var(--text); }
.reserve .sub { color: var(--text-2); font-size: 13px; }
.reserve-value { font-size: 18px; font-weight: 600; font-variant-numeric: tabular-nums; }

/* ---------- график ---------- */
.chart { position: relative; }
.chart-legend { display: flex; align-items: center; gap: 16px; flex-wrap: wrap; margin-bottom: 12px; font-size: 13px; color: var(--text-2); }
.chart-legend .key { display: inline-flex; align-items: center; gap: 6px; }
.chart-legend .sw { width: 10px; height: 10px; border-radius: 3px; }
.chart-legend .chart-title { color: var(--text); font-weight: 600; }
.chart-legend b { color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums; }
.chart svg { display: block; width: 100%; height: auto; overflow: visible; }
.chart svg text { fill: var(--text-3); font: 400 11px var(--font); font-variant-numeric: tabular-nums; }
.chart .grid { stroke: var(--border); stroke-width: 1; }
.chart .band { fill: transparent; }
/* Медиана и другие уровни: пунктир поверх столбиков, в легенде — такой же. */
.chart .mark { stroke: var(--text-2); stroke-width: 1.5; stroke-dasharray: 4 3; }
.chart-legend .sw.mark { height: 0; border-radius: 0; border-top: 2px dashed var(--text-2); }
/* Столбики и подписи лежат поверх полосы дня: наведение должна ловить полоса, а не они. */
.chart svg :not(.band) { pointer-events: none; }
.chart .band.hover { fill: rgba(255, 255, 255, .04); }
.chart-tip {
  position: absolute; z-index: 5; pointer-events: none; min-width: 150px; padding: 8px 10px;
  background: var(--surface-3); border: 1px solid var(--border-strong); border-radius: 8px; box-shadow: var(--shadow);
  font-size: 13px; color: var(--text);
}
.chart-tip .t { margin-bottom: 4px; color: var(--text-2); font-size: 12px; }
.chart-tip .r { display: flex; align-items: center; gap: 6px; }
.chart-tip .r b { margin-left: auto; font-variant-numeric: tabular-nums; }
.chart-tip .sw { width: 8px; height: 8px; border-radius: 2px; }
.chart-table { margin-top: 12px; }

/* ---------- источники ---------- */
.src-row td { vertical-align: middle; }
.order-cell { display: flex; align-items: center; gap: 6px; }
/* Колонка «#» — по содержимому: иначе таблица растягивает её и название источника уезжает вправо. */
td:has(> .order-cell) { width: 1%; white-space: nowrap; }
.src-row.dragging td { opacity: .4; }
.src-row.drop-before td { box-shadow: inset 0 2px 0 var(--accent); }
.src-row.drop-after td { box-shadow: inset 0 -2px 0 var(--accent); }
.grip { display: inline-flex; align-items: center; justify-content: center; width: 24px; height: 24px; padding: 0; border: 0; background: none; color: var(--text-3); cursor: grab; border-radius: 4px; }
.grip:hover { color: var(--text); background: var(--surface-3); }
.pos { color: var(--text-3); font-variant-numeric: tabular-nums; min-width: 16px; line-height: 24px; }

/* ---------- инбокс (Telegram Desktop, ночная тема) ---------- */
.inbox {
  display: grid; grid-template-columns: 340px minmax(0, 1fr);
  /* До окна по высоте: страница не прокручивается. Точную высоту ставит fitWindow (по месту на
     странице, с баннером, клавиатурой телефона); здесь — она же для компьютера до первого расчёта:
     окно минус шапка (56), отступы страницы (28 + 56) и заголовок (56). */
  height: calc(var(--app-h) - 196px);
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-card); overflow: hidden;
}
body.has-banner .inbox { height: calc(var(--app-h) - 196px - 37px); }
.inbox-side { display: flex; flex-direction: column; min-height: 0; border-right: 1px solid var(--border); }
/* Высота блока поиска задана: на её уровне — черта под «Все чаты» в колонке папок. */
.inbox { --inbox-head: 99px; }
.inbox-tools { display: flex; flex-direction: column; justify-content: center; gap: 8px; flex: 0 0 var(--inbox-head); padding: 0 12px; border-bottom: 1px solid var(--border); }
.inbox-tools .search input { border-radius: 18px; background: var(--bg); border-color: transparent; }
.inbox-tools .search input:focus { border-color: var(--accent); }
.inbox-tools select { height: 32px; background-color: var(--bg); border-color: transparent; }
.dialogs { flex: 1 1 auto; overflow-y: auto; padding-bottom: 8px; }
.list-head { display: flex; align-items: center; gap: 8px; padding: 14px 16px 6px; color: var(--text-2); font-size: 12px; font-weight: 600; }
.list-empty { padding: 8px 16px 12px; color: var(--text-3); font-size: 13px; }
.dialogs-empty { display: flex; flex-direction: column; gap: 6px; padding: 48px 28px; text-align: center; line-height: 1.5; }
.dialogs-empty strong { color: var(--text-2); font-size: 14px; font-weight: 600; }
.dialogs-empty p { margin: 0; color: var(--text-3); font-size: 13px; }
.list-note { padding: 10px 16px 0; color: var(--text-3); font-size: 12px; }
/* Папки строкой вкладок — только на узком экране (≤900), вместо колонки папок. */
.dialog-item { display: flex; gap: 12px; padding: 8px 10px; margin: 0 6px; border-radius: 10px; cursor: pointer; }
.dialog-item:hover { background: var(--surface-2); }
.dialog-item.active { background: var(--selected); }
.avatar { flex: 0 0 auto; width: 46px; height: 46px; border-radius: 50%; display: flex; align-items: center; justify-content: center; color: #fff; font-size: 17px; font-weight: 600; }
.avatar.sm { width: 38px; height: 38px; font-size: 15px; }
.avatar.xs { width: 24px; height: 24px; font-size: 11px; }
.avatar.xxs { width: 18px; height: 18px; font-size: 9px; }
.av-0 { background: linear-gradient(#FF885E, #FF516A); } .av-1 { background: linear-gradient(#FFCD6A, #FFA85C); }
.av-2 { background: linear-gradient(#82B1FF, #665FFF); } .av-3 { background: linear-gradient(#A0DE7E, #54CB68); }
.av-4 { background: linear-gradient(#53EDD6, #28C9B7); } .av-5 { background: linear-gradient(#72D5FD, #2A9EF1); }
.av-6 { background: linear-gradient(#E0A2F3, #D669ED); }
.dialog-body { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; justify-content: center; gap: 1px; }
.dialog-line { display: flex; align-items: center; gap: 8px; min-width: 0; }
.dialog-line .who { flex: 1 1 auto; min-width: 0; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dialog-line .time { flex: 0 0 auto; color: var(--text-3); font-size: 12px; }
.dialog-line .preview { flex: 1 1 auto; min-width: 0; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dialog-line .preview .you { color: var(--accent); }
.dialog-item.unread .preview { color: var(--text); }
.dialog-line .reaction { flex: 0 0 auto; font-size: 15px; line-height: 20px; }
.dialog-meta { display: flex; align-items: center; gap: 6px; min-width: 0; color: var(--text-3); font-size: 12px; }
.dialog-meta .meta-who { flex: 1 1 auto; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* Плашки не сжимаются: не помещаются рядом — переносятся под первую. */
.dialog-tags { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 6px; min-width: 0; margin-top: 3px; }
.dialog-tags .pill { display: block; flex: 0 0 auto; max-width: 100%; line-height: 22px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dialog-item.active .time, .dialog-item.active .preview, .dialog-item.active .preview .you, .dialog-item.active .dialog-meta { color: rgba(233, 238, 243, .78); }
.dialog-item.active .badge { background: #fff; color: var(--selected); }
mark { background: rgba(227, 178, 79, .38); color: inherit; border-radius: 3px; padding: 0 1px; }

.chat { display: flex; flex-direction: column; min-width: 0; min-height: 0; background: var(--chat-bg); }
/* Сжимается только лента: иначе при длинной переписке шапка и поле ввода теряют отступы. */
.chat > :not(.messages) { flex: 0 0 auto; }
.chat-empty { margin: auto; max-width: 440px; padding: 6px 14px; border-radius: 14px; background: var(--surface); color: var(--text-2); font-size: 13px; text-align: center; }
.chat-head { display: flex; align-items: center; gap: 12px; padding: 8px 16px; min-height: 58px; background: var(--surface); border-bottom: 1px solid var(--border); }
.chat-head .title { flex: 1 1 auto; min-width: 0; }
.chat-head .title strong { display: block; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-head .title .muted { font-size: 13px; overflow: hidden; }
/* Кнопки шапки: значок — только на телефоне (≤640), там подписи нет. */
.head-act > svg { display: none; }
.chat-alert { display: flex; align-items: center; gap: 12px; padding: 8px 16px; background: var(--surface); border-bottom: 1px solid var(--border); color: var(--bad); font-size: 13px; }
.chat-alert.info { color: var(--text-2); }
/* Другие чаты человека — одной строкой над перепиской, как другие плашки чата (цветной фон владелец
   счёл лишним: заметной её делает ссылка); на узком экране листается вбок. */
.chat-alert.chats { gap: 6px; min-height: 32px; padding-top: 0; padding-bottom: 0; overflow-x: auto; scrollbar-width: none; white-space: nowrap; }
.chat-alert.chats > * { flex: none; }
.chat-alert.chats .link { display: inline-flex; align-items: center; gap: 5px; font-size: 13px; }
.messages { flex: 1 1 auto; overflow-y: auto; padding: 16px 20px; display: flex; flex-direction: column; gap: 4px; }
.msg-day { display: flex; flex-direction: column; gap: 4px; }
/* Дата прилипает к верху ленты, пока виден её день (app.js: settleDates). */
.date-sep { position: sticky; top: 0; z-index: 2; align-self: center; margin: 10px 0 6px; padding: 3px 10px; border-radius: 12px; background: rgba(23, 33, 43, .9); color: var(--text-2); font-size: 12px; font-weight: 500; transition: opacity .3s; }
.date-sep.idle { opacity: 0; pointer-events: none; }
.msg-row { display: flex; align-items: flex-end; gap: 4px; max-width: 100%; }
.msg-row.out { justify-content: flex-end; }
.msg-row.first-in-group { margin-top: 6px; }
.msg { position: relative; max-width: min(540px, 76%); padding: 6px 10px 6px 12px; border-radius: 12px; white-space: pre-wrap; word-wrap: break-word; line-height: 20px; }
/* Строки в пузыре — целой высоты (было 1.42 → 19,88px): дробная высота сообщения ставила все ниже него
   на доли пикселя, и буквы с галочкой округлялись по-разному — галочка «съезжала» после правки соседнего. */
.msg-row.in .msg { background: var(--bubble-in); border-bottom-left-radius: 4px; }
.msg-row.out .msg { background: var(--bubble-out); border-bottom-right-radius: 4px; }
.msg .meta { float: right; display: inline-flex; align-items: center; gap: 3px; margin: 7px 0 -4px 12px; font-size: 11px; line-height: 16px; color: rgba(233, 238, 243, .5); white-space: nowrap; user-select: none; }
.msg-row.out .msg .meta { color: rgba(140, 200, 255, .8); }
.msg-row.pending .msg { opacity: .7; }
.msg-row.deleting .msg { opacity: .4; text-decoration: line-through; }
/* Удалено в Telegram или из панели: текст сохранён у нас, в чате — приглушённо. */
.msg-row.deleted .msg { opacity: .45; box-shadow: inset 0 0 0 1px var(--border); }
.msg-row.failed .msg { box-shadow: inset 0 0 0 1px rgba(240, 114, 114, .6); }
.msg-row.failed .msg .meta { color: var(--bad); }
.msg-more {
  flex: 0 0 auto; width: 28px; height: 28px; padding: 0; border: 0; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: transparent; color: var(--text-3); cursor: pointer; opacity: 0; transition: opacity .1s, background-color .1s;
}
.msg-row:hover .msg-more, .msg-more:focus-visible, .msg-more.open { opacity: 1; }
.msg-more:hover, .msg-more.open { background: var(--surface-2); color: var(--text); }
.msg-note { max-width: min(540px, 76%); margin: 2px 0 4px; font-size: 12px; color: var(--bad); }
.msg-row.out + .msg-note, .msg-note.out { align-self: flex-end; text-align: right; }
.msg-note .link { font-size: 12px; margin-left: 6px; }
/* Отложенный ответ: ждёт окна — спокойно, ждёт проверки или повтора — жёлтым. */
.msg-note.wait { color: var(--text-2); }
.msg-note.warn { color: var(--warn); }
.composer-wrap { background: var(--surface); border-top: 1px solid var(--border); }
.edit-bar { display: flex; align-items: center; gap: 10px; padding: 8px 16px 0; }
.edit-bar .bar { width: 2px; align-self: stretch; background: var(--accent); border-radius: 1px; }
.edit-bar .what { flex: 1 1 auto; min-width: 0; font-size: 13px; cursor: pointer; }
.edit-bar .what strong { display: block; color: var(--accent); font-weight: 600; }
.edit-bar .what span { display: block; color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.composer { display: flex; align-items: flex-end; gap: 8px; padding: 10px 16px; }
.composer textarea { min-height: 40px; max-height: 200px; height: 40px; padding: 9px 14px; border-radius: 20px; field-sizing: fixed; resize: none; background: var(--bg); border-color: transparent; overflow-y: hidden; }
.composer .send { width: 40px; height: 40px; border-radius: 50%; padding: 0; }
/* Стрелка — треугольник: вес слева, по рамке в центре она на глаз левее на 1,8px. На 1px вправо —
   середина между рамкой и весом, как центрируют «плей» и «отправить». */
.composer .send > svg { position: relative; left: 1px; }
.composer textarea::placeholder { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.composer-note { padding: 0 16px 8px; color: var(--text-3); font-size: 12px; text-align: center; }
/* Обход списка CRM — на месте подсказки: «Предыдущий» и «Следующий» по краям, номер посередине.
   Края кнопок — по краям поля ввода (скрепка и «Отправить»: те же 16px), снизу — те же 10px, что
   над полем; от поля — 6px (строка заходит в его нижний отступ). Ссылка — только «К списку CRM»:
   номер и точка рядом — обычный текст, на наведение не отвечают. */

/* Вложения в переписке */
.msg a { color: var(--accent); }
.msg-row.out .msg a { color: #BFE0FF; }
.msg.has-media { display: flex; flex-direction: column; gap: 6px; }
.msg.has-media .meta { align-self: flex-end; margin-top: 0; }
.msg-media { display: block; max-width: 100%; }
.msg-media img, video.msg-media { display: block; max-width: min(360px, 100%); max-height: 360px; border-radius: 8px; background: rgba(0, 0, 0, .2); }
.msg-media img.sticker { max-width: 160px; max-height: 160px; background: transparent; }
video.msg-media.round { width: 220px; height: 220px; max-width: 220px; object-fit: cover; border-radius: 50%; }
.msg-audio audio { display: block; width: 300px; max-width: 100%; height: 40px; }
.msg-file { display: flex; align-items: center; gap: 10px; min-width: 0; color: inherit; text-decoration: none; white-space: normal; }
a.msg-file:hover strong { text-decoration: underline; }
.msg-file-icon { flex: 0 0 auto; width: 40px; height: 40px; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: rgba(255, 255, 255, .1); color: var(--text); }
.msg-file-text { display: flex; flex-direction: column; min-width: 0; line-height: 18px; }
.msg-file-text strong { font-weight: 600; overflow-wrap: anywhere; }
.msg-file-text span { font-size: 12px; line-height: 16px; color: var(--text-2); }
.msg-row.out .msg-file-text span { color: rgba(200, 225, 255, .8); }
.attach-bar img.attach-thumb { width: 40px; height: 40px; object-fit: cover; border-radius: 6px; }
.attach-bar .what strong { color: var(--text); }
.chat.drop .messages { box-shadow: inset 0 0 0 2px var(--accent); }
/* Реакции: в нижнем левом углу пузыря, время справа на той же строке (как в Telegram) */
.msg-foot { display: flex; align-items: flex-end; gap: 8px; margin-top: 2px; }
.msg-foot .meta { float: none; margin: 0 0 -2px auto; }
.msg-reactions { display: flex; flex-wrap: wrap; gap: 4px; }
.react-chip {
  display: inline-flex; align-items: center; gap: 5px; height: 26px; padding: 0 4px 0 8px; border: 0; border-radius: 13px;
  background: rgba(169, 155, 255, .16); color: var(--text); font: inherit; font-size: 15px; line-height: 1; cursor: pointer; user-select: none;
}
.msg-row.out .react-chip { background: rgba(255, 255, 255, .14); }
.react-chip .who { display: inline-flex; }
.react-chip .who .avatar + .avatar { margin-left: -5px; }
.react-chip .avatar { box-shadow: 0 0 0 1.5px rgba(23, 33, 43, .9); }
/* Своя реакция — заливка; на своём сообщении — другого цвета, как в Telegram */
.react-chip.mine { background: var(--accent-fill); }
.msg-row.out .react-chip.mine { background: #6AB2F2; }
.react-chip.pending { opacity: .6; }
/* Цитата в ответе: на что ответили; клик — к исходному сообщению */
.msg-quote {
  display: flex; flex-direction: column; min-width: 0; padding: 3px 8px; border-left: 3px solid var(--accent); border-radius: 4px;
  background: rgba(169, 155, 255, .1); font-size: 13px; line-height: 18px; cursor: pointer; white-space: normal;
}
.msg-row.out .msg-quote { border-left-color: #BFE0FF; background: rgba(255, 255, 255, .1); }
.msg-quote strong { color: var(--accent); font-weight: 600; }
.msg-row.out .msg-quote strong { color: #BFE0FF; }
.msg-quote span { color: var(--text-2); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; max-width: 420px; }
.msg-row.out .msg-quote span { color: rgba(233, 238, 243, .8); }
.msg-quote.gone { cursor: default; }
.msg-quote.fragment span { display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 6; white-space: pre-wrap; overflow-wrap: anywhere; }
.msg-row.flash { animation: row-flash 2s ease-out; }
.msg-row.flash .msg { animation: msg-flash 2s ease-out; }
@keyframes msg-flash { 0%, 50% { box-shadow: 0 0 0 3px var(--accent); } 100% { box-shadow: 0 0 0 3px transparent; } }
.reply-bar .bar-icon { display: inline-flex; color: var(--accent); }

/* Столбик реакций растёт вверх из кнопки-сердечка: нижний пункт встаёт на её место, видно
   четыре, остальные — прокруткой вверх (как в Telegram Desktop) */
.react-picker {
  position: fixed; z-index: 35; display: flex; flex-direction: column-reverse; gap: 2px; width: 36px; height: 140px; padding: 4px;
  overflow-x: hidden; overflow-y: auto; overscroll-behavior: contain; scrollbar-width: none; border-radius: 18px;
  background: var(--surface); border: 1px solid var(--border-strong); box-shadow: var(--shadow); animation: viewer-in .1s ease-out;
}
.react-picker::-webkit-scrollbar { display: none; }
/* Пятая реакция выглядывает наполовину и тает вместе с верхом столбика: видно, что список
   листается вверх. Долистали до конца — показываем целиком. */
.react-picker:not(.at-end) {
  -webkit-mask-image: linear-gradient(to top, #000 calc(100% - 30px), transparent);
  mask-image: linear-gradient(to top, #000 calc(100% - 30px), transparent);
}
.react-picker.hidden { display: none; }
.react-opt {
  flex: 0 0 auto; width: 26px; height: 27px; padding: 0; border: 0; border-radius: 50%; background: transparent;
  font-size: 18px; line-height: 1; cursor: pointer; transition: transform .1s, background-color .1s;
}
.react-opt:hover { transform: scale(1.2); }
.react-opt.mine { background: var(--accent-soft); }
/* Кнопка-сердечко у нижнего угла сообщения со стороны середины чата: чуть заходит на пузырь
   и выступает снизу не больше зазора между сообщениями — соседнее не перекрывает (как в Telegram) */
.react-btn {
  position: absolute; bottom: -3px; width: 24px; height: 24px; padding: 0; border: 1px solid var(--border-strong); border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center; background: var(--surface); box-shadow: 0 1px 4px rgba(0, 0, 0, .3);
  font-size: 13px; line-height: 1; cursor: pointer; opacity: 0; pointer-events: none; transition: opacity .12s; user-select: none;
}
.msg-row.in .react-btn { right: -17px; }
.msg-row.out .react-btn { left: -17px; }
.msg-row:hover .react-btn, .react-btn.open, .react-btn:focus-visible { opacity: 1; pointer-events: auto; }

/* Сообщения подряд с одной стороны: углы, где они смыкаются, маленькие (верхний — у всех, кроме
   первого); у последнего вместо нижнего угла «хвостик» — со стороны отправителя, как в Telegram */
.msg-row.in:not(.first-in-group) .msg { border-top-left-radius: 4px; }
.msg-row.out:not(.first-in-group) .msg { border-top-right-radius: 4px; }
.msg-row.in.last-in-group .msg { border-bottom-left-radius: 0; }
.msg-row.out.last-in-group .msg { border-bottom-right-radius: 0; }
.msg-row.last-in-group .msg::before {
  content: ""; position: absolute; bottom: 0; width: 9px; height: 17px; background: inherit;
  -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='17'%3E%3Cpath d='M9 0C9 8 6.6 13.6 0 17h9z'/%3E%3C/svg%3E") no-repeat;
  mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='9' height='17'%3E%3Cpath d='M9 0C9 8 6.6 13.6 0 17h9z'/%3E%3C/svg%3E") no-repeat;
}
.msg-row.in.last-in-group .msg::before { left: -8px; }
.msg-row.out.last-in-group .msg::before { right: -8px; transform: scaleX(-1); }

.msg-media img { cursor: zoom-in; }
.msg-media img.sticker { cursor: default; }

/* Просмотр фото поверх переписки, как в Telegram Desktop */
.viewer { position: fixed; inset: 0; z-index: 45; display: flex; flex-direction: column; background: rgba(0, 0, 0, .95); animation: viewer-in .12s ease-out; }
@keyframes viewer-in { from { opacity: 0; } to { opacity: 1; } }
.viewer-bar { display: flex; align-items: center; gap: 8px; padding: 10px 16px; color: #fff; }
.viewer-who { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; line-height: 1.3; }
.viewer-who strong { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.viewer-who span { font-size: 13px; color: rgba(255, 255, 255, .6); }
.viewer-count { margin-right: 8px; font-size: 14px; color: rgba(255, 255, 255, .7); }
.viewer-btn { width: 40px; height: 40px; border: 0; border-radius: 50%; display: inline-flex; align-items: center; justify-content: center; background: transparent; color: rgba(255, 255, 255, .8); cursor: pointer; }
.viewer-btn:hover { background: rgba(255, 255, 255, .1); color: #fff; }
.viewer-stage { flex: 1 1 auto; min-height: 0; display: flex; align-items: center; justify-content: center; padding: 0 72px 24px; overflow: hidden; }
.viewer-stage.zoomed { display: block; overflow: auto; padding: 0; text-align: center; }
.viewer-img { max-width: 100%; max-height: 100%; object-fit: contain; border-radius: 4px; cursor: zoom-in; user-select: none; }
.viewer-img.zoomed { max-width: none; max-height: none; cursor: zoom-out; }
.viewer-nav { position: absolute; top: 50%; width: 56px; height: 56px; margin-top: -28px; border: 0; border-radius: 50%; display: flex; align-items: center; justify-content: center; background: rgba(255, 255, 255, .08); color: #fff; cursor: pointer; }
.viewer-nav:hover { background: rgba(255, 255, 255, .18); }
.viewer-nav.prev { left: 12px; }
.viewer-nav.next { right: 12px; }
.viewer-nav.hidden { display: none; }
@media (max-width: 560px) {
  .viewer-stage { padding: 0 0 16px; }
  .viewer-nav { width: 44px; height: 44px; margin-top: -22px; }
}

@media (max-width: 900px) {
  main { padding: 16px 12px 40px; }
  .tpl { grid-template-columns: 1fr; }
  /* minmax(0, …): широкое содержимое карточки не раздвигает страницу. */
  .form-grid.two { grid-template-columns: 1fr; }
  /* На телефоне — как в Telegram: список или переписка на весь экран, с кнопкой «назад». */
  .inbox { grid-template-columns: minmax(0, 1fr); }
  /* Как в Telegram на телефоне: переписка — во весь экран под шапкой, без полей страницы и
     заголовка (название раздела уже в шапке). */
  .page-head:has(+ .inbox) { display: none; }
  /* Только у показанного инбокса: тот, что собирается невидимым (.page-next), снимал бы поля
     у прежней страницы, пока грузится, — её заголовок прилипал к краю экрана. */
  main:has(.inbox:not(.page-next .inbox)), .page-next:has(.inbox) { padding: 0; }
  .inbox { border-width: 0; border-radius: 0; }
  .inbox.has-current .inbox-side { display: none; }
  .inbox:not(.has-current) .chat { display: none; }
  .inbox-side { border-right: 0; min-width: 0; }
  .msg, .msg-note { max-width: 86%; }
  .chat-head .pill, .composer-note:not(.queue-nav) { display: none; }
}
@media (max-width: 640px) {
  main { padding: 12px 12px 16px; }
  /* Переписка на телефоне — как в мобильном Telegram: имени собеседника — вся ширина, кнопки
     шапки — значками, поля у шапки, плашек, ленты и поля ввода уже. */
  .chat-head { gap: 8px; padding: 6px 8px 6px 4px; min-height: 52px; }
  /* Подпись — одной строкой: шапка всегда в две строки, вровень с аватаром и кнопками. */
  .chat-head .title .muted { white-space: nowrap; text-overflow: ellipsis; }
  .head-act { width: var(--h-control-sm); padding: 0; }
  /* Значок без подписи — по центру кнопки, без сдвига значков рядом с текстом. */
  .btn.head-act > svg { display: inline; top: 0; }
  .head-act .lbl { display: none; }
  .chat-alert { padding: 8px 12px; }
  .edit-bar { padding: 8px 12px 0; }
  .messages { padding: 12px 10px; }
  .composer { gap: 4px; padding: 8px; }
}
/* Карточка клиента не видна сама (≤1180) — открывается и нажатием на имя, как в Telegram. */
@media (max-width: 1180px) {
  .chat-head .card-tap { cursor: pointer; }
}
@media (prefers-reduced-motion: reduce) {
  * { transition: none !important; animation: none !important; }
  html.boot body { animation: boot-fallback 0s 10s forwards !important; }
}

/* Переписка в окне карточки: сообщения по времени. */
.hist-item { padding: 8px 12px; border-radius: var(--r-control); background: var(--surface-2); }
.hist-item.msg.in { background: var(--bubble-in); border: 1px solid var(--border); }
.hist-item.msg.out { background: var(--bubble-out); }
.hist-text { margin-top: 4px; white-space: pre-wrap; overflow-wrap: anywhere; }
.hist-text.deleted { color: var(--text-3); text-decoration: line-through; }

/* ---------- CRM: карточка кандидата ---------- */
.inbox.with-crm { position: relative; grid-template-columns: 340px minmax(0, 1fr) 320px; }
.inbox-filters { display: grid; grid-template-columns: 1fr; gap: 8px; }
.crm-side { display: flex; flex-direction: column; min-height: 0; overflow-y: auto; background: var(--surface); border-left: 1px solid var(--border); }
.crm-side-head { display: flex; align-items: center; gap: 8px; min-height: 58px; padding: 8px 12px 8px 16px; border-bottom: 1px solid var(--border); }
.crm-side-head h2 { flex: 1 1 auto; font-size: 15px; }
.crm-side-head .btn, .crm-toggle { display: none; }
.crm-empty { margin: auto; padding: 24px; color: var(--text-3); font-size: 13px; text-align: center; }
.cand { display: flex; flex-direction: column; }
.cand-head { display: flex; flex-direction: column; gap: 8px; padding: 12px 16px; border-bottom: 1px solid var(--border); }
.cand-head-top { display: flex; align-items: flex-start; gap: 8px; min-width: 0; }
.cand-head-top .grow { min-width: 0; }
.cand-head strong { display: block; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
/* DWH: главное о человеке метками (бот, «написал сам», «Спецусловия», проблема) и строка автоматики. */
.facts { display: flex; flex-wrap: wrap; gap: 6px; }
.fact {
  display: inline-flex; align-items: center; height: 22px; padding: 0 8px; border-radius: 11px;
  background: var(--surface-3); color: var(--text); font-size: 12px; font-weight: 500; white-space: nowrap;
}
.fact.ok { background: var(--ok-bg); color: var(--ok); }
.fact.bad { background: var(--bad-bg); color: var(--bad); }
.fact.info { background: var(--accent-soft); color: var(--accent); }
/* «Спецусловия» — своя плашка вместо строки автоматики: клиент на особых условиях, защита не снимается здесь. */
.cand-label-note { color: var(--text-3); font-weight: 400; }
.cand-sec { display: flex; flex-direction: column; gap: 8px; padding: 12px 16px; border-bottom: 1px solid var(--border); }
.cand-sec:last-child { border-bottom: 0; }
.cand-label { color: var(--text-2); font-size: 12px; font-weight: 600; }
.cand textarea { min-height: 72px; }
.cand .row.nowrap { flex-wrap: nowrap; }
.cand .form-actions { justify-content: flex-end; }
.modal .cand { margin: -4px -20px -20px; }
.modal .cand-head, .modal .cand-sec { padding-left: 20px; padding-right: 20px; }
.modal .cand details.help { margin-left: 20px; margin-right: 20px; }
.day-btn { flex: 1 1 auto; justify-content: flex-start; }
.day-btn > span { flex: 1 1 auto; text-align: left; }
.day-btn.overdue { border-color: rgba(240, 114, 114, .6); }
.tag {
  display: inline-flex; align-items: center; gap: 2px; height: 24px; padding: 0 9px; border-radius: 12px;
  background: var(--surface-3); color: var(--text); font-size: 12px; font-weight: 500; white-space: nowrap;
}
.tag:has(.tag-x) { padding-right: 3px; }
/* На карточке (surface-2) чип темнее не бывает: светлее фон и основной цвет текста — иначе тег сливается. */
.tag.sm { height: 20px; gap: 5px; padding: 0 7px; background: var(--surface-3); color: var(--text); font-size: 11.5px; }
.notes { display: flex; flex-direction: column; gap: 8px; }
/* Поле с кнопкой — один блок, список заметок — другой: между ними 24px (решение владельца
   2026-10-25 — 16px мало, кнопка всё ещё липла к заметкам). */
.note-form { display: flex; flex-direction: column; gap: 8px; }
.cand-sec > .note-form + .notes { margin-top: 16px; }
.note { position: relative; padding: 8px 10px; border-radius: var(--r-control); background: var(--surface-2); }
.note-meta { padding-right: 24px; color: var(--text-2); font-size: 12px; }
.note-text { margin-top: 2px; white-space: pre-wrap; overflow-wrap: anywhere; }
.note-text .form-actions { margin-top: 6px; }
.note-more { position: absolute; top: 4px; right: 4px; width: 24px; height: 24px; }
.note:hover .note-more { opacity: 1; }
dl.origin { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: 4px 12px; margin: 0; font-size: 13px; }
dl.origin dt { color: var(--text-2); }
dl.origin dd { margin: 0; overflow-wrap: anywhere; }
dl.notify-facts { font-size: 14px; gap: 6px 16px; }
.notify-link { padding: 12px 14px; border-radius: var(--r-control); background: var(--surface-2); }
.notify-link ol { margin: 0; padding-left: 20px; line-height: 1.5; }
.notify-link li + li { margin-top: 12px; }
.notify-link li .row, .notify-link .cmd-line { margin-top: 8px; }
.notify-link p { margin: 12px 0 0; }
.cmd-line { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.cmd { font-family: ui-monospace, Consolas, monospace; font-size: 13px; padding: 4px 8px; border-radius: 4px; background: var(--surface-3); overflow-wrap: anywhere; user-select: all; }
.cand details.help { margin: 12px 16px 16px; }
.stage-history { margin: 0; padding: 0 14px 12px 32px; font-size: 13px; color: var(--text-2); }
.stage-history li + li { margin-top: 4px; }
/* Колонки не шире окна: длинная причина переносится в кнопке, а не раздвигает окно вбок. */
.hist-item.crm { background: var(--accent-soft); }

/* Быстрые ответы над полем ввода. */
.composer .quick { width: 40px; height: 40px; border-radius: 50%; }
.qr-menu { width: 380px; max-width: calc(100vw - 16px); display: flex; flex-direction: column; gap: 6px; padding: 8px; }
.qr-list { display: flex; flex-direction: column; gap: 2px; max-height: 320px; overflow-y: auto; }
.menu .qr-list button { flex-direction: column; align-items: flex-start; gap: 2px; height: auto; padding: 8px 10px; }
.qr-list button span {
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden;
  color: var(--text-2); font-size: 12px; line-height: 1.4; white-space: normal;
}
.qr-empty { padding: 8px 10px; color: var(--text-2); font-size: 13px; }
.qr-body { display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; max-width: 760px; white-space: pre-wrap; }

/* ---------- CRM: доска ---------- */
.card.filters { margin-bottom: 16px; }
/* Между блоками страницы — 16px. В колонке и сетке промежуток задаёт gap, поэтому свои отступы
   блоков (.card + .card, .card.filters…) там обнулены: иначе они складываются в 32px. */
:is(.stack, .stack-md, .stack-sm, .grid) > :is(.card, .notice, .cards) { margin-top: 0; margin-bottom: 0; }
/* Длинный список (listCard в app.js, по образцу «Все клиенты»): карточка на высоту окна —
   фильтры, группы и шапка таблицы на месте, прокручиваются строки. */
.list-card { display: flex; flex-direction: column; min-height: 0; overflow: hidden; }
/* Сжимается только список: шапка в две строки, фильтры и счётчик — в полный рост (иначе
   max-height карточки срезал вторую строку шапки). */
.list-card > :not(.list-scroll, .card-body), .list-card > .card-body > :not(.list-scroll) { flex: none; }
/* card(..., { fit: true }): тело — колонкой, список в нём (.list-scroll) забирает остаток высоты. */
.list-card > .card-body { display: flex; flex-direction: column; flex: 1 1 auto; min-height: 0; }
/* Прокрутка — у .list-scroll в обе стороны: своя прокрутка обёртки таблицы сломала бы закреплённую шапку. */
.list-scroll .table-wrap { overflow: visible; }
/* Редкие фильтры (listCard more): за кнопкой «Ещё фильтры», своим рядом ровных колонок. */
.more-filters { display: none; flex: 1 1 100%; grid-template-columns: repeat(6, minmax(0, 1fr)); gap: 8px; }
.toolbar.list-filters.open > .more-filters { display: grid; }
.toolbar.list-filters.one-row .more-filters select { width: 100%; min-width: 0; }
/* Действия с отмеченными встают на место групп и счётчика: таблица под ними не сдвигается. */
.list-bar { display: grid; grid-template-columns: minmax(0, 1fr); border-bottom: 1px solid var(--border); }
.list-bar > * { grid-area: 1 / 1; }
.list-bar-main { display: flex; align-items: center; gap: 12px; min-height: 56px; padding: 8px 20px; }
/* Групп много, а экран узкий: группы листаются вбок, счётчик остаётся на виду. */
.list-bar-main > * { min-width: 0; }
.list-bar-main > .list-count { flex: none; }
.list-bar .selection-bar, .list-bar > .toolbar { border-bottom: 0; }
.list-bar:has(> .selection-bar:not(.hidden)) > :is(.list-bar-main, .toolbar) { visibility: hidden; }
/* Фильтры строкой: поиск забирает остаток, у списков одна ширина; без групп справа — счётчик. */
.toolbar.list-filters.one-row .search { flex: 1 1 260px; }
.toolbar.list-filters.one-row select { flex: 0 0 220px; width: 220px; }
/* На компьютере строка listCard не переносится: тесно — сужаются списки, поле поиска остаётся такой
   ширины, чтобы подсказка в нём была видна целиком. */
@media (min-width: 1181px) {
  .toolbar.list-filters.in-line { flex-wrap: nowrap; }
  .toolbar.list-filters.in-line > .search { flex: 1 0 280px; }
  .toolbar.list-filters.in-line > select { flex: 0 1 220px; min-width: 150px; }
  /* Ряд редких фильтров — своей строкой, поэтому перенос нужен; ширина списков — с запасом под кнопку. */
  .toolbar.list-filters.in-line.has-more { flex-wrap: wrap; }
  .toolbar.list-filters.in-line.has-more > select { flex: 0 1 200px; }
}
/* Планшет и узкое окно: поиск — отдельной строкой, под ним списки делят ширину поровну. */
@media (min-width: 641px) and (max-width: 1180px) {
  :is(.toolbar.list-filters.has-more, .board-filters .toolbar.list-filters) > .search { flex: 1 1 100%; }
  :is(.toolbar.list-filters.has-more, .board-filters .toolbar.list-filters) > select { flex: 1 1 140px; width: auto; min-width: 0; }
  .more-filters { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}
/* Ширина счётчика постоянная, текст — вправо: «Всего 10 446» и «Найдено 1 из 10 446» разной длины,
   и без этого поле поиска сжималось и растягивалось с каждым фильтром. */
.toolbar.list-filters.one-row .list-count { flex: 0 0 200px; margin-left: auto; text-align: right; }
/* Ширины колонок заданы (colWidths): со сменой строк колонки не прыгают; длинное — переносится. */
table.fixed { table-layout: fixed; }
/* Планшет: заголовок, который не влез в колонку, — по словам, а не поверх соседнего. Таблица шире
   экрана (colWidths minWidth): колонки не сжимаются уже чисел — листается вбок в своей карточке;
   первая колонка (sticky-first) с именем строки остаётся на месте. На компьютере шире 1180 не
   меняется ничего, на телефоне строки — карточками. */
@media (max-width: 1180px) {
  table.fixed th { white-space: normal; overflow-wrap: normal; }
  /* Стрелка сортировки стоит в поле ячейки и места в строке не занимает: из-за неё заголовок
     не уходит на вторую строку, а стрелка — от слова (как у CRM «Все»). */
  table.fixed th .sort-mark { margin-right: -16px; }
  table.fixed th.qty .sort-mark { margin: 0 4px 0 -16px; }
  table.min-w { min-width: var(--min-w); }
}
@media (min-width: 641px) and (max-width: 1180px) {
  table.sticky-first > * > tr > :first-child { position: sticky; left: 0; z-index: 1; background-color: var(--surface); }
  table.sticky-first > tbody > tr:hover > td:first-child { background-image: linear-gradient(rgba(255, 255, 255, .015), rgba(255, 255, 255, .015)); }
  table.sticky-first > tbody > tr.clickable:hover > td:first-child { background: var(--surface-2); }
}
/* Список в окне (listCard fit: false): прокручивается вместе с окном, как любое его содержимое;
   шапка таблицы прилипает к верху окна. Окно не уменьшается со сменой группы (modal steady). */
.list-card.in-modal, .list-card.in-modal .list-scroll { overflow: visible; }
.modal-body .list-card.in-modal thead th { top: -20px; }
/* Список на странице без рамки (listCard fit: "page"): идёт вниз со страницей, как таблицы «Отчётов». */
.list-card.flow { overflow: visible; }
.list-card.flow .list-scroll { flex: none; overflow-x: auto; overflow-y: visible; scrollbar-gutter: auto; }
.list-card.flow .list-scroll thead th { position: static; }
/* Вкладки в окне — над содержимым с тем же промежутком, что между блоками (gap колонки). */
.modal .stack > .tabs { margin-bottom: 0; }
/* Таблица на вкладке окна: шапка прилипает к верху окна (с учётом его отступа). */
.modal-pane thead th { position: sticky; top: -20px; z-index: 2; background: var(--surface); border-bottom: 0; box-shadow: inset 0 -1px 0 var(--border); }
table.fixed td { overflow-wrap: anywhere; }
/* Размер — как у кнопок и групп рядом: при разном размере буквы стоят на разной высоте, хотя рамки ровные. */
.list-count { color: var(--text-2); font-size: 14px; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Место под полосу прокрутки — всегда: в короткой группе её нет, и без него таблица становится
   шире, а колонки (в процентах) сдвигаются. */
.list-scroll { flex: 1 1 auto; min-height: 0; overflow: auto; scrollbar-gutter: stable; }
/* Черта под шапкой — тенью: рамка ячейки при border-collapse уезжает вместе со строками. */
.list-scroll thead th { position: sticky; top: 0; z-index: 2; background: var(--surface); border-bottom: 0; box-shadow: inset 0 -1px 0 var(--border); }
/* Последний открытый из обхода списка — на миг подсвечен, когда вернулись к списку. */
@keyframes row-flash { from { background-color: var(--accent-soft); } to { background-color: transparent; } }
/* Распорки на месте строк вне экрана (virtualRows): высоту ставит скрипт. */
table tbody tr.v-gap { height: auto; }
table tbody tr.v-gap td { padding: 0; border: 0; background: none; }

/* Над доской — фильтры в виде списка «Все» (listCard): поиск и списки, под ними группы, справа
   «Сбросить» и «Этапы». Под группами черты нет: под ней не таблица, а сама доска. */
.board-filters { margin-bottom: 16px; }
.board-filters .list-bar { border-bottom: 0; }

/* Без нижнего отступа: низ колонок — на одной линии с низом списка «Все» и инбокса. */
.board { display: flex; gap: 12px; align-items: stretch; overflow-x: auto; min-height: 360px; }
.kcol {
  /* min-width: 0 — иначе длинное имя на карточке растягивает колонку вместо многоточия. */
  flex: 0 0 272px; display: flex; flex-direction: column; min-width: 0; min-height: 0;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-card);
  transition: border-color .12s, background-color .12s, opacity .12s;
}
.kcol.drop { border-color: var(--accent); background: #1A2836; }
.kcol.dragging { opacity: .45; }
.kcol.drop-before { box-shadow: -3px 0 0 var(--accent); }
.kcol.drop-after { box-shadow: 3px 0 0 var(--accent); }
.kcol-head { display: flex; align-items: center; gap: 6px; min-height: 48px; padding: 8px 8px 8px 14px; border-bottom: 1px solid var(--border); font-weight: 600; }
.kcol-head[draggable="true"] { cursor: grab; }
.kcol-title { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kcol-entry { padding: 0 6px; border-radius: 5px; background: var(--accent-soft); color: var(--accent); font-size: 11px; font-weight: 500; line-height: 18px; }
.kcol-more { width: 26px; height: 26px; }
.kcol-head:hover .kcol-more, .kcol-more.open, .kcol-more:focus-visible { opacity: 1; }
.kcol-head .inline-edit { flex: 1 1 auto; height: 30px; font-weight: 600; }
.kcol-body { display: flex; flex-direction: column; gap: 8px; flex: 1 1 auto; min-height: 0; padding: 8px; overflow-y: auto; }
/* Сколько карточек этапа ещё не догружено: догружаются при прокрутке колонки. */
.kcol-rest { padding: 6px 4px 2px; text-align: center; }
.kcol-rest:empty { display: none; }
.kcol-empty { padding: 14px 8px; border: 1px dashed var(--border); border-radius: var(--r-control); color: var(--text-3); font-size: 12px; text-align: center; }
.kcol-new { border-style: dashed; border-color: var(--accent); }
.kcol-new .kcol-head input { height: 32px; }
.kcol-new .kcol-body p { margin: 4px 6px; }
.kcol-add {
  flex: 0 0 160px; display: flex; align-items: center; justify-content: center; gap: 6px; align-self: flex-start; height: 48px;
  border: 1px dashed var(--border-strong); border-radius: var(--r-card); background: none; color: var(--text-3); font: inherit; font-weight: 500; cursor: pointer;
}
.kcol-add:hover { border-color: var(--accent); color: var(--text); }

/* Карточка: кто — откуда — теги; внизу следующий шаг и сколько дней на этапе. */
.kcard {
  display: flex; flex-direction: column; gap: 8px; padding: 10px 10px 10px 12px; cursor: grab;
  background: var(--surface-2); border: 1px solid var(--border-strong); border-radius: 10px;
}
.kcard:hover { border-color: #41586F; }
.kcard:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.kcard.dragging { opacity: .4; }
/* Вернулись на доску из очереди — карточка последнего открытого на миг обведена, как найденное сообщение. */
.kcard.flash { animation: msg-flash 1.2s ease-out; }
.kcard-top { display: flex; align-items: center; gap: 8px; min-width: 0; }
.kcard-top strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kcard-more { width: 24px; height: 24px; }
.kcard:hover .kcard-more, .kcard:focus-within .kcard-more { opacity: 1; }
.unread-dot { flex: 0 0 auto; width: 8px; height: 8px; border-radius: 50%; background: var(--accent); }
.kcard-meta { margin-top: -4px; overflow: hidden; color: var(--text-3); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
.kcard-foot { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-width: 0; padding-top: 8px; border-top: 1px solid var(--border); }
.kcard-foot:not(:has(.pill, .kcard-age)) { display: none; }
.kcard-foot .pill { flex: none; white-space: nowrap; line-height: 22px; }
.kcard-age { margin-left: auto; color: var(--text-3); font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }
/* Buying Support: текст тикета или ответа на опрос — до трёх строк, целиком — в окне карточки. */
.kcard-text {
  display: -webkit-box; margin-top: -4px; overflow: hidden; color: var(--text-2); font-size: 13px; line-height: 18px;
  overflow-wrap: anywhere; -webkit-line-clamp: 3; -webkit-box-orient: vertical;
}
/* Окно карточки доски: вопрос автору и ответ — блоком, автор — ссылкой на чат. */
.card-author { font-weight: 600; text-align: left; }
.card-text { margin-top: 0; }
/* «Разделить» в окне карточки фидбека: строки с галочками, под ними кнопка и подсказка. */
/* Карточка — разговор с человеком, в ней 1..N тикетов (вариант A, 12.11.2026). На доске тикеты —
   метками с точкой итога; в окне — две колонки: переписка и тикеты, на планшете и телефоне — одна. */
.dot { flex: none; width: 8px; height: 8px; border-radius: 50%; background: var(--text-3); }
.dot.ok { background: var(--ok); }
.dot.bad { background: var(--bad); }
.dot.info { background: var(--accent); }
.tk-chips { display: flex; flex-wrap: wrap; gap: 4px; margin-top: -4px; min-width: 0; }
.tk-chip { display: inline-flex; align-items: center; gap: 6px; height: 22px; padding: 0 8px; border-radius: 6px; background: var(--surface-3); color: var(--text-2); font-size: 12px; font-variant-numeric: tabular-nums; white-space: nowrap; }
.tk-chip b { color: var(--text); font-weight: 600; }
.card-cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.15fr); border-bottom: 1px solid var(--border); }
.card-cols > .cand-sec { border-bottom: 0; }
.card-cols > .cand-sec + .cand-sec { border-left: 1px solid var(--border); }
.card-chat { display: flex; flex-direction: column; gap: 8px; min-width: 0; }
.card-chat [data-pick], .card-piece { user-select: text; cursor: text; }
.card-piece { padding: 10px 12px; border-radius: var(--r-control); background: var(--surface-2); }
.tk { display: flex; flex-direction: column; gap: 8px; min-width: 0; padding: 12px; border: 1px solid var(--border); border-radius: var(--r-card); background: var(--surface); }
.tk.done { background: var(--surface-2); }
/* Окно открыли из списка итога — тикет, по которому нажали, обведён. */
.tk.hl { border-color: var(--accent); }
/* Строка списка итога — тикет (на доске тикетов итог — тикеты, а не карточки). */
.tk-row { cursor: pointer; }
.tk-row .kcard-top .num { flex: none; }
.tk-row-dept { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tk-row-note { margin-top: -4px; padding-left: 8px; border-left: 2px solid var(--accent); color: var(--text-2); font-size: 13px; line-height: 18px; overflow-wrap: anywhere; }
.tk-row-by { min-width: 0; overflow: hidden; color: var(--text-3); font-size: 12px; text-overflow: ellipsis; white-space: nowrap; }
.tk-head { display: flex; align-items: center; gap: 8px; min-width: 0; }
.tk-head .grow { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tk-more { flex: none; width: 24px; height: 24px; opacity: 1; }
.tk-desc { overflow-wrap: anywhere; white-space: pre-wrap; }
.tk-note { display: flex; align-items: flex-start; gap: 8px; padding: 6px 6px 6px 10px; border-left: 2px solid var(--accent); border-radius: 0 var(--r-control) var(--r-control) 0; background: var(--accent-soft); font-size: 13px; overflow-wrap: anywhere; }
.tk-note .grow { min-width: 0; }
.note-del { flex: none; width: 24px; height: 24px; opacity: 1; }
.seg-out { display: inline-flex; align-self: flex-start; max-width: 100%; overflow-x: auto; border: 1px solid var(--border-strong); border-radius: var(--r-control); scrollbar-width: none; }
.seg-out::-webkit-scrollbar { display: none; }
.seg-out button { flex: none; height: var(--h-control-sm); padding: 0 12px; border: 0; background: var(--surface-2); color: var(--text-2); font: inherit; font-size: 14px; font-weight: 500; white-space: nowrap; cursor: pointer; }
.seg-out button + button { border-left: 1px solid var(--border-strong); }
.seg-out button:hover { color: var(--text); background: var(--surface-3); }
.seg-out button[aria-pressed="true"] { background: var(--accent-soft); color: var(--accent); }
.seg-out button.ok[aria-pressed="true"] { background: var(--ok-bg); color: var(--ok); }
.seg-out button.bad[aria-pressed="true"] { background: var(--bad-bg); color: var(--bad); }
.seg-out button.work[aria-pressed="true"] { background: var(--warn-bg); color: var(--warn); }
/* Выделили кусок ответа — под сообщением выбор, к какому тикету его прикрепить. */
.selpop { display: flex; flex-direction: column; gap: 2px; align-self: flex-start; min-width: 0; max-width: 100%; padding: 6px; border: 1px solid var(--border-strong); border-radius: 10px; background: var(--surface); box-shadow: var(--shadow); }
.selpop-head { padding: 2px 8px 4px; color: var(--text-3); font-size: 12px; }
.selpop-opt { display: flex; align-items: center; gap: 8px; min-width: 0; height: var(--h-control-sm); padding: 0 8px; border: 0; border-radius: 6px; background: none; color: var(--text); font: inherit; font-size: 14px; text-align: left; cursor: pointer; }
.selpop-opt:hover, .selpop-opt:focus-visible { background: var(--accent-soft); color: var(--accent); }
.selpop-note { min-width: 0; overflow: hidden; color: var(--text-2); text-overflow: ellipsis; white-space: nowrap; }
:is(.card-history, .card-others-done) > summary { cursor: pointer; list-style: none; }
:is(.card-history, .card-others-done) > summary::-webkit-details-marker { display: none; }
:is(.card-history, .card-others-done) > summary::before { content: "▸ "; color: var(--text-3); }
:is(.card-history, .card-others-done)[open] > summary::before { content: "▾ "; }
.card-others-done > summary { width: fit-content; color: var(--text-2); font-size: 13px; }
.card-others-done[open] > .card-others { margin-top: 8px; }
.card-history .stage-history { padding: 0; list-style: none; }
.card-foot-note { min-width: 0; margin-right: auto; align-self: center; }
@media (max-width: 900px) {
  .card-cols { grid-template-columns: minmax(0, 1fr); }
  .card-cols > .cand-sec + .cand-sec { border-left: 0; border-top: 1px solid var(--border); }
}
.survey-answer { overflow-wrap: anywhere; }
.survey-answer .link { text-align: left; }
.card-others { display: flex; flex-direction: column; gap: 8px; margin: 0; padding: 0; list-style: none; font-size: 13px; }
.card-others-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* Исходы — панель внизу экрана, пока карточка в руке. */
.outcome-bar {
  position: fixed; left: 50%; bottom: 20px; z-index: 20; display: flex; align-items: center; gap: 10px;
  padding: 10px; border: 1px solid var(--border-strong); border-radius: 14px; background: var(--surface); box-shadow: var(--shadow);
  transform: translate(-50%, 140%); opacity: 0; pointer-events: none; transition: transform .16s ease-out, opacity .16s;
}
.outcome-bar.show { transform: translate(-50%, 0); opacity: 1; pointer-events: auto; }
.outcome-hint { padding: 0 6px; color: var(--text-3); font-size: 13px; }
.outcome {
  display: flex; align-items: center; justify-content: space-between; gap: 16px; min-width: 150px; height: 56px; padding: 0 18px;
  border: 1.5px dashed var(--border-strong); border-radius: var(--r-card); color: var(--text-2); font-weight: 500;
  transition: border-color .12s, background-color .12s, color .12s;
}
.outcome b { color: var(--text-3); font-weight: 500; font-variant-numeric: tabular-nums; }
.outcome.drop { border-color: var(--accent); background: var(--accent-soft); color: var(--text); }
.outcome.ok.drop { border-color: var(--ok); background: var(--ok-bg); }
.outcome.bad.drop { border-color: var(--bad); background: var(--bad-bg); }

/* Правка на месте. */
.inline-edit { height: 28px; padding: 0 8px; font: inherit; }

/* Редактор этапов (панель «Этапы» и «Настройки → CRM»). */
.stage-editor { display: flex; flex-direction: column; gap: 24px; }
.se-head h3 { margin: 0; }
.se-head p { margin: 2px 0 0; }
.se-list { display: flex; flex-direction: column; margin-top: 8px; border: 1px solid var(--border); border-radius: var(--r-control); }
.se-row { display: flex; align-items: center; gap: 8px; min-height: 44px; padding: 4px 8px; border-bottom: 1px solid var(--border); }
.se-row:last-child { border-bottom: 0; }
.se-row.off .se-name { color: var(--text-3); }
.se-row.dragging { opacity: .4; }
.se-row.drop-before { box-shadow: inset 0 2px 0 var(--accent); }
.se-row.drop-after { box-shadow: inset 0 -2px 0 var(--accent); }
.se-name { padding: 2px 4px; border-radius: 4px; font-weight: 500; }
.se-name[title] { cursor: text; }
.se-name[title]:hover { background: var(--surface-3); }
.se-row .inline-edit { flex: 1 1 auto; }
.se-count { min-width: 22px; padding: 0 6px; border-radius: 6px; background: var(--surface-3); color: var(--text-2); font-size: 12px; line-height: 20px; text-align: center; font-variant-numeric: tabular-nums; }
.se-add { display: inline-flex; align-items: center; gap: 6px; margin-top: 8px; padding: 6px 4px; border: 0; background: none; color: var(--accent); font: inherit; font-size: 13px; font-weight: 500; cursor: pointer; }
.se-add:hover { text-decoration: underline; }
.se-add-form { display: flex; align-items: center; gap: 8px; margin-top: 8px; }
.se-add-form input { flex: 1 1 auto; height: var(--h-control-sm); }
.se-add-form select { width: auto; height: var(--h-control-sm); }

/* ---------- отчёт «Воронка» ---------- */
tr.total td { font-weight: 600; border-top: 1px solid var(--border-strong); }
tr.off td { color: var(--text-2); }

@media (max-width: 1180px) {
  .inbox.with-crm { grid-template-columns: 340px minmax(0, 1fr); }
  .inbox.with-crm .crm-side { display: none; }
  .inbox.with-crm.show-crm .crm-side {
    display: flex; position: absolute; top: 0; right: 0; bottom: 0; z-index: 6; width: min(360px, 100%);
    box-shadow: var(--shadow);
  }
  .crm-side-head .btn, .crm-toggle { display: inline-flex; }
}
@media (max-width: 900px) {
  .inbox.with-crm { grid-template-columns: minmax(0, 1fr); }
  /* Высота блока поиска — по содержимому: равнять её с колонкой папок незачем, колонки нет. */
  .inbox-tools { flex-basis: auto; padding: 10px 12px; }
  .kcol { flex-basis: 82vw; }
}

/* Телефон: переключатель направлений (если их несколько) помещается рядом с названием раздела. */
@media (max-width: 640px) {
  .brand img { height: 18px; }
  .ws-switch a { position: relative; padding: 0 8px; font-size: 12px; }
  /* Значок — в углу кнопки, как у «☰»: ширину у названия раздела не отнимает. */
  .ws-switch a .badge { position: absolute; top: -8px; right: -6px; z-index: 1; min-width: 16px; height: 16px; padding: 0 4px; font-size: 10px; box-shadow: 0 0 0 2px var(--surface); }
}

/* Архивный этап в истории: нынешнее название + пометка. */

/* DWH (проект 06): проблема покупателя в карточке, переключатель «не писать» у причины. */
.pill.toggle { border: 0; font: inherit; font-size: 12px; cursor: pointer; }
.pill.toggle.off { background: transparent; color: var(--text-3); }
.pill.toggle.off:hover { color: var(--text-2); background: var(--surface-3); }
/* Выключенный переключатель — только при наведении на строку или фокусе: иначе «не писать» у каждой
   причины читается как включённый. */
.se-row:not(:hover) .pill.toggle.off:not(:focus-visible) { opacity: 0; }

/* DWH (проект 06): страница «Бот» — таблица выгрузки в духе Google Sheets. */
.bad-text { color: var(--bad); }
.warn-text { color: var(--warn); }
.sheet { display: grid; grid-template-columns: minmax(0, 1fr); gap: 0; }
.sheet-wrap { overflow: auto; max-height: calc(var(--app-h) - 300px); min-height: 240px; outline: none; scrollbar-gutter: stable; }  /* точную высоту ставит fitSheets() */
.sheet-wrap:focus-visible { box-shadow: inset 0 0 0 2px var(--accent); }
/* Полосы — по номеру строки, а не по месту в разметке: там первой стоит распорка (virtualRows). */
.sheet + .muted, .sheet > .muted { padding: 8px 16px; }
/* DWH: карточка группы — участники и кто из них в нашей базе; «Прочитали». */
.group-about { white-space: pre-wrap; overflow-wrap: anywhere; color: var(--text-2); line-height: 1.45; }
.group-status { display: flex; align-items: center; gap: 8px; }
.members { display: flex; flex-direction: column; gap: 12px; }
.member, .reader { display: flex; align-items: flex-start; gap: 10px; min-width: 0; }
.reader { align-items: center; }
.member .grow, .reader .grow { min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.member-name { display: flex; align-items: center; gap: 6px; min-width: 0; }
.member-name strong, .reader strong { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.member-name .pill { flex: 0 0 auto; }
.member-ours { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; margin-top: 4px; }
.readers { display: flex; flex-direction: column; gap: 12px; }
/* DWH: шаги воронки в карточке и подпись автоматического сообщения в чате. */
.card-note { margin: 0; padding: 0 20px 14px; }
.card-note.after-table { padding-top: 12px; }
/* DWH: подзаголовок внутри таблицы («Порядок отправки» → рассылки). */
/* Переключатель «По условиям | По списку» внутри формы: отступ задаёт сетка. */
/* DWH: автор входящего в группе — над первым сообщением подряд. */
.msg-sender { margin-bottom: 2px; font-size: 13px; line-height: 18px; font-weight: 600; color: var(--accent); }
.msg-auto { align-self: flex-end; margin: 6px 0 2px; font-size: 12px; color: var(--text-3); }
/* DWH: в карточке два списка «подпись — значение» подряд («В боте», «Откуда») — общая ширина
   подписей, чтобы значения стояли одной колонкой. */
.cand dl.origin { grid-template-columns: 124px minmax(0, 1fr); }
/* Две карточки рядом (блоки панели «Бот», две базы проработки); на узком экране — друг под другом. */
.grid.two { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 16px; align-items: start; }
@media (max-width: 1100px) { .grid.two { grid-template-columns: minmax(0, 1fr); } }
.grid.two > .card { margin: 0; }
/* Переключатель внутри вкладки («Тексты и настройки | Очередь»). */
/* Своих внешних отступов нет (их задаёт тот, кто ставит переключатель), высота — как у полей
   (--h-control): в строке фильтров он стоит вровень с поиском и списками. */
.segmented { display: inline-flex; gap: 2px; margin: 0; padding: 3px; border: 1px solid var(--border); border-radius: var(--r-control); background: var(--surface); }
/* Толщина текста одна у выбранной и остальных, цифры одной ширины: кнопки не меняют ширину ни
   при переключении, ни когда меняются числа. */
.segmented button { height: calc(var(--h-control) - 8px); padding: 0 14px; border: 0; border-radius: 6px; background: none; color: var(--text-2); font: inherit; font-weight: 500; font-variant-numeric: tabular-nums; cursor: pointer; }
/* Календари (periodPicker, dayPicker): кнопка с датой и окошко у неё — у периода быстрый выбор
   слева и два месяца справа, у дня — один месяц. Кнопка показывает значение, как список рядом:
   толщина текста, отступ и наведение — как у поля, а не как у кнопки действия. */
.btn.period-btn { gap: 8px; padding: 0 12px; font-weight: 400; font-variant-numeric: tabular-nums; }
.btn.period-btn:hover { background: var(--surface-2); }
.period-btn svg { color: var(--text-2); }
.pp-pop { position: fixed; z-index: 60; display: flex; gap: 16px; padding: 12px; background: var(--surface); border: 1px solid var(--border-strong); border-radius: var(--r-card); box-shadow: 0 12px 32px rgba(0, 0, 0, .55); }
.pp-presets { display: flex; flex-direction: column; gap: 2px; min-width: 150px; padding-right: 12px; border-right: 1px solid var(--border); }
.pp-presets button { height: 34px; padding: 0 10px; border: 0; border-radius: 6px; background: none; color: var(--text-2); font: inherit; text-align: left; cursor: pointer; }
.pp-presets button:hover { background: var(--surface-2); color: var(--text); }
.pp-presets button.active { background: var(--surface-3); color: var(--text); font-weight: 500; }
/* Быстрый выбор дня: надпись слева, день недели и число справа. */
.dp-quick { min-width: 196px; }
.dp-quick button { display: flex; align-items: center; justify-content: space-between; gap: 12px; }
.dp-day { color: var(--text-3); font-variant-numeric: tabular-nums; }
.dp-quick button:hover .dp-day, .dp-quick button.active .dp-day { color: var(--text-2); }
.pp-cal { display: flex; flex-direction: column; gap: 8px; }
.pp-nav { display: flex; align-items: center; justify-content: space-between; gap: 8px; }
.pp-next svg { transform: rotate(180deg); }
.pp-hint { color: var(--text-3); font-size: 12px; }
.pp-months { display: flex; gap: 24px; }
.pp-month { display: grid; grid-template-columns: repeat(7, 34px); align-content: start; }
.pp-title { grid-column: 1 / -1; height: 28px; font-size: 13px; font-weight: 600; line-height: 28px; text-align: center; }
.pp-dow { height: 24px; color: var(--text-3); font-size: 11px; line-height: 24px; text-align: center; }
.pp-day { height: 32px; padding: 0; border: 0; background: none; color: var(--text); font: inherit; font-size: 13px; font-variant-numeric: tabular-nums; cursor: pointer; }
.pp-day:hover:not(:disabled) { background: var(--surface-3); border-radius: 6px; }
.pp-day.in { background: var(--accent-soft); border-radius: 0; }
.pp-day.edge { background: var(--accent-fill); color: #fff; border-radius: 6px; }
.pp-day.today:not(.edge) { box-shadow: inset 0 0 0 1px var(--border-strong); border-radius: 6px; }
.pp-day:disabled { color: var(--text-3); opacity: .45; cursor: default; }
.pp-day:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 6px; }
/* Телефон: окошко календаря — полосой снизу во всю ширину (место задаёт CSS, а не popover),
   быстрый выбор — строкой кнопок над одним месяцем. */
@media (max-width: 640px) {
  .pp-pop { top: auto !important; left: 0 !important; right: 0; bottom: 0; flex-direction: column; gap: 12px; max-height: var(--app-h); overflow-y: auto; padding: 16px 16px 20px; border-width: 1px 0 0; border-radius: var(--r-modal) var(--r-modal) 0 0; }
  .pp-presets { flex-direction: row; flex-wrap: wrap; gap: 6px; min-width: 0; padding: 0 0 12px; border-right: 0; border-bottom: 1px solid var(--border); }
  .pp-presets button { height: var(--h-control-sm); padding: 0 12px; border: 1px solid var(--border-strong); border-radius: 999px; }
  /* У дня с числом справа кнопки разной длины ложатся рваными рядами — списком, как на компьютере. */
  .dp-quick { flex-direction: column; gap: 2px; }
  .dp-quick button { height: 40px; padding: 0 10px; border: 0; border-radius: 6px; }
  .pp-months { justify-content: center; }
  .pp-month { grid-template-columns: repeat(7, minmax(0, 44px)); }
  .pp-day { height: 40px; }
}
/* В шапке карточки кнопки малые — и переключатель той же высоты. */
.card-head .segmented button { height: calc(var(--h-control-sm) - 8px); }
.segmented button:hover { color: var(--text); }
.segmented button.active { background: var(--surface-3); color: var(--text); }
/* Аккаунты: служебный и рассылка — две таблицы с одной сеткой колонок; узкий экран листает вбок. */
.accounts-table table { table-layout: fixed; width: 100%; min-width: 1000px; }
.accounts-table th:nth-child(1) { width: 16%; }
.accounts-table th:nth-child(2) { width: 17%; }
.accounts-table th:nth-child(3) { width: 21%; }
.accounts-table th:nth-child(4) { width: 16%; }
.accounts-table th:nth-child(5) { width: 15%; }
.accounts-table td { overflow-wrap: anywhere; }

/* DWH: цепочки («Рассылка → Цепочки»): три счётчика вместо четырёх. */
.tpl-stats.three { grid-template-columns: repeat(3, 1fr); }
/* Карточка цепочки: описание таблицей «Кому / Как часто / Когда», у каждого текста — заголовок с
   пояснением; между частями воздух, чтобы блоки не сливались. */
.chain-body { display: flex; flex-direction: column; gap: 18px; min-width: 0; }
.chain-body .tpl-title { margin-bottom: 0; }
.chain-facts { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 4px 16px; margin: 0; font-size: 13px; }
.chain-facts dt { color: var(--text-3); }
.chain-facts dd { margin: 0; color: var(--text-2); }
.chain-part { display: flex; flex-direction: column; gap: 8px; }
.chain-part-head { display: flex; flex-direction: column; gap: 2px; }
.chain-part-head strong { font-size: 13.5px; font-weight: 600; color: var(--text); }
.chain-part-head span { font-size: 12.5px; color: var(--text-3); }
textarea.fit { min-height: 96px; }

/* Без мыши наведения нет: кнопки «⋯», которые на компьютере появляются при наведении, видны
   всегда, выключенный «не писать» у причины — тоже (приглушённым). */
@media (hover: none) {
  .msg-more, .kcard-more, .kcol-more, .note-more { opacity: 1; }
  .se-row:not(:hover) .pill.toggle.off:not(:focus-visible) { opacity: 1; }
}

.notice.small { padding: 6px 10px; font-size: 13px; }

/* ---------- телефон: таблицы карточками (решение владельца 2026-10-25) ---------- */
/* Строка — карточка, ячейка — «подпись: значение» справа (подпись — data-label из шапки,
   labelCells в app.js). Первая ячейка — заголовок карточки, галочка — в правом верхнем углу,
   действия — строкой внизу. Ширины колонок и шапка не нужны; «Выбрать всех» — строкой сверху. */
.sort-pick { display: none; }
@media (max-width: 640px) {
  .table-wrap > select.sort-pick { display: block; width: auto; max-width: calc(100% - 40px); margin: 12px 20px; }
  table.card-rows { display: block; width: 100%; min-width: 0 !important; }
  table.card-rows > colgroup, table.card-rows > thead th:not(.check) { display: none; }
  table.card-rows > tbody, table.card-rows > tfoot { display: block; }
  table.card-rows > thead { display: block; }
  table.card-rows > thead > tr { display: block; }
  table.card-rows > thead th.check { display: flex; align-items: center; gap: 10px; width: auto; padding: 10px 20px; color: var(--text-2); font-size: 13px; }
  table.card-rows > thead th.check::after { content: "Выбрать всех"; }
  table.card-rows > thead:not(:has(th.check)) { display: none; }
  table.card-rows > tbody > tr, table.card-rows > tfoot > tr { position: relative; display: block; padding: 12px 20px; border-bottom: 1px solid var(--border); }
  table.card-rows > tbody > tr:last-child { border-bottom: 0; }
  table.card-rows > tfoot > tr { border-top: 1px solid var(--border-strong); }
  /* flow-root: подпись (float) не обтекает следующую ячейку. */
  table.card-rows td { display: flow-root; width: auto !important; padding: 2px 0; border: 0; text-align: right; overflow-wrap: anywhere; white-space: normal; }
  table.card-rows td[data-label]::before { content: attr(data-label); float: left; margin-right: 12px; color: var(--text-2); font-size: 13px; line-height: 21px; text-align: left; }
  table.card-rows td:empty:not([colspan]) { display: none; }
  /* Заголовок карточки — первая ячейка (после галочки): без подписи, слева, крупнее. */
  table.card-rows td:first-child:not(.check), table.card-rows td.check + td { padding: 0 40px 4px 0; text-align: left; font-weight: 600; }
  table.card-rows td:first-child:not(.check)::before, table.card-rows td.check + td::before { display: none; }
  table.card-rows td.check { position: absolute; top: 14px; right: 20px; padding: 0; }
  table.card-rows td.actions { padding-top: 8px; text-align: left; }
  table.card-rows td.actions .row { justify-content: flex-start; flex-wrap: wrap; }
  table.card-rows td .pills { justify-content: flex-end; }
  table.card-rows td .cell-sub { font-weight: 400; }
  /* Имя-ссылка в заголовке карточки — по ней открывают: пальцем попасть легко. */
  table.card-rows td .link { min-height: 32px; text-align: left; }
  /* День в журнале и подзаголовок группы — полосой во всю карточку, как были. */
  table.card-rows tr.feed-day { padding: 0; }
  table.card-rows tr.feed-day td:first-child { padding: 8px 20px; text-align: left; font-weight: 600; }
  /* Ручка порядка с номером — в правом верхнем углу, заголовок карточки — название рядом с ней. */
  table.card-rows td:has(> .order-cell) { position: absolute; top: 8px; right: 12px; padding: 0; }
  table.card-rows td:has(> .order-cell) + td { padding: 0 72px 4px 0; text-align: left; font-weight: 600; }
  table.card-rows td:has(> .order-cell) + td::before { display: none; }
  table.card-rows tr.v-gap { padding: 0; border: 0; }
}
/* CRM «Все клиенты» на телефоне: своя карточка постоянной высоты (--row-h, по ней считаются
   распорки virtualRows) — имя и время сообщения, этап и теги, следующий шаг, откуда. Подписи не
   нужны: плашки говорят сами за себя. */
@media (max-width: 640px) {
  /* Этап читается целиком, сжимается дата смены этапа рядом; тегов много — они не забирают всю строку. */
  .list-bar-main .sort-pick { display: block; width: auto; height: var(--h-control-sm); }
}

/* ---------- телефон: фильтры и группы списка (listCard) ---------- */
/* Переключатель групп не обрезается краем карточки, а листается вбок, как вкладки. */
.segmented { max-width: 100%; overflow-x: auto; scrollbar-width: none; }
.segmented::-webkit-scrollbar { display: none; }
.segmented button { flex: none; white-space: nowrap; }
/* Кнопка фильтров — в ряду списков и выглядит как они: тот же фон, обычный текст слева, стрелка справа
   (открыто — вверх); кнопкой действия с жирным текстом по центру она выпадала из ряда. */
.toolbar .filters-toggle {
  display: none; flex: none; justify-content: flex-start; padding: 0 34px 0 12px;
  border-color: var(--border-strong); color: var(--text); font-weight: 400;
  background-color: var(--surface-2); background-repeat: no-repeat; background-position: right 10px center; background-size: 16px 16px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 6l4 4 4-4' fill='none' stroke='%2393A4B5' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
.toolbar .filters-toggle:hover { border-color: #41586F; }
.toolbar .filters-toggle[aria-expanded="true"] {
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 16 16'%3E%3Cpath d='M4 10l4-4 4 4' fill='none' stroke='%2393A4B5' stroke-width='1.6' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
}
/* Ширина — под текст со значком числа: число не сдвигает соседние поля. */
.toolbar .filters-toggle.has-more { display: inline-flex; min-width: 176px; }
.filters-toggle :is(.on-wide, .on-phone) { display: inline-flex; align-items: center; gap: 8px; }
.filters-toggle .on-phone { display: none; }
/* Есть что сбрасывать — цветом ссылки: серый текст сливался со счётчиком рядом. Погашенная остаётся серой. */
.btn.reset-filters:not(:disabled) { color: var(--accent); }
.btn.reset-filters:not(:disabled):hover { background: var(--accent-soft); color: var(--accent); }
@media (max-width: 640px) {
  .toolbar.list-filters, .toolbar.list-filters.one-row { display: flex; flex-wrap: wrap; gap: 8px; }
  /* Поиск — во всю строку (подсказка видна целиком), под ним кнопка «Фильтры» и «Сбросить», списки — ещё ниже. */
  .toolbar.list-filters .search, .toolbar.list-filters.one-row .search { flex: 1 1 100%; min-width: 0; order: -2; }
  .toolbar.list-filters .filters-toggle { display: inline-flex; flex: 1 1 calc(100% - 110px); order: -1; }
  .toolbar.list-filters select, .toolbar.list-filters.one-row select { padding-right: 28px !important; background-position: right 8px center; }
  .toolbar.list-filters .filters-toggle { padding-right: 28px; background-position: right 8px center; }
  .filters-toggle .on-phone { display: inline-flex; }
  .filters-toggle .on-wide { display: none; }
  .toolbar.list-filters select, .toolbar.list-filters.one-row select { flex: 1 1 calc(50% - 4px); width: auto; min-width: 0; }
  .toolbar.list-filters.open > .more-filters { display: contents; }
  .toolbar.list-filters:has(> .filters-toggle):not(.open) > :not(.search, .btn, .list-count) { display: none; }
  .toolbar.list-filters .list-count, .toolbar.list-filters.one-row .list-count { flex: 1 1 100%; margin: 0; text-align: right; }
  .list-bar-main { flex-wrap: wrap; gap: 8px 12px; padding: 8px 20px; }
  .list-bar-main > * { min-width: 0; max-width: 100%; }
  .list-bar-main > .spacer { display: none; }
  .list-bar-main > .list-count { margin-left: auto; }
  /* «Этапы» на доске — справа, на месте счётчика списка «Все». */
  .board-filters .list-bar-main > .btn:last-child { margin-left: auto; }
}
/* Таблицы бота на телефоне — тоже карточками постоянной высоты (--sheet-card-h ставит app.js по
   числу показанных колонок): строка на колонку, «подпись — значение». Номер строки, шапка и
   выделение ячеек не нужны; подсказка про Ctrl+C — тоже. */
@media (max-width: 640px) {
  .toolbar > select.sort-pick { display: block; }
}
/* Сенсорный экран: кнопка-ссылка (имя в списке, «Выбрать всех») — по высоте пальца. */
@media (pointer: coarse) {
  button.link { display: inline-flex; align-items: center; min-height: 32px; }
  /* Число-ссылка в колонке чисел — 9px в ширину, пальцем не попасть; цифра — у правого края колонки. */
  td.qty button.link { min-width: 32px; justify-content: flex-end; }
}

/* ---------- инбокс на сенсорном экране и телефоне ---------- */
/* Меню сообщения не шире экрана; реакции в нём (сенсорный экран) — строкой, листается вбок. */
.menu { max-width: calc(100vw - 16px); }
.menu-reacts { display: flex; gap: 2px; padding: 2px 2px 6px; margin-bottom: 4px; border-bottom: 1px solid var(--border); overflow-x: auto; scrollbar-width: none; }
.menu-reacts::-webkit-scrollbar { display: none; }
.menu-reacts .react-opt { flex: none; width: 38px; height: 38px; font-size: 22px; }
.menu-reacts .react-opt:hover { transform: none; background: var(--surface-3); }
@media (hover: none) {
  /* Реакции — из меню долгого нажатия; сердечко по наведению пальцем не вызвать, а случайное
     касание ставило бы реакцию. Долгое нажатие не выделяет текст (копировать — пунктом меню). */
  .react-btn, .react-picker { display: none !important; }
  .msg { -webkit-user-select: none; user-select: none; -webkit-touch-callout: none; }
}
@media (max-width: 640px) {
  /* Карточка клиента — во весь экран поверх переписки, закрывается крестиком в шапке. */
  .inbox.with-crm.show-crm .crm-side { width: 100%; }
}
@media (pointer: coarse) {
  /* Крестик тега — по пальцу. */
  .tag:has(.tag-x) { padding-right: 0; }
}
/* Просмотр фото: горизонтальный жест — листание (app.js), приближение пальцами остаётся. */
.viewer-stage { touch-action: pan-y pinch-zoom; }
.viewer-stage.zoomed { touch-action: auto; }

/* ---------- CRM: доска на телефоне и сенсорном экране ---------- */
/* Колонка — почти во весь экран, доска листается по одной колонке. Исходы во время
   перетаскивания (мышью, на планшете) — не шире экрана. */
.outcome-bar { max-width: calc(100vw - 24px); flex-wrap: wrap; justify-content: center; }
@media (max-width: 640px) {
  .board { scroll-snap-type: x mandatory; scroll-padding: 0 12px; }
  .kcol { flex-basis: calc(100vw - 48px); scroll-snap-align: start; }
  .outcome { min-width: 0; flex: 1 1 120px; }
}
/* Ручка порядка: пальцем строку тянут за неё (makeReorderable), поэтому она по пальцу и не
   прокручивает страницу. */
@media (pointer: coarse) {
  .grip { width: 36px; height: 36px; touch-action: none; }
}
@media (pointer: coarse) {
  /* «⋯» карточки, колонки, заметки и тикета, «×» комментария тикета — по пальцу. */
  .kcard-more, .kcol-more, .tk-more, .note-del, .note-more { width: 36px; height: 36px; }
  .kcard-top { margin: -6px -6px -6px 0; }
  .tk-head { margin: -6px -6px -6px 0; }
  .tk-note { padding-top: 0; padding-bottom: 0; align-items: center; }
}
@media (max-width: 640px) {
  /* Действия с отмеченными — по строке на действие. */
  .selection-bar > div { flex: 1 1 100%; }
  .selection-bar > div > select { width: 100%; }
}
/* Редактор этапов на телефоне: длинное название и кнопки строки («Вернуть») переносятся, а не
   уходят за край; плашки-кнопки (тип исхода, «не писать») — по пальцу. */
@media (max-width: 640px) {
  /* Первая строка — ручка, название, число и действие; плашки (тип, «не писать», архив) —
     второй строкой под названием. */
  .se-row { flex-wrap: wrap; row-gap: 6px; padding: 6px 8px; }
  .se-row > .se-name { flex: 1 1 0; min-width: 0; overflow-wrap: anywhere; }
  .se-row > .spacer { display: none; }
  .se-row > .se-count { order: 2; }
  .se-row > .btn { order: 3; }
  .se-row:has(> .pill)::after { content: ""; flex-basis: 100%; order: 4; }
  .se-row > .pill { order: 5; }
  .se-row > .se-name + .pill { margin-left: 44px; }
}
@media (pointer: coarse) {
  .pill.toggle { height: 32px; padding: 0 10px; }
  .se-add { min-height: 36px; }
}

/* ---------- остальные страницы на телефоне ---------- */
@media (max-width: 1100px) {
  /* Часть подписи карточки, которая сама шире экрана, переносится и внутри себя. */
  .card-head .meta .seg { white-space: normal; }
}

/* ---------- низкое окно (ноутбук 1366×768, крупный масштаб браузера) ---------- */
/* Высота — переписке и спискам: поля страницы меньше, заголовка инбокса нет (раздел виден в
   меню), подсказка под полем ввода не нужна. */
@media (max-height: 700px) {
  main { padding-top: 16px; padding-bottom: 16px; }
  .page-head { margin-bottom: 12px; }
  .page-head:has(+ .inbox) { display: none; }
  .composer-note:not(.queue-nav) { display: none; }
}

/* ---------- маленький экран: списки прокручиваются со страницей ---------- */
/* Телефон, телефон горизонтально, крупный масштаб (то же условие — FLOW_LISTS в app.js): рамка
   на высоту окна там вмещала бы строку-две. Список — во всю длину, прокручивается страница
   (решение владельца 2026-10-26); вбок широкая таблица по-прежнему листается сама. */
@media (max-width: 640px), (max-height: 560px) {
  .list-card.fit-window { overflow: visible; }
  .list-card.fit-window .list-scroll { flex: none; overflow-x: auto; overflow-y: visible; }
  .list-card.fit-window .list-scroll thead th { position: static; }
  .sheet-wrap { max-height: none; min-height: 0; overflow-y: visible; }
}

/* ---------- разделы «Тикеты» и «Фидбек» (решения владельца 12.11.2026) ---------- */
.halves { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 16px; align-items: start; margin-top: 16px; }
.halves > .card { margin-top: 0; }

/* «Отчёты»: плитки сводки, полоска итогов, разрезы тикетов (макет, вариант A, 12.11.2026).
   Итоги одного вида везде: закрыто — зелёный, не решено — красный, ждут итога — серый. */
.rep-top { margin-top: 0; }
.rep-tiles { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); gap: 8px; }
.rep-tile { display: flex; flex-direction: column; gap: 2px; min-width: 0; padding: 12px 14px; border-radius: var(--r-control); background: var(--surface-2); }
.rep-tile .v { display: flex; align-items: baseline; gap: 6px; }
.rep-tile .v b { font-size: 22px; font-weight: 600; line-height: 28px; font-variant-numeric: tabular-nums; }
.rep-tile .v span { color: var(--text-2); font-size: 13px; font-weight: 500; font-variant-numeric: tabular-nums; }
.rep-tile .l { display: flex; align-items: center; gap: 6px; color: var(--text-2); font-size: 13px; }
.rep-tile .sw, .rep-legend .sw { flex: none; width: 10px; height: 10px; border-radius: 3px; }
.rep-meter, .rep-bar { display: flex; gap: 2px; height: 8px; overflow: hidden; border-radius: 4px; background: var(--surface-2); }
.rep-meter { margin-top: 12px; }
.rep-bar { width: 100%; }
.rep-ok { background: var(--ok); }
.rep-bad { background: var(--bad); }
.rep-wait { background: var(--wait-fill); }
.rep-other { background: var(--accent); }
.rep-meter > i, .rep-bar > i { display: block; height: 100%; flex: 1 1 0; }
.rep-note { margin: 12px 0 0; color: var(--text-3); font-size: 12.5px; }
.rep-pick { padding: 16px 20px 4px; }
.rep-legend { margin: 0; }
.rep-hi { color: var(--bad); }
.rep-total td { color: var(--text-2); font-weight: 500; }
@media (max-width: 640px) {
  .rep-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .rep-bar { width: 100%; }
}
/* Текст сообщения автоматики — по высоте текста (fitArea), без запаса textarea.fit. */
.auto-msg textarea.fit { min-height: 0; }
/* «Автоматика»: путь человека шагами; кружок с заливкой — пишет автоматика. */
.auto-flow-wrap { padding: 4px 20px 18px; border-bottom: 1px solid var(--border); }
.auto-flow { list-style: none; margin: 0; padding: 0; display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)); }
.auto-flow li { position: relative; display: flex; flex-direction: column; gap: 4px; padding-right: 16px; }
.auto-flow li::after { content: ""; position: absolute; top: 11px; left: 32px; right: 8px; height: 2px; background: var(--border-strong); }
.auto-flow li:last-child::after { display: none; }
.auto-flow-k { display: flex; align-items: center; gap: 8px; }
.auto-flow-k strong { position: relative; z-index: 1; padding-right: 8px; background: var(--surface); font-weight: 600; }
.auto-flow-n {
  position: relative; z-index: 1; flex: none; width: 24px; height: 24px; border-radius: 50%;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--accent-soft); color: var(--accent); font-size: 13px; font-weight: 600;
}
.auto-flow li.auto .auto-flow-n { background: var(--accent-fill); color: #fff; }
.auto-flow .sub { color: var(--text-2); font-size: 13px; }
.auto-msg:last-child { border-bottom: 0; }
.auto-stats { display: flex; flex-direction: column; gap: 6px; }
.auto-text { padding: 10px 12px; border-radius: var(--r-control); background: var(--surface-2); color: var(--text-2); white-space: pre-wrap; overflow-wrap: anywhere; }
.bad-text { color: var(--bad); }
/* Правая панель переписки: кто это. */
.person-head { flex-direction: row; align-items: center; gap: 12px; }
.person-head .grow { min-width: 0; }
.person-list { display: flex; flex-direction: column; gap: 6px; }
.person-item {
  display: flex; flex-direction: column; gap: 2px; width: 100%; padding: 8px 10px; border: 0; border-radius: var(--r-control);
  background: var(--surface-2); color: var(--text); font: inherit; text-align: left; cursor: pointer;
}
.person-item:hover { background: var(--surface-3); }
.person-item:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.person-line { display: flex; align-items: center; gap: 8px; min-width: 0; }
.person-line .grow { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.person-text { overflow-wrap: anywhere; }
/* «Сотрудники» (13.11.2026): список и справа та же панель «кто это», что в переписке; до 1180 она
   открывается окном сбоку. Выбранная строка — подсветкой акцента. */
.staff-split { display: grid; grid-template-columns: minmax(0, 1fr) 360px; gap: 16px; align-items: start; }
.staff-split > .card + .card { margin-top: 0; }
/* «Найдено 2 395 из 2 400» и «Всего 2 400» — одной ширины: «Сбросить» перед счётчиком не двигается. */
.staff-split .list-bar-main > .list-count { min-width: 180px; text-align: right; }
.staff-person { overflow-y: auto; }
tr.picked > td, tr.picked.clickable:hover > td { background: var(--accent-soft); }
@media (max-width: 1180px) {
  .staff-split { grid-template-columns: minmax(0, 1fr); }
  .staff-person { display: none; }
}
.group-tickets { display: flex; flex-wrap: wrap; gap: 4px 16px; color: var(--text-2); }
.group-tickets b { color: var(--text); font-variant-numeric: tabular-nums; }
@media (max-width: 1100px) {
  .halves { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 760px) {
  .auto-flow { grid-template-columns: minmax(0, 1fr); gap: 12px; }
  .auto-flow li::after { display: none; }
}
/* Переписки раздела на узком экране: заголовок и подвкладки — над списком, с полями страницы;
   открытый чат — во весь экран, без них (как прежний инбокс). */
@media (max-width: 900px) {
  .page-head:has(~ .inbox), .tabs:has(+ .inbox) { margin-left: 12px; margin-right: 12px; }
  .page-head:has(~ .inbox) { margin-top: 16px; }
  .tabs:has(+ .inbox) { margin-bottom: 0; }
  .page-head:has(~ .inbox.has-current), .tabs:has(+ .inbox.has-current) { display: none; }
}
/* Ответ на опрос несколькими сообщениями — по сообщению, как в переписке рядом. */
.card-parts { display: flex; flex-direction: column; gap: 8px; }
