/* СоцПульс AI — дизайн-система (чистый UI, без внешних зависимостей) */
:root {
  --bg: #f6f7f9;
  --surface: #ffffff;
  --surface-2: #f1f3f7;
  --border: #e3e6ec;
  --border-strong: #cdd2dc;
  --text: #1a1f2b;
  --text-2: #5a6473;
  --text-3: #8a93a3;
  --accent: #4f46e5;
  --accent-600: #4338ca;
  --accent-soft: #eef0fe;
  --green: #15803d;
  --green-soft: #e7f6ec;
  --amber: #b45309;
  --amber-soft: #fdf2e2;
  --red: #b91c1c;
  --red-soft: #fdecec;
  --blue: #1d4ed8;
  --blue-soft: #e8effe;
  --shadow: 0 1px 2px rgba(20,26,40,.04), 0 4px 16px rgba(20,26,40,.06);
  --shadow-lg: 0 10px 40px rgba(20,26,40,.16);
  --radius: 12px;
  --radius-sm: 8px;
  /* Полосы прокрутки: один вид на весь интерфейс — страница, модалки, таблицы,
     списки. Цвет ползунка держится в переменной, поэтому на тёмном фоне
     (сайдбар базовой темы) достаточно переопределить её на самом блоке. */
  /* Подсветка ссылки при наведении. Полупрозрачная нарочно: строчная ссылка
     встречается и на белой карточке, и на цветном чипе, и в подсказке факта —
     сплошной фон выпадал бы там пятном. */
  --link-hl: rgba(79, 70, 229, .12);
  --scroll-thumb: #c2c8d4;
  --scroll-thumb-hover: #9aa3b2;
  --scroll-size: 10px;
  --sidebar-w: 244px;
  --font: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "PT Sans", "Helvetica Neue", Arial, sans-serif;
  --mono: "SF Mono", "Cascadia Code", Consolas, "Liberation Mono", monospace;
}

* { box-sizing: border-box; }

/* ---------- Полосы прокрутки ----------
   Заказчик 16.09.2026: «в массиве жму — открывается модалка, и там есть
   горизонтальные и вертикальные прокрутки окна. Они не в стиле, и в других
   местах то же есть». Так и было: свой вид имели ровно четыре места (сайдбар,
   лента чата, список диалогов, поле ввода), а десятка полтора прокручиваемых
   блоков — таблица массива, боковая панель переменных, тело модалок, панели
   скоупа, реестр анкет, истории, поповеры — показывали системную полосу: в
   тёмной теме светлую и в полтора раза толще соседних.

   Поэтому правило ОДНО и на всё, включая саму страницу (`*` покрывает html,
   от которого Chrome берёт полосу документа): тонкая, без дорожки, ползунок в
   цвете границ с отступом от края (`border: 2px solid transparent` +
   `background-clip: padding-box` — так он выглядит тоньше желоба и не липнет к
   содержимому). Firefox/Safari получают тот же вид через `scrollbar-width` и
   `scrollbar-color`. */
* { scrollbar-width: thin; scrollbar-color: var(--scroll-thumb) transparent; }
*::-webkit-scrollbar { width: var(--scroll-size); height: var(--scroll-size); }
*::-webkit-scrollbar-track { background: transparent; }
*::-webkit-scrollbar-thumb {
  background: var(--scroll-thumb); border-radius: 999px;
  border: 2px solid transparent; background-clip: padding-box;
}
*::-webkit-scrollbar-thumb:hover { background: var(--scroll-thumb-hover);
  background-clip: padding-box; }
/* Угол между горизонтальной и вертикальной полосой: по умолчанию он серый и в
   тёмной теме светится белым квадратом в правом нижнем углу таблицы массива. */
*::-webkit-scrollbar-corner { background: transparent; }
/* Кнопки-стрелки на концах полосы. Windows-Chrome рисует их даже у
   стилизованной полосы, и в тёмной теме они светятся системными серыми
   треугольниками — в углу таблицы массива их видно первыми. `display: none`
   части полосы не слушаются (это не обычные элементы), поэтому убираем
   размером; варианты :start/:end перечислены явно — без них остаётся
   зарезервированное под кнопку место. */
*::-webkit-scrollbar-button,
*::-webkit-scrollbar-button:start,
*::-webkit-scrollbar-button:end,
*::-webkit-scrollbar-button:vertical:start:decrement,
*::-webkit-scrollbar-button:vertical:end:increment,
*::-webkit-scrollbar-button:horizontal:start:decrement,
*::-webkit-scrollbar-button:horizontal:end:increment {
  width: 0; height: 0; background: transparent; border: 0;
}
*::-webkit-scrollbar-track-piece { background: transparent; }

html, body { height: 100%; }
body {
  margin: 0; background: var(--bg); color: var(--text);
  font-family: var(--font); font-size: 14px; line-height: 1.5;
  -webkit-font-smoothing: antialiased;
}
/* ---------- Ссылки ----------
   Заказчик 16.09.2026: «убери подчерки в ссылках, это смотрится плохо, лучше
   подсветку сделать». Подчёркивание висело глобально на `a:hover`, а это
   правило (специфичность 0,1,1) перебивает `text-decoration: none`, заданное
   на классе компонента (0,1,0) — и подчёркивалось ВСЁ, что сделано ссылкой:
   кнопки `<a class="btn">`, логотип в углу меню, плитки и строки «Главной»
   целиком. Проверено в браузере: у .dash-kpi, .dash-att, .dash-line,
   .dash-bar, .brand и a.btn вычисленный text-decoration при наведении был
   `underline`.

   Теперь признак ссылки — цвет, а отклик на наведение — подсветка: у строчных
   ссылок мягкая «таблетка», у блочных (кнопки, строки, плитки) — их
   собственный фон, который у каждой уже есть. */
a { color: var(--accent); text-decoration: none; }
/* Строчные ссылки: без класса-компонента (внутри текста карточек, таблиц,
   инфомониторинга) плюс перечисленные поимённо. Список закрытый НАРОЧНО: у
   блочных ссылок (кнопки, пункты меню, строки и плитки «Главной») свой фон
   наведения, и общая «таблетка» ложилась бы поверх него. Появился новый класс
   строчной ссылки — дописывать сюда.
   Заливку даём box-shadow'ом, а не padding'ом: отступ у инлайн-элемента
   раздвинул бы строку в ячейке таблицы и в однострочной подписи с многоточием. */
a:not([class]):hover, a.small:hover, .lnk:hover, .fact-tip-link:hover,
.dash-models-link:hover, .grp-member-title:hover {
  color: var(--accent-600); background: var(--link-hl);
  border-radius: 4px; box-shadow: 0 0 0 2px var(--link-hl);
  box-decoration-break: clone; -webkit-box-decoration-break: clone;
}
/* <summary class="lnk"> («Все исследования архива» в панели скоупа) — блочный
   по природе: заливка растянулась бы во всю ширину панели. Ему оставляем
   только цвет. */
summary.lnk:hover { background: none; box-shadow: none; }
/* Клавиатурный фокус: подсветка видна только под курсором, а по Tab по
   ссылкам ходят из «Обратной связи» и из подсказок факта. */
a:focus-visible, .lnk:focus-visible, .grp-member-title:focus-visible {
  outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 4px;
}
h1,h2,h3,h4 { margin: 0; font-weight: 650; letter-spacing: -.01em; }
::selection { background: var(--accent-soft); }
/* размер иконок по умолчанию (специфичные .nav-item .ic / .btn .ic переопределяют) */
.ic { width: 18px; height: 18px; flex: none; }
.ic-sm { width: 12px; height: 12px; flex: none; }
.card-h .ic { color: var(--text-2); }

/* ---------- Layout ---------- */
.app { display: grid; grid-template-columns: var(--sidebar-w) 1fr; min-height: 100vh; }
/* Меню длиннее экрана — обычное дело: разделов десяток, а у администратора к
   ним добавляются «Администрирование» и «Настройки проекта». Без прокрутки
   нижние пункты уезжали за край экрана, и до «Выхода» было не добраться:
   контейнер задан ровно в высоту окна, а прокручивать его было нечем.
   overscroll-behavior — чтобы докрутив меню до конца, не утащить за собой
   страницу справа. */
.sidebar {
  background: #11151f; color: #c7ccd6; position: sticky; top: 0; height: 100vh;
  display: flex; flex-direction: column; padding: 18px 12px; gap: 4px;
  overflow-y: auto; overscroll-behavior: contain;
}
/* Пункты не должны ужиматься по высоте, когда меню не влезает: сжатый до
   нечитаемого пункт хуже прокрутки. Распорку это не трогает — она схлопывается
   первой (её собственное правило ниже), и прокрутка появляется только когда
   схлопывать уже нечего. */
.sidebar > *:not(.spacer) { flex-shrink: 0; }
/* Меню в базовой теме тёмное, поэтому ползунок светлый. Своих правил
   прокрутки здесь больше нет — общее правило берёт цвет из этих переменных, а
   в корпоративных темах меню светлое и переменные возвращаются к обычным
   (themes.css). */
.sidebar { --scroll-thumb: rgba(255, 255, 255, .18);
  --scroll-thumb-hover: rgba(255, 255, 255, .3); }
/* Логотип — ссылка на «Главную». Отклик на наведение ему нужен: раньше его
   давало общее подчёркивание, а теперь у ссылок его нет. */
.brand { display: flex; align-items: center; gap: 10px; padding: 6px 10px 12px;
  margin-bottom: 6px; border-radius: var(--radius-sm); transition: background .12s; }
.brand:hover { background: var(--link-hl); }
.brand .logo { width: 30px; height: 30px; border-radius: 8px; background: var(--accent);
  display: grid; place-items: center; flex: none; }
.brand .logo svg { width: 18px; height: 18px; }
.brand b { color: #fff; font-size: 15px; letter-spacing: -.02em; }
.brand small { display: block; color: #6b7280; font-size: 11px; font-weight: 500; }
.nav-group { font-size: 10.5px; text-transform: uppercase; letter-spacing: .08em;
  color: #5b6373; padding: 14px 12px 6px; }
.nav-item {
  display: flex; align-items: center; gap: 10px; padding: 9px 12px; border-radius: 9px;
  color: #c7ccd6; cursor: pointer; font-weight: 500; font-size: 13.5px;
  text-decoration: none; transition: background .12s, color .12s;
}
.nav-item:hover { background: #1b2130; color: #fff; text-decoration: none; }
.nav-item.active { background: var(--accent); color: #fff; }
.nav-item .ic { width: 18px; height: 18px; flex: none; opacity: .9; }
.sidebar .spacer { flex: 1; }

.main { display: flex; flex-direction: column; min-width: 0; }
.topbar {
  height: 60px; background: var(--surface); border-bottom: 1px solid var(--border);
  display: flex; align-items: center; gap: 14px; padding: 0 22px; position: sticky; top: 0; z-index: 20;
}
.topbar .page-title { font-size: 16px; font-weight: 650; }
.topbar .grow { flex: 1; }
.content { padding: 22px; max-width: 1280px; width: 100%; }

/* ---------- Buttons ---------- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 7px;
  padding: 8px 14px; border-radius: var(--radius-sm); border: 1px solid var(--border-strong);
  background: var(--surface); color: var(--text); font: inherit; font-weight: 550; font-size: 13.5px;
  cursor: pointer; transition: background .12s, border-color .12s, transform .05s; white-space: nowrap;
}
.btn:hover { background: var(--surface-2); }
.btn:active { transform: translateY(1px); }
.btn:disabled { opacity: .5; cursor: not-allowed; }
.btn.primary { background: var(--accent); border-color: var(--accent); color: #fff; }
.btn.primary:hover { background: var(--accent-600); }
.btn.danger { color: var(--red); border-color: #eccaca; background: var(--red-soft); }
.btn.ghost { border-color: transparent; background: transparent; }
.btn.ghost:hover { background: var(--surface-2); }
.btn.sm { padding: 5px 10px; font-size: 12.5px; }
.btn .ic { width: 16px; height: 16px; }

/* ---------- Cards ---------- */
.card { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); }
.card .card-h { padding: 15px 18px; border-bottom: 1px solid var(--border); display: flex;
  align-items: center; gap: 10px; }
.card .card-h h3 { font-size: 14.5px; }
.card .card-b { padding: 18px; }
.grid { display: grid; gap: 16px; }
.grid.cols-2 { grid-template-columns: repeat(2, 1fr); }
.grid.cols-3 { grid-template-columns: repeat(3, 1fr); }
.grid.cols-4 { grid-template-columns: repeat(4, 1fr); }
@media (max-width: 980px) { .grid.cols-3, .grid.cols-4 { grid-template-columns: repeat(2,1fr);} }

.stat { padding: 16px 18px; }
.stat .label { color: var(--text-2); font-size: 12.5px; font-weight: 500; }
.stat .val { font-size: 26px; font-weight: 700; letter-spacing: -.02em; margin-top: 4px; }
.stat .sub { color: var(--text-3); font-size: 12px; margin-top: 2px; }

/* ---------- Forms ---------- */
.field { margin-bottom: 14px; }
.field > label { display: block; font-size: 12.5px; font-weight: 600; color: var(--text-2); margin-bottom: 6px; }
.input, .select, .textarea {
  width: 100%; padding: 9px 12px; border: 1px solid var(--border-strong); border-radius: var(--radius-sm);
  background: var(--surface); color: var(--text); font: inherit; font-size: 14px; transition: border-color .12s, box-shadow .12s;
}
.input:focus, .select:focus, .textarea:focus {
  outline: none; border-color: var(--accent); box-shadow: 0 0 0 3px var(--accent-soft);
}
.textarea { resize: vertical; min-height: 80px; }
.row { display: flex; gap: 12px; flex-wrap: wrap; align-items: flex-end; }
.row > * { flex: 1; min-width: 140px; }

/* ---------- Table ---------- */
table.tbl { width: 100%; border-collapse: collapse; font-size: 13.5px; }
table.tbl th { text-align: left; color: var(--text-2); font-weight: 600; font-size: 12px;
  text-transform: uppercase; letter-spacing: .03em; padding: 10px 12px; border-bottom: 1px solid var(--border); }
table.tbl td { padding: 11px 12px; border-bottom: 1px solid var(--border); vertical-align: middle; }
table.tbl tr:last-child td { border-bottom: none; }
table.tbl tbody tr:hover { background: var(--surface-2); }
.clickable { cursor: pointer; }

/* ---------- Badges ---------- */
.badge { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: 100px;
  font-size: 11.5px; font-weight: 600; background: var(--surface-2); color: var(--text-2); }
.badge.green { background: var(--green-soft); color: var(--green); }
.badge.amber { background: var(--amber-soft); color: var(--amber); }
.badge.red { background: var(--red-soft); color: var(--red); }
.badge.blue { background: var(--blue-soft); color: var(--blue); }
.badge.accent { background: var(--accent-soft); color: var(--accent-600); }
.dot { width: 7px; height: 7px; border-radius: 50%; background: currentColor; }

/* Маркер версии интерфейса в сайдбаре */
/* Маркер сборки — ссылка на историю версий. Подчёркивания нет: он живёт в
   углу меню и не должен выглядеть пунктом навигации, но курсор и подсветка
   на наведении обязаны показать, что по нему можно щёлкнуть. */
.build-mark { display: block; padding: 6px 14px 10px; font-size: 10.5px;
  color: var(--text-3); letter-spacing: .02em; text-decoration: none;
  transition: color .12s, background .12s; }
.build-mark:hover { color: var(--text-2); background: var(--link-hl); }
.build-mark.active { color: var(--accent-600); }

/* ---------- История версий ---------- */
.chg-list { list-style: none; margin: 0; padding: 0; }
.chg-item { display: flex; gap: 10px; align-items: flex-start; padding: 9px 0;
  border-bottom: 1px solid var(--border); }
.chg-item:last-child { border-bottom: 0; padding-bottom: 0; }
.chg-item:first-child { padding-top: 0; }
/* метка вида изменения не сжимается и не переносится: она задаёт колонку,
   по которой список читается сверху вниз */
.chg-kind { flex: 0 0 auto; margin-top: 1px; white-space: nowrap; }
.chg-text { flex: 1 1 auto; min-width: 0; line-height: 1.55; }

/* ---------- Мастер презентаций ---------- */
.wiz-steps { display: flex; gap: 4px; flex-wrap: wrap; }
.wiz-step { display: flex; align-items: center; gap: 8px; padding: 8px 16px; border-radius: 100px;
  font-size: 13px; font-weight: 550; color: var(--text-3); background: var(--surface-2); }
.wiz-step.active { background: var(--accent-soft); color: var(--accent-600); }
.wiz-step.done { color: var(--text-2); }
.wiz-num { width: 20px; height: 20px; border-radius: 50%; background: var(--border);
  display: inline-flex; align-items: center; justify-content: center; font-size: 11.5px; font-weight: 700; }
.wiz-step.active .wiz-num { background: var(--accent); color: #fff; }
.wiz-step.done .wiz-num { background: var(--green-soft); color: var(--green); }
.pres-frame { width: 100%; height: calc(100vh - 250px); min-height: 480px; border: none; display: block;
  border-radius: 0 0 12px 12px; background: #525659; }
.pres-frame:fullscreen { border-radius: 0; background: #525659; }
/* панель действий мастера презентаций остаётся видимой при прокрутке
   длинного редактора/просмотра (под липкой верхней панелью 60px) */
.pres-toolbar { position: sticky; top: 60px; z-index: 15; background: var(--bg, var(--surface-2));
  padding: 8px 0 10px; margin-bottom: 10px; border-bottom: 1px solid var(--border); }
/* каталог презентаций */
.pres-store td { vertical-align: middle; }
.pres-store .pres-actions { white-space: nowrap; }
.pres-store .pres-actions .btn { padding: 4px 8px; font-size: 12px; }
/* карточки шаблонов презентации + пример структуры справа */
.tpl-layout { display: grid; grid-template-columns: minmax(0, 1fr) 340px; gap: 14px; align-items: start; }
@media (max-width: 1100px) { .tpl-layout { grid-template-columns: 1fr; } }
.tpl-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(210px, 1fr)); gap: 10px; }
.tpl-preview { position: sticky; top: 72px; border: 1px solid var(--border); border-radius: 10px;
  padding: 10px 12px; background: var(--surface-2); max-height: calc(100vh - 100px); overflow: auto; }
.tpl-preview:empty { display: none; }
.tpl-preview-h { display: flex; flex-direction: column; gap: 2px; margin-bottom: 8px; font-size: 13px; }
.tpl-slides { display: flex; flex-direction: column; gap: 6px; }
.tpl-slide { border: 1px solid var(--border); border-left: 4px solid var(--accent); border-radius: 6px;
  background: var(--surface); padding: 6px 9px; }
.tpl-slide.is-title { color: #fff; border-color: transparent; }
.tpl-slide-top { display: flex; align-items: center; gap: 6px; font-size: 10.5px; color: var(--text-3); }
.tpl-slide.is-title .tpl-slide-top { color: rgba(255,255,255,.8); }
.tpl-slide-no { font-weight: 700; }
.tpl-slide-kind { padding: 0 6px; border-radius: 100px; background: var(--surface-2); color: var(--text-2); }
.tpl-slide-hdr { margin-left: auto; letter-spacing: .06em; font-size: 9px; opacity: .8; }
.tpl-slide-title { font-size: 12.5px; font-weight: 600; margin-top: 2px; line-height: 1.3; }
.tpl-slide-hint { font-size: 11px; color: var(--text-3); margin-top: 2px; line-height: 1.35; }
.tpl-slide.is-title .tpl-slide-hint { color: rgba(255,255,255,.8); }
.tpl-card { border: 1px solid var(--border); border-radius: 10px; padding: 10px 12px; cursor: pointer;
  background: var(--surface); transition: border-color .12s, box-shadow .12s; }
.tpl-card:hover { border-color: var(--border-strong); }
.tpl-card.sel { border-color: var(--accent); box-shadow: 0 0 0 2px var(--accent-soft); }
.tpl-card:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.tpl-swatch { height: 6px; border-radius: 3px; margin-bottom: 9px; }
.tpl-name { font-weight: 600; font-size: 13.5px; display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.tpl-short { font-size: 12px; color: var(--text-2); margin-top: 4px; line-height: 1.4; }
.tpl-struct { font-size: 11.5px; color: var(--text-3); margin-top: 6px; line-height: 1.4; }
.tpl-based { font-size: 11px; color: var(--text-3); margin-top: 4px; font-style: italic; }
.pres-len { margin-top: 6px; font-size: 12px; color: var(--text-3); }
.pres-len.warn { color: var(--amber); font-weight: 600; }

/* ---- Род исследования в презентациях ----
   Количественное и качественное различаются ФОРМОЙ (заливка / контур) и
   глифом со словом, а не только цветом: в corporate-темах --blue совпадает
   с --accent, и «синий» бейдж там того же оранжевого, что и всё выделенное.
   green не берём — в тех же таблицах он значит статус «Принята». */
.badge.kind-quant { background: var(--blue-soft); color: var(--blue); }
.badge.kind-qual { background: transparent; color: var(--text-2);
  box-shadow: inset 0 0 0 1px var(--border-strong); }
.badge.kind-unknown { background: transparent; color: var(--text-3);
  border: 1px dashed var(--border-strong); padding: 2px 8px; }
.kind-g { font-weight: 700; line-height: 1; }
.rp-method .kind-g { opacity: .8; }
/* тип задан вручную в карточке исследования (05.10.2026): приписка «· вручную»
   тише слова — главное в бейдже тип, пометка лишь объясняет расхождение с методом */
.kind-m { font-weight: 400; opacity: .8; white-space: nowrap; }
/* строка рода под выбором исследования (шаг «Параметры») */
.pres-kindbox:empty { display: none; }
.pres-kindbox { margin: -2px 0 14px; }
.pres-kindbox .sp-note { margin: 8px 0 0; }
.pres-kindline { display: flex; align-items: center; flex-wrap: wrap; gap: 8px;
  font-size: 12.5px; color: var(--text-2); }
.pres-kindline-l { font-weight: 600; }
.rp-kind { display: block; margin-top: 3px; }
.rp-kind .badge { font-size: 10.5px; padding: 1px 7px; }
.rp-kind .badge.kind-unknown { padding: 0 6px; }
/* шаблоны чужого рода — за ссылкой и приглушены, но выбрать их можно */
.tpl-card.off { opacity: .55; }
.tpl-card.off:hover, .tpl-card.off:focus-visible, .tpl-card.off.sel { opacity: 1; }
.tpl-kind { font-size: 11.5px; color: var(--text-2); margin-top: 3px; }
.tpl-more:empty, .tpl-warn:empty { display: none; }
.tpl-more { margin-top: 8px; }
.tpl-warn .chat-incomplete { margin: 10px 0 0; }
.tpl-slide.is-divider { color: #fff; border-color: transparent; }
.tpl-slide.is-divider .tpl-slide-top, .tpl-slide.is-divider .tpl-slide-hint { color: rgba(255,255,255,.8); }
.tpl-slide.is-divider .tpl-slide-kind { background: rgba(255,255,255,.18); color: #fff; }
.tpl-slide.is-divider .tpl-slide-title { text-transform: uppercase; letter-spacing: .02em; }
.pres-opts { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0 14px; }
@media (max-width: 900px) { .pres-opts { grid-template-columns: 1fr; } }
.pres-ref-struct { margin-top: 6px; line-height: 1.45; }
.pres-checks { display: flex; flex-direction: column; gap: 6px; }
/* счётчик знаков против бюджета эталонов — у подписи поля */
.pres-extra .field > label, .pres-f > label { display: flex; justify-content: space-between;
  align-items: baseline; gap: 8px; }
.pres-cnt { font-weight: 500; font-size: 11.5px; color: var(--text-3); font-variant-numeric: tabular-nums;
  white-space: nowrap; }
.pres-cnt.warn { color: var(--amber); font-weight: 650; }
/* план: разделитель — одна строка, пунктиром, как «шов» между блоками */
.pres-plan-div { display: flex; align-items: center; gap: 6px; padding: 8px 12px;
  border: 1px dashed var(--border-strong); border-radius: var(--radius); background: var(--surface-2); }
.pres-plan-div .input { flex: 1; min-width: 160px; font-weight: 600; }
.pres-block { font-size: 11.5px; color: var(--text-3); white-space: nowrap; overflow: hidden;
  text-overflow: ellipsis; max-width: 260px; }
/* редактор: поля слайда по его виду */
.pres-extra { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 10px 14px; }
.pres-extra .field { margin-bottom: 0; min-width: 0; }
.pres-extra .span-2 { grid-column: 1 / -1; }
@media (max-width: 800px) { .pres-extra { grid-template-columns: 1fr; } }
.pres-kpi { display: grid; grid-template-columns: 130px minmax(0, 1fr) 190px; gap: 10px 14px; }
.pres-kpi .field { margin-bottom: 0; }
@media (max-width: 800px) { .pres-kpi { grid-template-columns: 1fr; } }
.pres-ro { padding: 8px 10px; border-radius: var(--radius-sm); background: var(--surface-2);
  font-size: 13px; line-height: 1.45; color: var(--text-2); }
.pres-segs { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 10px; }
.pres-seg { display: grid; gap: 8px; align-content: start; padding: 10px;
  border: 1px solid var(--border); border-radius: var(--radius-sm); background: var(--surface-2); }
.pres-seg .input { font-weight: 600; }
.pres-seg-add { align-self: start; justify-self: start; }
.pres-div-card { border-style: dashed; }
.pres-mismatch { margin-left: 6px; white-space: nowrap; }
.badge.kind-quant, .badge.kind-qual, .badge.kind-unknown { white-space: nowrap; }
/* с колонкой «Род» в каталоге стало девять колонок: без нижней границы
   название презентации сжималось до трёх-четырёх слов в строке. Больше
   180px не даём — иначе на 1366–1440 таблица снова шире карточки */
.pres-store td:nth-child(2) { min-width: 180px; }
/* поля ячеек уже, как в архиве исследований: девять колонок по 24px полей
   съедали ширину целой колонки, и на 1440 таблица не помещалась */
table.tbl.pres-store th, table.tbl.pres-store td { padding-left: 8px; padding-right: 8px; }
.pres-nsl { margin-top: 3px; white-space: nowrap; }
/* Действия прилипают к правому краю: если таблица всё же шире окна, уезжают
   под прокрутку средние колонки, а не «Открыть» и «Скачать». Фон — свой, у
   ячейки (подсветка строки висит на tr и под липкой ячейкой не видна). */
.pres-store th:last-child, .pres-store td.pres-actions { position: sticky; right: 0; z-index: 1;
  background: var(--surface); }
table.tbl.pres-store tbody tr:hover td.pres-actions { background: var(--surface-2); }
.pres-store-wrap.ovf .pres-store th:last-child, .pres-store-wrap.ovf .pres-store td.pres-actions {
  box-shadow: inset 1px 0 0 var(--border), -10px 0 10px -10px rgba(0, 0, 0, .35); }
.pres-store .pres-actions .btn .ic { width: 15px; height: 15px; }
.pres-dl { gap: 2px; }
.pres-dl-caret { font-size: 10px; opacity: .7; }
/* ---- черновик выводов и мер детальной колоды (вариант В) ----
   Жёлтая плашка над полями слайда: пункты генерации на карточках поверхности
   (тексту и предупреждениям нужен контраст, которого на жёлтом фоне нет),
   опоры — мелко под пунктом, снятое проверками — свёрнуто. Отмеченный
   «Проверено» черновик — приглушённый, с зелёной полосой. */
.pres-draft { margin: 0 0 14px; padding: 10px 12px 12px; border-radius: 8px; background: var(--amber-soft);
  border-left: 4px solid var(--amber); font-size: 13px; line-height: 1.45; color: var(--text); }
.pres-draft.ok { background: var(--surface-2); border-left-color: var(--green); padding-bottom: 10px; }
.pres-draft-h { display: flex; align-items: flex-start; gap: 8px; flex-wrap: wrap; }
.pres-draft-h > .ic { width: 16px; height: 16px; flex: none; margin-top: 2px; color: var(--amber); }
.pres-draft.ok .pres-draft-h > .ic { color: var(--green); }
.pres-draft-hl { flex: 1; min-width: 240px; }
.pres-draft-note { margin-top: 2px; font-size: 12.5px; color: var(--text-2); }
.pres-draft-act { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-left: auto; }
.pres-draft-who { font-size: 12.5px; color: var(--text-2); }
.pres-draft-hint { margin: 10px 0 0; padding: 8px 10px; border-radius: 6px; background: var(--surface);
  border: 1px dashed var(--border-strong); font-weight: 600; }
.pres-draft-sub { display: flex; align-items: baseline; gap: 4px; flex-wrap: wrap; margin: 10px 0 4px;
  font-size: 11.5px; font-weight: 650; color: var(--text-2); text-transform: uppercase; letter-spacing: .4px; }
.pres-draft-subn { font-weight: 400; text-transform: none; letter-spacing: 0; }
.pres-draft-sub .pres-draft-all { margin-left: auto; font-size: 12px; text-transform: none; letter-spacing: 0; }
/* компактно (вариант В2): пункт — строка «номер · шапка · метки» и его
   предупреждения; текст, опоры и действия раскрываются по клику. Номер —
   строка поля тезисов слайда (пунктир — в поле такого пункта нет). */
.pres-draft [hidden] { display: none !important; }
.pres-draft-sum { margin-top: 1px; font-size: 12.5px; color: var(--text-2); }
.pres-draft-cnum.hot { color: var(--amber); font-weight: 650; }
.pres-draft-item { margin-top: 4px; padding: 5px 10px; border-radius: 6px; background: var(--surface);
  border: 1px solid var(--border); }
.pres-draft-item.cur { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent); }
.pres-draft-cap { display: flex; align-items: baseline; gap: 2px 10px; flex-wrap: wrap; }
.pres-draft-tog { display: inline-flex; align-items: baseline; gap: 6px; min-width: 0; max-width: 100%; padding: 1px 0;
  border: 0; background: none; font: inherit; color: var(--text); text-align: left; cursor: pointer; }
.pres-draft-tog:hover b { color: var(--accent-600); }
.pres-draft-tog:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; border-radius: 3px; }
.pres-draft-chev { width: 10px; flex: none; font-size: 11px; color: var(--text-2); transition: transform .12s; }
.pres-draft-tog[aria-expanded="true"] .pres-draft-chev { transform: rotate(90deg); }
.pres-draft-no { flex: none; min-width: 20px; padding: 0 5px; border-radius: 10px; text-align: center;
  font-size: 11.5px; font-weight: 700; font-variant-numeric: tabular-nums; background: var(--accent-soft);
  color: var(--accent-600); border: 1px solid transparent; }
.pres-draft-no.off { background: none; border: 1px dashed var(--border-strong); color: var(--text-3); }
.pres-draft-miss { color: var(--amber); font-weight: 600; }
.pres-draft-body { margin: 2px 0 2px 42px; }
.pres-draft-tools { display: flex; align-items: center; gap: 4px 12px; flex-wrap: wrap; margin-top: 4px; font-size: 12px; }
.pres-draft-tools .lnk { font-size: 12px; }
.pres-draft-meta { font-size: 11.5px; color: var(--text-2); white-space: nowrap; }
.pres-draft-text { margin-top: 3px; font-size: 12.5px; color: var(--text-2); }
.pres-draft-warn { display: flex; align-items: flex-start; gap: 6px; margin: 3px 0 0 16px; font-size: 12.5px;
  font-weight: 600; color: var(--amber); }
.pres-draft-warn .ic { width: 14px; height: 14px; flex: none; margin-top: 2px; }
.pres-draft-jump { font-size: inherit; font-weight: inherit; text-decoration: underline; text-underline-offset: 2px; }
/* пробелы колоды — на виду, над пунктами */
.pres-draft-gaps { margin-top: 8px; padding: 6px 10px; border-radius: 6px; background: var(--surface);
  border: 1px solid var(--amber); font-size: 12.5px; }
.pres-draft-gaps-h { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-weight: 650; color: var(--amber); }
.pres-draft-gaps-h .ic { width: 14px; height: 14px; flex: none; }
.pres-draft-gaps-h .pres-draft-meta { font-weight: 400; white-space: normal; }
.pres-draft-gaps ul { margin: 4px 0 0; padding-left: 18px; }
.pres-draft-gaps li { margin-top: 2px; }
.pres-line-at { font-weight: 500; font-size: 11.5px; color: var(--accent-600); font-variant-numeric: tabular-nums; }
.pres-draft-sups { margin: 6px 0 0; padding: 0; list-style: none; }
.pres-draft-sup { margin-top: 3px; padding-left: 8px; border-left: 2px solid var(--border-strong);
  font-size: 12px; color: var(--text-2); overflow-wrap: anywhere; }
.pres-draft-sup i { color: var(--text); }
.pres-draft-drop, .pres-draft-fold { margin-top: 10px; font-size: 12px; color: var(--text-3); }
.pres-draft-drop > summary, .pres-draft-fold > summary { cursor: pointer; width: fit-content;
  font-weight: 600; color: var(--text-2); }
.pres-draft-drop > summary:hover, .pres-draft-fold > summary:hover { color: var(--accent-600); }
.pres-draft-drop ul { margin: 6px 0 0; padding-left: 18px; }
.pres-draft-drop li { margin-top: 3px; color: var(--text-2); }
/* снятое: текст целиком, «Вернуть на слайд» — справа в строке пункта */
.pres-draft-drop ul.pres-draft-dlist { padding-left: 0; list-style: none; }
.pres-draft-drop li.pres-draft-dropi { display: flex; align-items: flex-start; gap: 4px 12px; margin-top: 0; padding: 6px 0;
  border-top: 1px dashed var(--border-strong); }
.pres-draft-drop li.pres-draft-dropi:first-child { border-top: 0; }
.pres-draft-dmain { flex: 1; min-width: 0; }
.pres-draft-dropi .pres-draft-tools { flex: none; margin-top: 0; }
.pres-draft-dropi b { color: var(--text); }
.pres-draft-stage { color: var(--text-3); }
.pres-draft-cnt { align-self: center; white-space: nowrap; }
.pres-draft-view { align-items: center; }
.pres-draft-view .grow { flex: 1; min-width: 0; }
/* 409 принятия — карточка непроверенного черновика подсвечивается на миг */
.card.pres-flash { box-shadow: 0 0 0 2px var(--amber); transition: box-shadow .3s; }
/* «Быстрая генерация» заблокирована галочкой детального режима */
.pres-checks label.is-locked { cursor: default !important; opacity: .6; }
/* ---- вкладка «Эталоны и формулировки» ---- */
.ref-why { margin-bottom: 14px; }
table.tbl.ref-tbl td, table.tbl.phr-tbl td { vertical-align: top; }
.ref-theme { margin-top: 2px; line-height: 1.35; }
.ref-off td, .phr-off td { color: var(--text-3); }
.ref-off a, .phr-off .badge { opacity: .7; }
.ref-kind-sel, .phr-slot-sel { width: auto; max-width: 100%; padding: 3px 6px; font-size: 12px; }
table.tbl tbody tr.ref-detail:hover, .ref-detail td { background: var(--surface-2); }
.ref-struct { margin: 0; padding: 0; list-style: none; columns: 2 320px; column-gap: 28px; font-size: 12.5px; }
.ref-struct li { display: flex; gap: 6px; align-items: baseline; padding: 2px 0; break-inside: avoid; }
.ref-struct .no { color: var(--text-3); min-width: 22px; text-align: right; font-variant-numeric: tabular-nums; }
.ref-role { flex: none; font-size: 10.5px; padding: 0 6px; border-radius: 100px; white-space: nowrap;
  background: var(--surface); color: var(--text-2); box-shadow: inset 0 0 0 1px var(--border); }
.ref-role.r-divider, .ref-role.r-title { background: var(--accent-soft); color: var(--accent-600); box-shadow: none; }
.ref-note { display: flex; gap: 6px; align-items: baseline; margin-top: 10px; font-size: 12.5px; }
.ref-note .phr-cell { flex: 1; }
.phr-filters { display: flex; gap: 6px; flex-wrap: wrap; align-items: center; margin-bottom: 12px; }
.phr-tbl { table-layout: fixed; }
.phr-tbl td { font-size: 13px; overflow-wrap: anywhere; }
.phr-cell { min-height: 20px; margin: -3px -5px; padding: 3px 5px; border-radius: 6px;
  white-space: pre-wrap; line-height: 1.45; }
.phr-cell.can { cursor: text; }
.phr-cell.can:hover { background: var(--surface-2); box-shadow: inset 0 0 0 1px var(--border-strong); }
.phr-cell.can:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.phr-cell.editing { margin: 0; padding: 0; }
.phr-cell .textarea { min-height: 56px; font-size: 13px; padding: 6px 8px; }
.phr-note { margin-top: 5px; font-size: 11.5px; color: var(--text-3); }
/* сохранение не прошло — поле остаётся открытым с введённым текстом */
.phr-cell.err .textarea { border-color: var(--red); }
.phr-cell-err { margin-top: 4px; font-size: 11.5px; line-height: 1.4; color: var(--red); white-space: normal; }
.phr-kind-sel { width: auto; max-width: 100%; padding: 3px 6px; font-size: 11.5px; }
/* превью графика в редакторе — как на слайде: доли, база подписью */
.pres-chart-prev .chart-bar-row.is-grey .chart-bar-fill { background: var(--border-strong); }
.pres-chart-foot { margin-top: 8px; font-size: 12px; color: var(--text-2); line-height: 1.45; }
.pres-chart-foot > div { color: var(--text-3); }
.tpl-err { display: flex; align-items: center; gap: 6px; color: var(--text-2); }
.tpl-err .ic { color: var(--amber); }
.phr-ph { background: var(--accent-soft); color: var(--accent-600); border-radius: 4px; padding: 0 3px; }

/* ---------- Редактор тегов (чипы) ---------- */
.tag-edit { display: flex; flex-wrap: wrap; align-items: center; gap: 6px; min-height: 30px; }
.tag-chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 4px 3px 9px;
  border-radius: 100px; font-size: 11.5px; font-weight: 600;
  background: var(--surface-2); color: var(--text-2); max-width: 100%; }
.tag-chip.ai { background: var(--accent-soft); color: var(--accent-600); }
.tag-chip .tag-text { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tag-edit.ro .tag-chip { padding: 3px 9px; }
.tag-x { border: none; background: none; cursor: pointer; color: inherit; opacity: .45;
  font-size: 10px; line-height: 1; padding: 3px 4px; border-radius: 50%; flex: none; }
.tag-x:hover { opacity: 1; background: rgba(0, 0, 0, .08); }
.tag-add { border: 1px dashed var(--border); background: transparent; color: var(--text);
  border-radius: 100px; padding: 3px 10px; font-size: 12px; font-family: inherit;
  width: 118px; outline: none; }
.tag-add:focus { border-color: var(--accent); border-style: solid; width: 160px; }
.tag-add:disabled { opacity: .5; }
.tag-row { display: flex; gap: 16px; align-items: flex-start; flex-wrap: wrap; }
.tag-row-label { width: 210px; flex: none; }

/* ---------- Tabs ---------- */
.tabs { display: flex; gap: 4px; border-bottom: 1px solid var(--border); margin-bottom: 18px; flex-wrap: wrap; }
.tab { padding: 9px 14px; cursor: pointer; font-weight: 550; font-size: 13.5px; color: var(--text-2);
  border-bottom: 2px solid transparent; margin-bottom: -1px; }
.tab:hover { color: var(--text); }
.tab.active { color: var(--accent); border-bottom-color: var(--accent); }
/* вкладки с ролью tab (раздел «Презентации») доступны с клавиатуры */
.tab[role=tab]:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; border-radius: 6px 6px 0 0; }

/* ---------- Misc ---------- */
.muted { color: var(--text-2); }
.small { font-size: 12.5px; }
.mono { font-family: var(--mono); font-size: 12.5px; }
.pill-tags { display: flex; gap: 6px; flex-wrap: wrap; }
.divider { height: 1px; background: var(--border); margin: 16px 0; }
.empty { text-align: center; color: var(--text-3); padding: 40px 20px; }
.empty svg { width: 40px; height: 40px; opacity: .5; margin-bottom: 10px; }
.flex { display: flex; align-items: center; gap: 10px; }
.flex.between { justify-content: space-between; }
.flex.wrap { flex-wrap: wrap; }
.gap-6 { gap: 6px; } .gap-16 { gap: 16px; }
.mt-12 { margin-top: 12px; } .mt-18 { margin-top: 18px; } .mb-12 { margin-bottom: 12px; }
.scroll-x { overflow-x: auto; }

/* citations / sources */
.source-card { border: 1px solid var(--border); border-radius: var(--radius-sm); padding: 10px 12px;
  background: var(--surface-2); font-size: 12.5px; }
.cite-ref { color: var(--accent); font-weight: 600; }
/* сноска [n] ответа, у которой есть карточка в «Источниках», — нажимаемая;
   номер без карточки — приглушённый, без перехода (chat.js, wireCites) */
.cite-ref.is-link { cursor: pointer; border-radius: 3px; }
.cite-ref.is-link:hover { background: var(--link-hl); }
.cite-ref.is-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
.cite-ref.cite-missing { color: var(--text-3); font-weight: 400; cursor: help; }
.source-card.source-flash { animation: fb-flash 1.3s ease-in-out 2; }
/* строка действий карточки источника: карточка исследования, скачать документ */
.source-actions { display: flex; align-items: baseline; gap: 4px 16px; flex-wrap: wrap;
  margin-top: 6px; font-size: 12px; }
.source-actions .lnk { font-size: 12px; color: var(--accent); }
.answer-body { line-height: 1.65; white-space: pre-wrap; }
.answer-body sup { color: var(--accent); font-weight: 700; }

/* spinner */
.spinner { width: 16px; height: 16px; border: 2px solid var(--border-strong); border-top-color: var(--accent);
  border-radius: 50%; animation: spin .7s linear infinite; display: inline-block; }
@keyframes spin { to { transform: rotate(360deg); } }
.loading { display: flex; align-items: center; gap: 10px; color: var(--text-2); padding: 30px; justify-content: center; }

/* toast */
#toast-root { position: fixed; right: 18px; bottom: 18px; display: flex; flex-direction: column;
  gap: 10px; z-index: 100; }
.toast { background: var(--text); color: #fff; padding: 11px 15px; border-radius: var(--radius-sm);
  box-shadow: var(--shadow-lg); font-size: 13.5px; max-width: 360px; animation: slideup .2s ease; }
.toast.err { background: #7f1d1d; } .toast.ok { background: #14532d; }
@keyframes slideup { from { transform: translateY(8px); opacity: 0; } }

/* плавающая кнопка «Наверх» (длинные списки): над тостами, в углу окна */
.to-top { position: fixed; right: 24px; bottom: 84px; z-index: 30; width: 42px; height: 42px;
  border-radius: 50%; border: 1px solid var(--accent-600); background: var(--accent); color: #fff;
  display: inline-grid; place-items: center; cursor: pointer; box-shadow: var(--shadow-lg);
  opacity: 0; transform: translateY(12px); pointer-events: none;
  transition: opacity .25s ease, transform .25s ease, background .15s; }
.to-top.show { opacity: .92; transform: translateY(0); pointer-events: auto; }
.to-top:hover { opacity: 1; background: var(--accent-600); }
.to-top:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
@media (max-width: 760px) { .to-top { right: 14px; bottom: 74px; width: 38px; height: 38px; } }

/* modal */
#modal-root:empty { display: none; }
.modal-backdrop { position: fixed; inset: 0; background: rgba(16,20,30,.45); display: grid; place-items: center;
  z-index: 90; padding: 20px; }
.modal { background: var(--surface); border-radius: var(--radius); box-shadow: var(--shadow-lg);
  width: 100%; max-width: 560px; max-height: 88vh; overflow: auto; }
.modal .modal-h { padding: 16px 20px; border-bottom: 1px solid var(--border); display: flex;
  justify-content: space-between; align-items: center; }
.modal .modal-b { padding: 20px; }
.modal .modal-f { padding: 14px 20px; border-top: 1px solid var(--border); display: flex;
  justify-content: flex-end; gap: 10px; }

/* login */
.login-wrap { min-height: 100vh; display: grid; place-items: center; background:
  radial-gradient(1200px 600px at 70% -10%, #eef0fe, transparent), var(--bg); }
.login-card { width: 380px; max-width: 92vw; }
.login-card .brand { justify-content: center; padding-bottom: 8px; }
/* .brand b белый — это для тёмного сайдбара; на светлой карточке входа
   название было белым на белом */
.login-card .brand b { color: var(--text); }
/* баннер ошибки входа — в карточке над формой (тост в углу не замечали) */
.login-alert {
  display: flex; gap: 9px; align-items: flex-start; margin-bottom: 14px;
  padding: 11px 13px; border: 1px solid var(--red); border-left-width: 4px;
  border-radius: var(--radius-sm); background: var(--red-soft); color: var(--text);
  font-size: 13.5px; font-weight: 600; line-height: 1.35;
}
/* текст — основным цветом (красный по красноватой подложке в корпоративных
   темах давал контраст ~4:1), сигнал ошибки несут рамка и иконка */
.login-alert .ic { width: 18px; height: 18px; flex: none; margin-top: 1px; color: var(--red); }
.login-alert.shake { animation: alert-shake .32s ease; }
@keyframes alert-shake {
  0%, 100% { transform: translateX(0); }
  25% { transform: translateX(-5px); }
  50% { transform: translateX(4px); }
  75% { transform: translateX(-2px); }
}
/* информационная плашка входа (куда отправлен код 2ФА) */
.login-note {
  display: flex; gap: 9px; align-items: flex-start; margin-bottom: 14px;
  padding: 11px 13px; border: 1px solid var(--border); border-left: 4px solid var(--accent);
  border-radius: var(--radius-sm); background: var(--surface-2); color: var(--text);
  font-size: 13px; line-height: 1.4;
}
.login-note .ic { width: 18px; height: 18px; flex: none; margin-top: 1px; color: var(--accent); }
/* поле одноразового кода: крупно, по центру, с разрядкой */
.code-input {
  font-family: var(--mono); font-size: 24px; letter-spacing: 8px; text-align: center;
  padding: 10px 12px;
}
.input.invalid { border-color: var(--red); }
.input.invalid:focus { box-shadow: 0 0 0 3px var(--red-soft); border-color: var(--red); }
@media (prefers-reduced-motion: reduce) { .login-alert.shake { animation: none; } }

/* switch */
.switch { position: relative; display: inline-block; width: 42px; height: 24px; flex: none; }
.switch input { opacity: 0; width: 0; height: 0; }
.switch .track { position: absolute; inset: 0; background: var(--border-strong); border-radius: 100px; transition: .15s; }
.switch .track::before { content: ''; position: absolute; height: 18px; width: 18px; left: 3px; top: 3px;
  background: #fff; border-radius: 50%; transition: .15s; box-shadow: 0 1px 2px rgba(0,0,0,.2); }
.switch input:checked + .track { background: var(--accent); }
.switch input:checked + .track::before { transform: translateX(18px); }
.setting-row { display: flex; gap: 14px; align-items: flex-start; padding: 14px 0; border-bottom: 1px solid var(--border); }
.setting-row:last-child { border-bottom: none; }

/* ---------- Поле пароля с «глазиком» ---------- */
.pw-wrap { position: relative; display: block; }
.pw-wrap .input { padding-right: 42px; }
.pw-eye { position: absolute; top: 0; right: 4px; height: 100%; width: 32px; padding: 0;
  display: inline-flex; align-items: center; justify-content: center; border: none;
  background: none; color: var(--text-3); cursor: pointer; border-radius: var(--radius-sm); }
.pw-eye:hover { color: var(--text); }
.pw-eye .ic { width: 18px; height: 18px; }

/* ---------- Матрица «роли × разделы» ---------- */
.role-matrix { width: 100%; border-collapse: collapse; font-size: 13.5px; }
.role-matrix th, .role-matrix td { padding: 10px 12px; border-bottom: 1px solid var(--border); text-align: center; }
.role-matrix thead th { color: var(--text-2); font-weight: 600; font-size: 11.5px;
  text-transform: uppercase; letter-spacing: .02em; vertical-align: bottom; }
.role-matrix th.role-col, .role-matrix td.role-col { text-align: left; min-width: 160px; position: sticky; left: 0; background: var(--surface); }
.role-matrix tbody tr:hover td { background: var(--surface-2); }
.role-matrix tbody tr:hover td.role-col { background: var(--surface-2); }
.role-matrix input[type=checkbox] { width: 17px; height: 17px; cursor: pointer; accent-color: var(--accent); }
.role-matrix .col-all { font-weight: 500; color: var(--text-3); cursor: pointer; }
.role-matrix-wrap { overflow-x: auto; }
/* Колонки справочника сокращений (05.10.2026) сделали сетку шире экрана даже на
   1920px: ячейки только с галочками — поля уже, заголовки без разрядки, у колонки
   роли поля прежние. Права (не разделы, «Справочник: правка») — своей группой
   справа от «Все», с пометкой «право». */
.role-matrix th, .role-matrix td { padding-left: 5px; padding-right: 5px; }
.role-matrix th.role-col, .role-matrix td.role-col { padding-left: 12px; padding-right: 12px; }
.role-matrix thead th { font-size: 11px; letter-spacing: 0; }
.role-matrix .role-right-first { border-left: 1px solid var(--border); }
.role-matrix .role-right-tag { font-weight: 400; text-transform: none; color: var(--text-3); margin-top: 2px; }

/* reasoning steps (RLM) */
.rlm-step { border-left: 2px solid var(--accent); padding: 6px 0 6px 12px; margin: 8px 0; }
.rlm-step .step-act { font-weight: 600; font-size: 12.5px; }
.rlm-badge { background: linear-gradient(90deg, #4f46e5, #7c3aed); color: #fff; }

/* ---------- Главная ----------
   Плитки, строки «требует внимания», полосы покрытия и списки «чем
   продолжить» — всё кликабельное: цифра на дашборде бесполезна, если после
   клика приходится искать её источник руками. Поэтому почти каждый элемент
   здесь — <a>, и вид у него как у карточки, а не как у ссылки. */
.dash-head { display: flex; justify-content: space-between; align-items: flex-start;
  gap: 16px; flex-wrap: wrap; margin-bottom: 16px; }
.dash-actions { display: flex; gap: 8px; flex-wrap: wrap; }
.dash-kpi { display: block; text-decoration: none; color: inherit;
  transition: border-color .12s, background .12s; }
.dash-kpi:hover { border-color: var(--accent); background: var(--link-hl); }
.dash-kpi .val { font-variant-numeric: tabular-nums; }
/* «Требует внимания» шире соседа: там строки с объяснениями, а в покрытии —
   короткие полосы */
.dash-row-b, .dash-row-c { display: grid; gap: 16px; margin-bottom: 16px; }
.dash-row-b { grid-template-columns: 1.35fr 1fr; }
.dash-row-c { grid-template-columns: 1fr 1fr; }
@media (max-width: 1100px) {
  .dash-row-b, .dash-row-c { grid-template-columns: 1fr; }
}
/* min-width: 0 обязателен: у грид-элемента автоминимум равен min-content, а в
   карточках лежат строки с `white-space: nowrap` («Исследования по выборам» —
   название диалога). Без этого карточка не сжималась до своей колонки, и на
   экране 900px страница расползалась до 1038px с горизонтальной прокруткой. */
.dash-row-b > *, .dash-row-c > * { min-width: 0; }
.dash-att-t, .dash-line-t, .dash-bar-label { min-width: 0; }
.dash-line-title, .dash-line-t .small, .dash-bar-label { max-width: 100%; }
/* Строки списков — ссылки целиком, поэтому подсвечиваем строку, а не текст.
   Горизонтальный отступ с отрицательным полем: заливка выходит за колонку
   содержимого карточки, но текст остаётся на прежней сетке. */
.dash-att { display: flex; align-items: flex-start; gap: 10px;
  padding: 9px 8px; margin: 0 -8px; border-radius: var(--radius-sm);
  border-bottom: 1px solid var(--border); text-decoration: none; color: inherit; }
.dash-att:hover { background: var(--link-hl); }
.dash-att:last-child { border-bottom: 0; }
.dash-att:hover .dash-att-go { opacity: 1; }
.dash-att:hover .dash-att-t > span:first-child { color: var(--accent); }
.dash-att-n { min-width: 54px; text-align: right; font-size: 15px;
  font-variant-numeric: tabular-nums; }
.dash-att-t { display: flex; flex-direction: column; gap: 1px; min-width: 0; flex: 1; }
.dash-att-go { opacity: .25; align-self: center; }
.dash-dot { width: 8px; height: 8px; border-radius: 50%; background: var(--text-3);
  margin-top: 7px; flex: 0 0 auto; }
.dash-att .dash-dot { margin-top: 8px; }
.dash-dot.red { background: var(--red); }
.dash-dot.amber { background: var(--amber); }
.dash-dot.green { background: var(--green); }
.dash-bar { display: block; text-decoration: none; color: inherit;
  margin: 8px -8px; padding: 2px 8px 4px; border-radius: var(--radius-sm); }
.dash-bar:hover { background: var(--link-hl); }
.dash-bar-top { display: flex; justify-content: space-between; gap: 10px; font-size: 12.5px; }
.dash-bar-label { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.dash-bar-val { color: var(--text-2); white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.dash-bar.muted-row .dash-bar-label { color: var(--text-3); }
.dash-bar:hover .dash-bar-label { color: var(--accent); }
.dash-sub { font-size: 11.5px; text-transform: uppercase; letter-spacing: .04em;
  color: var(--text-3); font-weight: 600; }
.dash-line { display: flex; align-items: center; gap: 10px;
  padding: 9px 8px; margin: 0 -8px; border-radius: var(--radius-sm);
  border-bottom: 1px solid var(--border); text-decoration: none; color: inherit; }
.dash-line:hover { background: var(--link-hl); }
.dash-line:last-child { border-bottom: 0; }
.dash-line:hover .dash-line-title { color: var(--accent); }
.dash-line-t { display: flex; flex-direction: column; min-width: 0; flex: 1; gap: 1px; }
.dash-line-title, .dash-line-t .small { overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.dash-line-title { font-weight: 550; }
.dash-ok { display: flex; align-items: center; gap: 8px; color: var(--green); }
.dash-stamp-row { display: flex; align-items: center; gap: 10px;
  justify-content: flex-end; margin-bottom: 8px; }
.dash-foot { display: flex; flex-direction: column; gap: 5px; }
.dash-models { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.dash-models-link { margin-left: 4px; }

/* Чип активного фильтра архива: с «Главной» сюда приходят уже с отбором
   (?gap=period, ?data=no), и без подписи список выглядел бы просто коротким */
.arch-filter { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  padding: 8px 12px; border: 1px solid var(--accent); border-radius: var(--radius-sm);
  background: var(--accent-soft); font-size: 13px; }
.arch-filter .ic { color: var(--accent); }

/* chart */
/* Строка графика: [подпись][значение] сверху, полоса во всю ширину снизу.
   minmax(0, 1fr) обязателен — у обычного 1fr автоминимум равен min-content,
   и длинный вариант ответа распирал грид, выталкивая цифры за карточку.
   Вторая колонка max-content: ровно под «45,2% (10 750)» и ни пикселем больше. */
.chart-bar-row { display: grid; grid-template-columns: minmax(0, 1fr) max-content;
  gap: 3px 10px; align-items: baseline; margin: 10px 0; }
/* подпись — вариант ответа целиком, поэтому две строки, а не обрубок в одну;
   полный текст остаётся в подсказке. anywhere — на случай длинных слов
   («жилищно-коммунальные»), иначе слово всё равно распирает колонку */
.chart-bar-label { font-size: 12.5px; color: var(--text); min-width: 0;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow: hidden; overflow-wrap: anywhere; line-height: 1.35; }
/* цифры не переносятся и не сжимаются — их видно всегда */
.chart-bar-val { font-size: 12px; color: var(--text-2); text-align: right;
  font-variant-numeric: tabular-nums; white-space: nowrap; }
/* полоса под подписью, во всю ширину: и места больше, и разрешение выше */
.chart-bar-track { grid-column: 1 / -1; height: 18px; background: var(--surface-2);
  border-radius: 5px; overflow: hidden; position: relative; margin-top: 2px; }
.chart-bar-fill { height: 100%; background: var(--accent); border-radius: 5px; min-width: 2px; }

/* markdown-просмотр распознанного содержимого */
.md-body { font-size: 14px; line-height: 1.65; color: var(--text); }
.md-body h2 { font-size: 17px; margin: 18px 0 8px; }
.md-body h3 { font-size: 15px; margin: 14px 0 6px; }
.md-body h4, .md-body h5 { font-size: 13.5px; margin: 12px 0 5px; }
.md-body p { margin: 7px 0; }
.md-body ul, .md-body ol { margin: 7px 0 7px 22px; }
.md-body code { font-family: var(--mono); font-size: 12.5px; background: var(--surface-2); border: 1px solid var(--border); border-radius: 5px; padding: 1px 5px; }
.md-body blockquote { border-left: 3px solid var(--accent); margin: 8px 0; padding: 4px 12px; color: var(--text-2); background: var(--accent-soft); border-radius: 0 8px 8px 0; }
.md-body table { border-collapse: collapse; width: 100%; margin: 10px 0; font-size: 13px; }
.md-body th, .md-body td { border: 1px solid var(--border); padding: 6px 10px; text-align: left; }
.md-body th { background: var(--surface-2); font-weight: 600; }
.md-body hr { border: 0; border-top: 1px solid var(--border); margin: 14px 0; }
.modal.wide { max-width: 860px; width: min(94vw, 860px); }

/* файловое хранилище */
table.tbl.file-table { user-select: none; }
.file-row.selected,
table.tbl tbody tr.file-row.selected:hover { background: var(--accent-soft); outline: 1px solid var(--accent); outline-offset: -1px; }
.checkmark { color: var(--green); font-weight: 700; white-space: nowrap; }
.checkmark.double { letter-spacing: -2px; }
.status-x { color: var(--red); font-weight: 700; cursor: help; }
.status-excl { color: var(--text-3); font-weight: 700; cursor: help; }
.file-tooltip { position: fixed; z-index: 200; max-width: 320px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow-lg);
  padding: 10px 12px; font-size: 12.5px; pointer-events: none; }
.dropzone { position: relative; }
.dropzone .drop-overlay { display: none; }
.dropzone-over { outline: 2px dashed var(--accent); outline-offset: -2px; background: var(--accent-soft); }
.dropzone-over .drop-overlay { position: absolute; inset: 0; z-index: 5; display: flex; align-items: center;
  justify-content: center; gap: 10px; background: rgba(238,240,254,.88); border-radius: var(--radius);
  font-weight: 650; color: var(--accent-600); pointer-events: none; }
.progress { height: 10px; background: var(--surface-2); border-radius: 6px; overflow: hidden; }
.progress-fill { height: 100%; background: var(--accent); border-radius: 6px; transition: width .3s; }
.disk-node { font-size: 13px; }
.disk-row { display: flex; align-items: center; gap: 8px; padding: 4px 6px; border-radius: 6px; }
.disk-row.dir { cursor: pointer; }
.disk-row:hover { background: var(--surface-2); }
.disk-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.disk-size { font-variant-numeric: tabular-nums; color: var(--text-2); font-size: 12.5px; white-space: nowrap; }
.disk-bar { width: 120px; height: 8px; background: var(--surface-2); border: 1px solid var(--border);
  border-radius: 4px; overflow: hidden; flex: none; }
.disk-bar-fill { display: block; height: 100%; background: var(--accent); }
.disk-children { margin-left: 18px; border-left: 1px solid var(--border); padding-left: 6px; }

/* файловый проводник v2 */
/* переключатель вида (плитки / таблица) */
.view-switch { display: inline-flex; gap: 2px; padding: 2px; background: var(--surface-2);
  border: 1px solid var(--border); border-radius: var(--radius-sm); flex: none; }
.view-btn { display: inline-grid; place-items: center; width: 30px; height: 24px; padding: 0;
  border: none; border-radius: 6px; background: transparent; color: var(--text-3); cursor: pointer;
  transition: background .15s, color .15s; }
.view-btn:hover { color: var(--text); }
.view-btn.active { background: var(--surface); color: var(--accent); box-shadow: var(--shadow); }
.view-btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }

/* вид «плитки» */
.file-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(148px, 1fr)); gap: 10px;
  user-select: none; }
.file-tile { display: flex; flex-direction: column; align-items: center; text-align: center; gap: 7px;
  padding: 16px 10px 12px; border: 1px solid transparent; border-radius: var(--radius-sm);
  transition: background .15s, border-color .15s, transform .15s; }
.file-tile:hover { background: var(--surface-2); transform: translateY(-1px); }
.file-tile:focus-visible { outline: 2px solid var(--accent); outline-offset: -2px; }
.file-tile.selected, .file-tile.selected:hover { background: var(--accent-soft); border-color: var(--accent); }
.tile-ic { position: relative; line-height: 0; margin-bottom: 2px; }
.ft-icon { display: inline-flex; line-height: 0; flex: none; filter: drop-shadow(0 1px 1.5px rgba(20,26,40,.18)); }
.tile-name { max-width: 100%; font-size: 12.5px; font-weight: 550; line-height: 1.3; word-break: break-word;
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; }
.tile-meta { font-size: 11.5px; color: var(--text-3); }

/* хранилище: папки и хлебные крошки */
.crumb-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px;
  padding: 5px 8px; background: var(--surface-2); border-radius: var(--radius-sm); }
.crumbs { display: flex; align-items: center; gap: 2px; flex-wrap: wrap; min-width: 0; }
.crumb { border: 0; background: none; padding: 3px 7px; border-radius: 6px; font: inherit; font-size: 13px;
  color: var(--accent-600); cursor: pointer; max-width: 260px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.crumb:hover { background: var(--surface); }
.crumb.cur { color: var(--text); font-weight: 600; cursor: default; }
.crumb-sep { color: var(--text-3); font-size: 13px; padding: 0 1px; }
.folder-tile { cursor: pointer; }
.folder-tile .tile-name { font-weight: 600; }
.folder-row .fname { font-weight: 600; }
.folder-empty { padding: 30px 10px; text-align: center; color: var(--text-2); font-size: 13px; }

/* статус-накладки на иконке и статус в таблице */
.st-badge { display: inline-grid; place-items: center; width: 18px; height: 18px; border-radius: 50%; flex: none; }
.st-badge svg { width: 11px; height: 11px; display: block; }
.st-badge.st-indexed svg { width: 13px; }
.st-done, .st-indexed { background: var(--green); }
.st-error { background: var(--red); cursor: help; }
.st-excluded { background: var(--text-3); }
.st-busy { background: var(--surface); border: 1px solid var(--border-strong); }
.st-badge .spinner { width: 10px; height: 10px; border-width: 2px; }
.tile-badge { position: absolute; right: -7px; bottom: -4px; box-shadow: 0 0 0 2px var(--surface); }
.file-tile:hover .tile-badge { box-shadow: 0 0 0 2px var(--surface-2); }
.file-tile.selected .tile-badge, .file-tile.selected:hover .tile-badge { box-shadow: 0 0 0 2px var(--accent-soft); }
.tile-chips { position: absolute; left: -12px; top: -7px; display: flex; flex-direction: column;
  align-items: flex-start; gap: 3px; }
.tile-chip { padding: 1px 6px; border-radius: 100px; font-size: 9.5px; font-weight: 700; line-height: 1.5;
  letter-spacing: .02em; box-shadow: 0 0 0 2px var(--surface); }
.file-tile:hover .tile-chip { box-shadow: 0 0 0 2px var(--surface-2); }
.file-tile.selected .tile-chip { box-shadow: 0 0 0 2px var(--accent-soft); }
.tile-chip.pii { background: var(--red); color: #fff; }
.tile-chip.tx { background: var(--amber); color: #fff; }
.file-status { display: inline-flex; align-items: center; gap: 7px; white-space: nowrap; }

/* вид «таблица» */
table.tbl.file-table .fcell-name { min-width: 260px; }
.fname-wrap { display: flex; align-items: center; gap: 9px; min-width: 0; }
.fname-wrap .badge { flex: none; }
.fname { font-weight: 600; min-width: 0; max-width: 380px; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.fcell-kebab { width: 36px; text-align: right; }
.kebab-btn { width: 28px; padding: 3px 0; font-size: 15px; font-weight: 700; line-height: 1; color: var(--text-3); }
.file-row .kebab-btn { opacity: .4; transition: opacity .15s; }
.file-row:hover .kebab-btn, .file-row.selected .kebab-btn, .kebab-btn:focus-visible { opacity: 1; }

/* контекстное меню */
.ctx-menu { position: fixed; z-index: 210; min-width: 220px; padding: 5px; background: var(--surface);
  border: 1px solid var(--border); border-radius: var(--radius-sm); box-shadow: var(--shadow-lg);
  animation: ctx-in .1s ease; user-select: none; }
@keyframes ctx-in { from { opacity: 0; transform: scale(.98); } }
.ctx-head { padding: 6px 11px 4px; font-size: 11px; font-weight: 700; color: var(--text-3);
  text-transform: uppercase; letter-spacing: .05em; }
.ctx-item { display: flex; align-items: center; gap: 10px; width: 100%; padding: 7px 11px; border: none;
  border-radius: 6px; background: transparent; color: var(--text); font: inherit; font-size: 13px;
  text-align: left; cursor: pointer; transition: background .12s; }
.ctx-item:hover { background: var(--surface-2); }
.ctx-item.danger { color: var(--red); }
.ctx-item.danger:hover { background: var(--red-soft); }
.ctx-ic { display: inline-grid; place-items: center; width: 16px; height: 16px; flex: none; color: var(--text-2); }
.ctx-ic .ic { width: 15px; height: 15px; }
.ctx-item.danger .ctx-ic { color: var(--red); }
.ctx-glyph { font-size: 13.5px; font-weight: 700; line-height: 1; }
.ctx-sep { height: 1px; margin: 5px 7px; background: var(--border); }

/* tooltip имени файла (суммаризация в markdown, ограничена по высоте) */
.file-tooltip { max-width: 340px; min-width: 220px; z-index: 220; padding: 11px 13px; }
.file-tooltip .tip-name { display: block; margin-bottom: 2px; font-size: 13px; word-break: break-word; }
.tip-summary { position: relative; max-height: 180px; overflow: hidden; margin-top: 8px; }
.tip-summary::after { content: ''; position: absolute; left: 0; right: 0; bottom: 0; height: 36px;
  background: linear-gradient(transparent, var(--surface)); pointer-events: none; }
.tip-summary .md-body { font-size: 12.5px; line-height: 1.55; }
.tip-summary .md-body h2 { font-size: 13.5px; margin: 8px 0 4px; }
.tip-summary .md-body h3, .tip-summary .md-body h4, .tip-summary .md-body h5 { font-size: 12.5px; margin: 7px 0 3px; }
.tip-summary .md-body p { margin: 5px 0; }

/* суммаризация в модалке просмотра файла */
.view-summary { margin: 0 0 12px; padding: 10px 14px; background: var(--surface-2);
  border-left: 3px solid var(--accent); border-radius: 0 var(--radius-sm) var(--radius-sm) 0; }
.view-summary .md-body { font-size: 13px; }

/* drag&drop: плейсхолдер пустого хранилища и оверлей при перетаскивании */
.drop-placeholder { display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 8px;
  padding: 46px 20px; border: 2px dashed var(--border-strong); border-radius: var(--radius-sm);
  color: var(--text-2); text-align: center; transition: border-color .15s, background .15s, color .15s; }
.drop-placeholder .ic { width: 36px; height: 36px; color: var(--text-3); }
.drop-placeholder.clickable { cursor: pointer; }
.drop-placeholder.clickable:hover { border-color: var(--accent); background: var(--accent-soft); color: var(--accent-600); }
.drop-placeholder.clickable:hover .ic { color: var(--accent); }
.dropzone-over .drop-overlay { position: absolute; inset: 0; z-index: 6; display: flex; align-items: center;
  justify-content: center; border-radius: var(--radius); pointer-events: none;
  background: rgba(238, 240, 254, .92);
  background: color-mix(in srgb, var(--accent-soft) 92%, transparent); }
.drop-overlay-inner { display: flex; flex-direction: column; align-items: center; gap: 8px; padding: 24px 40px;
  border: 2px dashed var(--accent); border-radius: var(--radius); color: var(--accent-600); }
.drop-overlay-inner .ic { width: 34px; height: 34px; }
.drop-overlay-inner b { font-size: 15.5px; }
.drop-overlay-inner .small { opacity: .85; font-weight: 500; }

/* чат ИИ-аналитика */
.chat-layout { display: flex; gap: 14px; height: calc(100vh - 104px); min-height: 380px; }

/* левая панель: диалоги */
.chat-side { width: 260px; flex: none; display: flex; flex-direction: column; gap: 10px;
  padding: 12px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius); box-shadow: var(--shadow); overflow: hidden; }
.chat-back { color: var(--text-2); font-weight: 550; }
.chat-back:hover { color: var(--accent); }
.chat-new { width: 100%; }
.chat-dialog-list { flex: 1; min-height: 0; overflow-y: auto; display: flex; flex-direction: column;
  gap: 4px; margin: 0 -4px; padding: 0 4px; }
.chat-side-empty { padding: 12px 6px; text-align: center; }
.chat-dialog-item { display: flex; align-items: flex-start; gap: 6px; padding: 8px 10px;
  border: 1px solid transparent; border-radius: var(--radius-sm); cursor: pointer;
  transition: background .12s, border-color .12s; }
.chat-dialog-item:hover { background: var(--surface-2); }
.chat-dialog-item.active { background: var(--accent-soft); border-color: var(--accent); }
.chat-dialog-body { flex: 1; min-width: 0; }
.chat-dialog-title { font-size: 13px; font-weight: 550; line-height: 1.35; word-break: break-word;
  overflow: hidden; display: -webkit-box; -webkit-line-clamp: 2; line-clamp: 2; -webkit-box-orient: vertical; }
.chat-dialog-meta { margin-top: 2px; font-size: 11.5px; color: var(--text-3);
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.chat-dialog-del { flex: none; width: 20px; height: 20px; padding: 0; border: none; border-radius: 6px;
  background: transparent; color: var(--text-3); font-size: 12px; line-height: 1; cursor: pointer;
  opacity: 0; transition: opacity .12s, background .12s, color .12s; }
.chat-dialog-item:hover .chat-dialog-del, .chat-dialog-del:focus-visible { opacity: 1; }
.chat-dialog-del:hover { background: var(--red-soft); color: var(--red); }
.chat-rename { padding: 4px 8px; font-size: 13px; }

/* правая часть: лента сообщений */
.chat-main { flex: 1; min-width: 0; display: flex; flex-direction: column;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow); overflow: hidden; }
.chat-thread { flex: 1; min-height: 0; overflow-y: auto; padding: 18px 22px; }
.chat-thread-inner { max-width: 820px; min-height: 100%; margin: 0 auto;
  display: flex; flex-direction: column; gap: 16px; }
.chat-msg.user { display: flex; justify-content: flex-end; }
.chat-msg.user .chat-bubble { max-width: 70%; padding: 9px 14px; background: var(--accent-soft);
  border-radius: 14px 14px 4px 14px; line-height: 1.55; white-space: pre-wrap; word-break: break-word; }
.chat-msg.assistant { display: flex; align-items: flex-start; gap: 10px; }
.chat-avatar { flex: none; width: 28px; height: 28px; margin-top: 2px; border-radius: 50%;
  background: var(--accent-soft); color: var(--accent); display: grid; place-items: center; }
.chat-avatar .ic { width: 15px; height: 15px; }
.chat-msg-body { flex: 1; min-width: 0; }
.chat-stream-text { line-height: 1.65; white-space: pre-wrap; word-break: break-word; }
.chat-typing { display: inline-flex; align-items: center; gap: 8px; }
.chat-msg-err { margin-top: 6px; color: var(--red); }

/* свёрнутый блок источников под ответом */
.chat-sources { margin-top: 10px; }
.chat-sources > summary { cursor: pointer; user-select: none; font-size: 12.5px; font-weight: 600;
  color: var(--text-2); }
.chat-sources > summary:hover { color: var(--accent); }
.chat-sources-list { display: flex; flex-direction: column; gap: 6px; margin-top: 8px; }

/* композер */
.chat-composer { flex: none; padding: 12px 22px 16px; border-top: 1px solid var(--border);
  background: var(--surface); }
.chat-composer-inner { max-width: 820px; margin: 0 auto; display: flex; gap: 8px; align-items: flex-end; }
.chat-input { resize: none; overflow-y: auto; max-height: 132px; line-height: 1.45; }
.chat-send { flex: none; width: 38px; height: 38px; padding: 0; border-radius: 50%; }

/* пустое состояние по центру ленты */
.chat-hello { flex: 1; display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 8px; padding: 40px 20px; text-align: center; color: var(--text-2); }
.chat-hello .ic { width: 40px; height: 40px; color: var(--accent); opacity: .85; }
.chat-hello b { font-size: 16px; color: var(--text); }

/* быстрая навигация по отчёту: чипы разделов липнут к верху ленты,
   текущий раздел подсвечен — отчёт занимает несколько экранов */
.ans-nav { position: sticky; top: 0; z-index: 3; display: flex; flex-wrap: wrap; gap: 5px;
  padding: 7px 0 8px; margin-bottom: 4px; background: var(--surface);
  border-bottom: 1px solid var(--border); }
.ans-nav-chip { border: 1px solid var(--border); background: var(--surface-2); color: var(--text-2);
  border-radius: 999px; padding: 3px 11px; font-size: 12px; line-height: 1.5; cursor: pointer;
  max-width: 220px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  transition: background .12s, color .12s, border-color .12s; }
.ans-nav-chip:hover { border-color: var(--accent); color: var(--accent); }
.ans-nav-chip.sub { font-size: 11.5px; padding: 2px 9px; opacity: .82; }
.ans-nav-chip.active { background: var(--accent-soft); border-color: var(--accent); color: var(--accent);
  font-weight: 600; }

/* аннотация «Кратко»: выводы видны без чтения всего отчёта */
.ans-summary { border: 1px solid var(--accent); border-left-width: 3px; background: var(--accent-soft);
  border-radius: var(--radius-sm); padding: 4px 14px 10px; margin: 10px 0 14px; }
.ans-summary > h3 { margin-top: 8px; color: var(--accent); }
.ans-summary > :last-child { margin-bottom: 0; }

/* сноска-факт [F#] ультра-ответа и её подсказка-паспорт (период, метод,
   выборка, название исследования — единая структура, см. chat.js factTip*) */
/* без user-select:none: бейдж входит в выделенный текст так же, как в «стог»
   отметок «Замечаний» (feedback.js) — иначе выделение через сноску не
   находилось и отметка не наносилась */
.fact-ref { font-size: 9.5px; font-weight: 700; color: var(--accent); cursor: help;
  margin: 0 1px; padding: 0 2px; border-radius: 3px; }
/* Наведение — полупрозрачной подсветкой: блок «Кратко» (.ans-summary) залит
   тем же accent-soft, и на нём подсветка сноски была не видна вовсе.
   Раскрытая сноска остаётся на accent-soft: это состояние, а не наведение. */
.fact-ref:hover { background: var(--link-hl); }
.fact-ref.open { background: var(--accent-soft); }
.fact-ref:focus-visible { outline: 2px solid var(--accent); outline-offset: 1px; }
/* Подсказка ИНТЕРАКТИВНА (pointer-events: auto): в ней ссылка на карточку
   исследования, из неё копируют текст факта и прокручивают его, если факт
   длинный. Высоту выставляет factTipPlace по свободному месту. */
.fact-tip { position: fixed; z-index: 230; width: max-content; max-width: min(440px, calc(100vw - 16px));
  max-height: calc(100vh - 16px); overflow-y: auto; overscroll-behavior: contain;
  padding: 10px 12px 9px;
  background: var(--surface); color: var(--text); border: 1px solid var(--border);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); font-size: 12.5px;
  line-height: 1.45; }
/* ссылка на карточку исследования в строке «Наименование исследования» и в
   списке сводного факта */
.fact-tip-link { color: var(--accent); text-decoration: none;
  word-break: break-word; }
.fact-tip-link:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.fact-tip-ext { margin-left: 4px; font-size: 10.5px; color: var(--text-3); }
.fact-tip-link:hover .fact-tip-ext { color: var(--accent); }
.fact-tip-head { display: flex; align-items: baseline; gap: 7px; margin-bottom: 7px;
  font-size: 11.5px; color: var(--text-3); }
.fact-tip-head b { color: var(--accent); font-size: 12.5px; }
.fact-tip-rows { display: grid; grid-template-columns: max-content minmax(0, 1fr); gap: 3px 12px; }
/* строка — не ячейка: подпись и значение встают в колонки общей сетки */
.fact-tip-row { display: contents; }
.fact-tip-k { color: var(--text-2); white-space: nowrap; }
.fact-tip-v { font-weight: 500; word-break: break-word; }
.fact-tip-v.na { color: var(--text-3); font-weight: 400; }
.fact-tip-hint { display: block; color: var(--text-3); font-weight: 400; font-size: 11.5px; }
.fact-tip-note { color: var(--text-2); font-size: 12px; margin-bottom: 4px; }
.fact-tip-foot { margin: 6px 0 0; color: var(--text-3); font-size: 11.5px; }
.fact-tip-list { display: flex; flex-direction: column; gap: 6px; margin-top: 2px; }
.fact-tip-research { padding-top: 6px; border-top: 1px dashed var(--border); }
.fact-tip-research > b { display: block; word-break: break-word; }
.fact-tip-line { color: var(--text-2); font-size: 12px; line-height: 1.4; word-break: break-word; }
/* Текст самого факта — внизу и ЦЕЛИКОМ. Раньше он был обрезан тремя строками
   (а на сервере — 180 символами), и расчёт на 400 символов с долями и
   доверительными интервалами обрывался посреди слова: читалось как потеря
   данных. Подсказка прокручивается, если места не хватило. */
.fact-tip-fact { margin-top: 8px; padding-top: 7px; border-top: 1px solid var(--border);
  color: var(--text-2); font-size: 11.5px; line-height: 1.45; word-break: break-word; }

/* графики: карточка встаёт по месту в тексте, остаток — сеткой под ответом */
.chart-card { padding: 10px 12px; min-width: 0; margin: 10px 0; }
/* 300px вместо 260px: подпись столбика — вариант ответа целиком, и на 260px
   даже в две строки от него оставался обрубок; легенде круговой (230px) при
   такой ширине есть шанс встать рядом с кругом 130px */
.chart-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
  gap: 10px; margin-top: 10px; }
.chart-grid .chart-card { margin: 0; }

/* плеер под цитатой респондента в ответе ИИ-аналитика: цитату можно
   прослушать с её тайминга — доказательство «это правда сказали» */
.quote-player { margin: -4px 0 12px; padding-left: 15px; }
.quote-player-row { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.quote-play { display: inline-flex; gap: 5px; align-items: center; font-family: var(--mono);
  font-size: 12px; padding: 3px 9px; }
.quote-play-ic { display: inline-flex; line-height: 0; }
.quote-player audio { width: 100%; max-width: 480px; display: block; height: 36px; margin-top: 8px; }
.quote-player video { width: 100%; max-width: 480px; display: block; max-height: 280px;
  margin-top: 8px; background: #000; border-radius: var(--radius-sm); }

/* просмотр транскрибации: плеер + синхронизированный диалог */
.tr-sticky { position: sticky; top: 0; z-index: 2; background: var(--surface);
  margin: 0 -20px 12px; padding: 10px 20px 12px; border-bottom: 1px solid var(--border); }
.tr-player audio { width: 100%; display: block; height: 40px; }
.tr-player video { width: 100%; display: block; max-height: 340px; background: #000;
  border-radius: var(--radius-sm); }
.tr-player .loading { padding: 8px 0; }
.tr-search-row { display: flex; gap: 10px; align-items: center; margin-top: 10px; flex-wrap: wrap; }
.tr-follow { display: inline-flex; gap: 6px; align-items: center; cursor: pointer; white-space: nowrap; }
.tr-list { display: flex; flex-direction: column; gap: 2px; }
.tr-seg { padding: 8px 10px; border-radius: var(--radius-sm); }
.tr-seg.hidden { display: none; }
.tr-seg.seekable { cursor: pointer; }
.tr-seg.seekable:hover { background: var(--surface-2); }
.tr-seg.active { background: var(--accent-soft); box-shadow: inset 3px 0 0 var(--accent); }
.tr-seg .tr-head { display: flex; gap: 10px; align-items: baseline; margin-bottom: 2px; }
.tr-seg .tr-head b { font-size: 13px; }
.tr-seg.mod .tr-head b { color: var(--accent); }
.tr-ts { font-family: var(--mono); font-size: 12px; color: var(--accent); }
.tr-text { white-space: pre-wrap; }
.tr-text mark { background: var(--amber-soft); color: inherit; border-radius: 3px; padding: 0 1px; }

/* просмотр файла: инлайн-правка тегов и суммаризации */
.view-tags-row { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 8px; }
.view-tags-row .view-tags-label { width: 64px; flex: none; padding-top: 7px; }

/* --- чат: скоуп сквозного анализа (всплывающее дерево справа) --- */
.chat-main { position: relative; }
.chat-scope-btn { display: inline-flex; align-items: center; gap: 6px; }
.chat-scope-panel { position: absolute; top: 10px; right: 10px; bottom: 10px; width: 420px;
  max-width: 88%; background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: 0 14px 44px rgba(0,0,0,.20); z-index: 40;
  display: flex; flex-direction: column; }
.chat-scope-head { display: flex; align-items: center; gap: 8px; padding: 12px 14px;
  border-bottom: 1px solid var(--border); font-weight: 650; }
.chat-scope-head .chat-scope-close { margin-left: auto; }
.chat-scope-body { flex: 1; overflow: auto; padding: 8px 14px 12px; }
.chat-scope-sec { margin: 12px 0 5px; font-weight: 650; font-size: 11.5px;
  color: var(--text-2); text-transform: uppercase; letter-spacing: .4px; }
.chat-scope-row { display: flex; align-items: center; gap: 8px; padding: 3px 2px;
  font-size: 13.5px; cursor: pointer; border-radius: 6px; }
.chat-scope-row:hover { background: var(--surface-2); }
.chat-scope-row input { cursor: pointer; flex: none; }
.chat-scope-row .muted { margin-left: auto; }
/* строка исследования: название + паспорт (период · география · опрошено).
   Паспорт переносится, а не обрезается: обрезка съедала бы выборку — то самое,
   по чему исследования и различают */
.chat-scope-row.two-line { align-items: flex-start; padding: 5px 2px; }
.chat-scope-row.two-line > input { margin-top: 3px; }
.chat-scope-rowbody { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.chat-scope-rowtitle { min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; }
.chat-scope-sub { margin-top: 1px; font-size: 11.5px; line-height: 1.35; color: var(--text-3); }
/* чип исследования в конструкторах: название + период под ним */
.research-chip { display: inline-flex; flex-direction: column; align-items: flex-start;
  gap: 1px; line-height: 1.25; text-align: left; }
.research-chip-sub { font-size: 10.5px; opacity: .72; font-weight: 500; }
.chat-scope-empty { font-size: 12.5px; color: var(--text-2); padding: 2px 2px 6px; }
.chat-scope-foot { display: flex; gap: 8px; padding: 10px 14px; border-top: 1px solid var(--border); }
.chat-composer-tools { max-width: 820px; margin: 0 auto; display: flex; align-items: center; gap: 12px; }

/* --- чат: шестерёнка режимов ответа (слева под композером) ---
   Тумблеры режимов и глубина поиска убраны с полосы инструментов в выпадающую
   панель; счётчик на кнопке показывает, сколько режимов включено */
.chat-modes-wrap { position: relative; flex: none; }
.chat-modes-btn { display: inline-flex; align-items: center; gap: 6px; }
.chat-modes-panel { position: absolute; left: 0; bottom: calc(100% + 8px); width: 440px;
  max-width: calc(100vw - 48px); background: var(--surface); border: 1px solid var(--border);
  border-radius: 12px; box-shadow: 0 14px 44px rgba(0,0,0,.20); z-index: 40;
  padding: 10px 14px 12px; }
.chat-modes-head { font-weight: 650; font-size: 11.5px; color: var(--text-2);
  text-transform: uppercase; letter-spacing: .4px; margin: 2px 0 6px; }
.chat-modes-row { display: flex; align-items: center; gap: 10px; padding: 4px 0; }
.chat-modes-row .chat-tool-btn { flex: none; width: 150px; justify-content: center; }
.chat-modes-row .small { line-height: 1.3; }

/* --- чат: свёрнутый ход анализа в ответе --- */
.chat-steps { margin: 2px 0 8px; }
.chat-steps > summary { cursor: pointer; user-select: none; font-size: 12.5px; font-weight: 600;
  color: var(--text-2); }
.chat-steps > summary:hover { color: var(--accent); }
.chat-steps-list { padding: 6px 0 2px 6px; display: flex; flex-direction: column; gap: 3px; }
.chat-scope-search { margin: 2px 0 6px; padding: 6px 10px; font-size: 13px; width: 100%; }

/* --- чат в разделе «ИИ-аналитик»: над лентой есть полоса вкладок, поэтому
       на неё нужно оставить высоту; исследования выбирает пользователь --- */
.chat-layout.chat-embedded { height: calc(100vh - 162px); }
/* --- панель скоупа: описание исследования, шкала периода, массовый выбор ---
   Пользователи путались, ЧТО за исследования в списке: одного названия и
   паспорта мало. Под паспортом — описание (или темы из тегов), поиск идёт и
   по нему; период фильтруется шкалой с двумя ползунками. */
.chat-scope-desc { margin-top: 2px; font-size: 11.5px; line-height: 1.35; color: var(--text-2);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.chat-scope-desc.is-tags { color: var(--text-3); font-style: italic; }
.chat-scope-tools { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 0 0 6px; font-size: 12.5px; color: var(--text-2); }
.lnk { background: none; border: 0; padding: 0; color: var(--accent-600);
  font: inherit; font-size: 12.5px; cursor: pointer; }
.lnk:disabled { color: var(--text-3); cursor: default;
  background: none; box-shadow: none; }
/* строка «подобрать по вопросу» вверху раздела исследований */
.chat-scope-auto { display: flex; align-items: center; gap: 8px; padding: 8px 10px; margin: 4px 0 8px;
  border: 1px dashed var(--border-strong); border-radius: 8px; background: var(--surface-2); }
.chat-scope-auto .small { flex: 1; min-width: 0; line-height: 1.3; }
/* шкала периода: два наложенных range-инпута */
.chat-timeline { margin: 4px 0 8px; }
.chat-timeline-head { display: flex; align-items: baseline; gap: 8px; font-size: 12.5px; }
.chat-timeline-head b { font-weight: 600; color: var(--text); }
.chat-timeline-head .lnk { margin-left: auto; }
.chat-timeline-track { position: relative; height: 34px; margin: 2px 6px 0; }
.chat-timeline-track input[type=range] { position: absolute; left: 0; right: 0; top: 4px; width: 100%;
  margin: 0; height: 18px; background: none; -webkit-appearance: none; appearance: none;
  pointer-events: none; }
.chat-timeline-track input[type=range]::-webkit-slider-runnable-track { height: 4px; background: transparent; }
.chat-timeline-track input[type=range]::-moz-range-track { height: 4px; background: transparent; }
.chat-timeline-track input[type=range]::-webkit-slider-thumb { -webkit-appearance: none; appearance: none;
  width: 16px; height: 16px; margin-top: -6px; border-radius: 50%; background: var(--surface);
  border: 2px solid var(--accent); box-shadow: 0 1px 3px rgba(0,0,0,.2); cursor: grab;
  pointer-events: auto; }
.chat-timeline-track input[type=range]::-moz-range-thumb { width: 12px; height: 12px; border-radius: 50%;
  background: var(--surface); border: 2px solid var(--accent); cursor: grab; pointer-events: auto; }
.chat-timeline-track input[type=range]:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 3px var(--accent-soft); }
.chat-timeline-rail { position: absolute; left: 0; right: 0; top: 11px; height: 4px; border-radius: 2px;
  background: var(--border); }
.chat-timeline-fill { position: absolute; top: 11px; height: 4px; border-radius: 2px; background: var(--accent); }
/* засечки: где на шкале лежат исследования */
.chat-timeline-dots { position: absolute; left: 0; right: 0; top: 20px; height: 6px; }
.chat-timeline-dot { position: absolute; top: 0; width: 4px; height: 4px; margin-left: -2px; border-radius: 50%;
  background: var(--text-3); opacity: .55; }
.chat-timeline-dot.in { background: var(--accent); opacity: .9; }
.chat-timeline-ticks { position: relative; height: 14px; margin: 0 6px; font-size: 10.5px; color: var(--text-3); }
.chat-timeline-tick { position: absolute; top: 0; transform: translateX(-50%); white-space: nowrap; }
.chat-timeline-tick::before { content: ''; position: absolute; left: 50%; top: -6px; width: 1px; height: 4px;
  background: var(--border-strong); }
.chat-timeline-foot { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin-top: 4px;
  font-size: 12px; color: var(--text-2); }
.chat-timeline-foot label { display: inline-flex; align-items: center; gap: 5px; cursor: pointer; }
.chat-timeline-foot input { margin: 0; }

/* --- дерево групп в панели скоупа --- */
.chat-tree-row { gap: 6px; }
.chat-tree-tg { width: 18px; height: 18px; flex: none; border: 0; background: none; padding: 0;
  color: var(--text-3); cursor: pointer; display: inline-flex; align-items: center;
  justify-content: center; border-radius: 4px; }
.chat-tree-tg:hover { background: var(--surface-2); color: var(--text); }
.chat-tree-tg svg { transition: transform .12s; }
.chat-tree-tg.open svg { transform: rotate(90deg); }
.chat-tree-tg.spacer { cursor: default; }
.chat-tree-row.depth0 .chat-scope-rowtitle { font-weight: 600; }
.chat-tree-cnt { margin-left: auto; font-size: 11.5px; color: var(--text-3); padding-left: 8px; }

/* --- управление группами исследований (администратор) --- */
.grp-layout { display: grid; grid-template-columns: 380px minmax(0, 1fr); gap: 16px; align-items: start; }
@media (max-width: 1000px) { .grp-layout { grid-template-columns: 1fr; } }
.grp-tree-row { display: flex; align-items: center; gap: 6px; padding: 5px 8px 5px 6px; border-radius: 8px;
  cursor: pointer; font-size: 13.5px; user-select: none; }
.grp-tree-row:hover { background: var(--surface-2); }
.grp-tree-row.sel { background: var(--accent-soft); color: var(--accent-600); }
.grp-tree-row.root .grp-name { font-weight: 600; }
.grp-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.grp-cnt { margin-left: auto; font-size: 11.5px; color: var(--text-3); white-space: nowrap; padding-left: 8px; }
.grp-tree-row.sel .grp-cnt { color: inherit; opacity: .8; }
.grp-member { display: flex; gap: 10px; align-items: flex-start; padding: 9px 0; border-bottom: 1px solid var(--border); }
.grp-member:last-child { border-bottom: 0; }
.grp-member-title { font-weight: 600; font-size: 13.5px; background: none; border: 0; padding: 0; color: var(--text);
  cursor: pointer; text-align: left; font-family: inherit; }
.grp-member-title:hover { color: var(--accent); }
.grp-chips { display: flex; flex-wrap: wrap; gap: 4px 6px; margin-top: 5px; align-items: center; }
.grp-add-list { border: 1px solid var(--border); border-radius: 8px; max-height: 280px; overflow: auto; margin-top: 6px;
  background: var(--surface); }
.grp-add-row { display: flex; gap: 8px; align-items: center; padding: 7px 10px; border-bottom: 1px solid var(--border); }
.grp-add-row:last-child { border-bottom: 0; }
.grp-add-row:hover { background: var(--surface-2); }

/* --- архив: полоса фоновых операций (описания, дерево групп) --- */
.ops-row { padding: 10px 14px; border: 1px solid var(--border); border-radius: var(--radius-sm);
  background: var(--surface); }
.ops-head { display: flex; align-items: center; gap: 8px; font-size: 13px; }
.ops-track { height: 4px; border-radius: 2px; background: var(--border); margin-top: 8px; overflow: hidden; }
.ops-fill { height: 100%; background: var(--accent); transition: width .3s; }

/* --- модальное окно подборки исследований под вопрос --- */
.modal.scope-pick { max-width: 920px; width: min(94vw, 920px); max-height: 90vh; display: flex;
  flex-direction: column; overflow: hidden; }
.modal.scope-pick .modal-h, .modal.scope-pick .modal-f { flex: none; }
.modal.scope-pick .modal-b { flex: 1; min-height: 0; overflow: auto; padding: 14px 20px 16px; }
.modal.scope-pick .modal-f { justify-content: flex-start; align-items: center; flex-wrap: wrap; }
.modal.scope-pick .modal-f .spacer { flex: 1; }
.sp-q { font-size: 13px; color: var(--text-2); margin: 0 0 10px; line-height: 1.45; }
.sp-q b { color: var(--text); font-weight: 600; }
.sp-crit { display: flex; flex-wrap: wrap; gap: 6px 8px; align-items: center; margin: 0 0 10px; }
.sp-crit .lbl { font-size: 11.5px; font-weight: 650; color: var(--text-2); text-transform: uppercase;
  letter-spacing: .4px; margin-right: 2px; }
.sp-chip { display: inline-flex; align-items: center; gap: 5px; padding: 3px 9px; border-radius: 100px;
  font-size: 12px; background: var(--surface-2); border: 1px solid var(--border); color: var(--text);
  max-width: 100%; }
.sp-chip.accent { background: var(--accent-soft); border-color: transparent; color: var(--accent-600); }
.sp-chip .x { border: 0; background: none; padding: 0 0 0 2px; cursor: pointer; color: inherit;
  font: inherit; line-height: 1; opacity: .7; }
.sp-chip .x:hover { opacity: 1; }
.sp-note { margin: 0 0 12px; padding: 9px 12px; border-radius: 8px; background: var(--accent-soft);
  color: var(--accent-600); font-size: 13px; line-height: 1.45; display: flex; gap: 8px; align-items: flex-start; }
.sp-note.warn { background: var(--amber-soft); color: var(--amber); }
.sp-note .ic { width: 16px; height: 16px; flex: none; margin-top: 1px; }
.sp-sec { display: flex; align-items: center; gap: 8px; margin: 12px 0 5px; font-weight: 650;
  font-size: 11.5px; color: var(--text-2); text-transform: uppercase; letter-spacing: .4px; }
.sp-sec .lnk { margin-left: auto; text-transform: none; letter-spacing: 0; font-weight: 500; font-size: 12px; }
.sp-row { display: flex; align-items: flex-start; gap: 10px; padding: 7px 8px; border-radius: 8px;
  cursor: pointer; border: 1px solid transparent; }
.sp-row:hover { background: var(--surface-2); }
.sp-row.on { background: var(--accent-soft); border-color: transparent; }
.sp-row.locked { cursor: default; opacity: .9; }
.sp-row > input { margin-top: 3px; flex: none; cursor: pointer; }
.sp-row-body { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 1px; }
.sp-row-title { font-size: 13.5px; font-weight: 600; color: var(--text); overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.sp-row-sub { font-size: 11.5px; color: var(--text-3); line-height: 1.35; }
.sp-row-desc { font-size: 12px; color: var(--text-2); line-height: 1.4; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.sp-row-why { font-size: 12px; color: var(--accent-600); line-height: 1.4; margin-top: 1px; }
.sp-row-sig { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 3px; }
.sp-sig { font-size: 10.5px; padding: 1px 7px; border-radius: 100px; background: var(--surface-2);
  border: 1px solid var(--border); color: var(--text-2); white-space: nowrap; }
.sp-sig.ok { background: var(--green-soft); color: var(--green); border-color: transparent; }
.sp-sig.bad { background: var(--red-soft); color: var(--red); border-color: transparent; }
.sp-more { padding: 6px 8px 0; }
.sp-more .input { margin: 4px 0 6px; padding: 6px 10px; font-size: 13px; width: 100%; }
.sp-empty { font-size: 13px; color: var(--text-2); padding: 8px; }
.sp-progress { display: flex; flex-direction: column; align-items: center; gap: 10px; padding: 34px 10px 30px;
  color: var(--text-2); font-size: 13.5px; text-align: center; }
.sp-progress .step { font-size: 12.5px; color: var(--text-3); }
.sp-count { font-size: 13px; color: var(--text-2); }
/* чипы выбранных исследований на пустом экране раздела */
.chat-hello-scope { display: flex; flex-wrap: wrap; justify-content: center; gap: 6px; max-width: 640px;
  margin-top: 4px; }
.chat-hello-scope .sp-chip { max-width: 300px; }
.chat-hello-scope .sp-chip span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.chat-hello-hint { font-size: 12.5px; color: var(--text-3); max-width: 560px; text-align: center;
  line-height: 1.45; }
/* базовое исследование диалога: снять нельзя */
.chat-scope-row.locked { cursor: default; opacity: .95; }
.chat-scope-row.locked:hover { background: transparent; }
.chat-scope-row.locked input { cursor: default; }
/* Требование выбрать исследование — только ВНУТРИ панели ручного выбора: там
   человек выбирает сам, и пустой список действительно ни к чему не приведёт.
   На самой кнопке скоупа подсветки нет: пустой выбор — нормальное начало
   нового диалога, вопрос по нему запускает автоподбор. */
.chat-scope-req { font-size: 12.5px; color: var(--red); padding: 0 2px 4px; }
/* Кнопка действия на пустом экране — одинаковая во всех вкладках раздела.
   Сплошной заливки нет намеренно: акцент темы — насыщенный оранжевый, и
   залитый им блок посреди пустого экрана перетягивал на себя всё внимание.
   Текст берём accent-600, а не accent: в светлой корпоративной теме
   #dd6b1e на подложке даёт контраст 2,9:1 — нечитаемо. Подложка — surface,
   а не accent-soft: заливка accent-soft в продукте уже означает «выбрано»
   (.chat-dialog-item.active, .nav-item.active), и кнопка читалась бы как
   подсвеченный элемент списка. accent-soft оставлен наведению — так hover
   усиливает кнопку, а не гасит её. */
.chat-hello .btn.chat-hello-cta {
  margin-top: 6px; padding: 9px 16px; font-size: 14px; font-weight: 600;
  border-color: var(--accent); color: var(--accent-600); background: var(--surface);
}
/* специфичность выше .btn:hover (0,2,0), иначе фон откатывался к --surface-2 */
.chat-hello .btn.chat-hello-cta:hover { background: var(--accent-soft);
  border-color: var(--accent-600); color: var(--accent-600); }
.chat-hello .btn.chat-hello-cta:focus-visible { outline: 2px solid var(--accent);
  outline-offset: 2px; }
/* в разделе диалоги идут по всем исследованиям — подпись базового */
.chat-dialog-res { margin-top: 2px; font-size: 11.5px; color: var(--accent);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* ---------- Кросс-анализ: тот же каркас, что у чата ----------
   Метафору переписки НЕ берём: результат — карточка с паспортом среза, а не
   пузырь с аватаркой. Здесь считает SQL, а не модель, и вид не должен врать. */
.ct-layout .chat-thread { padding: 16px 18px; }
.ct-layout .chat-thread-inner { max-width: 980px; gap: 14px; }
.ct-card { margin: 0; }
.ct-card .card-b { padding: 14px 16px; }
.ct-pending { opacity: .85; }

/* формула среза в композере: [целевое поле] × [разбивка] */
.ct-formula { align-items: center; gap: 8px; max-width: 980px; }
.ct-slot { flex: 1; min-width: 0; justify-content: flex-start; text-align: left;
  font-weight: 500; color: var(--text-2); border-style: dashed; }
.ct-slot.filled { color: var(--text); border-style: solid; border-color: var(--accent); }
.ct-slot-label { display: block; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.ct-x { color: var(--text-3); font-size: 15px; flex: none; }
.ct-swap { flex: none; padding: 6px 9px; }

/* условия отбора — компактные чипы, редактор открывается по клику */
.ct-tools { max-width: 980px; flex-wrap: wrap; gap: 8px; }
.ct-filters { display: flex; flex-wrap: wrap; gap: 6px; }
.ct-chip { display: inline-flex; align-items: center; gap: 6px; max-width: 260px; }
.ct-chip > span:first-child { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.ct-chip.unset { border-style: dashed; color: var(--text-2); }
.ct-chip.missing { border-color: var(--amber); color: var(--amber); }
.ct-chip-x { flex: none; opacity: .6; font-size: 11px; }
.ct-chip-x:hover { opacity: 1; }
.ct-add-filter { flex: none; border-style: dashed; }

/* размер среза до расчёта */
.ct-base { font-size: 12.5px; color: var(--text-2); white-space: nowrap;
  font-variant-numeric: tabular-nums; }
.ct-base.low { color: var(--amber); font-weight: 600; }
.ct-base.warn { color: var(--red); font-weight: 600; }
.ct-run { flex: none; }

/* всплывающая панель поля/условия — над композером, во всю ширину:
   формулировки вопросов длинные, узкая колонка их режет */
.ct-pop { position: absolute; left: 12px; right: 12px; bottom: 96px; z-index: 41;
  display: flex; justify-content: center; }
.ct-pop-box { width: 100%; max-width: 860px; max-height: 58vh; background: var(--surface);
  border: 1px solid var(--border); border-radius: 12px;
  box-shadow: 0 14px 44px rgba(0,0,0,.20); display: flex; flex-direction: column; }
.ct-pop-body { flex: 1; overflow: auto; padding: 10px 14px 12px; }
.ct-pop-list { display: flex; flex-direction: column; }
.ct-pop-row { cursor: pointer; }
.ct-pop-row.active { background: var(--accent-soft); }
.ct-pop-title { line-height: 1.35; }
.ct-pop-clear { color: var(--text-2); font-style: italic; }
.ct-editor-field { margin-bottom: 10px; }
.ct-mode-row { display: flex; align-items: center; gap: 6px; margin: 8px 0; flex-wrap: wrap; }
.ct-custom { margin-top: 4px; }
.ct-hint { padding: 8px 14px 12px; font-size: 12px; color: var(--text-3); }

/* паспорт среза в шапке карточки — доказуемость числа */
.ct-passport { display: flex; flex-wrap: wrap; gap: 5px; align-items: center;
  margin-bottom: 10px; }
.ct-warn { margin: 0 0 10px; }
.ct-saved { margin-bottom: 8px; padding: 6px 10px; border-radius: 8px;
  background: var(--surface-2); color: var(--text-2); }
.ct-actions { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  margin-top: 12px; padding-top: 10px; border-top: 1px solid var(--border); }
.ct-json { margin: 8px 0 0; padding: 10px; background: var(--surface-2);
  border-radius: 8px; font-size: 11.5px; overflow: auto; max-height: 240px;
  font-family: var(--mono, ui-monospace, monospace); }
.ct-match { margin-bottom: 10px; }

/* исследование, по которому кросс-анализ считать не может */
.chat-scope-row.ct-nofields .chat-scope-rowtitle { color: var(--text-2); }
.ct-nofields-note { margin-top: 1px; font-size: 11.5px; line-height: 1.35;
  color: var(--amber); }
.ct-onlyfields { display: flex; align-items: center; gap: 7px; padding: 2px 2px 6px;
  font-size: 12.5px; color: var(--text-2); cursor: pointer; }
.ct-onlyfields input { cursor: pointer; flex: none; }
.ct-onlyfields .muted { margin-left: auto; }
.ct-nofields-box { gap: 10px; max-width: 620px; margin: 0 auto; text-align: left;
  align-items: flex-start; }
.ct-nofields-box .ic { color: var(--amber); }
.ct-nofields-list { display: flex; flex-direction: column; gap: 8px; width: 100%; }
.ct-nofields-item { padding: 8px 10px; border: 1px solid var(--border);
  border-radius: 8px; background: var(--surface-2); }

/* ---------- Виртуальный респондент ----------
   Никакого языка интервью: ни аватара, ни кавычек, ни «ответа респондента».
   Портрет собирательный, и вид не должен намекать на живого человека. */
.vr-layout .chat-thread-inner { max-width: 900px; gap: 14px; }
.vr-formula { align-items: center; gap: 8px; flex-wrap: wrap; max-width: 900px; }
.vr-slot { flex: 0 1 320px; min-width: 0; justify-content: flex-start; text-align: left;
  font-weight: 500; color: var(--text-2); border-style: dashed; }
.vr-slot.filled { color: var(--text); border-style: solid; border-color: var(--accent); }
.vr-q { resize: vertical; min-height: 46px; max-height: 140px; }
.vr-note { max-width: 460px; line-height: 1.35; }

/* дисклеймер — плашкой сверху, а не строчкой в конце, которую не дочитывают */
.vr-disclaimer { display: flex; gap: 8px; align-items: flex-start; margin-bottom: 10px;
  padding: 8px 11px; border-radius: 8px; background: var(--amber-soft, var(--surface-2));
  border: 1px solid var(--amber); color: var(--text); font-size: 12.5px; line-height: 1.4; }
.vr-disclaimer .ic { flex: none; color: var(--amber); margin-top: 1px; }
.vr-question { margin: 8px 0 4px; font-size: 13.5px; color: var(--text-2); }
.vr-answer { line-height: 1.6; }
.vr-refused .ct-passport { margin-top: 8px; }

/* распределения, на которых построен портрет */
.vr-dist { display: flex; flex-direction: column; gap: 2px; margin-top: 4px; }
.vr-dist-row { display: flex; gap: 10px; align-items: baseline; font-size: 12.5px; }
.vr-dist-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; color: var(--text-2); }
.vr-dist-val { flex: none; font-variant-numeric: tabular-nums; }
/* размер микрогруппы не раскрываем */
.vr-below-k { color: var(--text-3); font-style: italic; }

/* ---------- Динамика по волнам ----------
   Порядок волн — это ось графика, поэтому он пронумерован и переставляется
   мышью; стрелки оставлены для клавиатуры. Дата заполнена далеко не у всех
   исследований архива, автосортировкой одной не обойтись. */
.wv-layout .chat-thread-inner { max-width: 980px; gap: 14px; }
.wv-formula { align-items: center; gap: 8px; flex-wrap: wrap; max-width: 980px; }
.wv-waves { display: flex; flex-wrap: wrap; gap: 6px; flex: 1; min-width: 0; }
.wv-chip { display: inline-flex; align-items: center; gap: 6px; max-width: 300px;
  padding: 3px 5px 3px 8px; border: 1px solid var(--accent); border-radius: 999px;
  background: var(--accent-soft); font-size: 12.5px; user-select: none; }
.wv-sortable .wv-chip { cursor: grab; }
/* номер — это позиция на оси графика, он обязан читаться: белым по оранжевому
   в тёмной теме выходило 2,5:1, поэтому берём инверсный токен темы */
.wv-num { flex: none; display: inline-flex; align-items: center; justify-content: center;
  width: 18px; height: 18px; border-radius: 50%; background: var(--accent);
  color: var(--text-inverse, #fff); font-size: 11px; font-weight: 650; }
.wv-name { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.wv-date { flex: none; font-size: 10.5px; opacity: .7; white-space: nowrap; }

/* Кнопки внутри фишки. Сброс обязателен: у голого <button> своё оформление
   (серая заливка, outset-рамка, системный шрифт) — внутри цветной пилюли это
   выглядит кнопкой из чужого интерфейса. */
.wv-tools { flex: none; display: inline-flex; align-items: center; gap: 1px; }
.wv-move, .wv-chip-x { flex: none; display: inline-flex; align-items: center;
  justify-content: center; width: 18px; height: 18px; padding: 0; border: none;
  border-radius: 50%; background: transparent; color: var(--text-2); font: inherit;
  line-height: 1; cursor: pointer; transition: background .12s, color .12s; }
.wv-move { font-size: 15px; }
.wv-move:hover:not(:disabled) { background: var(--surface); color: var(--accent-600); }
.wv-move:disabled { opacity: .3; cursor: default; }
/* крестик отодвинут от стрелок: снять волну по промаху обиднее, чем не сдвинуть */
.wv-chip-x { margin-left: 3px; font-size: 10px; }
.wv-chip-x:hover { background: var(--surface); color: var(--red); }
.wv-move:focus-visible, .wv-chip-x:focus-visible { outline: 2px solid var(--accent);
  outline-offset: 1px; background: var(--surface); }

/* Перенос мышью: оригинал остаётся в потоке бледной меткой будущего места,
   за курсором едет копия — куда фишка встанет, видно до отпускания. */
.wv-chip.wv-ghost { background: transparent; border-style: dashed; opacity: .5; }
.wv-drag-clone { position: fixed; z-index: 90; margin: 0; pointer-events: none;
  box-shadow: var(--shadow-lg); }
body.wv-dragging { user-select: none; }
body.wv-dragging, body.wv-dragging .wv-chip { cursor: grabbing; }

.wv-q { resize: vertical; min-height: 46px; max-height: 140px; }
.wv-note { white-space: nowrap; }
.wv-foot { flex-wrap: wrap; }

.wv-trend { margin: 10px 0 14px; padding: 10px 12px; border: 1px solid var(--border);
  border-radius: 10px; background: var(--surface-2); }
.wv-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 10px; margin-top: 8px; }
.wv-wave { margin: 0; }
.wv-narrative { margin-top: 12px; padding: 10px 12px; border: 1px solid var(--accent);
  border-left-width: 3px; border-radius: 10px; background: var(--accent-soft); }
.wv-narrative .ic { color: var(--accent); }

/* --- кнопка отправки чата: анимация «идёт генерация» --- */
.chat-send .chat-send-spin { display: inline-block; width: 15px; height: 15px;
  border: 2px solid rgba(255,255,255,.35); border-top-color: #fff;
  border-radius: 50%; animation: chat-send-spin .8s linear infinite; }
@keyframes chat-send-spin { to { transform: rotate(360deg); } }
.chat-send.generating { opacity: 1 !important; cursor: progress;
  animation: chat-send-pulse 1.5s ease-in-out infinite; }
@keyframes chat-send-pulse { 0%, 100% { transform: scale(1); } 50% { transform: scale(1.08); } }

/* ─── Обратная связь по ответам ИИ ─────────────────────────────────────────── */

/* плавающий значок у выделенного фрагмента ответа */
.fb-pick { position: fixed; z-index: 120; display: none; align-items: center; gap: 6px;
  padding: 6px 11px; font-size: 12.5px; font-weight: 600; line-height: 1;
  color: #fff; background: var(--accent); border: none; border-radius: 100px;
  box-shadow: 0 6px 20px rgba(20,26,40,.28); cursor: pointer; }
.fb-pick:hover { background: var(--accent-600); }
.fb-pick .ic { width: 15px; height: 15px; }

/* цитата выделенного фрагмента (модалка и карточка замечания) */
.fb-quote { margin: 6px 0 2px; padding: 9px 12px; border-left: 3px solid var(--accent);
  background: var(--surface-2); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  font-size: 13.5px; color: var(--text); white-space: pre-wrap; overflow-wrap: anywhere;
  max-height: 220px; overflow: auto; }
.fb-prompt { padding: 8px 12px; background: var(--surface-2); border-radius: var(--radius-sm);
  font-size: 13.5px; white-space: pre-wrap; overflow-wrap: anywhere; }

/* страница раздела */
.fb-toolbar { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
.fb-toolbar .input { max-width: 280px; }
.fb-filters { display: flex; flex-wrap: wrap; gap: 6px; }
.fb-count { margin-left: 6px; padding: 0 6px; border-radius: 100px; font-size: 11px;
  background: var(--surface-2); color: var(--text-2); }
.btn.primary .fb-count { background: rgba(255,255,255,.22); color: #fff; }

.fb-cols { display: grid; grid-template-columns: minmax(280px, 360px) 1fr; gap: 16px;
  align-items: start; }
@media (max-width: 1100px) { .fb-cols { grid-template-columns: 1fr; } }

.fb-list { display: flex; flex-direction: column; gap: 8px; max-height: calc(100vh - 240px);
  overflow: auto; padding-right: 2px; }
.fb-item { background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  padding: 10px 12px; cursor: pointer; display: flex; flex-direction: column; gap: 5px; }
.fb-item:hover { border-color: var(--border-strong); }
.fb-item.active { border-color: var(--accent); box-shadow: 0 0 0 1px var(--accent) inset; }
.fb-item-h { display: flex; align-items: center; gap: 8px; }
.fb-item-h .grow { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
  text-align: right; }
.fb-item-q { font-size: 12.5px; color: var(--text-2); font-style: italic;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.fb-item-c { font-size: 13.5px; color: var(--text);
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.fb-item-f { display: flex; align-items: center; gap: 10px; }
.fb-item-f .fb-reply { display: inline-flex; align-items: center; gap: 3px; margin-left: auto; }

.fb-detail-h { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.fb-meta { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.fb-block { margin-top: 16px; }
.fb-block-t { font-size: 11.5px; font-weight: 650; letter-spacing: .4px; text-transform: uppercase;
  color: var(--text-3); margin-bottom: 6px; }
.fb-thread { display: flex; flex-direction: column; gap: 10px; }
.fb-msg { background: var(--surface-2); border-radius: var(--radius-sm); padding: 9px 12px; }
.fb-msg-h { display: flex; align-items: baseline; gap: 10px; margin-bottom: 3px; }
.fb-msg-b { font-size: 13.5px; white-space: pre-wrap; overflow-wrap: anywhere; }
.fb-sys { display: flex; align-items: center; gap: 6px; padding: 2px 2px; }
.ic-xs { width: 13px; height: 13px; flex: none; }

/* --- отметки замечаний прямо в тексте ответа --- */
.fb-mark { background: var(--amber-soft); color: inherit; border-bottom: 2px solid var(--amber);
  border-radius: 3px 3px 0 0; padding: 0 1px; cursor: pointer; }
.fb-mark[data-fb-status="in_progress"] { background: var(--blue-soft); border-bottom-color: var(--blue); }
.fb-mark[data-fb-status="resolved"] { background: var(--green-soft); border-bottom-color: var(--green); }
.fb-mark[data-fb-status="rejected"] { background: var(--surface-2); border-bottom-color: var(--text-3); }
.fb-mark:hover { filter: brightness(1.06); }
.fb-mark-flash { animation: fb-flash 1.3s ease-in-out 2; }
@keyframes fb-flash {
  0%, 100% { box-shadow: 0 0 0 0 transparent; }
  50% { box-shadow: 0 0 0 4px var(--accent-soft); }
}

/* подсказка над отметкой */
.fb-tip { position: fixed; z-index: 130; display: none; width: 360px; max-width: 88vw;
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--radius);
  box-shadow: var(--shadow-lg); padding: 10px 12px; font-size: 13px; }
.fb-tip-h { display: flex; align-items: center; gap: 8px; margin-bottom: 6px; flex-wrap: wrap; }
.fb-tip-b { white-space: pre-wrap; overflow-wrap: anywhere; max-height: 120px; overflow: auto; }
.fb-tip-reply { margin-top: 8px; padding-top: 8px; border-top: 1px solid var(--border);
  white-space: pre-wrap; overflow-wrap: anywhere; max-height: 110px; overflow: auto; }
.fb-tip-f { margin-top: 8px; }

/* ответы на ответы в обсуждении */
.fb-msg-wrap { display: flex; flex-direction: column; gap: 8px; }
.fb-msg-reply { border-left: 2px solid var(--border-strong); }
.fb-msg-h .grow { flex: 1; }
.fb-reply-btn { padding: 1px 8px; font-size: 11.5px; opacity: .75; }
.fb-msg:hover .fb-reply-btn { opacity: 1; }
.fb-replybar { display: flex; align-items: center; gap: 8px; margin-bottom: 6px;
  padding: 5px 8px; background: var(--surface-2); border-radius: var(--radius-sm); }
.fb-replybar-q { flex: 1; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }

/* подпись в легенде круговой диаграммы: полный текст — в подсказке */
/* две строки вместо однострочного обрубка: подпись здесь — вариант ответа
   целиком, и в 150px легенды от него оставалось многоточие */
.chart-legend-label { flex: 1; min-width: 0; overflow: hidden;
  display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical;
  overflow-wrap: anywhere; line-height: 1.35; }
/* «45,2% (137)» вместо «137» — легенде нужно больше места, иначе от подписи
   категории (flex:1 + ellipsis) остаётся одно многоточие */
.chart-legend { min-width: 230px; flex: 1 1 230px; }
/* маркер выравниваем по ПЕРВОЙ строке подписи, а не по её середине */
.chart-legend .dot { margin-top: 5px; }
.chart-legend-val { white-space: nowrap; font-variant-numeric: tabular-nums; flex: 0 0 auto; }
.chart-card-title { font-weight: 600; margin-bottom: 6px; display: -webkit-box;
  -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

/* страницы с широкими таблицами: снимаем ограничение ширины колонки текста */
.content.content-wide { max-width: none; }

/* Архив исследований: 11 колонок должны помещаться и на 1366px */
table.tbl.tbl-archive th, table.tbl.tbl-archive td { padding-left: 8px; padding-right: 8px; }
/* заголовки в разрядку задавали минимальную ширину колонок */
table.tbl.tbl-archive th { letter-spacing: 0; font-size: 11.5px; }
table.tbl.tbl-archive .cell-period { min-width: 92px; }
/* диапазон дат переносится, сами даты не рвутся */
table.tbl.tbl-archive .cell-period .nb { white-space: nowrap; }
table.tbl.tbl-archive .cell-chips { max-width: 190px; }
table.tbl.tbl-archive .badge { padding: 3px 7px; }
table.tbl.tbl-archive .pill-tags { gap: 4px; }
/* тип исследования — строкой под методом, мельче бейджа метода (как в выборе
   исследования у презентаций, .rp-kind) */
table.tbl.tbl-archive .cell-kind { margin-top: 4px; }
table.tbl.tbl-archive .cell-kind .badge { font-size: 10.5px; padding: 1px 7px; }
table.tbl.tbl-archive .cell-kind .badge.kind-unknown { padding: 0 6px; }

/* --- ответ неполный: плашка и повтор генерации --- */
.chat-incomplete { display: flex; align-items: flex-start; gap: 10px; margin: 0 0 12px;
  padding: 10px 12px; border-radius: var(--radius-sm);
  background: var(--amber-soft); border: 1px solid var(--amber);
  color: var(--text); }
.chat-incomplete .ic { flex: none; color: var(--amber); margin-top: 1px; }
.chat-incomplete .grow { flex: 1; min-width: 0; }
.chat-incomplete .btn { flex: none; }
.chat-msg-actions { margin-top: 10px; display: flex; gap: 8px; opacity: 0; transition: opacity .15s; }
.chat-msg.assistant:hover .chat-msg-actions, .chat-msg-actions:focus-within { opacity: 1; }
.chat-msg-err + .mt-6 .btn { margin-top: 2px; }

/* баннер «интерфейс обновлён»: открытая вкладка выполняет старый код */
.build-banner { position: fixed; left: 50%; transform: translateX(-50%); bottom: 18px;
  z-index: 300; display: flex; align-items: center; gap: 12px; max-width: 92vw;
  padding: 11px 14px; border-radius: var(--radius); background: var(--surface);
  border: 1px solid var(--accent); box-shadow: var(--shadow-lg); }
.build-banner .ic { flex: none; color: var(--accent); }
.build-banner .grow { flex: 1; min-width: 0; }

/* ---- мастер загрузки исследования архивом (arch-*, чтобы не пересечься
   с .wiz-step мастера презентаций) ---- */
.arch-step { display: flex; align-items: center; gap: 8px; padding: 4px 0; font-size: 13px; }
.arch-mark { width: 16px; text-align: center; color: var(--text-3); }
.arch-running .arch-mark { color: var(--accent); }
.arch-done .arch-mark { color: var(--green); }
.arch-error .arch-mark { color: var(--red); }
.arch-pending { color: var(--text-3); }
.drop-placeholder.over { border-color: var(--accent); background: var(--accent-soft); }

/* уведомления мастера складываются стопкой над баннером версии */
.arch-banner { position: fixed; right: 18px; left: auto; transform: none; bottom: 18px;
  max-width: min(520px, 92vw); }
.arch-banner ~ .arch-banner { bottom: 92px; }
.arch-banner ~ .arch-banner ~ .arch-banner { bottom: 166px; }
.arch-banner.err { border-color: var(--red); }
.arch-banner.err .ic { color: var(--red); }

/* ---------- Ревизор → «Сверка с записями» ----------
   Расхождение здесь — это обвинение интервьюера, поэтому вид обязан отделять
   твёрдое основание от слабого и нигде их не складывать. */
.tc-wrap { display: flex; flex-direction: column; gap: 16px; }
.tc-settings { position: relative; }
.tc-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap; }
.tc-row + .tc-row { margin-top: 12px; }
.tc-row .grow { flex: 1; }
.tc-pick { max-width: 460px; justify-content: flex-start; text-align: left;
  font-weight: 500; color: var(--text-2); border-style: dashed; }
.tc-pick.filled { color: var(--text); border-style: solid; border-color: var(--accent); }
.tc-pick-label { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.tc-hint { padding: 0; display: flex; gap: 8px; flex-wrap: wrap; align-items: center; }
.tc-dot { color: var(--text-3); }
.tc-warn { color: var(--amber); font-weight: 600; }
/* Строка запуска: «Сверить [25] анкет из 1 100 — примерно 5 мин».
   Срок стоит рядом с выбором, а не в примечании: размер выборки — единственная
   настройка, которая упирается во время, и без срока её выбирают наугад. */
.tc-run-row { display: flex; align-items: center; gap: 12px; flex-wrap: wrap;
  margin-top: 14px; }
.tc-run-row .grow { flex: 1; }
.tc-sample { display: inline-flex; align-items: center; gap: 8px; font-size: 14px; }
.tc-sample-sel { width: auto; min-width: 92px; padding: 6px 10px; }
.tc-sample-tail { color: var(--text-2); }
.tc-estimate { color: var(--text-2); font-size: 13.5px; white-space: nowrap; cursor: help; }

/* что именно сверяется — прямо под строкой запуска, а не в сноске */
.tc-scope { margin-top: 8px; font-size: 12.5px; line-height: 1.5; color: var(--text-2);
  max-width: 820px; }
.tc-scope b { color: var(--text); font-weight: 600; }

/* Переключатели: объяснение рядом, а не в подсказке при наведении. Обе
   настройки меняют не удобство, а то, чему в отчёте можно верить. */
.tc-opts { display: flex; flex-direction: column; gap: 10px; margin-top: 14px; }
.tc-opt { display: flex; gap: 9px; align-items: flex-start; cursor: pointer;
  padding: 9px 11px; border: 1px solid var(--border); border-radius: 9px;
  background: var(--surface-2); max-width: 820px; }
.tc-opt:hover { border-color: var(--border-strong); }
.tc-opt > input { flex: none; margin-top: 2px; cursor: pointer; }
.tc-opt-body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.tc-opt-t { font-size: 13.5px; font-weight: 600; }
.tc-opt-w { font-size: 12px; line-height: 1.45; color: var(--text-3); }
.tc-ready { margin-top: 1px; font-size: 11.5px; color: var(--green); }
/* Панель выбора выпадает ИЗ-ПОД КНОПКИ и НЕ раздвигает страницу. Раскладка
   задаётся здесь целиком, а не поверх .chat-scope-panel: тот рассчитан на чат
   (top/right/bottom + width: 420px), и вместе с top: 100% высота получалась
   отрицательной — список сплющивался в полосу.
   Ширину берём свою: кнопка узкая (около 140 px), а в списке паспорт, описание
   и шкала периода — по ширине кнопки они были бы нечитаемы. */
.tc-panel { position: absolute; left: 0; top: calc(100% + 6px);
  width: min(640px, calc(100vw - 48px));
  z-index: 30; display: flex; flex-direction: column; max-height: min(60vh, 560px);
  background: var(--surface); border: 1px solid var(--border); border-radius: 12px;
  box-shadow: var(--shadow-lg); overflow: hidden; }
/* кнопка выбора не должна растягиваться на всю строку: рядом с ней живёт
   подсказка о состоянии сверки */
.tc-pick-field { flex: none; }
.tc-panel .chat-scope-body { flex: 1; min-height: 0; overflow: auto; }
/* галочка стоит прямо в панели, а не внутри тела списка, — отступ ей нужен свой,
   иначе она не попадает в общую левую кромку с заголовком и строками */
.tc-panel .ct-onlyfields { padding: 9px 14px 5px; border-bottom: 1px solid var(--border); }
/* строки здесь кликабельны целиком (галочек нет) — им нужен воздух */
.tc-panel .chat-scope-row { padding: 7px 8px; border-radius: 8px; }
.tc-panel .chat-scope-rowtitle { font-size: 13.5px; }

/* прогресс фонового задания */
.tc-progress .card-b { padding: 14px 16px; }
/* ожидание сервиса — не ошибка: расчёт цел и продолжится сам */
.tc-progress.queued { border-style: dashed; }
.tc-progress.queued .tc-bar-fill { background: var(--border-strong); }
.tc-progress.waiting { border-color: var(--amber); }
.tc-progress.waiting .ic { color: var(--amber); }
.tc-progress.waiting .tc-bar-fill { background: var(--amber); }
.tc-bar { margin-top: 10px; height: 6px; border-radius: 999px; background: var(--surface-2);
  overflow: hidden; }
.tc-bar-fill { height: 100%; background: var(--accent); border-radius: 999px;
  transition: width .3s; }

/* итоги сверки */
.tc-card .card-b { padding: 16px 18px; }
.tc-stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr));
  gap: 10px; margin-bottom: 14px; }
.tc-stat { padding: 12px 14px; border: 1px solid var(--border); border-radius: 10px;
  background: var(--surface-2); }
.tc-stat-v { font-size: 22px; font-weight: 650; letter-spacing: -.02em; }
.tc-stat-l { font-size: 12.5px; color: var(--text-2); margin-top: 2px; }
.tc-stat-s { font-size: 11.5px; color: var(--text-3); margin-top: 4px; line-height: 1.35; }
.tc-stat.bad .tc-stat-v { color: var(--red); }
.tc-stat.good .tc-stat-v { color: var(--green); }
/* калибровка — главное число отчёта, поэтому отдельной плашкой, а не строкой */
.tc-calib { display: flex; gap: 10px; align-items: flex-start; margin-bottom: 12px;
  padding: 10px 12px; border: 1px solid var(--accent); border-left-width: 3px;
  border-radius: 10px; background: var(--accent-soft); }
.tc-calib .ic { flex: none; color: var(--accent); margin-top: 1px; }
.tc-calib .grow { flex: 1; min-width: 0; }
.tc-calib .small { line-height: 1.45; margin-top: 2px; }
.tc-params-line { margin-bottom: 14px; }
.tc-h { font-size: 14px; margin: 16px 0 10px; }

/* анкета с расхождениями */
.tc-findings { display: flex; flex-direction: column; gap: 10px; }
.tc-finding { padding: 12px 14px; }
.tc-finding-h { align-items: center; gap: 10px; flex-wrap: wrap; }
.tc-file { margin-top: 2px; font-size: 11.5px; word-break: break-all; }
.tc-items { display: flex; flex-direction: column; gap: 10px; margin-top: 10px; }
.tc-item { padding: 9px 11px; border-left: 3px solid var(--red); border-radius: 0 8px 8px 0;
  background: var(--surface-2); }
/* неточность (слабое основание) — жёлтая, разногласие — красная; цвет
   всегда дублируется текстовой меткой с подсказкой (.tc-tag) */
.tc-item.weak, .tc-item.inaccuracy { border-left-color: var(--amber); }
.tc-tag { position: relative; cursor: help; white-space: nowrap; }
.tc-tip { display: none; position: absolute; left: 0; top: calc(100% + 6px); z-index: 60;
  width: max-content; max-width: min(320px, 80vw); padding: 9px 11px; border-radius: 8px;
  background: var(--surface); color: var(--text); border: 1px solid var(--border);
  box-shadow: var(--shadow-lg); font-size: 12px; font-weight: 500; line-height: 1.45;
  white-space: normal; text-align: left; }
.tc-tip b { display: block; margin-bottom: 3px; }
.tc-tip-h { display: block; margin-top: 6px; color: var(--text-3); font-size: 11.5px; }
.tc-tag:hover .tc-tip, .tc-tag:focus .tc-tip, .tc-tag:focus-visible .tc-tip { display: block; }
.tc-legend { display: flex; align-items: center; gap: 8px 14px; flex-wrap: wrap; margin: -4px 0 12px; }
.tc-warn { color: var(--amber); font-weight: 600; }
.tc-th-tip { cursor: help; text-decoration: underline dotted; text-underline-offset: 3px; }
.tc-item-q { display: flex; gap: 8px; align-items: baseline; font-size: 13px;
  font-weight: 600; line-height: 1.35; }
.tc-ts { flex: none; font-family: var(--mono); font-size: 11px; color: var(--accent-600);
  background: var(--surface); border: 1px solid var(--border); border-radius: 5px;
  padding: 1px 5px; }
.tc-item-vs { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin-top: 7px; }
.tc-val { display: inline-flex; align-items: baseline; gap: 6px; padding: 3px 9px;
  border-radius: 7px; font-size: 12.5px; border: 1px solid var(--border); }
.tc-val-l { font-size: 10px; text-transform: uppercase; letter-spacing: .06em;
  color: var(--text-3); }
.tc-val.rec { background: var(--surface); }
/* «в массиве» — кликабельно: открывает массив на этой самой ячейке. Курсор и
   подчёркивание по наведению нужны именно здесь: рядом лежит «в записи» с тем
   же видом, и без подсказки никто не догадается, что одно из двух — кнопка. */
.tc-val-go { cursor: pointer; }
.tc-val-go:hover, .tc-val-go:focus-visible { border-color: var(--accent); color: var(--accent); }
.tc-val-go:hover .tc-val-l { color: var(--accent); }
.tc-val.heard { background: var(--surface); border-color: var(--accent); }
.tc-arrow { color: var(--text-3); font-weight: 650; }
.tc-weak { border-color: var(--border-strong); color: var(--text-2); }
.tc-quote { margin-top: 7px; font-size: 12.5px; line-height: 1.45; color: var(--text-2);
  font-style: italic; }
.tc-why { margin-top: 5px; font-size: 11.5px; color: var(--text-3); }

/* Плеер записи в отчёте. Текст расшифровки проверяется плохо — распознавание
   коверкает слова, и спорное расхождение решается только на слух. */
.tc-play { padding: 2px 8px; font-size: 11px; gap: 5px; flex: none;
  font-family: var(--mono); letter-spacing: -.02em; }
.tc-play-ic { font-size: 9px; line-height: 1; }
.tc-play:hover:not(:disabled) { border-color: var(--accent); color: var(--accent-600); }
/* приблизительная отметка (жёлтые пункты): место найдено по словам цитаты, а
   не дословно. Пунктир — чтобы отличалась от точной с одного взгляда: выдать
   её за точную значило бы уверять, что расхождение именно здесь. */
.tc-play-approx { border-style: dashed; color: var(--text-2); }
.tc-backlink { margin-bottom: 8px; }

/* ---- оконный список анкет с расхождениями ---- */
/* Слот — одна страница из 25 анкет. В документе их не больше WINDOW_PAGES:
   заглушек во всю высоту ненайденных страниц больше нет, поэтому и документ
   длиной с одну-две страницы, а не с весь отчёт.
   Промежутки между анкетами задаёт сам слот: детьми .tc-findings стали слоты,
   и её gap теперь разводит страницы, а не карточки. */
.tc-slot { contain: layout style; display: flex; flex-direction: column; gap: 10px; }
.tc-slot-err { display: flex; align-items: center; gap: 8px; padding: 10px 0; }
.tc-slot-load { padding: 14px 0; }
/* Метки краёв списка: по ним наблюдатель понимает, что пора подать следующую
   страницу сверху или снизу. Своей высоты у них нет. */
.tc-edge { height: 0; }
/* Якорение прокрутки БРАУЗЕРОМ здесь мешает: страницы добавляются и снимаются
   сверху, и сдвиг прокрутки считается в JS по измеренной высоте. Если этим
   займётся ещё и браузер, поправка применится дважды и список дёрнется. */
.tc-findings { overflow-anchor: none; }

/* content-visibility: auto у карточки СНЯТ — сознательно.
   Он был нужен, пока в документе лежал весь отчёт: тогда карточки вне экрана
   не считались браузером вовсе, и это была решающая экономия. Теперь в
   документе не больше двух страниц (WINDOW_PAGES), и замер показал, что он не
   экономит ничего: 120 кадров быстрой прокрутки туда-обратно дают 0 длинных
   задач и 16,5 мс на кадр и с ним, и без него.
   А цену он брал заметную. Высота непосчитанной карточки бралась из
   contain-intrinsic-size (оценка 520px), и стоило карточке подъехать к экрану,
   как она пересчитывалась в настоящую. Содержимое над экраном при этом ехало:
   на подъёме по отчёту это давало рывки до 982px почти на каждом шаге, а при
   смене страницы — до 3254px. Без него те же проходы дают 10px, и те
   вычищены поправкой прокрутки. Заодно отпала и подпорка с
   `content-visibility: visible` при наведении: paint containment обрезал
   .tc-tip, где написана ПРИЧИНА расхождения. */

/* Пагинатор липнет ПОД шапкой приложения: .topbar тоже sticky top:0 и с
   z-index 20 — на нуле пагинатор оказывался целиком под ней и был не виден
   никогда. */
.tc-pager { display: flex; align-items: center; gap: 8px; flex-wrap: wrap;
  margin: 10px 0 6px; position: sticky; top: 60px; z-index: 5;
  background: var(--surface); padding: 6px 0; }

/* ---------- Ревизор: вкладка «Проверка данных» ----------
   Раньше карточка задания показывала только плашки находок: что проверялось,
   что прошло чисто и чего в массиве нет — узнать было негде, и пустое место
   под находками читалось как «нет данных». */
.rv-about { margin: 6px 0 10px; padding-left: 20px; }
.rv-about li { margin: 2px 0; }
.rv-facts { display: flex; flex-wrap: wrap; gap: 8px 22px; margin-bottom: 12px; }
.rv-fact b { display: block; font-size: 15px; }
.rv-checks { margin-bottom: 12px; }
.rv-checks > summary { cursor: pointer; user-select: none; font-size: 12.5px;
  font-weight: 600; color: var(--text-2); }
.rv-checks > summary:hover { color: var(--accent); }
.rv-checks-t { margin-top: 8px; }
.rv-checks-t td { padding: 6px 10px; font-size: 13px; }
.rv-check-st { white-space: nowrap; font-weight: 600; }
.rv-check-st.rv-ok { color: var(--green); }
.rv-check-st.rv-bad { color: var(--red); }
.rv-check-st.rv-skip { color: var(--text-3); }
/* пояснение «когда так бывает законно» — приглушённое, но не мелкое */
.rv-hint { margin-top: 10px; padding: 8px 11px; border-left: 3px solid var(--border-strong);
  background: var(--surface-2); border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
  color: var(--text-2); }
.rv-details { margin-top: 10px; }
.rv-details > summary { cursor: pointer; user-select: none; font-size: 12.5px;
  font-weight: 600; color: var(--text-2); }
.rv-details > summary:hover { color: var(--accent); }
.rv-rows { margin-top: 8px; display: flex; flex-direction: column; }
.rv-row { display: grid; grid-template-columns: 70px 150px minmax(0, 1fr) auto;
  gap: 10px; align-items: center; padding: 5px 0; border-bottom: 1px solid var(--divider);
  font-size: 13px; }
/* у многомассивных исследований добавляется колонка файла: без неё номер
   строки не адресует ничего (у 70-го исследования 36 подвыборок) */
.rv-row.rv-row-m { grid-template-columns: 62px minmax(0, 150px) 140px minmax(0, 1fr) auto; }
.rv-row-h { border-bottom-color: var(--border-strong); text-transform: uppercase;
  letter-spacing: .03em; font-size: 11.5px; }
.rv-row > span { min-width: 0; overflow-wrap: anywhere; }
@media (max-width: 760px) {
  .rv-row { grid-template-columns: 60px minmax(0, 1fr); row-gap: 2px; }
}

/* Поиск по отчёту сверки: поле, переходы по совпадениям и подсказка «3 из 69».
   Найденная анкета обводится рамкой, а при поиске по тексту в ней помечаются
   сами совпадения — иначе на странице из 25 карточек её пришлось бы искать
   глазами (ровно на это и жаловались). */
.tc-find { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.tc-find-nav { padding: 4px 9px; line-height: 1; }
.tc-find-hint { white-space: nowrap; }
.tc-finding.tc-hit { outline: 2px solid var(--accent); outline-offset: 3px;
  background: color-mix(in srgb, var(--accent-soft) 45%, var(--surface)); }
.tc-hit-mark { background: var(--amber-soft); color: inherit; border-radius: 3px;
  padding: 0 1px; box-shadow: 0 0 0 1px var(--amber) inset; }

.tc-pager-status { margin: 0 auto 0 4px; }
/* Переход к странице целится в верх списка, а тот уехал бы под шапку и под сам
   пагинатор: scroll-margin отодвигает цель на их суммарную высоту. Та же
   величина продублирована в JS как HEAD_PX — по ней считается текущая
   страница, и разойтись им нельзя. */
.tc-slot, .tc-findings { scroll-margin-top: 108px; }
.tc-player:empty { display: none; }
.tc-player { margin: 8px 0 2px; padding: 8px 10px; border: 1px solid var(--border);
  border-radius: 9px; background: var(--surface-2); }
.tc-col { flex: none; font-size: 10.5px; color: var(--text-3); font-weight: 500;
  border: 1px solid var(--border); border-radius: 5px; padding: 0 5px; cursor: help; }
.tc-media-head { margin-bottom: 6px; word-break: break-all; }
.tc-media { width: 100%; display: block; }
audio.tc-media { height: 38px; }
video.tc-media { max-height: 320px; background: #000; border-radius: 6px; }

/* реестр всех анкет выборки */
.tc-roster-wrap { overflow-x: auto; margin-top: 8px; }
.tc-roster { font-size: 12.5px; }
.tc-roster td { padding: 7px 10px; }
.tc-roster .tc-bad { color: var(--red); font-weight: 650; }
.tc-roster tr.tc-unusable td { color: var(--text-3); }
.tc-roster th.tc-th-sort { cursor: pointer; user-select: none; white-space: nowrap; }
.tc-roster th.tc-th-sort:hover { color: var(--text); }
.tc-roster th.active { color: var(--accent); }
.tc-sort-ic { font-size: 9px; margin-left: 4px; vertical-align: 1px; }

/* История сверок: стоит над отчётом и открывается сразу, до выбора
   исследования — сверка идёт минутами, и возврат к результату это основной
   сценарий, а не побочный. */
.tc-hist-filter { display: inline-flex; align-items: center; gap: 6px; font-size: 12.5px;
  color: var(--text-2); cursor: pointer; font-weight: 500; }
.tc-hist-filter input { cursor: pointer; }
.tc-hist-body { padding: 8px 10px 10px; max-height: 340px; overflow: auto; }
.tc-hist-list { display: flex; flex-direction: column; gap: 2px; }
.tc-hist { padding: 8px 10px; border-radius: 8px; cursor: pointer;
  border: 1px solid transparent; }
.tc-hist:hover { background: var(--surface-2); }
.tc-hist.active { background: var(--accent-soft); border-color: var(--accent); }
/* незавершённая сверка: открывать нечего, и это должно быть видно курсором */
.tc-hist.pending { cursor: default; }
.tc-hist.pending:hover { background: transparent; }
.tc-hist.pending .tc-hist-name { color: var(--text-2); }
/* идущая сейчас сверка — не «прервана»: её видно и по кромке, и по подписи */
.tc-hist.running { border-color: var(--accent); background: var(--accent-soft); cursor: pointer; }
.tc-hist.running .tc-hist-name { color: var(--text); }
/* ждёт очереди: видно, что задание принято, но ничего пока не считает —
   отсюда пунктир вместо заливки и обычный курсор */
.tc-hist.queued { border-style: dashed; border-color: var(--border-strong); cursor: default; }
.tc-hist.queued:hover { background: transparent; }
.tc-hist.queued .tc-hist-name { color: var(--text-2); }
.tc-hist.pending:hover { background: var(--surface-2); }
.tc-resume { padding: 2px 8px; font-size: 11.5px; }
/* удаление отчёта — действие администратора, поэтому оно не лезет в глаза,
   но и не прячется: стоит первым в строке, чтобы не попасть по нему случайно
   вместо «Продолжить» */
/* Корзина — в правом углу строки, отдельно от «Продолжить»: промахнуться и
   снести отчёт вместо досчёта дороже всего. В покое приглушена, на наведении
   строки проявляется и краснеет. */
.tc-del { flex: none; padding: 3px; margin-left: 8px; border-color: transparent;
  background: transparent; opacity: .45; transition: opacity .12s, color .12s,
  background .12s, border-color .12s; }
.tc-del .ic { width: 15px; height: 15px; }
.tc-hist:hover .tc-del { opacity: .8; }
.tc-del:hover { opacity: 1; color: var(--red); border-color: var(--red);
  background: var(--red-soft); }
.tc-del:focus-visible { opacity: 1; outline: 2px solid var(--red); outline-offset: 1px; }
.tc-resume .ic { width: 13px; height: 13px; }
.tc-hist-main { display: flex; gap: 10px; align-items: baseline; }
.tc-hist-name { font-weight: 600; font-size: 13.5px; min-width: 0; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
.tc-hist-ts { margin-left: auto; flex: none; font-size: 12px; color: var(--text-3); }
.tc-hist-sum { display: flex; gap: 6px; align-items: center; flex-wrap: wrap;
  margin-top: 2px; font-size: 12.5px; color: var(--text-2); }
.tc-hist-sum .badge { font-size: 10.5px; }
.tc-ok { color: var(--green); }
.tc-bad { color: var(--red); }
/* Пустой экран собран на том же каркасе, что и у соседних вкладок: колонка с
   выравниванием по центру. Прежний .empty — обычный блок, и значок с
   заголовком вставали НА ОДНУ строку по базовой линии: низ значка приходился
   на линию букв, отчего они казались разной высоты. */
.tc-hello { max-width: 620px; margin: 0 auto; }
.tc-hello .muted { line-height: 1.5; margin: 6px 0; }

/* ---------- Просмотр массива SPSS (.sav) ---------- */
/* Окно шире всех прочих: 400 переменных в 860 px «широкой» модалки не влезают
   ни при каком масштабе. Скроллится не окно, а сама таблица — иначе шапка
   колонок липнет к модалке, а не к сетке, и уезжает вместе с ней. */
.modal.data { max-width: min(96vw, 1680px); width: min(96vw, 1680px);
  height: min(90vh, 1000px); max-height: 90vh; overflow: hidden;
  display: flex; flex-direction: column; }
.modal.data .modal-h, .modal.data .modal-f { flex: none; }
.modal.data .modal-b { flex: 1; min-height: 0; padding: 14px 16px; display: flex; }
.sv-wrap { display: flex; gap: 14px; flex: 1; min-height: 0; min-width: 0; }

/* боковая панель переменных */
.sv-side { width: 250px; flex: none; display: flex; flex-direction: column;
  min-height: 0; border-right: 1px solid var(--border); padding-right: 12px; }
.sv-side-h { display: flex; justify-content: space-between; align-items: baseline;
  margin-bottom: 8px; }
.sv-side-btns { margin: 8px 0 6px; }
.sv-vars { overflow-y: auto; flex: 1; min-height: 0; margin-right: -6px; padding-right: 6px; }
.sv-var { padding: 5px 0; border-bottom: 1px solid var(--border); }
.sv-var-h { display: flex; align-items: center; gap: 6px; cursor: pointer; }
.sv-vname { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; cursor: pointer; }
.sv-vname:hover { color: var(--accent); }
.sv-vlabel { margin-left: 22px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sv-exp { padding: 0 5px; line-height: 1; }
.sv-codes { margin: 4px 0 2px 22px; max-height: 190px; overflow: auto; }
.sv-code { display: flex; gap: 8px; font-size: 12px; color: var(--text-2); padding: 1px 0; }
.sv-code .mono { flex: none; min-width: 28px; color: var(--text-3); }

/* правая часть: панель инструментов, сетка, страницы */
.sv-main { flex: 1; min-width: 0; display: flex; flex-direction: column; min-height: 0; }
/* Вкладки листов книги Excel. Вид — общие вкладки раздела (.tabs/.tab), чтобы
   лист книги переключался тем же жестом и выглядел так же, как вкладка
   «Проверка данных»; здесь только то, чего в общих нет: полоса не переносится,
   а прокручивается (в сводном отчёте лист на каждый блок анкеты, и восемь
   названий по 30 символов в ширину окна не уложить), длинное имя обрезается. */
.sv-sheets { margin-bottom: 10px; flex-wrap: nowrap; overflow-x: auto; }
.sv-sheets .tab { flex: 0 0 auto; max-width: 260px; white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; border-width: 0 0 2px;
  background: transparent; font-family: inherit; }
.sv-sheets .tab.active { cursor: default; }
.sv-sheet-hid { margin-left: 6px; font-size: 11px; font-weight: 400;
  color: var(--text-3); }
/* Переключатель заголовков — справа от вкладок: он про лист целиком */
.sv-hdr-btn { flex: 0 0 auto; display: flex; align-items: center; gap: 6px;
  margin-left: auto; padding: 5px 10px; align-self: center; white-space: nowrap;
  font-size: 12.5px; color: var(--text-2); cursor: pointer; }
.sv-hdr-btn:hover { color: var(--text); }
.sv-bar { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 10px; }
.sv-note { margin-bottom: 8px; }
.sv-mini { padding: 5px 9px; font-size: 12.5px; }
.sv-chip { cursor: pointer; }
.sv-chip-x { margin-left: 5px; opacity: .6; }
.sv-chip-x:hover { opacity: 1; }
.sv-grid-wrap { flex: 1; min-height: 0; overflow: auto; border: 1px solid var(--border);
  border-radius: var(--radius-sm); }
.sv-foot { display: flex; align-items: center; gap: 10px; margin-top: 10px; }
.sv-foot .select { width: auto; }

/* сетка. border-collapse: collapse (как у .tbl) не даёт липкой шапке
   собственных границ — они рисуются на таблице и уезжают при прокрутке,
   поэтому здесь separate и границы на ячейках */
table.tbl.sv-grid { border-collapse: separate; border-spacing: 0; width: max-content;
  min-width: 100%; font-size: 12.5px; }
table.tbl.sv-grid th, table.tbl.sv-grid td { border-bottom: 1px solid var(--border);
  border-right: 1px solid var(--border); }
table.tbl.sv-grid thead th { position: sticky; top: 0; z-index: 2;
  background: var(--surface-2); text-transform: none; letter-spacing: 0;
  font-size: 11.5px; padding: 6px 8px; vertical-align: top;
  max-width: 240px; min-width: 76px; }
table.tbl.sv-grid td { padding: 5px 8px; max-width: 280px; overflow: hidden;
  text-overflow: ellipsis; white-space: nowrap; }
table.tbl.sv-grid tbody tr:hover td { background: var(--surface-2); }
.sv-th-top { display: flex; align-items: center; gap: 4px; }
.sv-th-name { cursor: pointer; font-size: 12px; color: var(--text); }
.sv-th-name:hover { color: var(--accent); }
.sv-th-menu { border: none; background: none; color: var(--text-3); cursor: pointer;
  padding: 0 2px; line-height: 1; font-size: 13px; }
.sv-th-menu:hover { color: var(--accent); }
.sv-th-label { font-weight: 400; color: var(--text-2); text-transform: none;
  white-space: normal; line-height: 1.25; max-height: 2.5em; overflow: hidden; margin-top: 2px; }
.sv-th.sv-sorted { background: var(--accent-soft); }
.sv-flash { outline: 2px solid var(--accent); outline-offset: -2px; }
/* переход из Ревизора: строка и ячейка, ради которых массив и открыли.
   Подсветка СТОЙКАЯ, а не мигающая на 900 мс, как .sv-flash: человек пришёл
   сверить значение и будет смотреть на него, листать колонки и возвращаться —
   всё это время ячейку надо видеть. Строка красится мягко, ячейка — резко:
   иначе на широкой таблице глаз не находит, какая из 51 колонки искомая. */
table.tbl.sv-grid tbody tr.sv-hot td { background: var(--accent-soft); }
table.tbl.sv-grid tbody tr.sv-hot:hover td { background: var(--accent-soft); }
table.tbl.sv-grid td.sv-focus { outline: 2px solid var(--accent); outline-offset: -2px;
  font-weight: 600; }
/* номер наблюдения — единственная закреплённая колонка: по нему сверяются
   с исходным массивом в SPSS, и он не должен уезжать при горизонтальной прокрутке */
table.tbl.sv-grid th.sv-rn, table.tbl.sv-grid td.sv-rn { position: sticky; left: 0;
  z-index: 1; background: var(--surface); color: var(--text-3); text-align: right;
  min-width: 56px; width: 56px; font-size: 11.5px; }
table.tbl.sv-grid thead th.sv-rn { z-index: 3; background: var(--surface-2); }
table.tbl.sv-grid tbody tr:hover td.sv-rn { background: var(--surface-2); }
.sv-rn-btn { cursor: pointer; }
.sv-rn-btn:hover { color: var(--accent); }
.sv-num { text-align: right; font-variant-numeric: tabular-nums; }
.sv-miss { color: var(--text-3); }
.sv-grid mark { background: var(--accent-soft); color: var(--accent-600); padding: 0 1px; }

/* карточка наблюдения — строкой под самим наблюдением: вторая модалка закрыла бы
   просмотрщик вместе с фильтрами (ui.js: modal() закрывает предыдущую) */
/* селектор во всю силу правил сетки: у table.tbl.sv-grid td стоят nowrap и
   max-width, и карточка иначе рисуется в одну строку с наезжающими подписями */
table.tbl.sv-grid tr.sv-rec td { background: var(--surface-2); white-space: normal;
  max-width: none; overflow: visible; padding: 0; }
.sv-rec-box { padding: 10px 12px; max-height: 320px; overflow: auto; position: sticky; left: 0;
  width: min(1100px, 92vw); }
.sv-rec-h { display: flex; justify-content: space-between; align-items: center; margin-bottom: 8px; }
.sv-rec-grid { display: grid; grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); gap: 8px 16px; }
.sv-rec-item { border-bottom: 1px solid var(--border); padding-bottom: 4px; min-width: 0; }
.sv-rec-item > div { overflow-wrap: anywhere; }

/* всплывающие панели (меню колонки, редактор фильтра) — над модалкой (90)
   и над контекстным меню файлов (210) */
.sv-pop { position: fixed; z-index: 220; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--radius-sm); box-shadow: var(--shadow-lg); padding: 8px; }
.sv-pop-h { display: flex; gap: 8px; align-items: baseline; margin-bottom: 6px; min-width: 0; }
.sv-pop-list { max-height: 260px; overflow: auto; margin-top: 6px; }
.sv-pop-row { display: flex; gap: 8px; align-items: center; padding: 4px 6px; border-radius: 6px;
  cursor: pointer; font-size: 12.5px; }
.sv-pop-row:hover { background: var(--surface-2); }
.sv-pop-f { display: flex; gap: 6px; justify-content: flex-end; margin-top: 8px;
  border-top: 1px solid var(--border); padding-top: 8px; }
.sv-pop-load { display: flex; gap: 8px; align-items: center; color: var(--text-2);
  padding: 12px; justify-content: center; font-size: 12.5px; }
.sv-ellip { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; min-width: 0; flex: 1; }

/* ---- правка анкеты по указанию (конструктор анкет) ---- */
/* Окно показывает РАЗБОР изменений, а не новую анкету: пользователю нужно
   видеть, что модель сделала, а не сличать два документа глазами. */
.qe-aim { display: flex; align-items: center; gap: 6px; flex-wrap: wrap;
  font-size: 12.5px; margin-bottom: 10px; }
.qe-presets { display: flex; gap: 6px; flex-wrap: wrap; margin-top: 8px; }
.qe-sum { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin: 10px 0; }
.qe-secs { margin: 6px 0 10px; }
.qe-item { border-left: 3px solid var(--border); padding: 7px 0 7px 10px; margin: 8px 0;
  background: var(--surface-2); border-radius: 0 8px 8px 0; }
.qe-item.added { border-left-color: var(--green); }
.qe-item.removed { border-left-color: var(--red); }
.qe-item.edited { border-left-color: var(--accent); }
.qe-item.moved { border-left-color: var(--text-3); }
.qe-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; margin-bottom: 4px; }
.qe-kind { font-size: 11px; font-weight: 600; border-radius: 6px; padding: 1px 7px;
  border: 1px solid var(--border); color: var(--text-2); }
.qe-kind.added { color: var(--green); border-color: var(--green); }
.qe-kind.removed { color: var(--red); border-color: var(--red); }
.qe-kind.edited { color: var(--accent); border-color: var(--accent); }
.qe-kind.moved { color: var(--text-2); }
.qe-q { font-size: 13px; }
.qe-q-sub { margin-top: 2px; display: flex; flex-wrap: wrap; gap: 4px 12px; }
/* вариант, которого нет во второй версии вопроса: добавленный — зелёным,
   исчезнувший — красным. Остальные приглушены, чтобы различие было видно
   сразу, а не вычитывалось построчно */
.qe-opt.diff { font-weight: 600; }
.qe-now .qe-opt.diff { color: var(--green); }
.qe-was .qe-opt.diff { color: var(--red); }
/* «было» приглушено, но НЕ зачёркнуто: в вопросе меняется пара слов, и
   зачёркнутый текст целиком читался бы как «удалили весь вопрос». */
.qe-was { display: flex; gap: 8px; opacity: .62; margin: 3px 0; }
.qe-now { display: flex; gap: 8px; margin: 3px 0; }
.qe-tag { flex: none; font-size: 10.5px; color: var(--text-3); padding-top: 2px; width: 38px; }
.qe-item.removed .qe-q { opacity: .75; }
/* Кнопка точечной правки приглушена, но ВИДНА всегда. Совсем прозрачная она
   оставалась кликабельной: на сенсорном экране наведения нет вовсе, и человек
   нажимал бы кнопку, которой не видит. */
.qe-one { opacity: .34; transition: opacity .12s; }
.qe-row:hover .qe-one, .qe-one:focus, .qe-one:focus-visible { opacity: 1; }

/* ---- общий выбор исследования (research-picker.js) ---- */
/* Строки и шкала переиспользуют оформление панели скоупа ИИ-аналитика: это
   намеренно один и тот же виджет, а не похожий. Своё здесь — только одиночный
   выбор: галочки у строки нет, выбранное помечается и подсвечивается. */
.rp-row { position: relative; padding-right: 22px; }
.rp-row.on { background: var(--surface-2); box-shadow: inset 2px 0 0 var(--accent); }
.rp-check { position: absolute; right: 4px; top: 6px; color: var(--accent); font-weight: 700; }
/* Непригодная строка кликабельна: по клику говорится, ПОЧЕМУ нельзя. Прятать
   её нельзя — «почему моего исследования нет в списке» первый вопрос. */
.rp-row.ct-nofields { opacity: .72; cursor: not-allowed; }

/* Кнопка-триггер: показывает выбранное и открывает панель. Ширину держит
   строкой названия, поэтому обрезаем её, а не растягиваем карточку.
   Отступы и кегль — как у .input (9 px и 14 px), а не кнопочные 8 и 13,5:
   триггер стоит в строке рядом с обычным полем ввода, и любая разница высоты
   уводит подписи над ними на разные уровни. С теми же числами высота
   совпадает точно: 21 (строка) + 18 (отступы) + 2 (рамки) = 41 px. */
.rp-trigger { display: flex; align-items: center; gap: 8px; width: 100%;
  justify-content: flex-start; text-align: left; padding-block: 9px; font-size: 14px; }
.rp-trigger-label { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; color: var(--text-2); }
.rp-trigger.filled .rp-trigger-label { color: var(--text); font-weight: 500; }
.rp-trigger-caret { flex: none; color: var(--text-3); font-size: 11px; }
.rp-field { position: relative; }
/* На вкладке «Проверка данных» панель раскрывается ПОД кнопкой, а не поверх
   всего раздела: она здесь единственный выбор, и перекрывать ей карточку
   запуска незачем. */
.rp-panel { position: absolute; left: 0; right: 0; top: calc(100% + 6px); bottom: auto;
  width: auto; max-height: min(70vh, 560px); z-index: 30; }
.rp-body { max-height: min(60vh, 470px); }
/* Галочка «только пригодные» теперь живёт ВНУТРИ тела списка, между поиском и
   шкалой: снаружи она отбивалась рамкой карточки, а внутри эта же рамка резала
   её по краю. */
.rp-body .ct-onlyfields { margin: 6px 0 2px; padding: 0; border: 0; }
/* Фильтр по методу (типу) исследования — ряд чипов под поиском. Общий для
   панели скоупа аналитика, обеих вкладок Ревизора и мастера презентаций
   (research-picker.methodFilter). Чип — кнопка с aria-pressed, а не
   галочка: методов шесть-восемь, и ряд компактных «таблеток» читается за
   один взгляд, тогда как столбик галочек занял бы столько же места, сколько
   список. Число справа — сколько исследований с таким методом среди тех,
   что вообще могут попасть в список. */
.rp-methods { display: flex; align-items: center; flex-wrap: wrap; gap: 5px;
  margin: 0 0 8px; font-size: 12.5px; color: var(--text-2); }
.rp-methods-label { margin-right: 2px; }
.rp-method { display: inline-flex; align-items: center; gap: 5px; padding: 2px 8px 2px 9px;
  border-radius: 100px; border: 1px solid var(--border-strong); background: var(--surface);
  color: var(--text); font: inherit; font-size: 12px; font-weight: 550; line-height: 1.4;
  cursor: pointer; white-space: nowrap; transition: background .12s, border-color .12s; }
.rp-method:hover { background: var(--surface-2); }
.rp-method-n { font-weight: 500; font-size: 11px; color: var(--text-3); }
.rp-method.on { background: var(--accent); border-color: var(--accent); color: #fff; }
.rp-method.on .rp-method-n { color: rgba(255,255,255,.8); }
/* «без метода» — не метод, а пробел в паспорте: чип пунктирный, чтобы не
   читался как ещё один тип исследования */
.rp-method.none { border-style: dashed; color: var(--text-2); }
.rp-method.none.on { border-style: solid; color: #fff; }
.rp-method:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.rp-methods .lnk { margin-left: 2px; }

/* ---------- Справочник сокращений (pages/abbr.js) ----------
   Таблица только для чтения: строки разной высоты (у ЗО полтора десятка
   написаний), поэтому ячейки выровнены по верху — иначе короткие поля
   «плавали» бы посередине длинной строки. Фильтр по типу — те же кнопки с
   числом, что в «Обратной связи». */
.abbr-intro { max-width: 900px; line-height: 1.55; }
.abbr-toolbar { display: flex; align-items: center; flex-wrap: wrap; gap: 12px; margin-bottom: 12px; }
.abbr-toolbar .input { max-width: 320px; margin-left: auto; }
.abbr-filters { display: flex; flex-wrap: wrap; gap: 6px; }
.abbr-count { margin-left: 6px; padding: 0 6px; border-radius: 100px; font-size: 11px;
  background: var(--surface-2); color: var(--text-2); }
.btn.primary .abbr-count { background: rgba(255,255,255,.22); color: #fff; }
.card .card-b.abbr-body { padding: 0 6px 6px; }
table.tbl.abbr-tbl td { vertical-align: top; }
.abbr-tbl .abbr-key { font-weight: 650; white-space: nowrap; }
.abbr-tbl .badge { white-space: nowrap; }
.abbr-tbl .abbr-vars, .abbr-tbl .abbr-not { color: var(--text-2); }
.abbr-tbl .abbr-vars { font-size: 12.5px; max-width: 260px; }
.abbr-tbl .abbr-where { margin-top: 4px; min-width: 160px; max-width: 220px; }
/* Правка справочника (05.10.2026, вечер; право «Справочник: правка»): кнопки
   строки — в один ряд, с переносом на узком экране; метки «своя запись» и
   «изменено» — под сокращением, мельче бейджа типа, чтобы не спорить с ним.
   Ошибка сервера стоит прямо под полем, к которому относится. */
.abbr-toolbar .btn.primary { flex: none; }
.abbr-tbl .abbr-mark { margin-top: 4px; font-size: 10.5px; padding: 1px 7px; font-weight: 600; }
.abbr-tbl td.abbr-act { white-space: nowrap; }
.abbr-actions { display: flex; flex-wrap: wrap; gap: 6px; justify-content: flex-end; min-width: 120px; }
.abbr-form .abbr-area { min-height: 0; }
/* сокращение и тип — по верху: подсказка под сокращением не должна тянуть тип вниз */
.abbr-form .row.abbr-row { align-items: flex-start; }
.abbr-form .abbr-hint { margin-top: 4px; line-height: 1.45; }
.abbr-err { color: var(--red); font-size: 12.5px; }
.abbr-err:not(:empty) { margin-top: 4px; }
.abbr-form > .abbr-err:not(:empty) { margin-top: 12px; }
.abbr-form [aria-invalid="true"] { border-color: var(--red); }
.abbr-warn { color: var(--amber); margin-bottom: 6px; }
.abbr-chk { margin-bottom: 12px; }
.abbr-chk input[type=checkbox] { width: 16px; height: 16px; accent-color: var(--accent); flex: none; }
.abbr-chk label { font-weight: 600; color: var(--text); cursor: pointer; }
.abbr-chk .abbr-hint { margin: 2px 0 0 22px; }
.abbr-code-box { padding: 12px 14px 0; margin-bottom: 14px; border-left: 3px solid var(--accent-soft);
  background: var(--surface-2); border-radius: var(--radius-sm); }
.abbr-check { margin-top: 6px; border: 1px solid var(--border); border-radius: var(--radius-sm); }
.abbr-check > summary { cursor: pointer; padding: 10px 12px; font-size: 13px; font-weight: 600; }
.abbr-check > summary:hover { color: var(--accent-600); }
.abbr-check-b { padding: 0 12px 12px; }
.abbr-check-out { margin-top: 10px; display: grid; gap: 6px; }
.abbr-check-text { padding: 8px 10px; background: var(--surface-2); border-radius: var(--radius-sm);
  white-space: pre-wrap; line-height: 1.55; font-size: 13px; }
.abbr-check-text mark { background: var(--amber-soft); color: inherit; border-radius: 3px; padding: 0 2px;
  box-shadow: inset 0 -2px 0 var(--amber); }
.abbr-check-ans { margin: 0; padding-left: 18px; }
.abbr-check-line { display: block; padding: 8px 10px; background: var(--surface-2); border-radius: var(--radius-sm);
  font-size: 12.5px; white-space: pre-wrap; word-break: break-word; }
.abbr-hidden { margin-top: 12px; }
.abbr-hidden > summary { cursor: pointer; padding: 12px 18px; font-size: 13px; font-weight: 600; color: var(--text-2); }
.abbr-hidden > summary:hover { color: var(--accent-600); }
.abbr-hidden-b { padding: 0 18px 14px; }
.abbr-hidden-list { list-style: none; margin: 0; padding: 0; }
.abbr-hidden-list li { display: flex; align-items: center; gap: 8px; padding: 6px 0; border-top: 1px solid var(--border);
  font-size: 13px; }
.abbr-hidden-list li .btn { margin-left: auto; }
.abbr-hidden-list li .grow { flex: 1; min-width: 0; }
.abbr-hidden-list li .grow + .btn { margin-left: 0; }
/* недействующая строка и неприменённая правка — красным, но обычным начертанием */
.abbr-problem { color: var(--red); font-weight: 400; white-space: normal; margin-top: 4px; max-width: 220px; }
.abbr-hidden-list .abbr-problem { max-width: none; }
.abbr-broken > summary { color: var(--red); }
.abbr-check-gloss > summary { cursor: pointer; color: var(--text-2); margin-bottom: 4px; }
