/* Шрифт интерфейса. Переменный Inter, подрезанный до латиницы и кириллицы
   (130 КБ), отдаётся из /fonts/ — файл общий для обоих калькуляторов.
   Веса объявлены диапазоном: в стилях используются 400, 600, 650, 700 и 750,
   а системные шрифты промежуточные 650 и 750 не умеют и округляют их —
   до этого четыре веса из пяти рисовались одинаково.
   font-display: swap — текст читается сразу, не дожидаясь загрузки шрифта.
   Версия в url() проставляется scripts/bump-assets: файл кэшируется на год. */
@font-face {
  font-family: Inter;
  src: url("/fonts/inter-variable.woff2?v=3678882866") format("woff2");
  font-weight: 100 900;
  font-style: normal;
  font-display: swap;
}

:root {
  --impact-bg: #fff9fb;
  --impact-border: #e4c7d1;
  /* Значения выровнены по тому, что действительно отдаётся: токены были
     объявлены один раз и забыты, а .cell-hist красился литералами #f8f9fb и
     #d7dee9 рядом с ними. Сохранён отдаваемый цвет, а не объявленный. */
  --hist-bg: #f8f9fb;
  --hist-border: #d7dee9;
  --calc-bg: #ffffff;
  --calc-text: #3d3d3d;
  --total-bg: #f4f6f9;
  --total-border: #dce3e8;
  --danger: #bf3f36;
  --danger-bg: #fff0ee;
  --positive-text: #244cb8;
  --highlight: #7e3f55;
  /* Заливка поля в фокусе. Тот же бордовый, разведённый до 10% на белом, —
     ровно то, что даёт активной ячейке таблицы её inset-тень. Одна заливка
     на форму и таблицу: фокус выглядит одинаково там и там. */
  --focus-tint: #f2eeef;
  --ink: #172033;
  --ink-soft: #657187;
  /* Самый тихий уровень текста. Значение взято из калькулятора 2: там оно
     одно на все сноски, здесь же было четыре разных серых вразнобой (#888,
     #8b95a7, #7b8492, #8794aa), и часть из них на белом давала контраст
     около 3,4:1 — ниже порога, под который подогнан второй калькулятор. */
  --ink-faint: #606c80;
  --line: #d9e1ee;
  /* Шкала отступов из UX-стандарта: шаг 4 px, ступени 4-8-12-16-24-32-40.
     До неё в файле лежали 24 разных значения, из них 5, 7, 9, 11, 13, 14, 17,
     18, 34, 42 и 52 px — вне какого-либо шага: каждое ставилось на глаз под
     свой случай, и соседние блоки расходились на пиксель-два без причины.
     Литералом остаются только два вида величин: оптическая подгонка внутри
     органа управления (2-3 px, компенсация рамки или базовой линии) и
     размеры, у которых своя причина, — ширина поля, ширина колонки подписей. */
  --sp-1: 4px;
  --sp-2: 8px;
  --sp-3: 12px;
  --sp-4: 16px;
  --sp-5: 24px;
  --sp-6: 32px;
  --sp-7: 40px;
  font-family: Inter, "Segoe UI", Arial, sans-serif;
  /* Помесячные таблицы — 12 колонок чисел: разноширокие цифры заставляют
     разряды «плясать» от месяца к месяцу. Ставим на :root, как в
     калькуляторе 2, чтобы правило было одно на оба проекта. */
  font-variant-numeric: tabular-nums;
}

* { box-sizing: border-box; }

/* Органы управления шрифт не наследуют: браузер ставит им собственный `font`,
   и Inter с :root до них не доходит — Arial рисовал 60 полей помесячной
   таблицы, пять полей формы, селект месяца, обе кнопки шага, переключатель
   канала, стрелки «заполнить всё» и кнопку подробного расчёта. Тот же
   шорткат `font` сбрасывает и font-variant-numeric, из-за чего в полях
   таблицы цифры шли пропорциональными и разряды прыгали от месяца к месяцу —
   ровно то, ради чего tabular-nums стоит на :root. Возвращаем оба свойства
   разом: точечные font-family у отдельных кнопок после этого не нужны. */
button, input, select, textarea {
  font-family: inherit;
  font-variant-numeric: inherit;
}

body {
  margin: 0;
  padding: var(--sp-5) clamp(var(--sp-4), 3vw, 48px) var(--sp-6);
  background: #fbfbf8;
  color: var(--ink);
}

.page-header { margin: 0 0 var(--sp-6); }
.page-kicker, .result-eyebrow {
  margin: 0 0 var(--sp-1);
  color: var(--highlight);
  font-size: 12px;
  font-weight: 700;
  letter-spacing: 0;
}

.page-header h1 {
  margin: 0;
  font-size: 30px;
  line-height: 1.08;
  letter-spacing: 0;
}

.page-lead { margin: var(--sp-2) 0 0; color: var(--ink-soft); font-size: 15px; }

.workflow {
  display: flex;
  gap: var(--sp-5);
  margin-top: var(--sp-4);
  color: var(--ink-faint);
  font-size: 12px;
  font-weight: 600;
}

.workflow a {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  color: inherit;
  text-decoration: none;
}

.workflow a:hover { color: var(--ink); }
.workflow a:hover b { color: #5d2e3f; }

.workflow a:focus-visible {
  outline: 2px solid var(--highlight);
  outline-offset: 3px;
  border-radius: 2px;
}

.workflow b { color: var(--highlight); font-size: 12px; }

/* Переход к разделу по ссылке из полосы шагов не должен ставить заголовок
   вплотную к верху окна. */
.step { scroll-margin-top: var(--sp-5); margin-bottom: var(--sp-7); }
.step:last-of-type { margin-bottom: 0; }

.step-head { margin-bottom: var(--sp-3); }

.step-head h2 {
  font-size: 20px;
  margin: 0 0 var(--sp-1);
  color: var(--ink);
}

.step-sub {
  font-size: 14px;
  color: var(--ink-soft);
  margin: 0;
  line-height: 1.35;
}

/* Одна колонка. Прежде справа стояла жёсткая колонка заметок в 230 px, и всё
   сжатие доставалось форме: на 900 px колонка подписи схлопывалась до 124 px
   при неразрывном хвосте «доставляемость, %i» в 155 px, и значок ложился
   поверх поля ввода. Лечилось это порогом перелома в 1000 px; с уходом
   заметок в шаг 2 причина исчезла, и порог больше не нужен. Инвариант всё
   равно проверяется в ui-test.js на девяти ширинах — подписи меняются. */
.top-grid {
  display: grid;
  grid-template-columns: 1fr;
  max-width: 1500px;
}

/* Три группы полей в один ряд. Раньше шаг 1 шёл в два этажа — полоса из двух
   верхних полей, под ней два блока, — и при этом справа стояла колонка
   заметок. После её ухода ширины хватает на один ряд, и шаг перестал занимать
   треть экрана по высоте. */
.assumptions-panel {
  display: grid;
  /* Колонки по содержимому, а не долями ширины. Доли делили экран между
     группами вслепую: первой (переключатель каналов и список месяцев, 180 px)
     доставалось 346 px, а «Естественный прирост базы, %» при своих 233 px
     ломался на две строки. Теперь ширина колонки — это самая длинная подпись
     группы плюс поле значения, поэтому подписи не переносятся, а поле стоит
     сразу за подписью, а не у дальнего края пустой колонки. Свободная ширина
     уходит в промежутки между группами (space-between), поэтому левый край
     первой группы и правый край третьей совпадают с краями таблицы ниже.
     Длины подписей измерены в браузере: 114, 233 и 322 px. */
  grid-template-columns: repeat(3, minmax(0, max-content));
  justify-content: space-between;
  gap: var(--sp-5) var(--sp-6);
  align-items: start;
}

/* Верхние два поля встали друг под другом: теперь это колонка, а не полоса
   во всю ширину, и разделительная линия под ней потеряла смысл. */
.assumptions-top {
  grid-template-columns: minmax(0, 1fr);
  gap: 0;
}

/* Средние экраны: три колонки перестают помещаться раньше, чем кажется, —
   в третьей стоит «Средний чек атрибутированного заказа, ₽», и неразрывный
   хвост со значком упирается в поле. Проверяется перебором ширин в ui-test.js. */
@media (max-width: 1180px) {
  .assumptions-panel { grid-template-columns: repeat(2, minmax(0, max-content)); gap: var(--sp-5) var(--sp-6); }
}

@media (max-width: 820px) {
  .assumptions-panel { grid-template-columns: minmax(0, max-content); gap: var(--sp-4); }
}

.assumption-group-title {
  margin: 0 0 var(--sp-1);
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 700;
}

.assumption-row {
  display: grid;
  grid-template-columns: minmax(min(260px, 100%), 1fr) 104px;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) 0;
  border-top: 1px solid #edf0f5;
}

.assumption-group .assumption-row {
  grid-template-columns: minmax(0, 1fr) 104px;
}

.assumptions-top .assumption-row {
  grid-template-columns: 1fr;
  align-content: start;
  gap: var(--sp-2);
}

/* Переключатель каналов и выбор месяца — одной ширины, и она задана по
   содержимому, а не по колонке. Без этого общее правило .assumption-row select
   (той же специфичности, но ниже по файлу) растягивало список месяцев на все
   365 px колонки, хотя самый длинный месяц занимает 66 px. */
.assumptions-top .channel-toggle,
.assumptions-top .assumption-row select {
  width: 180px;
}

.assumption-row:first-of-type { border-top: none; }

.assumption-row label {
  font-size: 13px;
  font-weight: 600;
  line-height: 1.3;
}

.assumption-row input, .assumption-row select {
  /* Снизу на 2 px меньше: под полем идёт линия, и равные отступы визуально
     сажают текст ниже середины. Это оптическая подгонка, а не шаг сетки. */
  padding: var(--sp-2) var(--sp-1) 6px;
  border: 0;
  border-bottom: 1px solid #cfd6df;
  background: transparent;
  border-radius: 0;
  font-size: 13px;
  width: 100%;
  /* По центру и в колонке поуже, как значения в таблице. Вправо значение
     прижималось к дальнему краю линии, и между подписью и числом оставался
     провал шириной с само поле. */
  text-align: center;
}

.assumptions-top select { text-align: left; }

/* Фокус утолщает линию, которая под полем и так есть, и подкрашивает поле, —
   рамки вокруг нет. Форма здесь принципиально без коробочек (UX-стандарт), а
   рамка в фокусе этому противоречила: покой и фокус говорили на разных языках.
   Заливка в паре с линией несёт индикатор целиком: по «Focus Appearance» из
   WCAG 2.2 площадь одной линии 2 px меньше требуемой, смена фона добирает её.
   Отсюда же снятые 1 px отступа: линия стала толще на пиксель, и без этого
   поле подрастало, дёргая подпись рядом. */
.assumption-row input:focus, .assumption-row select:focus {
  outline: 0;
  border-bottom: 2px solid var(--highlight);
  padding-bottom: 5px;
  background: var(--focus-tint);
}

/* Хвост подписи: последнее слово вместе со значком «i». Значок не должен
   отрываться от текста и уезжать на отдельную строку. Одного &nbsp; для этого
   мало — если следом в разметке идёт перенос строки, он схлопывается в обычный
   пробел, и разрыв случается уже по нему. Неразрывным делается весь хвост,
   поэтому правка переживёт переформатирование разметки. */
.label-tail { white-space: nowrap; }

/* Значок скрывается через атрибут hidden (подсказка у базы ждёт выбора
   канала), а display: inline-flex ниже сильнее браузерного правила для
   [hidden] — без этой строки значок остаётся на экране и ведёт в пустоту.
   Та же пара правил уже стоит у .info-pop. */
.info-icon[hidden] { display: none; }

.info-icon {
  /* Отступ от текста задаётся здесь, а не пробелом в разметке: внутри
     неразрывного хвоста пробел был бы лишней точкой разрыва. */
  margin-left: 4px;
  padding: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  color: var(--ink-faint);
  background: transparent;
  cursor: help;
  font-size: 12px;
  font-style: normal;
  font-weight: 700;
  border: 1px solid #cbd3df;
  border-radius: 50%;
  width: 16px;
  height: 16px;
  line-height: 1;
  vertical-align: 1px;
}

/* Значок — <button>, а не <span tabindex="0">, и это не косметика. Значок
   лежит внутри <label for>: клик по неинтерактивному потомку метки браузер
   переадресует полю, поэтому нажатие на подсказку прыгало фокусом в поле
   ввода. Кнопка — интерактивное содержимое, метка её клик не перехватывает.
   Заодно подсказка открывается с клавиатуры и с тач-экрана, где hover нет. */
.info-icon:hover, .info-icon.is-active {
  color: var(--ink);
  border-color: #9aa5b5;
}

.info-icon:focus-visible {
  outline: 2px solid var(--highlight);
  outline-offset: 2px;
}

/* Окно подсказки — один общий элемент в конце <body>, а не ::after у каждого
   значка, и position: fixed, а не absolute. Причина ровно одна: абсолютно
   позиционированное окно шириной 260 px расширяло область прокрутки документа
   — на 390 px ширина страницы при наведении скакала с 390 до 1053 px, и
   страницу можно было утащить вправо. Fixed в область прокрутки не входит.
   Координаты считает JS (positionInfoPop): он же разворачивает окно влево
   у правого края и вверх, если снизу не помещается — на CSS это не выражается,
   media-запрос по ширине экрана про край окна ничего не знает. */
.info-pop {
  position: fixed;
  z-index: 20;
  top: 0;
  left: 0;
  max-width: 280px;
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid #d7dde6;
  border-radius: 4px;
  background: #ffffff;
  box-shadow: 0 8px 20px rgba(32, 40, 55, 0.12);
  color: #404b5f;
  font-size: 12.5px;
  font-weight: 400;
  line-height: 1.35;
  text-align: left;
  pointer-events: none;
  opacity: 0;
  transform: translateY(-4px);
  transition: opacity 120ms ease, transform 120ms ease;
}

.info-pop[hidden] { display: none; }
.info-pop.is-open { opacity: 1; transform: translateY(0); }

/* Поле контекста, в которое ещё не ввели значение. Тихая холодная заливка и
   чуть более тёмная линия: пустое поле видно, заполненное сливается с
   полотном. Не рамка и не красный — форма здесь принципиально без коробочек
   (UX-стандарт), а ошибка обязательности на пустой форме запрещена им же:
   этот тон говорит «сюда ещё не ввели», а не «ошибка». Заливка светлее
   границы текста, контраст самого значения не меняется. */
.assumption-row input.is-empty,
.assumption-row select.is-empty {
  background: #eef1f6;
  border-bottom-color: #aeb9ca;
}

/* Поле, запертое до выбора канала. Серый — цвет недоступного действия по
   UX-стандарту; линия снизу остаётся, чтобы поле не переставало быть полем.
   Заливки «ещё не ввели» здесь нет намеренно: пустота запертого поля ничего
   не требует от пользователя, пока канал не выбран. */
.assumption-row input:disabled,
.assumption-row select:disabled {
  color: var(--ink-faint);
  background: transparent;
  border-bottom-color: #e2e7ee;
  cursor: not-allowed;
}

.assumption-row input:disabled.is-empty {
  background: transparent;
  border-bottom-color: #e2e7ee;
}

/* Тихая строка внутри группы формы: причина запрета и отзыв на правку базы.
   Тише подписи поля и шрифтом сноски — это сообщение о состоянии, а не
   название или значение. */
.assumption-note {
  grid-column: 1 / -1;
  margin: var(--sp-1) 0 0;
  color: var(--ink-faint);
  font-size: 12px;
  line-height: 1.35;
}

/* Строка о запрете шире колонки своей группы быть не должна: ширина колонок
   формы считается по содержимому (`max-content`), и 87 символов в одну строку
   растягивали первую группу с 180 до 568 px. Пока строка была видна — вместе с
   ней уезжали вбок и соседние группы, а при выборе канала возвращались
   обратно, на 194 px. Ограничение ширины делает колонку постоянной, а две
   строки текста — тем местом, которое остаётся занятым всегда. */
.assumption-note-lock {
  max-width: 260px;
}

/* Погашенная строка: место занято, содержимого не видно и скринридер его не
   читает. Через visibility, а не hidden: hidden убирает элемент из потока, и
   каждое появление строки двигало форму и всё, что ниже неё. */
.assumption-note.is-silent {
  visibility: hidden;
}

.assumption-echo {
  padding-top: var(--sp-1);
  border-top: 1px solid #edf0f5;
}

.assumption-echo strong {
  color: var(--ink);
  font-variant-numeric: tabular-nums;
}

.channel-toggle {
  display: flex;
  gap: var(--sp-2);
}

.channel-btn {
  padding: var(--sp-2) var(--sp-4);
  border: 1px solid var(--line);
  background: #f7f9fc;
  border-radius: 5px;
  cursor: pointer;
  font-size: 12.5px;
}

.channel-btn:hover { background: #fff0f5; }

.channel-btn.active {
  background: var(--highlight);
  border-color: var(--highlight);
  color: #fff;
  font-weight: 600;
}

.field-error {
  display: block;
  grid-column: 1 / -1;
  min-height: 0;
  font-size: 12px;
  color: var(--danger);
  font-weight: 600;
}

/* Значок обтекается подписью, а не встаёт под ней отдельной строкой: строка
   таблицы становится такой высоты, какой нужна подпись, и шесть повторов
   «Заполнить все месяцы» больше не занимают экран по вертикали. */
.fill-all {
  float: right;
  margin: 0 0 2px var(--sp-2);
}

.fill-all-btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 18px;
  height: 18px;
  padding: 0;
  border: 1px solid #cbd3df;
  border-radius: 4px;
  background: #fff;
  color: var(--highlight);
  cursor: pointer;
  font-size: 12px;
  line-height: 1;
}

.fill-all-btn:hover {
  border-color: var(--highlight);
  background: #fdf6f8;
}

.fill-all-btn:focus-visible {
  outline: 2px solid var(--highlight);
  outline-offset: 1px;
}

/* Шапка шага с действиями: заголовок слева, кнопки справа на той же строке.
   Отдельной полосы по высоте не занимают, а видны до первого пустого поля. */
.step-head-with-actions {
  display: flex;
  flex-wrap: wrap;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--sp-2) var(--sp-5);
}

.step-actions {
  display: flex;
  /* Кнопки с white-space: nowrap, поэтому перенос обязателен: без него
     минимальная ширина строки становится полом для всего блока. */
  flex-wrap: wrap;
  gap: var(--sp-2);
  align-items: center;
  /* 2 px — оптическая подгонка к базовой линии заголовка рядом. */
  padding-top: 2px;
}

.step-actions button {
  padding: var(--sp-2) var(--sp-3);
  border: 0;
  background: transparent;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
  white-space: nowrap;
}

.step-actions button:hover { background: #f0f1f3; }

/* Запертая кнопка примера шага 2 — тем же серым, что и запертые поля, и без
   отклика на наведение: иначе она выглядит рабочей и молча ничего не делает. */
.step-actions button:disabled {
  color: var(--ink-faint);
  font-weight: 400;
  cursor: not-allowed;
}

.step-actions button:disabled:hover { background: transparent; }

#btn-example, #btn-example-monthly { color: var(--ink); font-weight: 700; }
#btn-clear, #btn-clear-monthly { color: var(--ink-soft); }

/* Кнопка сброса в состоянии подтверждения: видно, что следующее нажатие
   сотрёт данные, и видно, что это то же самое действие, а не новое. */
#btn-clear.is-confirming,
#btn-clear-monthly.is-confirming {
  color: var(--danger);
  background: var(--danger-bg);
  font-weight: 700;
}

/* Легенда таблицы: горизонтальная полоса вплотную над таблицей, которую она
   описывает, — как `.matrix-guidance` в калькуляторе 2. Прежде это была правая
   колонка шага 1, то есть легенда стояла за 400 px до строк, о которых
   говорит, и читалась раньше, чем появлялся предмет разговора. */
.table-legend {
  display: flex;
  flex-wrap: wrap;
  gap: var(--sp-1) var(--sp-5);
  margin: 0 0 var(--sp-3);
  font-size: 12px;
  color: var(--ink-soft);
  line-height: 1.4;
}

.table-legend strong { color: var(--ink); font-weight: 700; }

@media (max-width: 660px) {
  /* Три колонки схлопываются в одну. Без этого правила подпись со значком «i»
     не помещалась в свою колонку и ложилась поверх поля ввода — на 390 px
     сразу в пяти строках. Раньше здесь перечислялись .assumptions-top и
     .assumption-groups; обёртки .assumption-groups больше нет, сетку держит
     сама .assumptions-panel. */
  .assumptions-panel { grid-template-columns: 1fr; gap: var(--sp-3); }
  /* Колонка значения перестаёт быть жёсткой: на 390 px фиксированные 132 px
     вместе с подписью не помещались в ширину экрана, и прокручивалась вся
     страница, а не таблица. */
  .assumption-group .assumption-row { grid-template-columns: minmax(0, 1fr) minmax(0, 132px); }
  /* Канал и начало прогноза остаются в стек: их органы управления шире
     колонки значения (переключатель каналов — два кнопочных блока). */
  .assumptions-top .assumption-row { grid-template-columns: minmax(0, 1fr); }
  .assumptions-top .channel-toggle,
  .assumptions-top select { width: 100%; max-width: 180px; }
  .channel-btn { flex: 1 1 0; min-width: 0; padding: var(--sp-2) var(--sp-3); }
}


/* Строка-переключатель подробного расчёта: правило одно. Раньше их было два
   в разных концах файла — одно задавало отступы, другое раскладку. */
.detail-toggle-row {
  display: flex;
  gap: var(--sp-3);
  align-items: center;
  margin: var(--sp-4) 0;
}

.detail-toggle-row span { color: var(--ink-soft); font-size: 12px; }

.detail-toggle-btn {
  padding: var(--sp-2) var(--sp-3);
  border: 1px solid var(--line);
  background: #f5f5f7;
  border-radius: 4px;
  cursor: pointer;
  font-size: 12px;
}

.detail-toggle-btn:hover { background: #ececf0; }

.table-wrap {
  overflow: auto;
  border: 0;
  border-radius: 0;
  max-width: 100%;
}

.compact-table-wrap {
  max-height: calc(100vh - 320px);
}

/* Две части в одну строку: слева — что сделать дальше, справа — счётчик
   заполненного. Сетка была на три колонки под надпись-кикер и пояснение,
   которых больше нет. */
.scenario-readiness {
  display: grid;
  grid-template-columns: minmax(210px, 1fr) auto;
  column-gap: var(--sp-4);
  row-gap: var(--sp-1);
  align-items: baseline;
  margin: var(--sp-4) 0;
  padding: var(--sp-3) 0;
  border-top: 1px solid #e1e5e9;
  border-bottom: 1px solid #e1e5e9;
}

/* Заголовок полосы меняется вместе с состоянием данных, а полоса стоит над
   таблицей: лишняя строка текста двигает вниз таблицу, результат и всю
   страницу — ровно в тот момент, когда пользователь заполняет форму. Поэтому
   место под две строки занято всегда там, где заголовок на две строки вообще
   способен разъехаться (ниже ~980 px; выше все четыре состояния укладываются
   в одну строку, и резерв был бы просто пустой строкой). Высота в em, а не в
   px: она должна следовать за размером шрифта, а не за замером одного дня.
   Ниже 360 px самое длинное состояние берёт три строки — это уже, у́же любого
   нынешнего телефона и у́же собственной узкой проверки проекта (390 px). */
.scenario-readiness strong { color: var(--ink); font-size: 13px; line-height: 1.25; }

@media (max-width: 1080px) {
  .scenario-readiness strong { min-height: 2.5em; }
}
.scenario-readiness em { color: var(--ink-faint); font-size: 12px; font-style: normal; white-space: nowrap; }
.scenario-readiness.is-ready { border-color: var(--line); }
.scenario-readiness.is-ready em { color: var(--positive-text); font-weight: 700; }

.detail-table-wrap {
  max-height: 60vh;
  margin-top: var(--sp-3);
}

table {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
}

th, td {
  border: 0;
  border-bottom: 1px solid #e3e8f1;
  padding: var(--sp-2) var(--sp-1);
  /* Значения по центру во всех таблицах: колонка — это месяц, её заголовок
     стоит по центру, и в рабочей таблице по центру же стоят поля ввода.
     Выравнивание вправо уводило число от своей колонки и делало подробный
     расчёт непохожим на рабочую таблицу над ним, хотя это те же месяцы.
     Подписи строк и рубрики остаются слева — их правила идут ниже. */
  text-align: center;
  font-size: 12px;
  white-space: nowrap;
}

thead th {
  position: sticky;
  top: 0;
  background: #f7f9fc;
  z-index: 3;
  color: var(--ink-soft);
  font-weight: 650;
  /* Заголовки колонок по центру: под ними стоят поля ввода с текстом по
     центру, и выравнивание заголовка вправо уводило название месяца от
     своего столбца значений. Подпись строки остаётся по левому краю —
     её правило идёт ниже и сильнее. */
  text-align: center;
}

.label-col {
  position: sticky;
  left: 0;
  background: #f7f9fc;
  text-align: left;
  min-width: 200px;
  max-width: 210px;
  white-space: normal;
  z-index: 2;
  font-size: 12px;
}

thead .label-col {
  z-index: 4;
  background: #f7f9fc;
}

tr.section-row td {
  background: transparent;
  border-bottom: 0;
  color: var(--ink-soft);
  font-size: 12px;
  font-weight: 700;
  text-align: left;
  position: sticky;
  left: 0;
  z-index: 1;
}

#compact-table tr.section-row td {
  padding: var(--sp-4) 0 var(--sp-2);
  color: var(--highlight);
  font-size: 12px;
}

/* Не block: блочный элемент занял бы всю ширину ячейки и не дал бы подписи
   обтекать плавающий значок заполнения — тот оказался бы под текстом. */
.row-label {
  display: inline;
}

.label-col .fill-all {
  margin: 0 0 2px var(--sp-2);
}

.label-col .field-error {
  white-space: normal;
  display: block;
}

.input-cell {
  /* Те же 4 px по горизонтали, что у обычной ячейки: раньше было 6, и колонки
     с вводом были на 4 px шире расчётных — на двенадцати колонках это 48 px
     ширины таблицы за счёт рассогласования, которого никто не просил. */
  padding: var(--sp-1);
}

.cell-impact {
  background: var(--impact-bg);
}

.cell-impact input {
  border: 0;
  border-bottom: 1px solid var(--impact-border);
  border-radius: 0;
  background: transparent;
  text-align: center;
  /* 3 px снизу плюс 1 px линии дают те же 4 px, что сверху. */
  padding: var(--sp-1) 0 3px;
}

.cell-impact input:hover {
  border-bottom-color: #ae7085;
}

/* Ненулевая точка воздействия отмечена только тонкой тёплой линией поля:
   отдельная синяя подложка визуально напоминала ошибку ввода. */
#compact-table .cell-impact.cell-edited input { border-bottom-color: #7e3f55; }

.cell-hist {
  background: var(--hist-bg);
}

.cell-hist input {
  border: 0;
  border-bottom: 1px solid var(--hist-border);
  border-radius: 0;
  background: transparent;
}

/* Пустая обязательная ячейка — тот же тон, что у пустого поля контекста
   (#eef1f6), и та же логика: тон гаснет, как только значение введено.
   Заливка чуть темнее собственного фона исторической строки, поэтому ряд
   читается как «этот ещё не заполнен», а не как ошибка. */
.input-cell.cell-empty {
  background: #eef1f6;
}

.input-cell.cell-empty input {
  border-bottom-color: #aeb9ca;
}

.detail-source-cell {
  background: var(--hist-bg);
  color: var(--ink-faint);
}

.detail-table-wrap .section-row td {
  padding-top: var(--sp-4);
  color: var(--ink);
  font-size: 12px;
}

.input-cell input {
  /* 64 px — ширина самого длинного вводимого значения («110 000») плюс запас
     на каретку. Ширина поля задаёт ширину месячной колонки, а колонок 12,
     поэтому каждый лишний пиксель здесь стоит двенадцати в ширине таблицы. */
  width: 64px;
  text-align: center;
  padding: var(--sp-1) 0 3px;
  font-size: 12px;
  border-radius: 0;
}

/* Поля таблицы заперты до выбора канала по той же причине, что и поля формы:
   их значения лежат в state.email / state.sms, и без канала ввод некуда
   положить. Курсор «нельзя» ставится на саму ячейку: мышь попадает в неё, а
   не только в 64 px поля. */
.input-cell input:disabled {
  color: var(--ink-faint);
  cursor: not-allowed;
}

.input-cell:has(input:disabled) { cursor: not-allowed; }

.fill-all-btn:disabled { cursor: not-allowed; opacity: 0.45; }

/* Фокус ячейки — та же утолщённая линия, что и в форме, для обеих ролей сразу.
   Прежде точки воздействия получали линию, а исторические ячейки — рамку 2 px
   внутри ячейки: одно действие в одной таблице выглядело двумя способами. Вместе
   с рамкой у `td.cell-active` это давало два вложенных прямоугольника одного
   цвета в 1 px друг от друга — не решение, а артефакт отрисовки.
   3 px снизу превращаются в 2 px: линия забирает пиксель, иначе поле подрастает
   и строка дёргается на каждом переходе фокуса. */
.input-cell input:focus {
  outline: 0;
  border-bottom: 2px solid var(--highlight);
  padding-bottom: 2px;
}

.calc-cell {
  background: var(--calc-bg);
  color: var(--calc-text);
}

/* Колонка итогов закреплена у правого края так же, как колонка подписей — у
   левого. Ниже ~1200 px таблица всё равно прокручивается вбок, и без этого
   первым за экран уезжало ровно то, ради чего таблицу читают, — итог за 12
   месяцев. Фон обязателен: без него сквозь закреплённую ячейку видны
   проезжающие под ней месяцы. */
.total-cell,
.total-col-head {
  position: sticky;
  right: 0;
  z-index: 2;
  background: var(--total-bg);
  border-left: 1px solid var(--total-border);
}

.total-cell {
  font-weight: 600;
  color: var(--ink);
  /* По центру, как значения в месячных колонках рабочей таблицы: колонка
     отделена и фоном, и линией слева, поэтому выравнивание вправо прижимало
     итог к самому краю таблицы. */
  text-align: center;
}

thead .total-col-head {
  z-index: 4;
}

/* Колонка итогов. Заголовок — короткое «Итого»: прежнее «Итого за 12 мес.»
   шло одной строкой в 118 px и вместе с полными названиями месяцев не давало
   таблице влезть в экран ноутбука. Период указан в заголовке шага и в блоке
   результата, повторять его в шапке колонки незачем. */
.total-col-head {
  min-width: 70px;
  line-height: 1.2;
}

.na-cell {
  color: var(--ink-faint);
  font-style: italic;
}

.input-cell.cell-error {
  background: var(--danger-bg);
}

/* Заливку несёт ячейка, полю внутри повторять её незачем. Граница у поля
   только нижняя (`border: 0` плюс `border-bottom`), поэтому и красится она. */
.input-cell.cell-error input {
  border-bottom-color: var(--danger);
}

/* подсветка строки/месяца при наведении и фокусе; активная ячейка заметнее всего */
tr.row-hover > td {
  box-shadow: inset 0 0 0 9999px rgba(126, 63, 85, 0.035);
}

td.col-hover {
  box-shadow: inset 0 0 0 9999px rgba(126, 63, 85, 0.035);
}

/* Активная ячейка — только заливка, без рамки. Заливка включается и от мыши,
   и от клавиатуры (`focusin` в attachHighlight), и после отказа от рамок она
   несущая, а не декоративная: вместе с линией под значением она и есть
   индикатор фокуса. Убрать её как «подсветку для мыши» — значит почти погасить
   фокус с клавиатуры; за этим следит проверка в .tools/ui-test.js. */
td.cell-active {
  box-shadow: inset 0 0 0 9999px rgba(126, 63, 85, 0.10);
}

.result-overview { display: grid; grid-template-columns: minmax(440px, 1.35fr) minmax(330px, 0.85fr); gap: var(--sp-7); align-items: stretch; }
.result-journey { padding: var(--sp-1) 0 var(--sp-4); border-bottom: 1px solid var(--line); }
.result-journey-flow { display: grid; grid-template-columns: minmax(0, 1fr) var(--sp-6) minmax(0, 1fr); gap: var(--sp-3); align-items: center; margin-top: var(--sp-3); }
.result-state { min-width: 0; padding: 2px 0 var(--sp-3); border-bottom: 2px solid #dfe4e9; }
.result-state-scenario { border-bottom-color: #b9768b; }
.result-state p { margin: 0 0 var(--sp-2); color: var(--ink-soft); font-size: 12px; }
.result-state strong { display: block; font-size: 30px; line-height: 1; color: var(--ink); font-variant-numeric: tabular-nums; }
.result-state span { display: block; margin-top: var(--sp-1); color: var(--ink-soft); font-size: 12px; }
.result-state em { display: block; margin-top: var(--sp-3); color: var(--ink); font-size: 13px; font-style: normal; font-weight: 700; font-variant-numeric: tabular-nums; }
.result-arrow { color: var(--highlight); font-size: 24px; text-align: center; }
.result-base-line { margin: var(--sp-4) 0 0; color: var(--ink-soft); font-size: 12px; }
.result-base-line strong { color: var(--ink); font-variant-numeric: tabular-nums; }
.result-base-line span { color: var(--positive-text); font-weight: 700; }
.result-hero { padding: var(--sp-1) 0 var(--sp-4) var(--sp-5); border-bottom: 1px solid var(--line); border-left: 2px solid #b9768b; }
.result-hero-value { margin: var(--sp-2) 0; color: var(--ink); font-size: 43px; font-weight: 750; line-height: 1; letter-spacing: 0; font-variant-numeric: tabular-nums; }
.result-hero-value.change-pos { color: var(--positive-text); }
.result-hero-value.change-neg { color: var(--danger); }
.result-hero-context { margin: 0; color: var(--ink-soft); font-size: 13px; line-height: 1.45; }
.result-hero-context strong { color: var(--ink); }

/* Объяснение под главным числом. Оформлено как .model-limits-details — один
   приём раскрывающегося блока на страницу, — но отдельным блоком, а не в
   строке: внутри абзац в три фразы, и инлайновый summary уводил бы его в
   набор основного текста. */
.result-hero-why { margin-top: var(--sp-3); }

.result-hero-why summary {
  cursor: pointer;
  color: var(--highlight);
  font-size: 12.5px;
}

.result-hero-why p {
  margin: var(--sp-2) 0 0;
  color: var(--ink-faint);
  font-size: 12.5px;
  line-height: 1.4;
}

@media (max-width: 820px) {
  .result-overview { grid-template-columns: 1fr; gap: var(--sp-5); }
  .result-hero { padding-left: var(--sp-4); }
}

@media (max-width: 680px) {
  .scenario-readiness { grid-template-columns: 1fr; gap: var(--sp-1); }
}

.model-limits {
  margin-top: var(--sp-4);
  padding: var(--sp-1) 0;
}

/* Подвал с единственной ссылкой наружу. Тон сноски, а не призыва: ссылка
   стоит после результата и оговорок, и соревноваться с ними ей незачем.
   Отбивка линией — чтобы строка читалась как подвал, а не как ещё одна
   оговорка модели. */
.page-footer {
  margin-top: var(--sp-5);
  padding-top: var(--sp-4);
  border-top: 1px solid var(--line);
}

.page-footer p {
  margin: 0;
  font-size: 12.5px;
  color: var(--ink-faint);
}

.page-footer a { color: var(--highlight); }

.model-limits p {
  font-size: 12.5px;
  color: var(--ink-faint);
  margin: 0;
  line-height: 1.4;
}

.model-limits-details {
  display: inline;
}

.model-limits-details summary {
  display: inline;
  cursor: pointer;
  color: var(--highlight);
  font-size: 12.5px;
}

.model-limits-details p {
  margin-top: var(--sp-1);
}
