/* Гудок — солнечный разрез.
   Экран прорезан сквозь рабочий день. Свет означает внимание: луч лежит на той
   области, где менеджеру сейчас место. Всё остальное — известь, поше и тень.
   Правила мира записаны в DESIGN.md; здесь только их исполнение. */

/* ---------- Гарнитуры ---------- */

@font-face {
  font-family: 'Golos Text';
  src: url('/fonts/golos-text-cyrillic-wght-normal.woff2') format('woff2-variations');
  font-weight: 400 900;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Golos Text';
  src: url('/fonts/golos-text-latin-wght-normal.woff2') format('woff2-variations');
  font-weight: 400 900;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}
@font-face {
  font-family: 'Martian Mono';
  src: url('/fonts/martian-mono-cyrillic-wght-normal.woff2') format('woff2-variations');
  font-weight: 300 800;
  font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Martian Mono';
  src: url('/fonts/martian-mono-latin-wght-normal.woff2') format('woff2-variations');
  font-weight: 300 800;
  font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC,
    U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215,
    U+FEFF, U+FFFD;
}

/* ---------- Токены ---------- */

:root {
  color-scheme: light dark;

  /* Плоскость листа и срез конструкции. Значения с карты мира; контраст
     извести к поше — 14.8:1 в обе стороны. */
  --surface-0: light-dark(#F2EFEA, #1A1D20);
  --surface-1: light-dark(#FAF8F5, #22262A);
  --surface-2: light-dark(#E7E3DC, #14171A);
  --poche:     light-dark(#1A1D20, #101315);
  --poche-ink: #F2EFEA;

  --ink-0: light-dark(#1A1D20, #F2EFEA);   /* 14.8:1 */
  --ink-1: light-dark(#5F6469, #BFC3C7);   /* 4.7:1 / 9.6:1 */
  --ink-2: light-dark(#5F6469, #8DA1B4);   /* 4.7:1 / 6.4:1 */

  --rule:        light-dark(#D5D0C7, #333A41);
  --rule-strong: light-dark(#B9B3A7, #454E57);

  /* Луч. Одинаков в обеих темах: солнце есть солнце, нарисован разрез на белой
     бумаге или освещена тёмная комната. Меняется фон, не свет.
     Текст на луче — всегда поше: от 7.0:1 до 12.1:1. */
  --beam:      #E8BC4D;
  --beam-ink:  #1A1D20;
  /* Золото как ТЕКСТ на светлом фоне даёт 1.6:1, поэтому для этого случая
     существует отдельное, затемнённое значение. Считано не по извести, а по
     самому светлому фону, на котором оно встречается — подсвеченной строке
     подписки (известь с 16% луча): там #8A6710 давало 4.35:1. */
  --beam-text: light-dark(#7A5A0E, #E8BC4D);

  --shadow-fill: light-dark(#DAD6CD, #2A343E);

  --danger: light-dark(#A33529, #E27567);
  --warn:   light-dark(#8A6710, #E8BC4D);
  --ok:     light-dark(#3D7A47, #58A46A);

  /* Разрез не знает скруглений. Значение существует только чтобы кольцо
     фокуса не выглядело случайным. */
  --r-0: 0;

  --s-1: 4px;
  --s-2: 8px;
  --s-3: 12px;
  --s-4: 16px;
  --s-5: 24px;
  --s-6: 32px;
  --s-7: 48px;

  --fs-1: .75rem;
  --fs-2: .8125rem;
  --fs-3: .9375rem;
  --fs-4: 1.0625rem;
  --fs-5: 1.1875rem;   /* шаги скрипта: их читают вслух */
  --fs-6: 1.5rem;
  --fs-7: 2rem;
  --fs-8: 2.75rem;

  --lh-tight: 1.2;
  --lh-base:  1.5;
  --lh-read:  1.6;

  --w-regular: 400;
  --w-medium:  500;
  --w-bold:    600;

  --bw: 1px;                 /* волосяная линия чертежа */
  --bw-thick: 3px;           /* кромка луча */

  --t-fast: 120ms;
  --t-base: 200ms;
  --ease: cubic-bezier(.2, 0, 0, 1);

  --sans: 'Golos Text', 'Segoe UI', system-ui, sans-serif;
  --mono: 'Martian Mono', 'Cascadia Mono', Consolas, ui-monospace, monospace;

  /* Наклон чертёжной аннотации. Только для коротких прописных подписей:
     тело и данные остаются прямыми, иначе смену в 6–8 часов не выдержать. */
  --tilt: oblique 10deg;

  --z-fault: 5;
  --z-overlay: 50;
  --z-toast: 100;

  --measure: 66ch;

  /* Доля оставшегося времени постобработки, 1 → 0. Пишется из app.js. */
  --beam-left: 1;
}

:root[data-theme="light"] { color-scheme: light; }
:root[data-theme="dark"]  { color-scheme: dark; }

/* Фаза звонка меняет только цвет луча. Слово состояния при этом никуда не
   девается: состояние никогда не передаётся одним лишь цветом. */
body[data-phase="dialing"]  { --beam: #F0D89A; }
body[data-phase="answered"] { --beam: #E8BC4D; }
body[data-phase="wrap_up"]  { --beam: #D99A3C; }

/* ---------- База ---------- */

* { margin: 0; padding: 0; box-sizing: border-box; }

html, body { height: 100%; }

body {
  font-family: var(--sans);
  font-size: var(--fs-3);
  line-height: var(--lh-base);
  color: var(--ink-0);
  background: var(--surface-0);
  -webkit-font-smoothing: antialiased;
  display: flex;
  flex-direction: column;
}

/* Колонка, а не сетка с заданными строками: скрытые дети выпадают из грида,
   строки съезжают, и панель результата уходит за экран — ровно в wrap_up,
   когда она единственное, что важно. Один раз это уже ловили. */
.masthead, .live, .fault, .result, .bay { flex: none; }
.work { flex: 1 1 auto; min-height: 0; }

/* Классы ниже задают display, а он перебивает атрибут hidden. Возвращаем приоритет. */
[hidden] { display: none !important; }

button, input, select { font: inherit; color: inherit; }
b, strong { font-weight: var(--w-bold); }

:focus-visible {
  outline: 2px solid var(--beam-text);
  outline-offset: 2px;
  border-radius: var(--r-0);
}
/* На поше затемнённое золото даёт 2.66:1 — кольца фокуса на всей нижней полосе
   и в шапке практически не было. Там берётся сам луч: 9.5:1. */
.masthead :focus-visible,
.bay :focus-visible,
.toast :focus-visible { outline-color: var(--beam); }

.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
  border: 0;
}

/* Ссылка «к работе»: первый Tab не должен вести через всю шапку. */
.skip {
  position: absolute;
  left: var(--s-3); top: -3rem;
  z-index: var(--z-toast);
  background: var(--beam);
  color: var(--beam-ink);
  padding: var(--s-2) var(--s-3);
  font-size: var(--fs-2);
  transition: top var(--t-fast) var(--ease);
}
.skip:focus { top: var(--s-3); }

/* ---------- Кнопки ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-3);
  border: var(--bw) solid var(--rule-strong);
  border-radius: var(--r-0);
  background: transparent;
  color: var(--ink-0);
  font-size: var(--fs-2);
  cursor: pointer;
  white-space: nowrap;
  text-decoration: none;
  transition: background var(--t-fast) var(--ease),
              border-color var(--t-fast) var(--ease),
              color var(--t-fast) var(--ease);
}
.btn:hover:not(:disabled)  { background: color-mix(in srgb, var(--ink-0) 8%, transparent); }
.btn:active:not(:disabled) { background: color-mix(in srgb, var(--ink-0) 16%, transparent); }
/* Недоступное уходит в тень, а не в прозрачность: на поше прозрачность съедает
   надпись целиком. */
.btn:disabled {
  color: var(--ink-2);
  border-color: var(--rule);
  cursor: not-allowed;
}

/* Основное действие — заливка лучом. Текст поше: 9.5:1 на солнце. */
.btn--go {
  background: var(--beam);
  border-color: var(--beam);
  color: var(--beam-ink);
  font-weight: var(--w-medium);
}
.btn--go:hover:not(:disabled)  { background: color-mix(in srgb, var(--beam) 86%, var(--ink-0)); }
.btn--go:active:not(:disabled) { background: color-mix(in srgb, var(--beam) 74%, var(--ink-0)); }
/* Приглушённые чернила на тени давали 4.12:1, а это главное действие самой
   спешной панели: пока итог не выбран, надпись всё равно надо читать. */
.btn--go:disabled {
  background: var(--shadow-fill);
  border-color: var(--rule);
  color: color-mix(in srgb, var(--ink-0) 80%, transparent);
}

.btn--quiet { border-color: transparent; color: var(--ink-1); }
.btn--quiet:hover { background: color-mix(in srgb, var(--ink-0) 8%, transparent); }

kbd {
  font-family: var(--mono);
  font-size: .6875rem;
  font-weight: var(--w-medium);
  padding: 2px var(--s-1);
  border: var(--bw) solid currentColor;
  border-radius: var(--r-0);
  opacity: .5;
  line-height: 1;
}
.btn--go kbd { opacity: .6; }
/* Пустой слот не должен рисовать рамку до того, как app.js впишет значение из KEYS. */
kbd:empty { display: none; }

.btn__badge { font-family: var(--mono); font-size: .6875rem; opacity: .5; }

/* ---------- Поше: верхняя и нижняя полосы ---------- */

/* Срез конструкции. Самая тяжёлая краска на листе — как в разрезе. */
.masthead, .bay {
  background: var(--poche);
  color: var(--poche-ink);
  display: flex;
  align-items: center;
  gap: var(--s-4);
}

/* Перенос разрешён всегда, а не только на узком экране: между 900 и 1200px
   инструменты справа не помещались в строку и уезжали за правый край вместе
   с горизонтальной полосой прокрутки на всю страницу. Пока ширины хватает,
   перенос ничего не меняет. */
.masthead {
  padding: var(--s-2) var(--s-4);
  min-height: 2.75rem;
  flex-wrap: wrap;
  row-gap: var(--s-2);
}
/* Лампы и знак — в одну строку до последнего: перенос внутри них означал бы
   «ЕРМ» и «ccTray» на разных строках. */
.lamps { flex-wrap: wrap; row-gap: var(--s-1); }

/* Знак работает и как заголовок страницы (пульт), и как ссылка (настройка). */
.mark, .mark__link {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  color: inherit;
  text-decoration: none;
  font-size: inherit;
  font-weight: inherit;
}
.mark__glyph { width: 17px; height: 17px; flex: none; color: var(--beam); }
.mark__word {
  font-size: var(--fs-2);
  font-style: var(--tilt);
  font-weight: var(--w-bold);
  text-transform: uppercase;
  letter-spacing: .14em;
}

.lamps { display: flex; align-items: center; gap: var(--s-4); margin-right: auto; }

.lamp {
  display: inline-flex;
  align-items: center;
  gap: var(--s-2);
  font-size: var(--fs-1);
  color: color-mix(in srgb, var(--poche-ink) 55%, transparent);
  white-space: nowrap;
}
.lamp i {
  width: 7px; height: 7px;
  flex: none;
  border-radius: 999px;      /* лампа круглая: это прибор, а не чертёж */
  background: currentColor;
  opacity: .45;
}
.lamp[data-live="yes"] { color: color-mix(in srgb, var(--poche-ink) 82%, transparent); }
.lamp[data-live="yes"] i { background: #58A46A; opacity: 1; }
.lamp[data-live="no"]  { color: #E27567; }
.lamp[data-live="no"] i { background: #E27567; opacity: 1; }
/* Токен доживает последние минуты: предупреждаем до того, как всё встанет. */
.lamp[data-live="soon"] { color: var(--beam); }
.lamp[data-live="soon"] i { background: var(--beam); opacity: 1; }

.lamp__left {
  font-family: var(--mono);
  font-size: .6875rem;
  font-variant-numeric: tabular-nums;
  opacity: .85;
}

.lamp--note {
  border: var(--bw) solid currentColor;
  border-radius: var(--r-0);
  padding: 2px var(--s-2);
  text-transform: uppercase;
  letter-spacing: .08em;
  font-size: .6875rem;
}

.masthead__tools { display: flex; align-items: center; gap: var(--s-1); }
.masthead .btn { border-color: color-mix(in srgb, var(--poche-ink) 22%, transparent); color: var(--poche-ink); }
.masthead .btn--quiet { border-color: transparent; color: color-mix(in srgb, var(--poche-ink) 74%, transparent); }
.masthead .btn:hover:not(:disabled) { background: color-mix(in srgb, var(--poche-ink) 12%, transparent); }

/* Переключатель темы: три положения, текущее видно всегда, а не всплывает тостом. */
.theme { display: inline-flex; border: var(--bw) solid color-mix(in srgb, var(--poche-ink) 22%, transparent); }
.theme__opt {
  padding: var(--s-1) var(--s-2);
  font-size: var(--fs-1);
  background: transparent;
  border: 0;
  color: color-mix(in srgb, var(--poche-ink) 66%, transparent);
  cursor: pointer;
  transition: background var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
.theme__opt:hover { background: color-mix(in srgb, var(--poche-ink) 12%, transparent); }
.theme__opt[aria-pressed="true"] { background: var(--beam); color: var(--beam-ink); }

/* ---------- Живая строка ---------- */

/* Одна строка, на которой лежит луч текущей фазы. В покое — тень. */
.live {
  display: grid;
  grid-template-columns: minmax(0, auto) minmax(0, 1fr) minmax(0, auto);
  align-items: center;
  gap: var(--s-5);
  padding: var(--s-3) var(--s-4);
  background: var(--shadow-fill);
  color: var(--ink-0);
  border-bottom: var(--bw) solid var(--rule);
  transition: background var(--t-base) var(--ease), color var(--t-base) var(--ease);
}
/* Заливка во всю ширину — для коротких фаз: 25 секунд набора и 45 секунд
   постобработки. Их надо заметить боковым зрением, и они быстро проходят. */
body[data-phase="dialing"] .live,
body[data-phase="wrap_up"] .live {
  background: var(--beam);
  color: var(--beam-ink);
  border-bottom-color: transparent;
}

/* Разговор длится сколько угодно, а смена идёт 6–8 часов: держать всю ширину
   залитой насыщенным золотом всё это время — прямой путь к усталости глаз,
   а её PRODUCT.md называет первым приоритетом. Поэтому здесь свет уходит
   в кромку и в само слово, а луч в это время и так лежит на скрипте. */
body[data-phase="answered"] .live {
  background: var(--surface-1);
  color: var(--ink-0);
  border-bottom-color: transparent;
  box-shadow: inset 0 calc(var(--bw-thick) * -1) 0 0 var(--beam),
              inset var(--bw-thick) 0 0 0 var(--beam);
}
body[data-phase="answered"] .live__phase { color: var(--beam-text); }

.live__phase {
  font-size: var(--fs-7);
  font-style: var(--tilt);
  font-weight: var(--w-bold);
  text-transform: uppercase;
  letter-spacing: .04em;
  line-height: var(--lh-tight);
  white-space: nowrap;
}

.live__who { min-width: 0; }
.live__name {
  font-size: var(--fs-4);
  font-weight: var(--w-medium);
  line-height: var(--lh-tight);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.live__meta {
  font-size: var(--fs-2);
  margin-top: 2px;
  opacity: .84;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.live__meta b { font-family: var(--mono); font-weight: var(--w-medium); font-variant-numeric: tabular-nums; }

.clock { text-align: right; white-space: nowrap; }
.clock__value {
  display: block;
  font-family: var(--mono);
  font-size: var(--fs-6);
  font-weight: var(--w-medium);
  font-variant-numeric: tabular-nums;
  line-height: 1;
  letter-spacing: -.02em;
}
.clock__label {
  font-size: var(--fs-1);
  font-style: var(--tilt);
  text-transform: uppercase;
  letter-spacing: .1em;
  opacity: .8;
}

/* ---------- Полоса сбоя ---------- */

.fault {
  padding: var(--s-2) var(--s-4);
  background: color-mix(in srgb, var(--danger) 16%, var(--surface-0));
  color: light-dark(#7A2318, #F2C0B8);
  border-bottom: var(--bw) solid color-mix(in srgb, var(--danger) 34%, transparent);
  /* На кегле подписи полосу читали через раз: она сообщает о том, из-за чего
     смена встанет, и не должна выглядеть примечанием. */
  font-size: var(--fs-3);
  position: relative;
  z-index: var(--z-fault);
}
/* «Сломается через двенадцать минут» — не то же, что «сломалось»: красная
   полоса на предупреждении приучает не читать красные полосы. */
.fault[data-kind="warn"] {
  background: color-mix(in srgb, var(--warn) 18%, var(--surface-0));
  color: light-dark(#6B4E08, #F0DCA8);
  border-bottom-color: color-mix(in srgb, var(--warn) 40%, transparent);
}

/* ---------- Рабочая область: две комнаты в разрезе ---------- */

/* Между комнатами — настоящий срез, а не волосяная линия. В разрезе именно
   поше показывает толщину конструкции; линией в 1px «две комнаты» не читаются. */
.work {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 12px minmax(0, 1fr);
  background: var(--rule);
  overflow: hidden;
}
.work__cut {
  background: var(--poche);
  border-inline: var(--bw) solid var(--rule);
}

.pane {
  background: var(--surface-1);
  padding: var(--s-4) var(--s-5) var(--s-6);
  overflow-y: auto;
  min-width: 0;
  transition: background var(--t-base) var(--ease);
}

/* Луч лежит на живой комнате. Свет ПАДАЕТ КОСО — это главное свойство разреза:
   солнце входит под углом и ложится на пол резкой полосой, а не заливает стену
   сверху вниз. Отсюда наклон 104°, жёсткая передняя кромка и мягкий сход. */
.pane[data-lit="yes"] {
  background:
    linear-gradient(104deg,
      color-mix(in srgb, var(--beam) 0%, transparent) 0,
      color-mix(in srgb, var(--beam) 0%, transparent) 10%,
      color-mix(in srgb, var(--beam) 22%, transparent) 15%,
      color-mix(in srgb, var(--beam) 16%, transparent) 48%,
      color-mix(in srgb, var(--beam) 0%, transparent) 88%),
    var(--surface-1);
  box-shadow: inset 0 var(--bw-thick) 0 0 var(--beam);
}

/* На комнате скрипта свет мягче и слабее: его текст читают вслух часами, и
   резкая кромка луча, проходящая сквозь строку, мешает читать. */
.pane--script[data-lit="yes"] {
  background:
    linear-gradient(104deg,
      color-mix(in srgb, var(--beam) 0%, transparent) 0,
      color-mix(in srgb, var(--beam) 13%, transparent) 26%,
      color-mix(in srgb, var(--beam) 9%, transparent) 60%,
      color-mix(in srgb, var(--beam) 0%, transparent) 94%),
    var(--surface-1);
}

.pane__label {
  display: flex;
  align-items: baseline;
  gap: var(--s-2);
  font-size: var(--fs-1);
  font-style: var(--tilt);
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--ink-2);
  font-weight: var(--w-medium);
  padding-bottom: var(--s-2);
  border-bottom: var(--bw) solid var(--rule);
  margin-bottom: var(--s-4);
}
/* Название продукта — имя собственное, капслок ему не идёт. */
.pane__label b { font-weight: var(--w-bold); text-transform: none; letter-spacing: .01em; color: var(--ink-1); }

.pane__sublabel {
  font-size: var(--fs-1);
  font-style: var(--tilt);
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--ink-2);
  font-weight: var(--w-medium);
  margin: var(--s-5) 0 var(--s-2);
}

.pane__idle { color: var(--ink-2); max-width: 42ch; font-size: var(--fs-2); }

/* ---------- Итог прогона: чем кончилась очередь ---------- */
/* Фаза «тень»: ровный фон, ни следа золота. Прогон, в котором никого не набрали, —
   это не сбой приложения, а сработавший ограничитель, и пугать им незачем. Но и
   промолчать нельзя: молчание здесь читается как поломка. */

.tally {
  display: grid;
  gap: var(--s-3);
  padding-bottom: var(--s-4);
  margin-bottom: var(--s-4);
  border-bottom: var(--bw) solid var(--rule-strong);
}

.tally__label {
  font-size: var(--fs-1);
  font-style: var(--tilt);
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--ink-2);
  font-weight: var(--w-medium);
}

.tally__lead {
  color: var(--ink-0);
  font-size: var(--fs-3);
  max-width: 46ch;
}

.tally__reasons { display: grid; gap: var(--s-2); list-style: none; }

.tally__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--s-3);
  padding-bottom: var(--s-2);
  border-bottom: var(--bw) solid var(--rule);
  color: var(--ink-1);
  font-size: var(--fs-2);
}

/* Счётчик — моноширинный и с табличными цифрами: строки причин читаются столбцом. */
.tally__count {
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink-0);
  white-space: nowrap;
}

/* ---------- Пустой экран: три шага запуска ---------- */

.onboard { display: grid; gap: var(--s-3); counter-reset: ob; list-style: none; }

.onboard__step {
  display: grid;
  grid-template-columns: 1.75rem minmax(0, 1fr);
  gap: var(--s-1) var(--s-3);
  padding-bottom: var(--s-3);
  border-bottom: var(--bw) solid var(--rule);
}
.onboard__step::before {
  counter-increment: ob;
  content: counter(ob);
  grid-row: 1 / span 3;
  font-family: var(--mono);
  font-size: var(--fs-2);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  border: var(--bw) solid var(--rule-strong);
  width: 1.75rem; height: 1.75rem;
  display: grid;
  place-items: center;
}
.onboard__step b { font-weight: var(--w-bold); }
.onboard__step span { color: var(--ink-1); font-size: var(--fs-2); }
.onboard__step .btn { justify-self: start; margin-top: var(--s-2); }

/* Шаг сделан — луч его коснулся. Не только цветом: рядом стоит слово «готово». */
.onboard__step[data-done="yes"]::before {
  content: '✓';
  background: var(--beam);
  border-color: var(--beam);
  color: var(--beam-ink);
}
.onboard__step[data-done="yes"] b { color: var(--ink-1); }
.onboard__step[data-done="yes"] .btn { display: none; }

.onboard__done {
  font-size: var(--fs-1);
  font-style: var(--tilt);
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--beam-text);
  font-weight: var(--w-medium);
}

/* ---------- Карточка клиента ---------- */

/* По умолчанию карточка идёт одной колонкой: в разговоре и в постобработке
   комната клиента узкая, и делить её нечем. Две колонки включаются ниже,
   на широком экране в режиме ожидания. */
.card__cols { display: grid; gap: var(--s-4); }
/* Верхний отступ несут сами блоки (.reason, .facts), и первый в колонке
   получал бы его ни за что — колонка и так начинается с новой строки. */
.card__col > :first-child { margin-top: 0; }

.who__name {
  font-size: var(--fs-6);
  font-weight: var(--w-bold);
  line-height: var(--lh-tight);
  overflow-wrap: anywhere;
}
.who__role { color: var(--ink-1); font-size: var(--fs-3); margin-top: var(--s-1); }

/* Повод — то, зачем вообще звоним. В разрезе это самая освещённая точка комнаты. */
.reason {
  margin-top: var(--s-4);
  padding: var(--s-3);
  background: var(--surface-2);
  border-left: var(--bw-thick) solid var(--beam);
}
.reason__label {
  font-size: var(--fs-1);
  font-style: var(--tilt);
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--ink-2);
  font-weight: var(--w-medium);
  margin-bottom: var(--s-1);
}
.reason__text { font-size: var(--fs-3); }

/* Поля карточки: подпись, выноска, значение — как на чертеже. */
.facts { margin-top: var(--s-5); display: grid; gap: var(--s-3); }
.facts__row {
  display: grid;
  grid-template-columns: 5.5rem minmax(0, 1fr);
  gap: var(--s-3);
  align-items: baseline;
}
.facts dt {
  color: var(--ink-2);
  font-size: var(--fs-1);
  font-style: var(--tilt);
  text-transform: uppercase;
  letter-spacing: .08em;
  position: relative;
}
/* Волосяная выноска от подписи к значению. */
.facts dt::after {
  content: '';
  position: absolute;
  left: 100%; top: .55em;
  width: var(--s-2);
  border-top: var(--bw) solid var(--rule-strong);
}
.facts dd { overflow-wrap: anywhere; }

.facts__phone {
  font-family: var(--mono);
  font-size: var(--fs-3);
  font-variant-numeric: tabular-nums;
  letter-spacing: -.02em;
}
.phone-line + .phone-line { margin-top: var(--s-2); }
.phone-line small {
  display: block;
  font-family: var(--sans);
  font-size: var(--fs-1);
  color: var(--ink-2);
  letter-spacing: 0;
  margin-top: 1px;
}

.notice {
  margin-top: var(--s-4);
  padding: var(--s-2) var(--s-3);
  background: var(--surface-2);
  border-left: var(--bw-thick) solid var(--rule-strong);
  font-size: var(--fs-2);
  color: var(--ink-1);
}

/* ---------- Покупки клиента (вкладка УКД) ---------- */

.subs { display: grid; gap: var(--bw); background: var(--rule); border-block: var(--bw) solid var(--rule); }

.sub {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  gap: var(--s-1) var(--s-3);
  align-items: baseline;
  background: var(--surface-1);
  padding: var(--s-2) var(--s-2);
}
.sub__product { font-size: var(--fs-2); font-weight: var(--w-medium); overflow-wrap: anywhere; }
.sub__span {
  font-family: var(--mono);
  font-size: var(--fs-1);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  white-space: nowrap;
}
/* Действующая подписка — единственная строка, которой касается свет. */
.sub[data-active="yes"] {
  background: color-mix(in srgb, var(--beam) 16%, var(--surface-1));
  box-shadow: inset var(--bw-thick) 0 0 0 var(--beam);
}
.sub__state { grid-column: 1 / -1; font-size: var(--fs-1); color: var(--ink-2); }

/* В разговоре и в постобработке комната клиента узкая, и срок подписки отбирал
   у названия столько, что «Электронный» ломалось пополам посреди слова. Там
   название занимает свою строку целиком, а срок и состояние встают под ним
   рядом — высота строки от этого не растёт. */
body[data-mode="read"] .sub,
body[data-mode="input"] .sub {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--s-1) var(--s-2);
}
body[data-mode="read"] .sub__product,
body[data-mode="input"] .sub__product { flex: 1 0 100%; overflow-wrap: break-word; }
.sub[data-active="yes"] .sub__state { color: var(--beam-text); font-weight: var(--w-medium); }
/* Подсвеченная строка светлее обычной, и приглушённые чернила на ней проваливались
   до 3.8:1. На свету текст идёт на ступень крепче. */
.sub[data-active="yes"] .sub__span { color: var(--ink-1); }

/* ---------- Прошлые звонки ---------- */

.history { display: grid; gap: var(--bw); background: var(--rule); list-style: none; border-block: var(--bw) solid var(--rule); }
.history__item { background: var(--surface-1); padding: var(--s-2); font-size: var(--fs-2); }
.history__item b { font-weight: var(--w-bold); }
.history__item span { display: block; color: var(--ink-2); margin-top: 1px; }

/* ---------- Скрипт ---------- */

/* Комната скрипта — три колонки, как устроен сам скрипт в ЕРМ: оглавление,
   открытый блок, возражения. Настоящий скрипт — это 7–24 блока и до 128
   возражений; плоским списком он показывал всё сразу и не давал ориентироваться
   ни в чём. Прокрутка — у каждой колонки своя: листая возражения, нельзя
   терять место в тексте, который читаешь вслух. */
.pane--script {
  display: flex;
  flex-direction: column;
  overflow: hidden;
  /* Раскладка комнаты считается по ЕЁ ширине, а не по ширине окна. Ширина
     комнаты зависит не только от экрана: в ожидании карточка забирает себе
     больше места, чем в разговоре. Медиазапрос об этом не знает — и при 1366px
     колонка, которую читают вслух, ужималась до тридцати знаков в строке,
     пока оглавление и возражения держали свою полную ширину. */
  container-type: inline-size;
  container-name: script;
}

/* Основа — одна колонка: то, что читают вслух. Всё остальное появляется,
   когда для него есть место, и уходит первым, когда места нет. */
.script {
  flex: 1 1 auto;
  min-height: 0;
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  grid-template-rows: minmax(0, 1fr);
  gap: 0;
}
/* Колонки разделяются волосяной линией, а не зазором с фоном: на подсвеченной
   комнате зазоры проступали целиком, и разрез читался серой плитой вместо
   освещённой поверхности. */
.script > * {
  overflow-y: auto;
  min-height: 0;
  padding-right: var(--s-3);
  /* Прокрутка у каждой колонки своя, и толстых полос в комнате оказалось
     четыре штуки разом — они спорили с текстом за внимание. */
  scrollbar-width: thin;
  scrollbar-color: var(--rule) transparent;
}
.script__reading {
  padding-inline: var(--s-4);
  border-left: var(--bw) solid var(--rule);
}
.script__side {
  padding-left: var(--s-4);
  border-left: var(--bw) solid var(--rule);
}

/* Как комната делится на колонки — ниже, после описания самих колонок:
   объявления там перебивают эти по порядку следования. */
/* Луч лежит на комнате целиком, а колонки на извести его перекрывали. */

/* Заголовок комнаты и поиск в одну строку. */
.script__head {
  display: flex;
  align-items: baseline;
  gap: var(--s-3);
  flex: none;
}
.script__head .pane__label { flex: 1 1 auto; margin-bottom: var(--s-3); }

.script__find {
  flex: 0 1 16rem;
  background: var(--surface-2);
  border: var(--bw) solid var(--rule);
  padding: var(--s-1) var(--s-2);
  font-size: var(--fs-2);
  color: var(--ink-0);
  margin-bottom: var(--s-3);
}
.script__find::placeholder { color: var(--ink-2); }
.script__find:focus { border-color: var(--beam); border-width: var(--bw-thick); padding: calc(var(--s-1) - 2px) calc(var(--s-2) - 2px); }
.script__key {
  font-family: var(--mono);
  font-size: var(--fs-1);
  color: var(--ink-2);
  margin-bottom: var(--s-3);
}

/* ---------- Оглавление скрипта ---------- */

.script__toc { display: grid; align-content: start; gap: var(--bw); }

.script__section {
  font-size: var(--fs-1);
  font-style: var(--tilt);
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--ink-2);
  font-weight: var(--w-medium);
  padding: var(--s-3) 0 var(--s-1);
}
.script__section:first-child { padding-top: 0; }

.script__jump {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: baseline;
  gap: var(--s-2);
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  padding: var(--s-2) var(--s-2) var(--s-2) var(--s-3);
  font-size: var(--fs-2);
  line-height: var(--lh-base);
  color: var(--ink-1);
  cursor: pointer;
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.script__jump:hover { color: var(--ink-0); background: var(--surface-2); }
/* Открытый блок — там, где сейчас место менеджера: кромка лучом, как у шага. */
.script__jump[aria-current="true"] {
  color: var(--ink-0);
  font-weight: var(--w-medium);
  background: color-mix(in srgb, var(--beam) 16%, transparent);
  box-shadow: inset var(--bw-thick) 0 0 0 var(--beam);
}
/* Сколько шагов в блоке — данные, значит моноширинные и табличные. */
.script__count {
  font-family: var(--mono);
  font-size: var(--fs-1);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
}

/* Название открытого блока: он же заголовок читаемого куска. */
.script__block {
  font-size: var(--fs-4);
  font-weight: var(--w-bold);
  color: var(--ink-0);
  padding-bottom: var(--s-2);
  margin-bottom: var(--s-3);
  border-bottom: var(--bw) solid var(--rule);
}

.script__none { color: var(--ink-2); font-size: var(--fs-2); padding-top: var(--s-3); }

/* ---------- Как комната делится на колонки ---------- */
/*
   Считается по ширине САМОЙ комнаты, а не окна: комната сужается не только от
   маленького экрана, но и от режима внимания — в ожидании карточка забирает
   себе больше места, чем в разговоре. Медиазапрос об этом не знает, и при
   1366px колонка, которую читают вслух, ужималась до тридцати знаков в строке,
   пока оглавление и возражения держали полную ширину.

   Порядок уступок обратный важности: сначала оглавление сворачивается в полосу,
   потом возражения уходят вниз. Текст, который произносят, не сжимается ниже
   своего предела никогда.
*/

/* Широкая комната: три колонки. */
@container script (min-width: 67rem) {
  .script {
    grid-template-columns: minmax(9rem, 12rem) minmax(26rem, 1fr) minmax(15rem, 22rem);
  }
}

/* Средняя: оглавление — полосой сверху во всю ширину, текст и возражения рядом. */
@container script (max-width: 67rem) {
  .script__toc {
    grid-column: 1 / -1;
    display: flex;
    flex-wrap: nowrap;
    overflow-x: auto;
    overflow-y: hidden;
    align-items: center;
    gap: var(--s-1);
    padding: 0 0 var(--s-2);
  }
  .script__toc .script__section {
    /* flex: none — иначе пункты сжимаются ниже своего текста, и подписи
       наезжают друг на друга: полоса прокручивается, а не ужимается. */
    flex: none;
    padding: 0 var(--s-2) 0 0;
    white-space: nowrap;
    align-self: center;
  }
  /* В полосе пункт становится ярлыком: волосяной контур вместо кромки луча. */
  .script__jump {
    flex: none;
    display: flex;
    align-items: baseline;
    gap: var(--s-2);
    width: auto;
    max-width: 18rem;
    white-space: nowrap;
    padding: var(--s-1) var(--s-2);
    outline: var(--bw) solid var(--rule);
    outline-offset: calc(var(--bw) * -1);
  }
  /* Длинное имя блока обрезается многоточием, а не растягивает полосу. */
  .script__jump > span:first-child {
    overflow: hidden;
    text-overflow: ellipsis;
  }
  /* Оглавление стало полосой сверху — линия под ним, а не слева от текста. */
  .script__toc { border-bottom: var(--bw) solid var(--rule); }
  .script__reading { padding-left: 0; border-left: 0; }
}

@container script (min-width: 47rem) and (max-width: 67rem) {
  .script {
    grid-template-columns: minmax(0, 1fr) minmax(13rem, 19rem);
    grid-template-rows: auto minmax(0, 1fr);
  }
}

/* Узкая: всё в одну колонку, возражения внизу. */
@container script (max-width: 47rem) {
  /* Предел у нижней строки обязателен. С `minmax(0, auto)` она сайзится по
     содержимому — а возражений там девяносто пять, — забирает всю высоту,
     и колонке с текстом достаётся ноль: скрипт просто исчезал с экрана.
     Доля от высоты комнаты решает это, а `max-height` на самом блоке нет:
     проценты там считаются от высоты строки, то есть ни от чего. */
  .script { grid-template-rows: auto minmax(0, 1fr) minmax(0, 38%); }
  .script__reading { padding-inline: 0; }
  /* Возражения ушли вниз — линия над ними, а не слева. */
  .script__side {
    padding-left: 0;
    border-left: 0;
    border-top: var(--bw) solid var(--rule);
    padding-top: var(--s-2);
  }
}

.steps { display: grid; gap: var(--s-1); counter-reset: step; list-style: none; max-width: var(--measure); }

.steps li {
  display: grid;
  grid-template-columns: 1.75rem minmax(0, 1fr);
  gap: var(--s-3);
  padding: var(--s-2) var(--s-3) var(--s-2) 0;
  font-size: var(--fs-5);
  line-height: var(--lh-read);
  color: var(--ink-1);
  cursor: pointer;
  transition: color var(--t-fast) var(--ease), background var(--t-fast) var(--ease);
}
.steps li::before {
  counter-increment: step;
  content: counter(step);
  font-family: var(--mono);
  font-size: var(--fs-1);
  font-variant-numeric: tabular-nums;
  color: var(--ink-2);
  padding-top: .5em;
  text-align: right;
}

/* В блоке лежат три разные вещи, и вид у них разный.
   Номер получает только то, что говорят вслух: иначе «шаг 7 из 30» не значит
   ничего, а «(если директор)» стоит в списке наравне с репликой. */

/* Заголовок внутри блока: «ЗАХОД С АНОНСА», «Вариант 1», «Отправка ДД».
   Наклонная прописная — почерк чертёжной аннотации, как у подписей комнат. */
.steps li[data-kind="head"] {
  counter-increment: none;
  cursor: default;
  font-size: var(--fs-1);
  font-style: var(--tilt);
  text-transform: uppercase;
  letter-spacing: .1em;
  font-weight: var(--w-medium);
  color: var(--ink-2);
  padding-top: var(--s-4);
  padding-bottom: var(--s-1);
}
.steps li[data-kind="head"]::before { content: ''; counter-increment: none; }
.steps li[data-kind="head"]:hover { color: var(--ink-2); }
/* Первый заголовок в блоке не отбивается сверху: под ним и так линия названия. */
.steps li[data-kind="head"]:first-child { padding-top: 0; }

/* Ремарка менеджеру: «/ответ клиента/», «(если директор)». Её нельзя прочитать
   вслух по ошибке, поэтому она мельче, тише и без номера. */
.steps li[data-kind="note"] {
  counter-increment: none;
  cursor: default;
  font-size: var(--fs-2);
  color: var(--ink-2);
  padding-block: var(--s-1);
}
.steps li[data-kind="note"]::before {
  content: '·';
  counter-increment: none;
  font-family: var(--sans);
  padding-top: 0;
}
.steps li[data-kind="note"]:hover { color: var(--ink-2); }
.steps li:hover { color: var(--ink-0); }

/* Текущий шаг поднят светом, остальные приглушены: читать вслух и не терять
   место — основная механика режима разговора. */
.steps li[aria-current="step"] {
  color: var(--ink-0);
  font-weight: var(--w-medium);
  background: color-mix(in srgb, var(--beam) 16%, transparent);
  box-shadow: inset var(--bw-thick) 0 0 0 var(--beam);
}
.steps li[aria-current="step"]::before { color: var(--beam-text); font-weight: var(--w-bold); }

/* Возражения живут в своей колонке, и она узкая: раскладывать «если» и «то»
   в два столбца там негде — обе половины получались по двадцать знаков в строку.
   Метка сверху, ответ под ней: метку ищут глазами, ответ читают. */
.objections { display: grid; gap: var(--s-3); max-width: var(--measure); }
.objections > div {
  display: grid;
  gap: var(--s-1);
  padding-bottom: var(--s-3);
  border-bottom: var(--bw) solid var(--rule);
}
/* Метка возражения — это то, что ищут глазами, пока клиент говорит. Свёрнутый
   список читается одним взглядом; ответ раскрывается нажатием. */
.objections dt { font-size: var(--fs-2); }
.objections__open {
  display: grid;
  grid-template-columns: .75rem minmax(0, 1fr);
  gap: var(--s-2);
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  padding: var(--s-1) 0;
  font-size: var(--fs-2);
  font-weight: var(--w-medium);
  line-height: var(--lh-base);
  color: var(--ink-0);
  cursor: pointer;
  transition: color var(--t-fast) var(--ease);
}
/* Треугольник поворачивается — единственное движение здесь, и оно означает
   «раскрыто», а не украшает. */
.objections__open::before {
  content: '▸';
  color: var(--ink-2);
  transition: transform var(--t-fast) var(--ease);
}
.objections__open[aria-expanded="true"]::before { transform: rotate(90deg); }
.objections__open[aria-expanded="true"] { color: var(--beam-text); }
.objections__open:hover { color: var(--beam-text); }
/* Переносы из ЕРМ сохраняются: ответ на возражение приходит несколькими
   вариантами («Вариант 1» / «Вариант 2»), и склеенные в один абзац они
   читаются как одна длинная фраза — а выбрать надо один из них. */
.objections dd {
  font-size: var(--fs-2);
  line-height: var(--lh-read);
  color: var(--ink-1);
  white-space: pre-line;
  padding: 0 0 var(--s-1) calc(.75rem + var(--s-2));
}

/* ---------- Сводка «сейчас» на странице настройки ---------- */

/* На страницу настройки приходят с вопросом «почему не работает». Ответ должен
   помещаться в три строки, а подробности — оставаться там, где были. */
.checks {
  display: grid;
  gap: var(--bw);
  background: var(--rule);
  border-block: var(--bw) solid var(--rule);
  list-style: none;
}
.check {
  display: grid;
  grid-template-columns: minmax(0, 11rem) minmax(0, 1fr) auto;
  gap: var(--s-3);
  align-items: baseline;
  background: var(--surface-1);
  padding: var(--s-3);
  /* Состояние не одним цветом: слева полоса, справа — слово. */
  box-shadow: inset var(--bw-thick) 0 0 0 var(--rule-strong);
}
.check[data-live="yes"] { box-shadow: inset var(--bw-thick) 0 0 0 var(--ok); }
.check[data-live="no"]  { box-shadow: inset var(--bw-thick) 0 0 0 var(--danger); }
.check__name  { font-weight: var(--w-medium); }
.check__state { color: var(--ink-1); font-size: var(--fs-2); }
.check[data-live="no"] .check__state { color: var(--danger); }
.check__go    { color: var(--ink-2); font-size: var(--fs-1); white-space: nowrap; }

/* ---------- Ведомость смены ---------- */

/* Живёт в комнате скрипта, пока звонков нет. Своих украшений не заводит:
   плитки те же, что в диалоге «Итоги», — числа дня должны выглядеть одинаково,
   где бы человек на них ни посмотрел. */
.ledger { display: grid; gap: var(--s-4); }
.ledger .btn { justify-self: start; }
/* Шесть плиток — два ровных ряда по три, а не «сколько влезет»: при подборе по
   ширине последний ряд оставался наполовину пустой серой плитой. */
.ledger .stats__row { grid-template-columns: repeat(3, minmax(0, 1fr)); }
/* Место одно, и занимает его что-то одно: «Скрипт» и «скрипт появится…» рядом
   с готовой ведомостью — это подписи к пустоте, которой уже нет. */
.pane--script:has(#ledger:not([hidden])) #script-empty,
.pane--script:has(#ledger:not([hidden])) #script-head { display: none; }
/* Пока комнату занимает ведомость, она и прокручивается сама. */
.pane--script:has(#ledger:not([hidden])) { overflow-y: auto; }

/* ---------- Панель результата ---------- */

.result {
  background: var(--surface-1);
  border-top: var(--bw) solid var(--rule);
  padding: var(--s-3) var(--s-4) var(--s-4);
  display: grid;
  gap: var(--s-3);
  position: relative;
}

/* Отсчёт до автоперехода — уходящий луч. Полоса, которую не нужно читать:
   ширина берётся из limits.wrap_up_sec, а не из числа в коде. */
.result__beam {
  position: absolute;
  left: 0; right: 0; top: 0;
  height: var(--bw-thick);
  background: var(--beam);
  transform: scaleX(var(--beam-left));
  transform-origin: left center;
  transition: transform var(--t-fast) linear;
}
body:not([data-mode="input"]) .result__beam { display: none; }

.result__head { display: flex; align-items: baseline; gap: var(--s-3); flex-wrap: wrap; }

/* Свёрнутая панель: пока идут гудки и разговор, итог ещё не выбирают.
   Двенадцать длинных меток и поле комментария занимали 260px — ровно ту треть
   экрана, в которой лежат карточка клиента и скрипт, и карточку приходилось
   листать в те самые 25 секунд, что отданы на подготовку к разговору. */
.result[data-open="no"] .result__statuses,
.result[data-open="no"] .result__row { display: none; }

/* Кнопка разворота уходит вправо; в постобработке её место занимает отсчёт,
   и сама она не нужна — там список открыт всегда. */
.result__toggle { margin-left: auto; }
body[data-mode="input"] .result__toggle { display: none; }
.result__label {
  font-size: var(--fs-1);
  font-style: var(--tilt);
  text-transform: uppercase;
  letter-spacing: .1em;
  color: var(--ink-2);
  font-weight: var(--w-medium);
}
.result__hint { font-size: var(--fs-2); color: var(--ink-2); }
.result__hint[data-suggested="yes"] { color: var(--beam-text); font-weight: var(--w-medium); }
/* Постобработка идёт, а итог не выбран: движок уйдёт дальше сам, и разговор
   останется неучтённым. Это не подсказка, это предупреждение. */
.result__hint[data-warn="yes"] { color: var(--danger); font-weight: var(--w-medium); }
/* Справочника ЕРМ нет — итог никуда не уедет. Это предупреждение, а не подсказка. */
.result[data-book="no"] .result__hint { color: var(--danger); font-weight: var(--w-medium); }

/* Отсчёт живёт здесь, рядом с тем, что выбирают. Раньше он был в правом
   верхнем углу, а выбор внизу: под лимитом это лишний путь для глаз. */
.result__left {
  margin-left: auto;
  font-family: var(--mono);
  font-size: var(--fs-3);
  font-variant-numeric: tabular-nums;
  color: var(--ink-1);
  transition: font-size var(--t-fast) var(--ease), color var(--t-fast) var(--ease);
}
/* Последние десять секунд. Не мигание — смена 6–8 часов такого не прощает —
   а рост кегля и цвет уходящего луча. */
.result__left[data-urgent="yes"] {
  font-size: var(--fs-4);
  font-weight: var(--w-medium);
  color: var(--beam-text);
}
body:not([data-mode="input"]) .result__left { display: none; }

/* Статусы списком, а не переносящимися чипами: метки длинные
   («Занято, не отвечают, сбой соединения» — 36 знаков), обрезать их нельзя. */
.result__statuses {
  display: grid;
  /* Колонки широкие: «Занято, не отвечают, сбой соединения» — 36 знаков, и
     обрезать метку нельзя. Узкие колонки ломали её на три строки. */
  grid-template-columns: repeat(auto-fit, minmax(21rem, 1fr));
  /* Прокручивается сам список, а не панель целиком. На узком экране статусы
     встают в одну колонку, и восемнадцать строк выталкивали за нижний край
     и отсчёт, и «Сохранить» — ровно в те 45 секунд, когда они единственное,
     что нужно. Заголовок с отсчётом и строка сохранения остаются на месте. */
  max-height: 42vh;
  overflow-y: auto;
  /* Фон панели, а не линии: незаполненные ячейки последнего ряда читались
     сплошной серой плитой. Волосяные разделители рисуют сами строки. */
  background: var(--surface-1);
  border: var(--bw) solid var(--rule);
}

/* На входе в постобработку фокус отдаётся сюда программно, а `:focus-visible`
   на такой фокус не срабатывает — кольца не было, и понять, что клавиатура уже
   в списке, было нельзя. Мышью сюда не попадают: клик уходит в саму строку. */
.result__statuses:focus {
  outline: 2px solid var(--beam-text);
  outline-offset: 2px;
}

.chip {
  display: grid;
  grid-template-columns: 1.5rem minmax(0, 1fr);
  align-items: baseline;
  gap: var(--s-2);
  padding: var(--s-2) var(--s-3);
  background: var(--surface-1);
  cursor: pointer;
  font-size: var(--fs-2);
  /* Контур, а не рамка: он не занимает места, и соседние строки сливаются
     в одну волосяную линию. */
  outline: var(--bw) solid var(--rule);
  outline-offset: 0;
  transition: background var(--t-fast) var(--ease);
}
/* Метка всегда во второй колонке. Дальше девятого статуса подсказки клавиши
   нет, и без этого метка съезжала в колонку шириной 1.5rem. */
.chip > span { grid-column: 2; }
.chip kbd { grid-column: 1; font-size: .6875rem; border: 0; opacity: .55; padding: 0; text-align: right; }
.chip:hover { background: var(--surface-2); }
.chip:has(:checked) { background: var(--beam); color: var(--beam-ink); font-weight: var(--w-medium); }
.chip:has(:checked) kbd { opacity: .72; }
.chip:has(:checked) { outline-color: var(--beam); position: relative; z-index: 1; }
.chip:has(:focus-visible) { outline: 2px solid var(--beam-text); outline-offset: -2px; position: relative; z-index: 2; }

.result__row { display: flex; gap: var(--s-2); align-items: center; }
.result__row input[type="text"] {
  flex: 1 1 auto;
  min-width: 0;
  padding: var(--s-2) var(--s-3);
  background: var(--surface-2);
  border: var(--bw) solid var(--rule-strong);
  border-radius: var(--r-0);
  color: var(--ink-0);
}
.result__row input[type="text"]:focus-visible {
  /* Кольцо остаётся кольцом: золотая рамка на нише давала 1.40:1, то есть
     фокуса на поле было фактически не видно. */
  outline: 2px solid var(--beam-text);
  outline-offset: 1px;
  border-color: var(--beam-text);
}
.result__row input::placeholder { color: var(--ink-2); }

/* ---------- Нижняя полоса: смена и управление ---------- */

.bay { padding: var(--s-2) var(--s-4); border-top: var(--bw) solid var(--rule); min-height: 2.75rem; }

.shift { display: flex; align-items: flex-end; gap: var(--s-3); min-width: 0; margin-right: auto; }

/* Часы смены: одна засечка на попытку, высота — как далеко дошёл звонок. */
.tape {
  display: flex;
  align-items: flex-end;
  gap: 2px;
  height: 1.25rem;
  width: min(22rem, 34vw);
  overflow: hidden;
  flex: none;
}
.tick {
  flex: 1 1 2px;
  min-width: 2px;
  max-width: 5px;
  background: currentColor;
  border-radius: var(--r-0);
}
.tick[data-outcome="answered"]  { height: 100%; background: var(--beam); opacity: 1; }
.tick[data-outcome="no_answer"] { height: 45%; opacity: .38; }
.tick[data-outcome="skipped"]   { height: 22%; opacity: .22; }
.tick[data-outcome="failed"]    { height: 100%; background: #E8503C; opacity: 1; }

.shift__count { font-size: var(--fs-1); color: color-mix(in srgb, var(--poche-ink) 64%, transparent); white-space: nowrap; }
.shift__count b {
  font-family: var(--mono);
  font-weight: var(--w-medium);
  font-variant-numeric: tabular-nums;
  color: var(--poche-ink);
}

.controls { display: flex; gap: var(--s-2); flex-wrap: wrap; margin-left: auto; }
.bay .btn { border-color: color-mix(in srgb, var(--poche-ink) 22%, transparent); color: var(--poche-ink); }
.bay .btn:hover:not(:disabled) { background: color-mix(in srgb, var(--poche-ink) 12%, transparent); }
/* Недоступная кнопка всё равно читается: её надпись — это состояние движка,
   и менеджер сверяется с ней постоянно. 40% давали 3.46:1 на поше. */
.bay .btn:disabled {
  color: color-mix(in srgb, var(--poche-ink) 62%, transparent);
  border-color: color-mix(in srgb, var(--poche-ink) 14%, transparent);
}
.bay .btn--go { background: var(--beam); border-color: var(--beam); color: var(--beam-ink); }
.bay .btn--go:disabled { background: transparent; }

/* ---------- Три режима внимания ---------- */

/* Ожидание: 25 секунд гудков — единственное свободное время менеджера.
   Карточка главная: кого набираем, повод, покупки, чем кончился прошлый звонок. */
body[data-mode="ambient"] .work { grid-template-columns: minmax(0, 1.35fr) 12px minmax(0, 1fr); }

/* И карточка раскладывается в две колонки: слева зачем звоним, справа чем
   набираем и чем кончилось прошлый раз. Порог — по ширине самой комнаты
   клиента, а не экрана: узкие колонки хуже прокрутки. */
@media (min-width: 1500px) {
  body[data-mode="ambient"] .card__cols {
    grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
    column-gap: var(--s-5);
    align-items: start;
  }
}

/* Разговор: ведёт скрипт, его читают вслух. Карточка сжимается, но повод и
   покупки обязаны остаться видны без прокрутки. */
body[data-mode="read"] .work  { grid-template-columns: minmax(0, 23rem) 12px minmax(0, 1fr); }

/* Прежнее деление комнаты надвое (шаги | возражения) заменено тремя колонками
   в `.script`: оглавление — открытый блок — возражения. Правило жило здесь,
   было объявлено через id и перебивало новую сетку. */

/* Постобработка: 45 секунд и клавиатура. Рабочая область отступает,
   выбор результата выходит вперёд. */
/* Постобработка забирает вес себе: рабочая область поджимается до полосы,
   по которой ещё можно свериться, но которая уже не спорит за внимание. */
body[data-mode="input"] .work { grid-template-columns: minmax(0, 19rem) 12px minmax(0, 1fr); }
/* Рабочая область забирает ровно то, что осталось от панели результата, — и не
   больше. Раньше здесь стоял предел 38vh, и остаток высоты не доставался никому:
   внизу экрана лежала мёртвая полоса в сотню пикселей, а карточку клиента в это
   же время приходилось листать. Вес постобработке даёт луч и место панели,
   а не пустота вокруг. */
body[data-mode="input"] .work { flex: 1 1 auto; min-height: 0; }
/* Панель результата выходит вперёд: собственный свет сверху и чуть больше
   воздуха вокруг выбора. */
body[data-mode="input"] .result {
  background:
    linear-gradient(180deg,
      color-mix(in srgb, var(--beam) 12%, transparent) 0,
      color-mix(in srgb, var(--beam) 0%, transparent) 5rem),
    var(--surface-1);
  padding-bottom: var(--s-5);
}
body[data-mode="input"] .result__label { color: var(--ink-0); font-size: var(--fs-2); }
body[data-mode="input"] .chip { padding: var(--s-3); }

/* Предпросмотр: пульт в нём выглядит точно так же, как боевой, поэтому режим
   назван словом в шапке — там же, где «Сухой прогон». */
.lamp--preview { background: var(--beam); border-color: var(--beam); color: var(--beam-ink); }

/* ---------- Диалоги ---------- */

.dlg {
  border: 0;
  padding: 0;
  background: var(--surface-1);
  color: var(--ink-0);
  max-width: 44rem;
  width: 92vw;
  border-radius: var(--r-0);
  /* Единственное место, где тень уместна: слой оторван от плоскости листа. */
  box-shadow: 0 24px 60px -12px light-dark(rgba(26, 29, 32, .35), rgba(0, 0, 0, .7));
}
.dlg::backdrop { background: light-dark(rgba(26, 29, 32, .45), rgba(0, 0, 0, .65)); }
.dlg__inner { padding: var(--s-5); display: grid; gap: var(--s-4); }
.dlg__title {
  font-size: var(--fs-4);
  font-style: var(--tilt);
  text-transform: uppercase;
  letter-spacing: .08em;
  font-weight: var(--w-bold);
  padding-bottom: var(--s-2);
  border-bottom: var(--bw) solid var(--rule);
}
.dlg__actions { display: flex; gap: var(--s-2); justify-content: flex-end; }

.stats { display: grid; gap: var(--s-4); }
.stats__row {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));
  gap: var(--bw);
  background: var(--rule);
  border: var(--bw) solid var(--rule);
}
.stat { background: var(--surface-1); padding: var(--s-3); }
.stat span {
  display: block;
  font-size: var(--fs-1);
  font-style: var(--tilt);
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--ink-2);
}
.stat b {
  display: block;
  font-family: var(--mono);
  font-size: var(--fs-6);
  font-weight: var(--w-medium);
  font-variant-numeric: tabular-nums;
  margin-top: var(--s-1);
}
/* Разговор, о котором ЕРМ не узнает: это не цифра в ряду, это потеря. */
.stats__warn {
  font-size: var(--fs-2);
  color: var(--danger);
  border-left: var(--bw-thick) solid var(--danger);
  padding-left: var(--s-3);
}

/* Кого именно потеряли. Список нужен не для отчёта, а чтобы эти разговоры
   закрыть руками: время, имя и телефон — всё, чем звонок ищется в ЕРМ. */
.lost {
  display: grid;
  gap: var(--bw);
  background: var(--rule);
  border-block: var(--bw) solid var(--rule);
  list-style: none;
}
.lost__row {
  display: grid;
  grid-template-columns: auto minmax(0, 1fr) auto;
  gap: var(--s-3);
  align-items: baseline;
  background: var(--surface-1);
  padding: var(--s-2) var(--s-3);
  font-size: var(--fs-2);
}
.lost__at,
.lost__phone {
  font-family: var(--mono);
  font-size: var(--fs-1);
  font-variant-numeric: tabular-nums;
  color: var(--ink-1);
  white-space: nowrap;
}
.lost__who { min-width: 0; }
.lost__who span { display: block; color: var(--ink-2); font-size: var(--fs-1); }

.stats table { width: 100%; border-collapse: collapse; font-size: var(--fs-2); }
.stats th, .stats td { padding: var(--s-2); text-align: right; border-bottom: var(--bw) solid var(--rule); }
.stats th:first-child, .stats td:first-child { text-align: left; }
.stats th {
  font-size: var(--fs-1);
  font-style: var(--tilt);
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--ink-2);
  font-weight: var(--w-medium);
}
.stats th:not(:first-child) { font-family: var(--sans); }
.stats td:not(:first-child) { font-family: var(--mono); font-variant-numeric: tabular-nums; }
.stats__idle { color: var(--ink-2); font-size: var(--fs-2); }

/* Подзаголовок внутри диалога: тише названия, но громче строки таблицы. */
.dlg__sub {
  font-size: var(--fs-2);
  font-style: var(--tilt);
  text-transform: uppercase;
  letter-spacing: .08em;
  color: var(--ink-2);
  font-weight: var(--w-medium);
}

/* Месяц смен — это тридцать строк, и вырасти диалогу за экран они не должны:
   сегодняшние числа и кнопки обязаны оставаться на месте. */
.stats--history { max-height: 42vh; overflow-y: auto; }
/* Шапка остаётся видимой при прокрутке — иначе к десятой строке уже непонятно,
   какой столбец что означает. */
.stats--history thead th {
  position: sticky;
  top: 0;
  background: var(--surface-1);
}
/* Итог за всё время — не такая же строка, как день: он подводит черту. */
.stats tfoot td {
  border-top: var(--bw-thick) solid var(--rule);
  border-bottom: 0;
  font-weight: var(--w-medium);
}

.keys { display: grid; grid-template-columns: auto minmax(0, 1fr); gap: var(--s-2) var(--s-4); font-size: var(--fs-2); }
.keys dt { white-space: nowrap; }
.keys dd { color: var(--ink-1); }

/* ---------- Тост ---------- */

.toast {
  position: fixed;
  /* Над нижней полосой, а не поверх неё: тост держится четыре секунды и всё это
     время закрывал «Один звонок» и «Паузу» — то есть ровно те кнопки, к которым
     тянутся, прочитав сообщение. */
  right: var(--s-4); bottom: calc(2.75rem + var(--s-4));
  z-index: var(--z-toast);
  max-width: min(28rem, 90vw);
  padding: var(--s-3) var(--s-4);
  background: var(--poche);
  color: var(--poche-ink);
  font-size: var(--fs-2);
  border-left: var(--bw-thick) solid var(--rule-strong);
  box-shadow: 0 16px 40px -12px light-dark(rgba(26, 29, 32, .4), rgba(0, 0, 0, .7));
  transition: opacity var(--t-base) var(--ease), translate var(--t-base) var(--ease);
}
/* «Записано» и «не открылось» больше не выглядят одинаково — и не только
   цветом: у каждого варианта своя кромка и свой знак в начале строки. */
.toast[data-kind="ok"]    { border-left-color: #58A46A; }
.toast[data-kind="error"] { border-left-color: #E27567; }
.toast[data-kind="info"]  { border-left-color: var(--beam); }
.toast::before { font-family: var(--mono); margin-right: var(--s-2); opacity: .9; }
.toast[data-kind="ok"]::before    { content: '✓'; color: #58A46A; }
.toast[data-kind="error"]::before { content: '!'; color: #E27567; }
.toast[data-kind="info"]::before  { content: '·'; color: var(--beam); }
.toast[data-leaving="yes"] { opacity: 0; translate: 0 6px; }

/* ---------- Страница настройки ---------- */

.page { display: block; height: auto; background: var(--surface-0); }
.sheet { max-width: 52rem; margin: 0 auto; padding: var(--s-6) var(--s-4) var(--s-7); display: grid; gap: var(--s-5); }
.sheet__title {
  font-size: var(--fs-7);
  font-style: var(--tilt);
  font-weight: var(--w-bold);
  text-transform: uppercase;
  letter-spacing: .04em;
  line-height: var(--lh-tight);
}
.sheet__block {
  background: var(--surface-1);
  border: var(--bw) solid var(--rule);
  padding: var(--s-4) var(--s-5);
  display: grid;
  gap: var(--s-3);
}
.sheet__head {
  font-size: var(--fs-4);
  font-weight: var(--w-bold);
  padding-bottom: var(--s-2);
  border-bottom: var(--bw) solid var(--rule);
}
.sheet__lead { color: var(--ink-1); max-width: var(--measure); }
.sheet__note { font-size: var(--fs-2); color: var(--ink-2); max-width: var(--measure); }
.sheet__block .onboard__step:last-child { border-bottom: 0; padding-bottom: 0; }

/* Пометка у заголовка раздела: что ставить, а что держать про запас. */
.sheet__tag {
  margin-left: var(--s-2);
  padding: 2px var(--s-2);
  border: var(--bw) solid var(--rule-strong);
  font-size: var(--fs-1);
  font-weight: var(--w-regular);
  font-style: var(--tilt);
  text-transform: uppercase;
  letter-spacing: .04em;
  color: var(--ink-1);
  vertical-align: middle;
  white-space: nowrap;
}

/* Первый раздел — рекомендованный путь, и его пометку подсвечивает луч:
   свет означает «сюда», в том числе на странице настройки. */
.sheet__block:first-of-type .sheet__tag {
  background: var(--beam);
  border-color: var(--beam);
  color: var(--beam-ink);
}

/* Путь к папке и адрес chrome://extensions переписывают руками: в моноширинном
   видно, где подчёркивание, а где дефис. */
.mono {
  font-family: var(--mono);
  font-size: var(--fs-2);
  word-break: break-all;
}

.dial { display: flex; gap: var(--s-2); flex-wrap: wrap; align-items: center; }
.dial__input {
  padding: var(--s-2) var(--s-3);
  min-width: 14rem;
  background: var(--surface-2);
  border: var(--bw) solid var(--rule-strong);
  border-radius: var(--r-0);
  color: var(--ink-0);
  font-family: var(--mono);
  font-variant-numeric: tabular-nums;
}
/* Раньше здесь стоял var(--accent), которого не существовало: правило было
   невалидным, и кольца фокуса на этом поле не рисовалось вовсе. */
.dial__input:focus-visible {
  outline: 2px solid var(--beam-text);
  outline-offset: 1px;
  border-color: var(--beam-text);
}

/* ---------- Экраны поменьше ---------- */

@media (max-width: 1200px) {
  body[data-mode="ambient"] .work { grid-template-columns: minmax(0, 1.2fr) 12px minmax(0, 1fr); }
  body[data-mode="read"] .work,
  body[data-mode="input"] .work { grid-template-columns: minmax(0, 19rem) 12px minmax(0, 1fr); }
  .tape { width: min(16rem, 30vw); }
  .live__phase { font-size: var(--fs-6); }
}

/* Раскладка комнаты скрипта живёт не здесь: она считается по ширине САМОЙ
   комнаты (`@container script` рядом с `.script`), потому что ширина комнаты
   зависит ещё и от режима внимания, а медиазапрос об этом не знает. */

@media (max-width: 900px) {
  .work,
  body[data-mode="ambient"] .work,
  body[data-mode="read"] .work,
  body[data-mode="input"] .work {
    grid-template-columns: minmax(0, 1fr);
    grid-template-rows: minmax(0, 1fr) auto;
    max-height: none;
  }
  /* Узкий экран: комнаты встают друг под друга, и срез между ними не нужен. */
  .work__cut { display: none; }
  /* Скрипт первым: его читают вслух. */
  .pane--script { order: -1; border-bottom: var(--bw) solid var(--rule); }
  .pane--client { max-height: 45vh; }
  .live { grid-template-columns: minmax(0, 1fr) auto; gap: var(--s-3); }
  .live__who { grid-column: 1 / -1; grid-row: 2; }
  .live__phase { font-size: var(--fs-6); }
  .clock__value { font-size: var(--fs-5); }
  .masthead { flex-wrap: wrap; gap: var(--s-3); padding: var(--s-2) var(--s-3); }
  .result__statuses { grid-template-columns: minmax(0, 1fr); }
}

/* Ноутбук 13–14": вертикали мало, всё важное обязано поместиться без прокрутки. */
@media (max-height: 800px) {
  .live { padding: var(--s-2) var(--s-4); }
  .live__phase { font-size: var(--fs-6); }
  .clock__value { font-size: var(--fs-5); }
  .pane { padding: var(--s-3) var(--s-4) var(--s-5); }
  .steps li { font-size: var(--fs-4); padding-block: var(--s-1); }
  .result { padding: var(--s-2) var(--s-4) var(--s-3); gap: var(--s-2); }
  .result__statuses { max-height: 34vh; }
}

@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    transition-duration: 1ms !important;
    animation-duration: 1ms !important;
    animation-iteration-count: 1 !important;
  }
  /* «Полдень»: луч просто стоит там, где должен, и не переезжает. */
  .result__beam { transition: none !important; }
}
