/* packages/ui/speech.css — раздел «Речевая аналитика» (ТЗ §13).
 *
 * Правила ТЗ §17.4/§20.3.6, которые эти стили обязаны держать:
 *   - desktop-first, минимальная ширина 1280 px; общего горизонтального
 *     переполнения страницы нет ни на одном экране;
 *   - широкие таблицы скроллятся ВНУТРИ своего контейнера (`.sp-scroll`), а
 *     не растягивают страницу;
 *   - цвет не является единственным кодом статуса: у каждой плашки и каждого
 *     состояния есть текст (см. `speech_views.js` — там все подписи).
 *
 * Покрывает вид ДВУХ вкладок («Дашборд», «Описание проекта») и всех пяти
 * рисовалок дашборда: секции, KPI-плитки, SVG-тренд, гистограмма баллов,
 * стек-бар потока (пятый маршрут — `--violet`), полосы Парето, тепловые
 * карты (`color-mix`), реестр с переключателем режима и листалкой, карточка
 * звонка (круг балла, полосы этапов, чек-лист, сетка «панель критерия +
 * транскрипция», панель флагов), форма ручной проверки, подсветка реплик,
 * превью недельной задачи, пресеты периода и чекбокс «Только критические».
 *
 * Ни одного собственного цвета: только токены `packages/theme/tokens.css`.
 */

/* `position: relative` здесь — НЕ оформление, а условие работоспособности
   раздела. `.state` (states.css) — это `position: absolute; inset: 0`, то есть
   он растягивается по ближайшему ПОЗИЦИОНИРОВАННОМУ предку. Пока у панели его
   не было, любое состояние (загрузка, «пусто», ошибка, отказ) уезжало
   растягиваться по `.frame-wrap` раздела «Дашборды» и накрывало собой ВСЁ —
   шапку, фильтры и полосу вкладок. Плашка прозрачная, поэтому выглядело это не
   как оверлей, а как намертво залипший экран: видно всё, не нажимается ничего,
   включая вкладку, которой можно было бы уйти обратно.

   Поймано на живом стенде: клик по «Недельному срезу» без заданной недели
   рисует `renderEmpty` — и раздел переставал отвечать на клики целиком.
   Соседи держат ровно это правило и ровно с этим комментарием
   (services.css:35, form.css:269, weekly.css:15). Правило действует на КАЖДУЮ
   панель раздела — вложенные секции дашборда несут тот же класс. */
.sp-panel {
  position: relative;
  padding: 1rem 1.1rem;
  overflow-y: auto;
  flex: 1;
  min-height: 0;
}

/* Плашка состояния внутри хоста раздела — В ПОТОКЕ, а не поверх него.
   `.state` из states.css абсолютная (`inset: 0`) и растягивается по хосту, а
   у пустого хоста высота — только его отступы: загрузка, ошибка с
   «Повторить», оба 403, 503 и «среза нет» обрезались до полоски ~32 px, и
   кнопка «Повторить» оказывалась вне видимой области. В потоке плашка
   занимает свою собственную высоту, а `min-height` оставляет место спиннеру
   загрузки. Позиционирование хоста (`position: relative` выше) остаётся —
   оно страхует от плашки, дорисованной чужим кодом. */
.sp-panel > .state,
.sp-transcript-slot > .state {
  position: relative;
  inset: auto;
  min-height: 8rem;
}

/* Тот же довод, что у `.sp-panel`: сюда `revealTranscript` рисует загрузку и
   пустые состояния раскрытия текста. `min-height` — чтобы плашке было где
   поместиться: у пустого слота высота нулевая, и абсолютная плашка внутри
   него легла бы поверх соседей вместо своего места. */
.sp-transcript-slot {
  position: relative;
  min-height: 6rem;
}

/* Соседние панели дашборда (обзор+тренд+гистограмма+поток+Парето, тепловые
   карты, «Как формируется оценка», реестр, карточка, недельный срез) — прямые
   дети общего `.sp-tab-panel`; между ними нужен воздух, не завязанный на
   конкретное имя блока. */
.sp-tab-panel > * + * {
  margin-top: 1rem;
}

/* --- фильтры ------------------------------------------------------------- */

.sp-filters {
  display: flex;
  flex-wrap: wrap;
  gap: .5rem .7rem;
  align-items: flex-end;
  padding: .7rem 1.1rem;
  border-bottom: 1px solid var(--border);
  background: var(--surface-3);
}
.sp-filter {
  display: flex;
  flex-direction: column;
  gap: .2rem;
  min-width: 0;
}
.sp-filter[hidden] { display: none; }
.sp-filter-label {
  font-size: .74rem;
  color: var(--ink-3);
  text-transform: uppercase;
  letter-spacing: .02em;
}
/* Подсказка ПОД полем, а не всплывающая по наведению: наводит тот, кто уже
   догадался, а нуждается в подсказке тот, кто нет. */
.sp-filter-hint {
  font-size: .72rem;
  color: var(--ink-3);
  max-width: 18rem;
}
.sp-input {
  border: 1px solid var(--border-2);
  border-radius: 6px;
  background: var(--surface);
  color: var(--ink);
  font: inherit;
  font-size: .86rem;
  padding: .34rem .5rem;
  min-width: 9rem;
}
.sp-input:focus-visible { outline: 2px solid var(--focus); outline-offset: 1px; }
.sp-textarea { min-height: 4.5rem; min-width: 24rem; resize: vertical; }

/* Чекбокс «Только критические» — поле в один ряд, а не в столбик, как у
   текстовых фильтров: подпись стоит РЯДОМ с квадратиком, не под ним. */
.sp-filter-critical_only {
  flex-direction: row;
  align-items: center;
  gap: .4rem;
}
.sp-check {
  width: 1rem;
  height: 1rem;
  accent-color: var(--blue);
}

/* Пресеты периода — кнопки-чипы в ряд. Своей строкой над полями: иначе
   полоса из шести полей не влезает в 1280 px и рвётся посередине, унося
   «Услугу» и «Только критические» вниз. Активный пресет подсвечен (и несёт
   `aria-pressed`): иначе было не понять, выбран ли он сейчас. */
.sp-presets {
  flex-direction: row;
  align-items: center;
  gap: .5rem;
  flex-basis: 100%;
}
.sp-preset {
  border: 1px solid var(--border-2);
  background: var(--surface);
  border-radius: 999px;
  padding: .28rem .8rem;
  font: inherit;
  font-size: .82rem;
  color: var(--ink-2);
  cursor: pointer;
}
.sp-preset:hover { background: var(--surface-2); }
.sp-preset:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.sp-preset-active { background: var(--blue-wash); border-color: var(--blue); color: var(--blue-deep); font-weight: 600; }
.sp-filters select.sp-input { max-width: 15rem; }
.sp-filter-critical_only { padding-bottom: .4rem; }
.sp-filter-critical_only .sp-filter-label {
  text-transform: none;
  letter-spacing: 0;
  font-size: .86rem;
  color: var(--ink);
}

/* Поле недели недельной секции — свой лёгкий ряд, не боевая полоса фильтров:
   рамка и подложка снимаются, чтобы не спорить с заголовком секции над ним. */
.sp-week-filter {
  border-bottom: 0;
  background: none;
  padding: 0 0 .6rem;
}

.sp-tabs { padding: 0 1.1rem; border-bottom: 1px solid var(--border); }

/* --- секции --------------------------------------------------------------- */

.sp-section { margin: 1.2rem 0 0; }
.sp-section-head { margin-bottom: .5rem; }
.sp-section-title { margin: 0; font-size: .98rem; color: var(--ink); }
.sp-section-hint { margin: .15rem 0 0; font-size: .82rem; color: var(--ink-2); max-width: 88ch; }
.sp-sub { margin: .9rem 0 .35rem; font-size: .9rem; color: var(--ink); }

.sp-note { margin: .45rem 0 0; font-size: .82rem; color: var(--ink-3); }
.sp-note-warn { color: var(--warn); }
.sp-muted { color: var(--ink-3); }
.sp-err { color: var(--err); }

/* --- окно расчёта и протухание --------------------------------------------- */

/* «Обзор команды»: заголовок слева, метка периода справа (прототип). */
.sp-overview { margin-top: 0; }
.sp-overview-head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: flex-start;
  gap: .4rem 1rem;
}
.sp-overview-head .sp-section-head { margin-bottom: 0; }
.sp-overview-head .sp-range {
  border: 1px solid var(--border);
  border-radius: 999px;
  padding: .2rem .7rem;
  background: var(--surface-3);
}

/* Пары панелей прототипа: «тренд + гистограмма» (1.25 : .75) и «поток +
   Парето» (поровну). На узком экране — одна колонка. */
.sp-dashboard-blocks > * + * { margin-top: 1rem; }
.sp-overview .sp-tiles { grid-template-columns: repeat(4, minmax(0, 1fr)); }
.sp-pair {
  display: grid;
  gap: 1rem;
  align-items: start;
}
.sp-pair-wide { grid-template-columns: minmax(0, 1.25fr) minmax(0, .75fr); }
.sp-pair-even { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); }
.sp-pair-cell {
  min-width: 0;
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: 0 .9rem .9rem;
  background: var(--surface);
}

.sp-range {
  display: flex;
  gap: .5rem;
  align-items: baseline;
  flex-wrap: wrap;
  font-size: .86rem;
}
.sp-range-label { color: var(--ink-3); }
.sp-range-value { color: var(--ink); font-weight: 600; }

/* Плашка «данные устарели» НЕ прячет цифры (ТЗ §15) — она стоит НАД ними и
   несёт время последнего пересчёта. Текст, а не только цвет. */
.sp-stale,
.sp-status,
.sp-saved,
.sp-deleted {
  display: flex;
  flex-direction: column;
  gap: .15rem;
  margin: .7rem 0 0;
  padding: .55rem .7rem;
  border: 1px solid var(--border-2);
  border-left: 3px solid var(--warn);
  border-radius: 6px;
  background: var(--surface-2);
  font-size: .84rem;
  color: var(--ink-2);
}
.sp-stale strong, .sp-deleted strong { color: var(--warn); }
/* Состояние обработки — не предупреждение: это положение дел, а не сбой,
   поэтому левая полоса синяя, а не янтарная. Различает их ТЕКСТ, цвет лишь
   помогает (ТЗ §13.7 — цвет не является единственным кодом статуса). */
.sp-status { border-left-color: var(--blue); }
.sp-status strong { color: var(--blue-deep); }
.sp-status-warn { border-left-color: var(--warn); }
.sp-status-warn strong { color: var(--warn); }
/* Успешная корректировка — тот же примитив плашки, зелёная полоса и слово
   «Сохранено» текстом: без текста состояние читалось бы одним цветом, что
   ТЗ §13.7 прямо запрещает. */
.sp-saved { border-left-color: var(--ok); }
.sp-saved strong { color: var(--ok); }
.sp-stale-at { color: var(--ink-3); }

/* --- плитки KPI ------------------------------------------------------------ */
/* `.sp-card-kpis` — та же сетка, что у `.sp-tiles` обзора дашборда: карточка
   звонка оборачивает плитки `renderCardKpis` в свой блок тем же классом-под-
   ходом (`block(host, "sp-card-kpis")` в `speech.js`), а не отдаёт их в общий
   поток хоста напролёт. */
.sp-tiles,
.sp-card-kpis {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(11rem, 1fr));
  gap: .6rem;
  margin: .9rem 0 0;
}
.sp-tile {
  border: 1px solid var(--border);
  border-radius: 8px;
  background: var(--surface-3);
  padding: .6rem .75rem;
}
.sp-tile-value {
  font-size: 1.5rem;
  font-weight: 600;
  color: var(--ink);
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}
.sp-tile-label { font-size: .82rem; color: var(--ink-2); margin-top: .1rem; }
.sp-tile-hint { font-size: .74rem; color: var(--ink-3); margin-top: .15rem; }

/* --- таблицы ---------------------------------------------------------------- */

/* Локальный скролл, а не переполнение страницы (ТЗ §20.3.6). */
.sp-scroll { overflow-x: auto; margin-top: .3rem; }
.sp-tbl { min-width: 100%; font-size: .85rem; }
.sp-tbl td { vertical-align: top; }
.sp-code { font-family: var(--mono); font-size: .8rem; white-space: nowrap; }

.sp-bar {
  display: block;
  height: .5rem;
  border-radius: 3px;
  background: var(--surface-2);
  min-width: 5rem;
}
.sp-bar-fill { display: block; height: 100%; border-radius: 3px; background: var(--blue); }
/* Пороги балла (ТЗ «Экран» п.7): ≥80 / 65–79 / <65. */
.sp-bar-good { background: var(--ok); }
.sp-bar-warn { background: var(--warn); }
.sp-bar-bad { background: var(--err); }
.sp-tone-good { color: var(--ok); }
.sp-tone-warn { color: var(--warn); }
.sp-tone-bad { color: var(--err); }
td.sp-tone-good, td.sp-tone-warn, td.sp-tone-bad { font-weight: 600; }
.sp-corrected {
  margin-left: .3rem;
  font-size: .7rem;
  font-weight: 400;
  color: var(--blue-deep);
  border-bottom: 1px dotted var(--blue-deep);
}

/* Колонка действия «прилипает» к правому краю внутреннего скролла: на
   1280 px реестр шире панели, и «Открыть» уезжала за горизонтальный скролл. */
.sp-actions {
  white-space: nowrap;
  position: sticky;
  right: 0;
  background: var(--surface);
  box-shadow: -1px 0 0 var(--divider);
}
/* Реестр — двенадцать колонок, и на 1440 px «Проверка», а на 1280 ещё
   «Уверенность» и «Критический флаг» уходили за прокрутку. В прототипе видны
   все колонки: заголовки здесь переносятся по словам, отступы ячеек уже
   общих, и таблица укладывается в ширину панели. */
.sp-registry-host .tbl th {
  white-space: normal;
  vertical-align: bottom;
  padding: .45rem .5rem;
}
.sp-registry-host .tbl td { padding: .45rem .5rem; }
.sp-registry-host .sp-tbl { font-size: .82rem; }
.sp-registry-host .sp-status-cell { min-width: 5.5rem; }
.sp-registry-host td > .sp-pill { white-space: nowrap; }
/* Строка открытой карточки. */
.sp-row-active, .sp-row-active > .sp-actions { background: var(--blue-wash); }
.sp-row-active > td:first-child { box-shadow: inset 3px 0 0 var(--blue); }
.sp-status-cell { font-size: .8rem; color: var(--ink-2); min-width: 7rem; }
.sp-status-cell .sp-pill { display: inline-block; margin-top: .2rem; }
/* Название критерия в Парето — не уже 11rem: в колонке пары оно иначе
   ломалось на слова-столбик. */
.sp-pair-cell .sp-tbl td:first-child { min-width: 11rem; }
/* Парето в половине ширины: название уже, полоса доли короче — все столбцы,
   включая «Долю», помещаются без внутренней прокрутки на 1280 px. */
.sp-pair-cell .sp-pareto .sp-tbl td:first-child { min-width: 8rem; }
.sp-pareto .sp-bar { min-width: 3.5rem; }
.sp-pareto .sp-tbl th, .sp-pareto .sp-tbl td { padding-left: .4rem; padding-right: .4rem; }
.sp-link {
  background: none;
  border: 0;
  padding: 0;
  color: var(--blue-deep);
  font: inherit;
  font-size: .85rem;
  text-decoration: underline;
  cursor: pointer;
}
.sp-link:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.sp-btn {
  border: 1px solid var(--blue);
  background: var(--blue);
  border-radius: 6px;
  padding: .38rem .75rem;
  font: inherit;
  font-size: .85rem;
  cursor: pointer;
}
.sp-btn:disabled { background: var(--surface-2); border-color: var(--border-2); color: var(--ink-3); cursor: default; }
.sp-btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
/* Единственная точка литерального белого текста файла (у `--blue`/`--violet`
   как подложки токена белого текста в теме нет): кнопка действия и её
   компактный близнец `.sp-action.sp-primary` в панели критерия. */
.sp-btn,
.sp-action.sp-primary {
  color: #fff;
}

.sp-pager { display: flex; gap: .5rem; align-items: center; margin-top: .7rem; }
.sp-page-btn {
  border: 1px solid var(--border-2);
  background: var(--surface);
  border-radius: 6px;
  padding: .3rem .7rem;
  font: inherit;
  font-size: .84rem;
  color: var(--ink-2);
  cursor: pointer;
}
.sp-page-btn:disabled { color: var(--ink-3); cursor: default; }
.sp-page-num { font-size: .84rem; color: var(--ink-3); }

/* --- карточка звонка: раскладка хоста --------------------------------------- */

/* Плитки KPI идут своим блоком `.sp-card-kpis` (см. выше) — хосту карточки
   остаётся просто выстроить секции колонкой, без allow-list по классам. */
.sp-card-host {
  display: flex;
  flex-direction: column;
  gap: 1rem;
}

.sp-detail-bar { display: flex; gap: .7rem; align-items: center; margin: .2rem 0 .7rem; }
.sp-card-head { border-bottom: 1px solid var(--divider); padding-bottom: .6rem; }
.sp-card-title { margin: 0; font-size: 1.05rem; }
.sp-card-meta { display: flex; flex-wrap: wrap; gap: .8rem; margin-top: .25rem; font-size: .83rem; color: var(--ink-2); }

/* --- круг балла и флаги шапки ------------------------------------------------ */

.sp-card-score { display: flex; align-items: flex-start; gap: .8rem; margin-top: .6rem; }
/* Круг балла заполняется по значению (`conic-gradient` ставит
   `speech_card.js` атрибутом, цвет — токеном по порогу балла); внутренний
   диск — поверх, число — на нём. */
.sp-score-circle {
  position: relative;
  flex: 0 0 auto;
  width: 4.6rem;
  height: 4.6rem;
  border-radius: 50%;
  background: var(--surface-2);
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 1.3rem;
  font-weight: 700;
  color: var(--ink);
}
.sp-score-circle::before {
  content: "";
  position: absolute;
  inset: 6px;
  border-radius: 50%;
  background: var(--surface);
}
.sp-score-circle strong { position: relative; }
.sp-flag-names { font-size: .8rem; color: var(--ink-2); max-width: 40rem; }
.sp-card-flag-info { display: flex; flex-direction: column; align-items: flex-start; gap: .25rem; padding-top: .2rem; }
.sp-pill {
  display: inline-block;
  border: 1px solid var(--border-2);
  border-radius: 10px;
  padding: 0 .5rem;
  font-size: .76rem;
  color: var(--ink-2);
  background: var(--surface-2);
}
.sp-pill-ok {
  border-color: var(--ok);
  color: var(--ok);
  background: color-mix(in srgb, var(--ok) 14%, var(--surface));
}
.sp-pill-warn {
  border-color: var(--warn);
  color: var(--warn);
  background: color-mix(in srgb, var(--warn) 14%, var(--surface));
}
.sp-pill-bad {
  border-color: var(--err);
  color: var(--err);
  background: color-mix(in srgb, var(--err) 12%, var(--surface));
}
.sp-pill-muted { color: var(--ink-3); }
.sp-badge {
  display: inline-block;
  margin-left: .4rem;
  border: 1px solid var(--border-2);
  border-radius: 10px;
  padding: 0 .4rem;
  font-size: .7rem;
  color: var(--ink-3);
  background: var(--surface-2);
}

/* --- полосы этапов (ТЗ §10) --------------------------------------------------- */

.sp-stage-bars { display: flex; flex-direction: column; gap: .4rem; }
.sp-stage-bar-row { display: flex; align-items: center; gap: .6rem; font-size: .84rem; }
.sp-stage-bar-label { min-width: 8rem; color: var(--ink-2); }
.sp-stage-bar-row .sp-bar { flex: 1; }
.sp-stage-bar-value { min-width: 2.6rem; text-align: right; color: var(--ink); font-variant-numeric: tabular-nums; }
.sp-stage-bar-empty { flex: 1; color: var(--ink-3); font-size: .8rem; }

/* --- чек-лист (ТЗ «Экран» п.11) ----------------------------------------------- */

.sp-criterion-cell { min-width: 12rem; }
.sp-reason-cell { min-width: 14rem; color: var(--ink-2); }
.sp-row-selected { background: var(--blue-wash); }
/* Строка чек-листа выбирается и мышью, и с клавиатуры (tabindex=0). */
.sp-row-pick { cursor: pointer; }
.sp-row-pick:hover { background: var(--surface-2); }
.sp-row-pick.sp-row-selected:hover { background: var(--blue-wash); }
.sp-row-pick:focus-visible { outline: 2px solid var(--focus); outline-offset: -2px; }
.sp-evidence-button { font-family: var(--mono); font-size: .78rem; }

/* --- сетка «панель критерия + транскрипция» (ТЗ §13.6) ------------------------ */

.sp-card-side {
  display: grid;
  grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr);
  gap: 1rem;
}
.sp-criterion-column { min-width: 0; display: flex; flex-direction: column; gap: .5rem; }
.sp-criterion-host { min-width: 0; }
.sp-transcript-column {
  min-width: 0;
  display: flex;
  flex-direction: column;
  gap: .5rem;
}

.sp-criterion-panel {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: .7rem .85rem;
  background: var(--surface-3);
}
.sp-criterion-panel h3 { margin: 0 0 .5rem; font-size: .95rem; color: var(--ink); }
.sp-criterion-evidence { margin: .6rem 0; }
.sp-reveal-suggest {
  border: 1px dashed var(--border-2);
  border-radius: 6px;
  padding: .6rem .7rem;
  color: var(--ink-2);
  font-size: .84rem;
}
.sp-reveal-suggest p { margin: 0 0 .5rem; }

.sp-detail-row { display: flex; gap: .5rem; margin: .3rem 0; font-size: .85rem; }
.sp-detail-label { flex: 0 0 auto; min-width: 6rem; color: var(--ink-3); }
.sp-detail-value { color: var(--ink); }

.sp-review-row { display: flex; gap: .5rem; flex-wrap: wrap; margin: .6rem 0; }
.sp-action {
  border: 1px solid var(--border-2);
  background: var(--surface);
  border-radius: 6px;
  padding: .32rem .65rem;
  font: inherit;
  font-size: .82rem;
  color: var(--ink-2);
  cursor: pointer;
}
.sp-action:hover { background: var(--surface-2); }
.sp-action:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.sp-action.sp-primary { border-color: var(--blue); background: var(--blue); }

.sp-history { margin-top: .7rem; border-top: 1px solid var(--divider); padding-top: .5rem; }
.sp-history h4 { margin: 0 0 .35rem; font-size: .85rem; color: var(--ink); }
.sp-history-item { display: flex; gap: .4rem; flex-wrap: wrap; font-size: .8rem; color: var(--ink-2); margin-bottom: .25rem; }

/* --- панель флагов (ТЗ §13.7) --------------------------------------------------- */

.sp-flags-host { display: flex; flex-direction: column; gap: .6rem; }
.sp-flags-host:empty, .sp-flag-review-slot:empty { display: none; }
.sp-flag {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: .6rem .75rem;
  background: var(--surface-3);
}
.sp-flag-head { display: flex; align-items: center; gap: .5rem; flex-wrap: wrap; margin-bottom: .4rem; }

/* --- ручная проверка ---------------------------------------------------------- */

.sp-review {
  border: 1px solid var(--border-2);
  border-radius: 8px;
  padding: .7rem .85rem;
  margin: .9rem 0;
  background: var(--surface-2);
}
.sp-field { display: flex; flex-direction: column; gap: .2rem; margin-bottom: .5rem; font-size: .85rem; color: var(--ink-2); }
.sp-review-feedback { margin-top: .5rem; }

/* --- транскрипция -------------------------------------------------------------- */

.sp-reveal { display: flex; gap: .7rem; align-items: center; margin: 1rem 0 .3rem; flex-wrap: wrap; font-size: .82rem; }
.sp-transcript { border-top: 1px solid var(--divider); padding-top: .5rem; }
.sp-transcript-head { display: flex; gap: .9rem; flex-wrap: wrap; font-size: .8rem; color: var(--ink-2); margin-bottom: .4rem; }
.sp-turn {
  display: grid;
  grid-template-columns: 3.4rem 5.5rem 1fr;
  gap: .5rem;
  padding: .3rem .4rem;
  border-radius: 5px;
  font-size: .86rem;
  align-items: start;
}
.sp-turn-id { font-family: var(--mono); font-size: .74rem; color: var(--ink-3); }
.sp-turn-speaker { font-weight: 600; color: var(--ink-2); font-size: .8rem; }
/* Роли различимы И текстом (подпись говорящего печатается всегда), и фоном —
   цвет здесь дополняет подпись, а не заменяет её (ТЗ §13.7). */
.sp-turn-operator { background: var(--surface-3); }
.sp-turn-client { background: var(--blue-wash); }
.sp-turn-unknown { background: var(--surface); }
.sp-turn-evidence { border-left: 3px solid var(--border-2); }
.sp-turn-active { border-left: 3px solid var(--blue); background: var(--surface-2); }
/* Названия критериев и флагов, что ссылаются на реплику (не коды). */
.sp-turn-codes { grid-column: 3; font-size: .74rem; color: var(--ink-3); }

/* --- тренд (SVG, ТЗ «Экран» п.4) ------------------------------------------------ */

.sp-trend { width: 100%; height: auto; margin-top: .6rem; }
.sp-trend-grid { stroke: var(--divider); stroke-width: 1; }
.sp-trend-point { stroke: var(--surface); stroke-width: 1.5; }
.sp-trend-point-score { fill: var(--blue); }
.sp-trend-point-coverage { fill: var(--ok); }
.sp-trend-value { font-size: 11px; font-weight: 600; }
.sp-trend-value.sp-trend-point-score { fill: var(--blue); stroke: none; }
.sp-trend-value.sp-trend-point-coverage { fill: var(--ok); stroke: none; }
.sp-trend-legend { display: flex; flex-wrap: wrap; gap: .4rem 1.2rem; margin-top: .4rem; font-size: .8rem; color: var(--ink-2); }
.sp-trend-key { display: inline-flex; align-items: center; gap: .4rem; }
.sp-trend-key::before { content: ""; display: inline-block; width: 1.2rem; height: 0; border-top: 2px solid var(--ink-3); }
.sp-trend-key-score::before { border-top-color: var(--blue); }
.sp-trend-key-coverage::before { border-top-color: var(--ok); }
.sp-trend-key-target::before { border-top: 1px dashed var(--ink-3); }
.sp-trend-target { stroke: var(--ink-3); stroke-width: 1; }
.sp-trend-line { fill: none; stroke-width: 2; }
.sp-trend-line-score { stroke: var(--blue); }
.sp-trend-line-coverage { stroke: var(--ok); }
.sp-trend-tick { fill: var(--ink-3); font-size: 11px; }

/* --- гистограмма баллов (ТЗ «Экран» п.5) ---------------------------------------- */

.sp-hist {
  display: flex;
  align-items: flex-end;
  gap: .6rem;
  height: 9rem;
  margin-top: .6rem;
  padding: 0 .2rem;
}
.sp-hist-col {
  flex: 1;
  min-width: 2.6rem;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: flex-end;
}
.sp-hist-fill {
  width: 100%;
  min-height: 2px;
  border-radius: 4px 4px 0 0;
  background: var(--ink-3);
}
/* Порядок диапазонов гистограммы — статусный ряд ТЗ: ниже 60 — ошибка,
   60–69 — предупреждение, 70–79 — нейтральный акцент, 80+ — успех. */
.sp-hist-band-low .sp-hist-fill { background: var(--err); }
.sp-hist-band-60 .sp-hist-fill { background: var(--warn); }
.sp-hist-band-70 .sp-hist-fill { background: var(--blue); }
.sp-hist-band-80 .sp-hist-fill { background: var(--ok); }
.sp-hist-count { margin-bottom: .25rem; font-size: .8rem; font-weight: 600; color: var(--ink); font-variant-numeric: tabular-nums; }
.sp-hist-label { font-size: .72rem; color: var(--ink-3); text-align: center; }

/* --- состав потока (ТЗ «Экран» п.6) --------------------------------------------- */

.sp-route-stack {
  display: flex;
  height: 1.4rem;
  border-radius: 6px;
  overflow: hidden;
  background: var(--surface-2);
  margin-top: .6rem;
}
.sp-route-segment {
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.sp-route-pct { font-size: .72rem; font-weight: 600; color: var(--surface); white-space: nowrap; }
.sp-route-segment.sp-route-none { background: var(--ink-2); }
/* Цвет маршрута — по его ключу, как в прототипе: новый запрос синий, после
   заказа оранжевый (`--warn` — ближайший оранжевый в замороженной теме),
   реактивация зелёная, прочие продажи фиолетовые (`--violet`, D-4),
   технические серые. Красного (`--err`) здесь нет: на экране он значит
   «плохо», а маршрут — нейтральная категория. «Без маршрута» — тёмно-серый,
   чтобы не сливаться с техническими. */
.sp-route-segment.sp-route-new { background: var(--blue); }
.sp-route-segment.sp-route-post { background: var(--warn); }
.sp-route-segment.sp-route-react { background: var(--ok); }
.sp-route-segment.sp-route-other { background: var(--violet); }
.sp-route-segment.sp-route-tech { background: var(--ink-3); }

.sp-route-legend {
  list-style: none;
  display: flex;
  flex-wrap: wrap;
  gap: .3rem .9rem;
  margin: .6rem 0 0;
  padding: 0;
  font-size: .82rem;
  color: var(--ink-2);
}
.sp-route-legend-item { display: flex; align-items: center; gap: .35rem; }
.sp-route-legend-item::before {
  content: "";
  width: .6rem;
  height: .6rem;
  border-radius: 2px;
  background: var(--ink-3);
}
.sp-route-legend-item.sp-route-new::before { background: var(--blue); }
.sp-route-legend-item.sp-route-post::before { background: var(--warn); }
.sp-route-legend-item.sp-route-react::before { background: var(--ok); }
.sp-route-legend-item.sp-route-other::before { background: var(--violet); }
.sp-route-legend-item.sp-route-tech::before { background: var(--ink-3); }
.sp-route-legend-item.sp-route-none::before { background: var(--ink-2); }

/* --- Парето по провалам (ТЗ «Экран» п.6) ---------------------------------------- */

.sp-pareto-switch { display: flex; gap: .4rem; margin-bottom: .5rem; }
.sp-pareto-tab {
  border: 1px solid var(--border-2);
  background: var(--surface);
  border-radius: 999px;
  padding: .3rem .8rem;
  font: inherit;
  font-size: .82rem;
  color: var(--ink-2);
  cursor: pointer;
}
.sp-pareto-tab:hover { background: var(--surface-2); }
.sp-pareto-tab:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.sp-pareto-tab-active { background: var(--blue-wash); border-color: var(--blue); color: var(--blue-deep); }
.sp-pareto-share-text { margin-left: .4rem; font-size: .8rem; color: var(--ink-2); font-variant-numeric: tabular-nums; }

/* --- тепловые карты (ТЗ «Экран» п.7–8) ------------------------------------------ */

/* Пороги ТЗ п.7 — цвет через `color-mix` с токеном темы поверх поверхности,
   не литеральным оттенком: ≥80 «хорошо», 65–79 «пограничное», <65 «плохо». */
.sp-heat-good { background: color-mix(in srgb, var(--ok) 22%, var(--surface)); }
.sp-heat-warn { background: color-mix(in srgb, var(--warn) 22%, var(--surface)); }
.sp-heat-bad { background: color-mix(in srgb, var(--err) 22%, var(--surface)); }
.sp-heat-none { background: var(--surface); color: var(--ink-3); }

/* --- реестр: переключатель режима и листалка (ТЗ «Экран» п.10) ----------------- */

.sp-registry-head { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: .6rem; }
.sp-registry-head .sp-section-title { margin: 0; }
.sp-registry-mode { display: flex; gap: .4rem; }
.sp-mode-btn {
  border: 1px solid var(--border-2);
  background: var(--surface);
  border-radius: 999px;
  padding: .3rem .8rem;
  font: inherit;
  font-size: .82rem;
  color: var(--ink-2);
  cursor: pointer;
}
.sp-mode-btn:hover { background: var(--surface-2); }
.sp-mode-btn:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }
.sp-mode-btn-active { background: var(--blue-wash); border-color: var(--blue); color: var(--blue-deep); }

/* --- ключ-значение (недельный срез) --------------------------------------------- */

.sp-kv { display: grid; grid-template-columns: max-content 1fr; gap: .15rem .8rem; margin: .4rem 0 0; font-size: .85rem; }
.sp-kv dt { color: var(--ink-3); }
.sp-kv dd { margin: 0; color: var(--ink); font-variant-numeric: tabular-nums; }
.sp-kv-mono dd { font-family: var(--mono); font-size: .78rem; overflow-wrap: anywhere; }

/* --- очередь, недельный срез, превью задачи (ТЗ «Экран» п.10, п.13) ------------- */

.sp-weekly { margin-bottom: 1.6rem; }
.sp-weekly-head { border-bottom: 1px solid var(--divider); padding-bottom: .4rem; }
.sp-summary { font-size: .9rem; color: var(--ink); max-width: 88ch; }
.sp-list { margin: .2rem 0; padding-left: 1.1rem; font-size: .86rem; }
.sp-list li { margin-bottom: .2rem; }
.sp-basis { margin-left: .4rem; font-family: var(--mono); font-size: .72rem; color: var(--ink-3); }

.sp-weekly-section > * + * { margin-top: .6rem; }
.sp-weekly-list > .sp-weekly + .sp-weekly { border-top: 1px solid var(--divider); padding-top: 1.2rem; }

.sp-weekly-details { margin-top: .8rem; }
.sp-weekly-summary {
  cursor: pointer;
  color: var(--blue-deep);
  font-size: .85rem;
  padding: .3rem 0;
}
.sp-weekly-summary:focus-visible { outline: 2px solid var(--focus); outline-offset: 2px; }

/* Недельная задача по прототипу (ADR-0224): задачи слева, «Контроль
   выполнения» справа; на узком экране — одна колонка. */
.sp-section-lead { margin: .2rem 0 .6rem; color: var(--ink-2); font-size: .85rem; }
.sp-bitrix-preview { display: grid; grid-template-columns: 1fr .45fr; gap: 18px; align-items: start; }
.sp-task-list { display: grid; gap: 14px; min-width: 0; }
.sp-task { background: var(--surface); border: 1px solid var(--border-2); border-radius: 9px; padding: 20px; min-width: 0; }
.sp-task-title { margin: 14px 0 0; font-size: 1.05rem; color: var(--ink); overflow-wrap: anywhere; }
.sp-task-meta {
  display: flex; flex-wrap: wrap; gap: 8px 18px;
  color: var(--ink-3); font-size: 12px;
  margin: 9px 0 18px; padding-bottom: 14px; border-bottom: 1px solid var(--divider);
}
.sp-task-summary { margin: 0 0 .6rem; font-size: .9rem; color: var(--ink); overflow-wrap: anywhere; }
.sp-task-actions { padding-left: 20px; margin: 0; }
.sp-task-actions li { margin: 8px 0; font-size: 13px; }
.sp-task-full { margin-top: .8rem; }
.sp-task-aside { background: var(--surface-2); border-left: 5px solid var(--blue); padding: 18px; border-radius: 0 9px 9px 0; }
.sp-task-aside-label { color: var(--ink-3); font-size: .8rem; }
.sp-task-aside strong { display: block; font-size: 28px; margin: 8px 0; color: var(--ink); }
.sp-task-aside-note { color: var(--ink-3); font-size: .8rem; margin: 0 0 .4rem; }
.sp-task-aside .sp-action { display: inline-block; margin-top: 14px; text-decoration: none; }
@media (max-width: 900px) {
  .sp-bitrix-preview { grid-template-columns: 1fr; }
}

.sp-task-preview {
  border: 1px solid var(--border-2);
  border-radius: 8px;
  padding: .7rem .85rem;
  margin: .7rem 0;
  background: var(--surface-3);
}
.sp-task-description { margin: .4rem 0; color: var(--ink-2); font-size: .85rem; white-space: pre-line; overflow-wrap: anywhere; }
.sp-task-checklist { margin: .4rem 0; padding-left: 1.1rem; font-size: .85rem; }
.sp-task-checklist li { margin-bottom: .2rem; }

/* --- вкладка «Описание проекта» (ТЗ «Экран» п.9, п.14) -------------------------- */

.sp-about-lead { font-size: .92rem; color: var(--ink-2); max-width: 80ch; margin: .6rem 0 1rem; }
.sp-about-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(20rem, 1fr));
  gap: .8rem;
}
.sp-about-block {
  border: 1px solid var(--border);
  border-radius: 8px;
  padding: .8rem .9rem;
  background: var(--surface-3);
}
.sp-about-block h3 { margin: 0 0 .4rem; font-size: .92rem; color: var(--ink); }
.sp-about-block p, .sp-about-block li { font-size: .85rem; color: var(--ink-2); }
.sp-about-block ol, .sp-about-block ul { margin: .4rem 0; padding-left: 1.1rem; }
.sp-about-wide { grid-column: 1 / -1; }

.sp-formula {
  background: var(--surface-2);
  border-radius: 6px;
  padding: .6rem .75rem;
  margin: .6rem 0 0;
}
.sp-formula p { margin: 0 0 .4rem; font-size: .84rem; color: var(--ink-2); }
.sp-formula p:last-child { margin-bottom: 0; }

.sp-state-table { width: 100%; border-collapse: collapse; margin-top: .6rem; font-size: .84rem; }
.sp-state-table th, .sp-state-table td {
  text-align: left;
  padding: .35rem .6rem;
  border-bottom: 1px solid var(--divider);
}
.sp-state-table th { color: var(--ink-3); font-weight: 600; font-size: .78rem; text-transform: uppercase; letter-spacing: .02em; }

.sp-score-rule {
  display: grid;
  grid-template-columns: 9rem 8rem 1fr;
  gap: .3rem .6rem;
  padding: .35rem 0;
  border-bottom: 1px solid var(--divider);
  font-size: .84rem;
  color: var(--ink-2);
}
.sp-score-rule:last-child { border-bottom: 0; }
.sp-score-rule strong { color: var(--ink); }

/* Мобильное использование не является приёмочным сценарием первой итерации
   (ТЗ §17.4), но интерфейс обязан оставаться читаемым: колонки реплики
   схлопываются, сетка карточки и карточки «О проекте» — в столбик, таблицы
   сохраняют собственный скролл. */
@media (max-width: 1100px) {
  .sp-pair-wide, .sp-pair-even { grid-template-columns: minmax(0, 1fr); }
  .sp-overview .sp-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

@media (max-width: 560px) {
  .sp-overview .sp-tiles { grid-template-columns: minmax(0, 1fr); }
  .sp-hist { gap: .3rem; }
  .sp-hist-col { min-width: 0; }
  .sp-hist-count { font-size: .7rem; }
}

@media (max-width: 900px) {
  /* На узком экране прилипшая «Открыть» накрывала соседние ячейки обрезками:
     здесь таблица и так прокручивается целиком, и колонка едет вместе с ней. */
  .sp-actions { position: static; box-shadow: none; }
  .sp-turn { grid-template-columns: 3.4rem 1fr; }
  .sp-turn-text { grid-column: 1 / -1; }
  .sp-turn-codes { grid-column: 1 / -1; }
  .sp-textarea { min-width: 0; width: 100%; }
  .sp-card-side { grid-template-columns: 1fr; }
  .sp-score-rule { grid-template-columns: 1fr; }
}
