/* CORVAST — компоненты портала: шапка, бланки, таблицы, доска, карточка, блоки этапов.
   Только переменные из tokens.css: цветов, шрифтов и своих ширин @media здесь нет. */

/* ── Штамп-навигация (основная надпись сверху) ──────────────────────────── */

/* Штамп в одну строку: знак с наименованием, вкладки, графа пользователя.
   Строка не должна переноситься — перенесённый ряд повисает без разделителя, а
   вертикальные линовки обрываются на полуслове. Поэтому названия вкладок короткие,
   а номер листа и подпись под наименованием уходят раньше, чем строка сломается. */
.stamp-bar {
  display: flex;
  align-items: stretch;
  border-bottom: 1.5px solid var(--color-ink);
}

.brand {
  padding: 9px 18px 8px 14px;
  border-right: 1px solid var(--color-line);
  text-decoration: none;
  color: var(--color-ink);
  display: flex;
  align-items: center;
  gap: 11px;
  white-space: nowrap;
}
/* Знак — первая графа штампа. Высота 40 px укладывается в две строки наименования,
   поэтому шапка от логотипа не подросла. */
.brand-mark { display: block; width: auto; height: 40px; }
.brand-text { display: block; }
.brand-name {
  display: block;
  font-family: var(--font-display);
  font-size: var(--text-2xl);
  font-weight: 700;
  letter-spacing: .1em;
  text-transform: uppercase;
  line-height: 1.05;
}
.brand-sub {
  display: block;
  font-family: var(--font-mono);
  margin-top: 2px;
  font-size: var(--text-xs);
  color: var(--color-ink-muted);
  letter-spacing: .04em;
}
/* На служебных страницах (вход, регистрация, оферта) меню нет — ширину забирает
   наименование, чтобы графа не осталась пустой. */
.stamp-bar.no-tabs .brand { flex: 1; }
/* Тариф, который открывает закрытый раздел: «BUSINESS» объясняет больше замка. */
.plan-badge { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: .04em;
  color: var(--color-primary); border: 1px solid currentColor; padding: 1px 5px; }

/* ── Карточки-формы на титульном листе ──────────────────────────────────── */

.forms-grid {
  display: grid;
  gap: 18px;
  grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
  margin-top: 28px;
}

.form-card {
  display: block;
  position: relative;
  text-decoration: none;
  color: var(--color-ink);
  border: 1px solid var(--color-ink);
  padding: 46px 20px 18px;
  background: var(--color-surface);
  transition: box-shadow .12s ease, transform .12s ease;
}
.form-card:hover {
  box-shadow: 3px 3px 0 var(--color-primary);
  transform: translate(-1px, -1px);
}
.form-card .index {
  position: absolute;
  top: 0; left: 0;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: .08em;
  color: var(--color-primary);
  border-right: 1px solid var(--color-line);
  border-bottom: 1px solid var(--color-line);
  padding: 5px 10px;
  text-transform: uppercase;
}
.form-card .title {
  font-size: var(--text-lg);
  font-weight: 600;
  margin-bottom: 8px;
}
.form-card .desc { color: var(--color-ink-muted); font-size: var(--text-md); }

/* ── Формы-документы ─────────────────────────────────────────────────────── */

form.doc, .doc-sheet { max-width: 640px; display: grid; gap: 0; border: 1px solid var(--color-ink);
  background: var(--color-surface); }
/* Длинная форма (акты, поставка) — несколько листов подряд. Шапка листа называет раздел,
   как графа-заголовок на унифицированном бланке; подпись и поле — те же doc-row. */
.doc-sheet + .doc-sheet { margin-top: 20px; }
.doc-sheet.wide { max-width: none; }
.doc-caption {
  padding: 8px 16px;
  border-bottom: 1px solid var(--color-ink);
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--color-primary);
}
/* Пояснение к листу — последней графой, мелко. Отрицательный отступ кладёт его линовку
   на линовку строки над ним, а не второй линией рядом. */
.doc-note {
  padding: 10px 16px;
  margin-top: -1px;
  border-top: 1px solid var(--color-line-soft);
  font-size: var(--text-sm);
  color: var(--color-ink-muted);
}
.doc-table { overflow-x: auto; }
.doc-table .installers { margin: 0; }
.doc-table td:first-child { width: 40%; }
.doc-table input { width: 100%; min-width: 3em; padding: 5px 7px; font-size: var(--text-sm); }

/* Графа бланка: подпись над полем, а не в серой колонке слева. Колонка съедала 220 px —
   на телефоне форма раздвигала страницу вбок, а в половине листа (карточка) полю
   оставалась сотня пикселей. Линовка между графами и рамка листа — прежние. */
.doc-row {
  display: flex;
  flex-direction: column;
  gap: var(--space-1);
  padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-line-soft);
  min-width: 0;
}
.doc-row:last-of-type { border-bottom: 0; }
.doc-row > .doc-label {
  font-size: var(--text-sm);
  font-weight: 600;
  min-width: 0;
}
/* Подсказка — мелким серым под подписью, обычным шрифтом: моноширинный оставлен меткам. */
.doc-row > .doc-label .hint {
  font-size: var(--text-xs);
  font-weight: 400;
  color: var(--color-ink-muted);
  display: block;
}
.doc-row > .doc-field { display: flex; align-items: center; min-width: 0;
  flex-wrap: wrap; gap: 6px 10px; }
/* Ошибка поля: красная рамка и текст под полем (ui.js ставит фокус на первое). */
.doc-row.has-error > .doc-field :is(input, select, textarea) { border-color: var(--color-bad); }
.doc-row .field-error { color: var(--color-bad); font-size: var(--text-xs); flex-basis: 100%; }
/* Список с подсказкой-ссылкой рядом («Этап» — «настроить воронку»): список берёт ширину
   графы, а ссылка переносится строкой ниже целиком, а не режет его до «Заявка под». */
.doc-row > .doc-field > select { flex: 1 1 10em; min-width: 0; }
/* Одиночное поле занимает графу целиком — на всех бланках одинаково, а не по ширине,
   которую браузер даёт полю по умолчанию. Графы с полем и кнопкой рядом не трогаем. */
.doc-row > .doc-field > :is(input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
  select, textarea):only-child { width: 100%; min-width: 0; }


/* Длинный реквизит («Муниципальное казённое дошкольное…») — textarea, растущая под текст:
   в однострочном поле видно только первые слова. field-sizing — Chrome 123+; где его
   нет, высоту досчитывает скрипт в base.html. */
textarea.grow { field-sizing: content; resize: none; overflow: hidden;
  min-height: calc(1.4em + 16px); }
/* Многострочное поле (запросы, требования, заметки, характеристики) тоже растёт под
   текст, а не прячет половину под прокрутку; переносы в нём — данные, Enter работает. */
textarea.grow-lines { field-sizing: content; min-height: 4.4em; resize: vertical; }
/* Графа с полем и единицей («₽», «мес.», «%») или кнопкой рядом: поле забирает остаток
   ширины, единица стоит вплотную, а не уезжает на свою строку. */
.doc-field.inline { gap: 8px; flex-wrap: wrap; }
.doc-field.inline > :is(input:not([type="checkbox"]):not([type="radio"]):not([type="file"]),
  select, textarea) { flex: 1 1 10em; min-width: 0; }
/* Бланк внутри блока этапа: те же графы, что на страницах форм. Блок уже подписан
   своей шапкой, поэтому лист без .doc-caption. */
.stage-block .doc-sheet { max-width: 760px; margin-bottom: 8px; }

.btn {
  display: inline-block;
  font: 600 var(--text-md)/1 var(--font-body);
  letter-spacing: .02em;
  background: var(--color-primary);
  color: var(--color-on-primary);
  border: 0;
  border-radius: var(--radius-1);
  padding: 13px 26px;
  cursor: pointer;
  text-decoration: none;
  transition: background .12s ease;
}
.btn:hover { background: var(--color-primary-press); }
.btn:disabled { opacity: .55; cursor: wait; }
.btn-row { margin-top: 22px; display: flex; gap: 16px; align-items: center; }

/* ── Плашки состояний ────────────────────────────────────────────────────── */

.note { border: 1px solid; padding: 12px 16px; margin: 18px 0; font-size: var(--text-md);
  overflow-wrap: anywhere; }
.note.error { border-color: var(--color-bad); background: var(--color-bad-bg); color: var(--color-bad); }
.note.warn { border-color: var(--color-accent); background: var(--color-accent-bg); color: var(--color-accent-ink); }
.note.ok { border-color: var(--color-good); background: var(--color-good-bg); color: var(--color-good); }
.note code { font-family: var(--font-mono); font-size: var(--text-sm); }

/* Прогресс долгой операции (подбор идёт минуты) */
.progress-panel { display: none; margin-top: 20px; }
.progress-panel.on { display: block; }
.progress-panel .bar {
  height: 4px; background: var(--color-line-soft); overflow: hidden; position: relative;
}
.progress-panel .bar::after {
  content: "";
  position: absolute; inset: 0; width: 38%;
  background: var(--color-primary);
  animation: slide 1.6s ease-in-out infinite;
}
@keyframes slide {
  0% { transform: translateX(-110%); }
  100% { transform: translateX(290%); }
}
@media (prefers-reduced-motion: reduce) {
  .progress-panel .bar::after { animation: none; width: 100%; opacity: .35; }
  .form-card, .form-card:hover { transition: none; transform: none; }
}

/* ── Таблица подбора (графы как в КС-2) ─────────────────────────────────── */

/* table-layout: fixed — графы держат заданную ширину, а текст переносится ВНУТРИ ячейки.
   Без этого браузер раздаёт ширину по содержимому: длинные описания расползались, а
   наименование позиции сжималось до столбика из отдельных слов. min-width включает
   горизонтальную прокрутку на узком экране вместо сплющивания граф. */
.ks-table { width: 100%; min-width: 1180px; table-layout: fixed;
  border-collapse: collapse; font-size: var(--text-sm); border: 1px solid var(--color-ink); }
.ks-table td, .ks-table th { overflow-wrap: anywhere; }
/* Ширины граф. При table-layout: fixed графы без ширины делят таблицу поровну — в каталоге
   «Позиция» получала те же 20%, что и «Цена» с одним числом, и название шло в столбик.
   Узким графам — класс по содержимому, главная текстовая графа остаётся без класса и
   забирает остаток. */
.ks-table th.w-xs { width: 90px; }
.ks-table th.w-s { width: 120px; }
.ks-table th.w-m { width: 160px; }
.ks-table th.w-l { width: 220px; }
.ks-table th.w-half { width: 34%; }
/* Из какого документа позиция. Появляется только когда смет было несколько — см. шаблон
   проверки подбора: на одной смете подпись в каждой строке ничего не различает. */
.row-doc { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--color-ink-muted);
  margin-top: 3px; }
.ks-table th {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-sm);
  text-align: left;
  padding: 9px 10px;
  border: 1px solid var(--color-line-soft);
  border-bottom: 0;
  background: var(--color-sunken);
}
.ks-table .grafa td {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-ink-muted);
  text-align: center;
  padding: 2px 4px;
  border: 1px solid var(--color-line-soft);
  background: var(--color-sunken);
}
.ks-table tbody:not(.grafa) td {
  padding: 9px 10px;
  border: 1px solid var(--color-line-soft);
  vertical-align: top;
}
.ks-table .num { font-family: var(--font-mono); font-size: var(--text-xs); white-space: nowrap; }
.ks-table tr.manual td { background: var(--color-accent-bg); }
/* Прайс дороже цены заказчика: на этой позиции поставка в минус. */
.ks-table tr.loss td { background: var(--color-bad-bg); }
.ks-table .margin { font-size: var(--text-xs); margin-top: 3px; }
.ks-table .margin.loss { color: var(--color-bad); }
.ks-table .margin.gain { color: var(--color-good); }
/* разделитель блоков в проверке подбора: оборудование / монтажные работы */
.ks-table tr.group td { background: transparent; font-weight: 600; padding-top: 12px; }
.ks-table .src { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--color-ink-muted); margin-top: 3px; }
.ks-table input[type="text"] { width: 100%; min-width: 90px; }
.ks-table input.manual-price { border-color: var(--color-accent); }
/* Остаток на складе: поле и «✓» в одну строку — поле во всю ширину графы выталкивало
   кнопку поверх соседней графы. */
.ks-table .qty-form { display: flex; gap: 6px; align-items: center; }
.ks-table .qty-form input { min-width: 0; flex: 1 1 auto; }
.ks-table .status-mark { font-family: var(--font-mono); font-size: var(--text-xs); white-space: nowrap; }
/* Подобранный товар и поставщик пишутся прямо в графе — переносить их можно и нужно. */
.ks-table .status-mark.offered { white-space: normal; }
.ks-table .status-mark .mark { margin-bottom: 4px; }
/* Список подходящих предложений: цена берётся из отмеченного, а переключают его по марке —
   регистратор одной марки и камеры другой на объекте не дружат. */
.ks-table .offer { display: grid; grid-template-columns: auto 1fr; gap: 6px;
  align-items: start; font-family: var(--font-body); font-size: var(--text-xs); line-height: 1.3;
  padding: 4px 0; border-top: 1px dotted var(--color-line-soft); cursor: pointer; }
.ks-table .offer input { margin-top: 3px; }
.ks-table .offer.picked { font-weight: 600; }
.ks-table .offer .src { margin-top: 2px; font-weight: 400; }
/* Графа «Характеристики»: требование закупки, по которому и идёт подбор. */
.ks-table .specs { font-size: var(--text-xs); line-height: 1.35; color: var(--color-ink-muted); }
.ks-table .specs div { margin-bottom: 2px; }
.ks-table .specs summary { cursor: pointer; font-size: var(--text-xs); font-family: var(--font-mono); }
/* Строки заявки из ЕИС, где подставлена граница условия: сверить с паспортом модели. */
.spec-checks { margin-top: 6px; padding: 4px 8px; font-size: var(--text-xs); line-height: 1.35;
  border: 1px solid var(--color-accent); background: var(--color-accent-bg); color: var(--color-accent-ink); }
.spec-checks summary { cursor: pointer; font-family: var(--font-mono); font-size: var(--text-xs); }
.spec-checks ul { margin: 4px 0 0; padding-left: 16px; }
/* Объекты закупки в карточке: шесть граф помещаются без горизонтальной прокрутки. */
.objects-table { min-width: 720px; }
/* «Условная единица» и прочие длинные единицы — переносом под числом, а не в соседний столбец */
.objects-table .num .unit { white-space: normal; overflow-wrap: break-word; }
.objects-box summary .small { text-transform: none; letter-spacing: 0; }
/* Предложение на проверку: товар найден, но прайс не подтвердил его характеристики.
   Цену подставляет человек отметкой «принять» — молча она в расчёт не попадает. */
.ks-table .status-mark.suggesting { white-space: normal; color: var(--color-ink); }
.ks-table .suggest { display: flex; gap: 6px; align-items: flex-start; text-align: left;
  font-family: inherit; font-size: var(--text-xs); cursor: pointer; }
.ks-table .suggest input { margin-top: 2px; }
.status-matched { color: var(--color-good); }
.status-approximate { color: var(--color-accent); }
.status-none { color: var(--color-bad); }

.table-scroll { overflow-x: auto; }
/* Проверка подбора. Графы 1–7 раньше стояли в пикселях и съедали почти всю min-width —
   графе «Подбор» доставалось 80–200px, и каждое предложение прайса ломалось по слову,
   растягивая строку в высоту. Теперь текстовые графы в процентах, узкие — в пикселях,
   а «Подбор» забирает остаток: на 1440px это ~400px, на широком экране больше. */
.ks-table.calc-review { min-width: 1200px; }
.calc-review .c-num { width: 44px; }
.calc-review .c-inc { width: 64px; overflow-wrap: normal; }
.calc-review .c-name { width: 14%; }
.calc-review .c-specs { width: 15%; }
.calc-review .c-brand { width: 11%; }
.calc-review .c-qty { width: 76px; }
.calc-review .c-price { width: 110px; }
.calc-review .c-cust { width: 124px; }
.calc-review .c-offers { width: 30%; }
.calc-review textarea.grow { width: 100%; font-size: var(--text-sm); line-height: 1.35;
  overflow-wrap: anywhere; }
.calc-review .offer > span { overflow-wrap: break-word; }
.calc-review .offer .src { display: block; }

/* ── Виза «сформировано» ────────────────────────────────────────────────── */

.visa {
  display: inline-block;
  font-family: var(--font-mono);
  font-size: var(--text-md);
  letter-spacing: .18em;
  text-transform: uppercase;
  color: var(--color-primary);
  border: 2px solid var(--color-primary);
  border-radius: var(--radius-1);
  padding: 7px 18px 6px;
  transform: rotate(-2deg);
  margin-bottom: 22px;
}

/* ── Ответ консультанта ─────────────────────────────────────────────────── */

.answer-sheet {
  border: 1px solid var(--color-ink);
  padding: 22px 26px;
  margin-top: 26px;
  white-space: pre-wrap;
}
.sources { margin-top: 18px; }
.sources h3 {
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--color-ink-muted);
  margin: 0 0 8px;
}
.sources ul { margin: 0; padding-left: 22px; font-size: var(--text-sm); color: var(--color-ink-muted); }

/* ── Нижний штамп ───────────────────────────────────────────────────────── */

footer.stamp-foot {
  border-top: 1.5px solid var(--color-ink);
  display: flex;
  font-family: var(--font-mono);
  font-size: var(--text-xs);
  color: var(--color-ink-muted);
  letter-spacing: .05em;
}
footer.stamp-foot > div { padding: 7px 16px; border-right: 1px solid var(--color-line); }
footer.stamp-foot > div:last-child { border-right: 0; margin-left: auto; }

/* ── Адаптив ────────────────────────────────────────────────────────────── */

/* Штамп держится в одну строку: первой уходит подпись под наименованием — она
   декоративна, а сломанная строка выглядит браком. */
@media (max-width: 1199px) {
  .brand-sub { display: none; }
  .brand { padding: 10px 14px; gap: 9px; }
  .brand-mark { height: 32px; }
  .brand-name { font-size: var(--text-xl); }
}

@media (max-width: 767px) {
  .sheet { width: calc(100% - 16px); margin: 10px auto 20px; outline-offset: 3px; }
  main { padding: 22px 18px 30px; }
  /* На телефоне наименование занимает свою строку, а вкладки прокручиваются вбок:
     перенос ряда здесь выглядел бы так же криво, как и на широком экране. */
  .stamp-bar { flex-wrap: wrap; }
  .brand { width: 100%; border-right: 0; border-bottom: 1px solid var(--color-line); }
  /* База 60%: при нулевой вкладки уместились бы в одну строку с наименованием (ширины 0
     хватает всегда) и схлопнулись бы в ничто, а при auto — вытолкнули бы почту
     на третью строку. 60% и переносит ряд, и оставляет место графе пользователя. */
  h1 { font-size: var(--text-2xl); }
  /* Подвал: три графы в ряд на телефоне не помещаются — последняя вылезала за лист и
     раздвигала страницу вбок. Графы встают друг под другом, линовка — горизонтальная. */
  footer.stamp-foot { flex-direction: column; }
  footer.stamp-foot > div { border-right: 0; border-bottom: 1px solid var(--color-line); }
  footer.stamp-foot > div:last-child { border-bottom: 0; margin-left: 0; }
}

@media (max-width: 479px) {
  /* Сравнению тарифов (четыре графы, «Комплектование», «BUSINESS») 320 px не хватает даже
     без полей — таблица прокручивается сама, а лист остаётся на месте. */
  .installers { display: block; overflow-x: auto; }
}
/* Таблицы (сравнение тарифов, реквизиты в оферте) на узком телефоне раздвигали лист:
   поля ужимаются. Перенос посреди слова — только в правовых документах: там в графах
   длинные номера (ОГРНИП, расчётный счёт), а в тарифах он рвал обычные слова. */
@media (max-width: 479px) {
  .installers th { padding: 6px 4px; letter-spacing: 0; }
  .installers td { padding: 7px 4px; }
  .legal .installers td { overflow-wrap: anywhere; }
  /* Формы входа и регистрации: поле ввода по умолчанию шире узкого экрана и распирало
     графу вместе с листом. Графа может сжаться, поле занимает её ширину. */
  .doc-row > .doc-field input:not([type="checkbox"]):not([type="radio"]) { width: 100%; min-width: 0; }
}

/* ══ Модуль «Тендеры»: поиск, канбан, карточка, календарь ═════════════════ */

/* Перенос обязателен: на телефоне шесть пунктов настроек или подменю канбана в одну
   строку не влезают и раздвигали страницу вбок. */
.sub-nav { display: flex; flex-wrap: wrap; gap: 8px 18px; align-items: center;
  margin: 0 0 20px; font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: .04em; }
.sub-nav a { color: var(--color-ink); text-decoration: none; }
.sub-nav a:hover { color: var(--color-primary); }
/* ссылка-кнопка стоит на штамповой сини — текст белый, иначе тонет в фоне */
.sub-nav a.btn, .sub-nav a.btn:hover { color: var(--color-on-primary); }

.btn.small { padding: 8px 16px; font-size: var(--text-sm); text-decoration: none; display: inline-block; }
.small { font-size: var(--text-sm); }

/* поиск */
.search-bar { display: flex; gap: 10px; margin: 0 0 20px; }
.search-bar input { flex: 1; font: var(--text-md)/1.4 var(--font-body); color: var(--color-ink);
  background: var(--color-surface); border: 1px solid var(--color-line); border-radius: var(--radius-1); padding: 10px 12px; }
.search-bar input:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 1px; }

.tender-list { display: flex; flex-direction: column; gap: 2px; }
.tender-item { display: flex; justify-content: space-between; gap: 16px; align-items: center;
  padding: 14px 16px; border: 1px solid var(--color-line-soft); border-left: 3px solid var(--color-primary);
  background: var(--color-surface); }
.tender-item + .tender-item { border-top: 0; }
/* Только что взятая в работу закупка: после возврата на выдачу глаз должен найти
   строку, ради которой нажимали кнопку. */
.tender-item.just { border-left-color: var(--color-good); background: var(--color-good-bg); }
.tender-title { font-weight: 600; color: var(--color-ink); text-decoration: none; display: block; margin-bottom: 6px; }
.tender-title:hover { color: var(--color-primary); }
.tender-meta { display: flex; flex-wrap: wrap; gap: 6px 14px; font-size: var(--text-sm); color: var(--color-ink-muted); }
.tender-meta .price { color: var(--color-ink); font-weight: 600; }
.tender-item-action { flex-shrink: 0; }

.chip { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: .04em; padding: 2px 7px;
  border: 1px solid var(--color-line); border-radius: var(--radius-1); color: var(--color-primary); background: var(--color-surface-raised); white-space: nowrap; }
.chip.done { color: var(--color-good); border-color: var(--color-good); }
.chip.mini { font-size: var(--text-xs); padding: 1px 5px; color: var(--color-ink-muted); }
/* Способ закупки (core/tenders/methods.py): первым значком в строке и с заливкой — от
   него зависит тактика, поэтому он должен читаться раньше закона и цены. Цвет по виду. */
.chip.method { font-family: var(--font-body); font-weight: 600; font-size: var(--text-xs); letter-spacing: 0;
  color: var(--color-ink); border-color: var(--color-line); background: var(--color-bg); }
.chip.method.m-auction { color: var(--color-primary); border-color: var(--color-primary); background: var(--color-primary-bg); }
.chip.method.m-quote { color: var(--color-good); border-color: var(--color-good); background: var(--color-good-bg); }
.chip.method.m-proposal { color: var(--color-violet); border-color: var(--color-violet); background: var(--color-violet-bg); }
.chip.method.m-contest { color: var(--color-warn); border-color: var(--color-warn-dot); background: var(--color-warn-bg); }
.chip.method.m-small, .chip.method.m-single { color: var(--color-accent); border-color: var(--color-accent); background: var(--color-accent-bg); }
.chip.method.big { font-size: var(--text-sm); padding: 4px 10px; }
.method-line { margin: 4px 0 2px; display: flex; gap: 10px; align-items: center; flex-wrap: wrap; }
/* «На площадку» в выдаче: рабочая ссылка и её запертый близнец на бесплатном тарифе.
   Замок не прячем — вкладки в шапке заперты по той же причине: невидимую функцию
   не покупают. */
a.chip.link { color: var(--color-good); border-color: var(--color-good); text-decoration: none; }
a.chip.link:hover { background: var(--color-good-bg); }
a.chip.locked { color: var(--color-ink-muted); border-style: dashed; text-decoration: none; }
a.chip.locked:hover { color: var(--color-accent); border-color: var(--color-accent); }

/* канбан */
.deadlines-week ul { margin: 6px 0 0; padding-left: 18px; }
.deadlines-week a { color: inherit; }
.kanban { position: relative; display: flex; gap: 12px; overflow-x: auto; padding-bottom: 10px; }
/* Вторая полоса прокрутки сверху: доска в девять колонок шире экрана, и тянуться каждый
   раз к нижнему краю неудобно. Распорку по ширине доски проставляет скрипт. */
.kanban-scroll { overflow-x: auto; overflow-y: hidden; }
.kanban-rail { height: 1px; }
.kanban-col { flex: 0 0 220px; background: var(--color-sunken); border: 1px solid var(--color-line-soft);
  border-top: 3px solid var(--stage, var(--color-line)); }
.kanban-col-head { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: .04em;
  text-transform: uppercase; padding: 8px 10px; border-bottom: 1px solid var(--color-line-soft);
  color: var(--color-primary); display: flex; justify-content: space-between; }
.kanban-col-head .count { color: var(--color-ink-muted); }
.kanban-card { position: relative; background: var(--color-surface); border: 1px solid var(--color-line-soft); margin: 8px; padding: 10px; }
/* Плитка, которую только что перевели стрелкой или селектом: короткая вспышка, чтобы глаз
   нашёл её на новом месте. */
.kanban-card.just-moved { animation: just-moved 1.6s ease-out; }
@keyframes just-moved { from { box-shadow: 0 0 0 3px var(--color-primary); } to { box-shadow: 0 0 0 3px transparent; } }
/* Перетаскивание мышью: плитка-оригинал бледнеет, колонка под курсором подсвечивается
   цветом этапа. Ссылки и кнопки внутри работают как раньше. */
.kanban-card[draggable="true"] { cursor: grab; }
.kanban-card[draggable="true"]:active { cursor: grabbing; }
.kanban-card a, .kanban-card button, .kanban-card select { cursor: pointer; }
.kanban-card.dragging { opacity: .4; }
.kanban-col.drop-over { outline: 2px dashed var(--stage, var(--color-primary)); outline-offset: -2px; }
.kanban-card-title { font-weight: 600; font-size: var(--text-sm); color: var(--color-ink); text-decoration: none; display: block; }
.kanban-card-title:hover { color: var(--color-primary); }
.kanban-card-meta { font-size: var(--text-xs); color: var(--color-ink-muted); margin-top: 6px; display: flex; gap: 4px 8px; align-items: center; flex-wrap: wrap; }
.kanban-card-price { white-space: nowrap; }
/* Способ закупки на плитке: своей строкой и с переносом — колонка узкая (220px). */
.kanban-card-method { margin-top: 6px; }
.kanban-card-method .chip.method { white-space: normal; display: inline-block; max-width: 100%; }
.kanban-col { min-width: 0; }
/* Ключевых дат на плитке до трёх (подача, подписание, исполнение): первая отбивается
   от точек прогресса, следующие идут строками вплотную. Просроченная — красная. */
.kanban-card-deadline { font-size: var(--text-xs); color: var(--color-accent); margin-top: 6px; }
.kanban-card-deadline + .kanban-card-deadline { margin-top: 2px; }
.kanban-card-deadline.overdue { color: var(--color-bad); font-weight: 600; }
.kanban-card-actions { display: flex; gap: 6px; align-items: center; margin-top: 8px; }
.kanban-card-actions .status-move { flex: 1; min-width: 0; margin-top: 0; }
.kanban-card-actions .link-btn { font-size: var(--text-sm); line-height: 1; padding: 4px 3px; }
.status-move { margin-top: 8px; }

/* Архив под доской: закрытые этапы («Завершён», «Проиграно») колонками не рисуются —
   копятся годами и растягивали бы канбан. Вкладка на этап, таблица со своей прокруткой. */
.archive { margin-top: 22px; border: 1px solid var(--color-line-soft); background: var(--color-surface); }
.archive > summary { cursor: pointer; padding: 10px 14px; display: flex; flex-wrap: wrap;
  gap: 4px 14px; align-items: baseline; font-family: var(--font-mono); font-size: var(--text-xs);
  letter-spacing: .04em; text-transform: uppercase; color: var(--color-primary); }
.archive-count { color: var(--color-ink-muted); text-transform: none; letter-spacing: 0; }
/* Доски канбана: вкладки над сводкой. Активная — штамповой синью сверху. */
.board-tabs { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 18px; }
.board-tabs a { font-family: var(--font-mono); font-size: var(--text-xs); padding: 6px 12px; color: var(--color-ink);
  text-decoration: none; background: var(--color-surface); border: 1px solid var(--color-line-soft);
  border-top: 3px solid var(--color-line); }
.board-tabs a:hover { color: var(--color-primary); }
.board-tabs a.active { color: var(--color-primary); border-top-color: var(--color-primary); }
.board-tabs .count { color: var(--color-ink-muted); margin-left: 4px; }

/* Настройки → Команда: строка доски — название, участники, кнопки. */
.board-edit { display: flex; flex-wrap: wrap; align-items: center; gap: 8px 14px;
  padding: 10px 0; border-bottom: 1px solid var(--color-line-soft); }
.board-edit input[type="text"] { min-width: 0; flex: 0 1 240px; }
.board-edit .board-people { display: flex; flex-wrap: wrap; gap: 4px 14px; flex: 1 1 260px;
  font-size: var(--text-sm); overflow-wrap: anywhere; }

.archive-tabs { display: flex; flex-wrap: wrap; gap: 6px; padding: 0 14px 10px; }
.archive-tabs a { font-family: var(--font-mono); font-size: var(--text-xs); padding: 4px 10px; color: var(--color-ink);
  text-decoration: none; border: 1px solid var(--color-line-soft);
  border-top: 3px solid var(--stage, var(--color-line)); }
.archive-tabs a.active { background: var(--color-sunken); color: var(--color-primary); }
.archive-tabs .count { color: var(--color-ink-muted); margin-left: 4px; }
.archive-scroll { overflow-x: auto; padding: 0 14px 14px; }
.archive-empty { padding: 0 14px 14px; margin: 0; }
.archive-table { width: 100%; border-collapse: collapse; font-size: var(--text-sm); }
.archive-table th { text-align: left; font-family: var(--font-mono); font-size: var(--text-xs); font-weight: 400;
  letter-spacing: .04em; text-transform: uppercase; color: var(--color-ink-muted); white-space: nowrap;
  border-bottom: 1px solid var(--color-line); padding: 6px 8px; }
.archive-table td { border-bottom: 1px solid var(--color-line-soft); padding: 7px 8px; vertical-align: top; }
.archive-table td:first-child { min-width: 220px; }
.archive-table td a { color: var(--color-ink); text-decoration: none; font-weight: 600; }
.archive-table td a:hover { color: var(--color-primary); }
.archive-table .num { text-align: right; }
.archive-table .num, .archive-table .date { font-family: var(--font-mono); font-size: var(--text-xs); white-space: nowrap; }
.archive-table .overdue { color: var(--color-bad); font-weight: 600; }
.archive-table .link-btn { white-space: nowrap; font-size: var(--text-sm); }
.status-move select, .deadline-add select, .card-grid select, .deadline-add input {
  font: var(--text-sm) var(--font-body); border: 1px solid var(--color-line); border-radius: var(--radius-1); padding: 5px 7px; background: var(--color-surface); width: 100%; }

/* карточка */
.link-row { margin: 18px 0 4px; }
.card-grid { display: grid; grid-template-columns: 1.2fr 1fr; gap: 26px; margin-top: 22px; align-items: start; }
/* Кнопка под бланком, а за ней строка поиска (склад): без отступа они слипались. */
.btn-row + .search-form { margin-top: 20px; }
.deadlines-box h3, .history summary { font-weight: 600; font-size: var(--text-md); }
.deadline-list { list-style: none; padding: 0; margin: 0 0 14px; }
.deadline-list li { display: flex; align-items: center; gap: 8px; padding: 7px 0;
  border-bottom: 1px solid var(--color-line-soft); font-size: var(--text-sm); }
.deadline-list .dl-date { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--color-ink); white-space: nowrap; }
.deadline-list .dl-label { flex: 1; color: var(--color-ink-muted); }
.deadline-add { display: flex; gap: 8px; align-items: center; }
.deadline-add select { width: auto; flex: 1; }
.inline { display: inline; }
.link-btn { background: none; border: 0; color: var(--color-ink); cursor: pointer; font-size: var(--text-sm); padding: 0 2px; }
.link-btn:hover { color: var(--color-bad); }
.history { margin-top: 26px; font-size: var(--text-sm); color: var(--color-ink-muted); }
.history ul { padding-left: 18px; }
.tender-context { border-color: var(--color-primary); background: var(--color-primary-bg); color: var(--color-primary-press); }
.tender-context a { color: var(--color-primary); text-decoration: none; }

/* календарь */
.calendar-list { list-style: none; padding: 0; margin: 0; }
.calendar-list li { display: flex; gap: 18px; padding: 12px 0; border-bottom: 1px solid var(--color-line-soft); }
.cal-date { font-family: var(--font-mono); font-size: var(--text-sm); color: var(--color-ink-muted); min-width: 90px;
  display: flex; flex-direction: column; }
.cal-date b { color: var(--color-primary); font-size: var(--text-md); }
.cal-kind { display: block; font-size: var(--text-xs); color: var(--color-ink-muted); text-transform: uppercase; letter-spacing: .04em; }
.cal-body a { color: var(--color-ink); text-decoration: none; font-weight: 600; }
.cal-body a:hover { color: var(--color-primary); }

@media (max-width: 767px) {
  .card-grid { grid-template-columns: 1fr; }
  .tender-item { flex-direction: column; align-items: flex-start; }
}

/* ── Тендеры: аналитика (стат-плитки) и фильтры поиска ──────────────────── */
.stat-row { display: flex; flex-wrap: wrap; gap: 10px; margin: 0 0 22px; }
.stat-tile { flex: 1 1 92px; border: 1px solid var(--color-line-soft); border-top: 3px solid var(--color-line);
  background: var(--color-surface); padding: 10px 12px; display: flex; flex-direction: column; gap: 2px; }
.stat-tile.wide { flex: 1 1 150px; }
.stat-tile .num { font-weight: 600; font-size: var(--text-xl); line-height: 1.1; color: var(--color-ink);
  font-variant-numeric: tabular-nums; }
.stat-tile .lbl { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: .04em; color: var(--color-ink-muted); text-transform: uppercase; }
.stat-tile.won { border-top-color: var(--color-good); }
.stat-tile.won .num { color: var(--color-good); }
.stat-tile.rejected { border-top-color: var(--color-bad); }
.stat-tile.rejected .num { color: var(--color-bad); }
a.stat-tile { text-decoration: none; }
a.stat-tile:hover { border-top-color: var(--color-accent); }
.stat-tile.hot { border-top-color: var(--color-accent); }
.stat-tile.hot .num { color: var(--color-accent); }

/* ── Главная вошедшего: сводка (core/dashboard.py) ──────────────────────── */
.dash-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(280px, 1fr));
  gap: 14px; margin: 0 0 26px; }
.dash-panel { border: 1px solid var(--color-line-soft); background: var(--color-surface); padding: 12px 14px;
  min-width: 0; }
.dash-panel h2 { font-size: var(--text-lg); margin: 0 0 10px; }
.dash-list { list-style: none; margin: 0 0 10px; padding: 0; display: flex;
  flex-direction: column; gap: 7px; }
.dash-list li { font-size: var(--text-md); overflow-wrap: anywhere; }
.dash-when { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--color-ink-muted); margin-right: 4px; }
.dash-verdicts { display: flex; flex-wrap: wrap; gap: 6px; margin: 0 0 10px; }
.dash-tools { display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 20px; }
.dash-count { margin: 0 0 8px; }
.dash-count a { font-weight: 600; font-size: var(--text-2xl); font-variant-numeric: tabular-nums; line-height: 1; text-decoration: none;
  color: var(--color-accent); margin-right: 6px; }
.link-btn.watching { color: var(--color-good); }
.watch-error { color: var(--color-accent); overflow-wrap: anywhere; }
.dash-setup { border-color: var(--color-accent); }

/* ── Мастер первой настройки /start (portal/onboarding.py) ──────────────── */
.wizard { display: grid; grid-template-columns: minmax(180px, 240px) minmax(0, 1fr); gap: 28px;
  margin: 8px 0 24px; }
.wizard-steps { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column;
  gap: 10px; }
.wizard-steps li { font-size: var(--text-md); padding-left: 2em; position: relative; }
.wizard-steps .mark { position: absolute; left: 0; font-family: var(--font-mono); color: var(--color-ink-muted); }
.wizard-steps li.done .mark { color: var(--color-good); }
.wizard-steps li.current a { color: var(--color-ink); font-weight: 600; text-decoration: none; }
.wizard-body { min-width: 0; }
.wizard-inline { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }
.wizard-inline input { flex: 1 1 160px; min-width: 0; }
.wizard-foot { display: flex; flex-wrap: wrap; gap: 16px; align-items: center;
  margin-top: 22px; padding-top: 12px; border-top: 1px solid var(--color-line-soft); }
.wizard-head { display: flex; flex-wrap: wrap; gap: 4px 16px; align-items: baseline; }
.wizard-skip { font-family: var(--font-body); letter-spacing: 0; text-transform: none;
  font-size: var(--text-sm); }
@media (max-width: 767px) {
  .wizard { grid-template-columns: minmax(0, 1fr); gap: 16px; }
  /* На телефоне список шагов занимал полэкрана над формой: «шаг N из M» уже в заголовке,
     оставляем только номера-отметки строкой. */
  .wizard-steps { flex-direction: row; flex-wrap: wrap; gap: 6px; }
  .wizard-steps li { padding-left: 0; }
  .wizard-steps li .muted, .wizard-steps li a { display: none; }
  .wizard-steps .mark { position: static; display: inline-block; min-width: 1.8em; padding: 2px 6px;
    text-align: center; border: 1px solid var(--color-line-soft); }
  .wizard-steps li.current .mark { border-color: var(--color-ink); color: var(--color-ink); }
}

.search-form { margin: 0 0 20px; }
.search-form .search-bar { margin: 0 0 10px; }
.search-filters { display: flex; flex-wrap: wrap; gap: 10px; }
.search-filters select, .search-filters input {
  font: var(--text-sm)/1.4 var(--font-body); color: var(--color-ink); background: var(--color-surface);
  border: 1px solid var(--color-line); border-radius: var(--radius-1); padding: 8px 10px; }
.search-filters input { max-width: 150px; }
.search-filters .price-field { display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--text-sm); color: var(--color-ink-muted); }
.search-filters .price-field input { width: 130px; }
.search-more > summary { display: none; }
.tracked-now { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
@media (max-width: 767px) {
  /* Телефон: выдача — выше. Подсказки к уже введённому запросу и фильтры сворачиваются. */
  .lead.has-query, .search-form .search-hint { display: none; }
  .search-more > summary { display: block; cursor: pointer; padding: 10px 0; font-weight: 600; }
  .tracked-now { align-items: flex-start; }
}
.search-filters select:focus-visible, .search-filters input:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 1px; }

/* расширенный поиск: варианты строками, минус-слова, выбор галочками, сохранённые поиски */
.search-bar textarea { flex: 1; font: var(--text-md)/1.4 var(--font-body); color: var(--color-ink); resize: vertical;
  background: var(--color-surface); border: 1px solid var(--color-line); border-radius: var(--radius-1); padding: 10px 12px; }
.search-bar textarea:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 1px; }
.search-bar-multi { align-items: flex-start; }
.search-hint { margin: -4px 0 10px; }
.search-filters input.wide { max-width: 320px; flex: 1 1 220px; }
.multi-pick { position: relative; }
.multi-pick > summary { cursor: pointer; list-style: none; white-space: nowrap;
  font: var(--text-sm)/1.4 var(--font-body); color: var(--color-ink); background: var(--color-surface);
  border: 1px solid var(--color-line); border-radius: var(--radius-1); padding: 8px 10px; }
.multi-pick > summary::-webkit-details-marker { display: none; }
.multi-pick > summary::after { content: "▾"; margin-left: 6px; font-size: var(--text-xs); }
.multi-pick[open] > summary::after { content: "▴"; }
.multi-pick-body { position: absolute; z-index: 30; top: calc(100% + 4px); left: 0;
  width: min(640px, 92vw); max-height: 60vh; overflow: auto; padding: 12px 14px;
  background: var(--color-surface); border: 1px solid var(--color-line); box-shadow: var(--shadow-pop); }
.multi-pick-group { border: 0; margin: 0 0 12px; padding: 0; columns: 2 220px; column-gap: 18px; }
.multi-pick-group legend { font-weight: 600; margin: 0 0 4px; padding: 0; }
.multi-pick-group legend .check { color: var(--color-ink); }
.multi-pick .check { display: flex; align-items: flex-start; gap: 6px; font-size: var(--text-sm);
  line-height: 1.5; padding: 1px 0; break-inside: avoid; }
.multi-pick .check input { margin: 3px 0 0; flex: none; }
/* Кнопка всегда видна у нижнего края списка — не надо листать все округа до конца. */
.multi-pick-actions { position: sticky; bottom: -12px; margin: 0 -14px -12px; padding: 10px 14px;
  background: var(--color-surface); border-top: 1px solid var(--color-line-soft); }
/* Внутри большой формы (мастер, профиль агента) список раскрывается в потоке и сдвигает
   поля ниже, а не накрывает их вместе с кнопкой сохранения. */
.multi-pick.inline > summary::after { float: right; }
.multi-pick.inline .multi-pick-body { position: static; width: auto; max-height: 50vh;
  margin-top: -1px; box-shadow: none; }
@media (max-width: 767px) {
  .multi-pick[open] { flex-basis: 100%; }
  .multi-pick-body { position: static; width: auto; margin-top: -1px; box-shadow: none; }
  .multi-pick > summary { white-space: normal; }
}
.saved-searches { display: flex; flex-wrap: wrap; gap: 6px 10px; align-items: center; margin: 0 0 12px; }
.saved-search { display: inline-flex; align-items: center; gap: 2px; font-size: var(--text-sm);
  border: 1px solid var(--color-line-soft); background: var(--color-surface); padding: 2px 4px 2px 8px; }
.saved-search a { color: var(--color-primary); text-decoration: none; }
.saved-search a:hover { text-decoration: underline; }
.saved-search form { display: inline; margin: 0; }
.save-search { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin: 0 0 12px; }
.save-search input { font: var(--text-sm)/1.4 var(--font-body); border: 1px solid var(--color-line);
  border-radius: var(--radius-1); padding: 6px 8px; min-width: 220px; }

/* пагинация выдачи и правка тендера */
.pager { display: flex; gap: 16px; align-items: center; margin: 20px 0 6px;
  font-family: var(--font-mono); font-size: var(--text-sm); }
.pager a { color: var(--color-primary); text-decoration: none; }
.pager a:hover { text-decoration: underline; }
.show-more { display: block; width: 100%; margin: 20px 0 6px; }
.edit-tender { margin: 18px 0; border: 1px solid var(--color-line-soft); }
.edit-tender > summary { cursor: pointer; padding: 10px 14px; font-family: var(--font-mono);
  font-size: var(--text-xs); letter-spacing: .04em; color: var(--color-primary); background: var(--color-sunken); }
.edit-tender[open] > summary { border-bottom: 1px solid var(--color-line-soft); }
.edit-tender .doc { margin: 0; border: 0; }

/* файлы карточки, исполнители */
.chip.warn { color: var(--color-accent); border-color: var(--color-accent); background: var(--color-accent-bg); }
.kanban-card-installer { font-size: var(--text-xs); color: var(--color-ink-muted); margin-top: 6px; }
.kanban-card-installer.warn { color: var(--color-accent); }

.files-box { margin-top: 26px; border-top: 1px solid var(--color-line-soft); padding-top: 16px; }
.files-box h3 { font-weight: 600; font-size: var(--text-md); }
.files-head { display: flex; align-items: center; justify-content: space-between;
  gap: 12px; flex-wrap: wrap; }
.file-group-head { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: .04em;
  text-transform: uppercase; color: var(--color-primary); margin-top: 12px; }
.file-list { list-style: none; padding: 0; margin: 4px 0 0; }
.file-list li { display: flex; align-items: center; gap: 10px; padding: 6px 0;
  border-bottom: 1px solid var(--color-line-soft); font-size: var(--text-sm); }
.file-list a { color: var(--color-ink); }
.file-list .file-note { flex: 1; color: var(--color-ink-muted); font-size: var(--text-sm); }
.file-list .file-dl { color: var(--color-ink-muted); text-decoration: none; font-size: var(--text-sm); }
.file-list a[data-view] { cursor: zoom-in; }
.file-list .file-kind { margin-left: auto; }
.file-list .file-note + .file-kind { margin-left: 0; }
.file-list .file-kind select { font-size: var(--text-xs); padding: 2px 4px; color: var(--color-ink-muted);
  background: transparent; border: 1px solid var(--color-line-soft); border-radius: 4px; }

/* просмотр файла поверх карточки */
.doc-viewer { width: min(1200px, 100vw - 24px); height: calc(100vh - 24px); max-width: none;
  max-height: none; padding: 0; border: 1px solid var(--color-line); border-radius: var(--radius-1);
  background: var(--color-surface); flex-direction: column; }
.doc-viewer[open] { display: flex; }
.doc-viewer::backdrop { background: var(--color-overlay); }
.doc-viewer-bar { display: flex; align-items: center; gap: 10px; padding: 8px 12px;
  border-bottom: 1px solid var(--color-line-soft); }
.doc-viewer-bar .link-btn { font-size: var(--text-lg); }
.doc-viewer-name { flex: 1; min-width: 0; overflow: hidden; text-overflow: ellipsis;
  white-space: nowrap; font-weight: 500; }
.doc-viewer-wait { padding: 8px 12px; color: var(--color-ink-muted); font-size: var(--text-sm); }
.doc-viewer-frame { flex: 1; width: 100%; border: 0; background: var(--color-surface-raised); }
@media (max-width: 767px) {
  .doc-viewer { width: 100vw; height: 100vh; border: 0; }
  .doc-viewer-pos, .doc-viewer-dl { display: none; }
}

.eis-docs { display: flex; flex-wrap: wrap; gap: 10px; align-items: center; margin: 10px 0 4px; }
.file-add { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-top: 14px; }
.file-add select, .file-add input[type="text"], .file-add input[type="file"] {
  font: var(--text-sm) var(--font-body); border: 1px solid var(--color-line); border-radius: var(--radius-1);
  padding: 5px 7px; background: var(--color-surface); }
.file-add input[type="text"] { flex: 1; min-width: 160px; }

.installers { width: 100%; border-collapse: collapse; font-size: var(--text-sm); margin-bottom: 18px; }
.installers th { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: .04em;
  text-transform: uppercase; color: var(--color-primary); text-align: left;
  border-bottom: 1px solid var(--color-line); padding: 6px 8px; }
.installers td { padding: 8px; border-bottom: 1px solid var(--color-line-soft); }
.installers tr.archived td { color: var(--color-ink-muted); }
/* Справочник исполнителей правится прямо в строке: поля тянутся по графе, а не по
   умолчанию браузера, иначе длинная почта обрезается. Пять граф с полями в телефон не
   влезают — таблица прокручивается вбок внутри .table-scroll, а не жмёт «Иванов И.И.»
   до «Иванов И». */
.installers input[type="text"], .installers input[type="email"] {
  width: 100%; min-width: 0; padding: 5px 7px; font-size: var(--text-sm); }
.installers-edit { min-width: 720px; }
.installers-edit .row-actions { gap: 10px; }
/* Команда: расход ИИ «N из [потолок] задать» одной строкой. */
.ai-limit { display: flex; align-items: center; gap: 6px; white-space: nowrap; }
.installers .ai-limit input[type="text"] { width: 5.5em; }

.installer-add { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.installer-add input { font: var(--text-sm) var(--font-body); border: 1px solid var(--color-line);
  border-radius: var(--radius-1); padding: 8px 10px; background: var(--color-surface); }

/* каталог прайсов */
.prices-table td { vertical-align: middle; }
.prices-table tr.archived td, .ks-table tr.archived td { color: var(--color-ink-muted); }
.section-h { font-weight: 600; font-size: var(--text-lg); margin: 26px 0 10px; }
.price-supplier { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.price-supplier select, .price-supplier input { font: var(--text-sm) var(--font-body); padding: 6px 8px;
  border: 1px solid var(--color-line); border-radius: var(--radius-1); background: var(--color-surface); }
.catalog-panel { display: flex; flex-wrap: wrap; gap: 8px 12px; align-items: center; }
.catalog-suppliers { display: flex; flex-wrap: wrap; gap: 6px; }
.gone-list { columns: 2; font-size: var(--text-sm); color: var(--color-ink-muted); }
.check { font-size: var(--text-sm); color: var(--color-ink-muted); display: flex; align-items: center; gap: 6px; }
/* Длинная подпись у галочки (согласия при регистрации) — один элемент, который переносится. */
.check > span { min-width: 0; }
@media (max-width: 767px) {
  /* Согласия в формах — под палец, а не 13 пикселей, в которые приходится целиться. */
  .doc .check input[type=checkbox] { width: 22px; height: 22px; flex: none; }
}
.rename { display: flex; gap: 6px; align-items: center; }
.rename input { font: var(--text-sm) var(--font-body); padding: 4px 6px; border: 1px solid var(--color-line);
  border-radius: var(--radius-1); background: var(--color-surface); width: 150px; flex: 1 1 auto; }
/* описание позиции: показываем целиком, но не даём таблице разъехаться */
.item-desc { max-height: 4.5em; overflow-y: auto; white-space: normal; max-width: 520px; }

/* отчётность по периодам: выбор разреза и таблица разбивки */
.report-picker { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
.report-picker select { font: var(--text-sm) var(--font-body); padding: 6px 8px; border: 1px solid var(--color-line);
  border-radius: var(--radius-1); background: var(--color-surface); }
.report-table tr.current td { background: var(--color-accent-bg); font-weight: 600; }
.report-table tr.empty td { color: var(--color-ink-muted); }
.report-table tr.total td { border-top: 2px solid var(--color-ink); font-weight: 700; }

/* --- «Заявка»: массовая простановка страны и таблица позиций ------------------------- */
.bulk-row { display: flex; gap: 10px; align-items: center; flex-wrap: wrap;
  margin: 18px 0 10px; font-size: var(--text-sm); }
.bulk-row input { font: var(--text-sm) var(--font-body); border: 1px solid var(--color-line);
  padding: 7px 10px; background: var(--color-surface-raised); width: 170px; }
.bid-table textarea { width: 100%; font: var(--text-sm) var(--font-body); border: 1px solid var(--color-line);
  padding: 6px 8px; background: var(--color-surface-raised); }
.bid-table textarea.grow-lines { resize: vertical; min-height: 62px; }
.bid-table textarea.grow { line-height: 1.35; overflow-wrap: anywhere; }
.bid-table input[type=text] { width: 100%; font: var(--text-sm) var(--font-body); padding: 6px 8px; }
.bid-table td { vertical-align: top; }
/* Графы заявки. Наименование и товарный знак — растущие поля: в однострочном
   «Видеорегистратор IP 16-канальный Hikvision…» обрывался на третьем слове. */
.bid-table .c-inc { width: 64px; overflow-wrap: normal; }
.bid-table .c-num { width: 140px; }
.bid-table td .src { overflow-wrap: break-word; }
.bid-table .c-name { width: 22%; }
.bid-table .c-brand { width: 16%; }
.bid-table .c-country { width: 220px; }

/* --- «Реквизиты»: действия в строке профиля ------------------------------------------ */
.row-actions { display: flex; gap: 12px; align-items: center; white-space: nowrap; }
.link-btn.danger { color: var(--color-bad); }
.btn.secondary { background: transparent; color: var(--color-primary); border: 1px solid var(--color-primary); }
.btn.secondary:hover { background: var(--color-primary); color: var(--color-on-primary); }

/* --- админка подписок ------------------------------------------------------------------ */
.admin-nav a.active { color: var(--color-primary); border-bottom: 2px solid var(--color-primary); }
.admin-stats { display: flex; flex-wrap: wrap; gap: 12px; margin: 0 0 26px; }
.admin-stat { flex: 1 1 150px; border: 1px solid var(--color-line); padding: 12px 14px;
  display: flex; flex-direction: column; gap: 4px; }
.admin-stat .num { font-weight: 600; font-size: var(--text-2xl); font-variant-numeric: tabular-nums; color: var(--color-ink);
  text-decoration: none; }
.admin-stat .lbl { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--color-ink-muted); }
.admin-stat.hot { border-color: var(--color-accent); background: var(--color-accent-bg); }
.extend-row { display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }

/* Ворон (ИИ-агент) в карточке: кнопка, ход шагов. Иконка — ворон из логотипа. */
.raven-ico { width: 1.3em; height: 1.3em; vertical-align: -0.3em; }
.agent-panel { margin: 16px 0; padding: 12px 14px; border: 1px dashed var(--color-primary);
  background: var(--color-primary-bg); display: flex; flex-wrap: wrap; gap: 8px 14px; align-items: center; }
.agent-busy { color: var(--color-primary-press); font-weight: 600; }
.agent-steps { list-style: none; margin: 4px 0 0; padding: 0; width: 100%; font-size: var(--text-sm); }
.agent-result { width: 100%; }
.agent-result > summary { cursor: pointer; list-style: none; display: flex; flex-wrap: wrap; gap: 4px 10px; align-items: baseline; }
.agent-result > summary::-webkit-details-marker { display: none; }
.agent-toggle { color: var(--color-primary); font-size: var(--text-sm); }
.agent-result[open] .when-closed, .agent-result:not([open]) .when-open { display: none; }
.agent-err { color: var(--color-bad); }
.agent-step { padding: 3px 0; }
.agent-mark { display: inline-block; width: 1.2em; font-weight: 700; }
.agent-step.ok .agent-mark { color: var(--color-good); }
.agent-step.error .agent-mark { color: var(--color-bad); }
.agent-step.skip { color: var(--color-ink-muted); }
/* Вердикт агента: на канбане и в списке рассмотренного. */
.verdict-chip.go { color: var(--color-good); border-color: var(--color-good);
  background: var(--color-good-bg); }
.verdict-chip.caution { color: var(--color-warn); border-color: var(--color-warn-dot); }
.verdict-chip.stop { color: var(--color-ink-muted); }
.verdict-chip.unknown { color: var(--color-ink-muted); border-style: dashed; }
/* Шаг «Что ищете» мастера: подпись над полем, одинаковые отступы между полями. */
.wizard-form { display: flex; flex-direction: column; gap: 16px; }
.wizard-form > label, .wizard-form .wizard-label { display: flex; flex-direction: column; gap: 6px; }
.wizard-form .btn-row { margin-top: 4px; }
.wizard-form .agent-row { display: flex; flex-wrap: wrap; gap: 10px 18px; }
.wizard-form .agent-row label { display: flex; flex-direction: column; gap: 6px; flex: 1 1 160px; }

/* Чат по карточке: реплики человека и агента, шаги инструментов мелко — откуда ответ. */
.card-chat { margin: 26px 0 0; border-top: 1px solid var(--color-line); padding-top: 16px; }
.chat-log { list-style: none; margin: 0 0 12px; padding: 0; display: flex;
  flex-direction: column; gap: 8px; }
.chat-msg { max-width: 80%; padding: 8px 12px; font-size: var(--text-sm); white-space: pre-wrap; }
.chat-msg.user { align-self: flex-end; background: var(--color-primary-bg); border: 1px solid var(--color-line-soft); }
.chat-msg.assistant { align-self: flex-start; background: var(--color-surface);
  border: 1px solid var(--color-line); }
.chat-msg.tool { align-self: flex-start; padding: 0 12px; font-family: var(--font-mono);
  font-size: var(--text-xs); color: var(--color-ink-muted); }
.chat-form { display: flex; gap: 8px; align-items: flex-end; flex-wrap: wrap; }
.chat-form textarea { flex: 1 1 320px; min-height: 2.6em; }
@media (max-width: 767px) { .chat-msg { max-width: 100%; } }

/* Ориентир снижения по похожим закупкам: в блоке торгов и на странице анализа проигранных тендеров. */
.hint-line { margin: 8px 0 0; padding: 6px 10px; font-size: var(--text-sm); color: var(--color-primary-press);
  background: var(--color-primary-bg); border-left: 3px solid var(--color-primary); }
.reset-link { word-break: break-all; }
/* Пробный период — сведение, а не тревога: штамповая синь, а не сурик квоты. */
.trial-bar {
  border: 1px solid var(--color-primary);
  background: var(--color-primary-bg);
  color: var(--color-primary-press);
  padding: 8px 16px;
  margin: 0 0 18px;
  font-size: var(--text-sm);
}
.quota-bar {
  border: 1px solid var(--color-accent);
  background: var(--color-accent-bg);
  color: var(--color-accent-ink);
  padding: 10px 16px;
  margin: 0 0 18px;
  font-size: var(--text-sm);
}
.plan-grid {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(220px, 1fr));
  gap: 18px;
  margin: 22px 0;
}
.plan-card { border: 1px solid var(--color-ink); padding: 18px 18px 20px; background: var(--color-surface); }
.plan-card.current { box-shadow: 3px 3px 0 var(--color-primary); }
.plan-card h2 { margin: 0 0 4px; font-size: var(--text-xl); }
.plan-card .price { font-family: var(--font-mono); font-size: var(--text-xl); margin: 6px 0 2px; }
.plan-card .year { color: var(--color-ink-muted); font-size: var(--text-sm); margin-bottom: 12px; }
.plan-card ul { margin: 12px 0 0; padding-left: 18px; font-size: var(--text-sm); }
.plan-card li { margin-bottom: 5px; }
.plan-card .chip { display: inline-block; margin-bottom: 8px; }

.form-card.locked { opacity: .78; }
.form-card.locked .lock { font-size: var(--text-xs); }
/* Кнопка-контур. Определение одно на весь портал: раньше их было два, и при наведении
   белый текст из первого ложился на белый фон второго — кнопка становилась пустой. */
.btn.ghost {
  background: transparent;
  color: var(--color-ink);
  border: 1px solid var(--color-ink);
}
.btn.ghost:hover { background: var(--color-hover); color: var(--color-ink); }


/* ── этапы воронки: цвет, шаг по этапам, редактор ─────────────────────────────────────── */

/* Цвет этапа — ключ палитры, а не произвольный hex: лист свёрстан на нескольких чернилах,
   и свободный цвет из него выпадает. Одна переменная --stage красит и колонку, и панель. */
.stage-c-grey   { --stage: var(--color-line); }
.stage-c-blue   { --stage: var(--color-primary); }
.stage-c-teal   { --stage: var(--color-teal); }
.stage-c-green  { --stage: var(--color-good); }
.stage-c-orange { --stage: var(--color-accent); }
.stage-c-red    { --stage: var(--color-bad); }
.stage-c-violet { --stage: var(--color-violet); }

.kanban-col .kanban-col-head { color: var(--stage, var(--color-primary)); }

.step-btn { font-family: var(--font-mono); font-size: var(--text-sm); line-height: 1; padding: 4px 6px;
  background: var(--color-surface); color: var(--color-ink); border: 1px solid var(--color-line-soft);
  cursor: pointer; }
.step-btn:hover:enabled { border-color: var(--color-primary); color: var(--color-primary); }
.step-btn:disabled { color: var(--color-line); cursor: default; }

.stage-panel { display: flex; align-items: center; gap: 12px; margin: 18px 0 10px;
  padding: 8px 12px; background: var(--color-surface); border: 1px solid var(--color-line-soft);
  border-left: 4px solid var(--stage, var(--color-line)); }
.stage-panel-title { flex: 1; display: flex; align-items: center; gap: 10px;
  font-weight: 600; font-size: var(--text-md); }
.stage-dot { width: 10px; height: 10px; border-radius: 50%;
  background: var(--stage, var(--color-line)); }

/* предельный срок этапа — листок отрывного календаря справа в панели этапа */
.stage-due { display: flex; align-items: center; gap: 8px; --due: var(--color-primary); }
.stage-due.soon { --due: var(--color-accent); }
.stage-due.overdue { --due: var(--color-bad); }
.stage-due-text { display: flex; flex-direction: column; align-items: flex-end;
  font-size: var(--text-xs); line-height: 1.25; text-align: right; }
.stage-due-label { color: var(--color-ink); }
.stage-due-left { color: var(--due); font-family: var(--font-mono); }
.tearoff { display: flex; flex-direction: column; align-items: center; width: 52px;
  background: var(--color-surface); border: 1px solid var(--color-line-soft);
  box-shadow: 0 2px 0 -1px var(--color-surface), 0 2px 0 0 var(--color-line-soft),
              0 4px 0 -1px var(--color-surface), 0 4px 0 0 var(--color-line-soft); }
.tearoff-month { align-self: stretch; text-align: center; background: var(--due);
  color: var(--color-on-primary); font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: .04em;
  text-transform: uppercase; padding: 2px 0; }
.tearoff-day { font-weight: 600; font-size: var(--text-xl); font-variant-numeric: tabular-nums; line-height: 1.1;
  color: var(--color-ink); padding-top: 2px; }
.tearoff-wd { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--due);
  padding-bottom: 3px; }
@media (max-width: 767px) { .stage-panel { flex-wrap: wrap; }
  .stage-due-text { display: none; } }

.stages-table td { vertical-align: top; }
.stages-table input[type=text] { width: 100%; }
.stages-table .num-cell { text-align: right; font-family: var(--font-mono); }
.stage-colors { display: flex; gap: 4px; }
.stage-swatch { position: relative; cursor: pointer; }
.stage-swatch input { position: absolute; opacity: 0; width: 0; height: 0; }
.stage-swatch span { display: block; width: 16px; height: 16px;
  background: var(--stage); border: 1px solid var(--color-line-soft); }
.stage-swatch input:checked + span { outline: 2px solid var(--color-ink);
  outline-offset: 1px; }
.stage-blocks { display: flex; flex-direction: column; gap: 2px; font-size: var(--text-xs); }

/* ── действия этапа в карточке ────────────────────────────────────────────────────────── */

.stage-actions { display: flex; flex-direction: column; gap: 8px; margin: 0 0 18px; }
.stage-block { background: var(--color-surface); border: 1px solid var(--color-line-soft);
  border-left: 3px solid var(--stage, var(--color-line)); padding: 10px 12px; }
.stage-block.locked { opacity: .7; }
.stage-block-head { display: flex; align-items: baseline; gap: 8px; margin-bottom: 6px;
  font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: .04em; text-transform: uppercase;
  color: var(--color-primary); }
.stage-block-head .muted { text-transform: none; letter-spacing: 0; }
.block-row { display: flex; align-items: center; gap: 10px; flex-wrap: wrap; margin: 0; }
.block-main { flex: 1; min-width: 220px; display: flex; align-items: baseline;
  gap: 8px; flex-wrap: wrap; }
.block-main label { display: flex; flex-wrap: wrap; align-items: baseline; gap: 6px; min-width: 0; max-width: 100%; }
.block-main select { max-width: 100%; min-width: 0; }
.kanban-card-dots { display: flex; gap: 4px; margin-top: 6px; }
.kanban-card-dots .dot { width: 7px; height: 7px; border-radius: 50%;
  border: 1px solid var(--color-line); background: transparent; }
.kanban-card-dots .dot.done { background: var(--color-good); border-color: var(--color-good); }
.bid-limit { padding: 6px 10px; margin-bottom: 8px; background: var(--color-accent-bg);
  border-left: 3px solid var(--color-accent); }
.send-files { display: flex; flex-direction: column; gap: 2px; margin: 8px 0; }
.send-files label { display: flex; align-items: baseline; gap: 6px; font-size: var(--text-sm); }
.settings-nav a.active { color: var(--color-primary); border-bottom: 2px solid var(--color-primary); }
.settings-nav a.locked { color: var(--color-ink-muted); }

/* Комплектование: широкая таблица закупки внутри блока этапа. Девять колонок влезают
   в лист 1060px только с заданными ширинами — по содержимому браузер ужимает поля до
   нечитаемых полосок: «шт» в поле шириной 20px не видно вовсе, и единицы измерения
   выглядят непроставленными. */
.proc-table { font-size: var(--text-xs); table-layout: fixed; min-width: 900px; }
.proc-table th { padding: 6px 7px; }
.proc-table tbody:not(.grafa) td { padding: 6px 7px; vertical-align: top; }
.proc-table .c-num { width: 46px; }
/* Галочка массовых действий и номер строки — одной графой, щелчок по номеру тоже ставит
   галочку. */
.proc-table .proc-sel { display: flex; align-items: center; gap: 3px; cursor: pointer; }
.proc-table .proc-sel input, .proc-table th input[type="checkbox"] { margin: 0; }
.proc-bulk { flex-wrap: wrap; gap: 6px; align-items: center; }
.proc-bulk select, .proc-bulk input[type="text"] { width: auto; font: inherit; padding: 4px 6px; }
.proc-table .c-qty { width: 104px; }
.proc-table .c-where { width: 136px; }
.proc-table .c-price { width: 76px; }
.proc-table .c-stage { width: 152px; }
.proc-table .c-ship { width: 100px; }
.proc-table .c-stock { width: 82px; }
.proc-table .c-del { width: 38px; }
/* Кнопки строки — по мерке графы: «вернуть» и «есть 120» в неё не влезали и наезжали
   на соседнюю. */
.proc-table .btn.small { padding: 4px 6px; font-size: var(--text-xs); max-width: 100%; }
.proc-table input[type="text"], .proc-table select, .proc-table textarea {
  width: 100%; min-width: 0; font: inherit; padding: 4px 6px; }
/* Наименование видно целиком: поле переносит строки и растёт под текст. field-sizing —
   Chrome 123+; где его нет, остаются две строки с прокруткой, а не обрезанная строка. */
.proc-table textarea.proc-name { line-height: 1.3; field-sizing: content; }
.proc-table input.proc-art, .proc-table .proc-note, .proc-table .proc-track { margin-top: 3px; }
/* Количество и единица — одной графой: врозь они читаются как два разных числа, а
   вместе занимают меньше места и всегда помещаются в строку. */
.proc-table .proc-qty { display: flex; gap: 4px; }
.proc-table .proc-qty input { flex: 1 1 auto; text-align: right; }
.proc-table input.proc-unit { flex: 0 0 40px; text-align: left; }
.proc-table select { max-width: none; }
/* Похожее на складе — отдельной строкой во всю ширину таблицы: названия товаров в
   82 пиксела графы «Склад» не читаются. Свёрнуто по умолчанию, потому что подсказка
   нужна не всегда, а место занимает всегда. */
.proc-table tr.proc-near td { padding-top: 0; border-top: 0; }
.stock-near > summary { cursor: pointer; font-size: var(--text-xs); color: var(--color-ink-muted);
  list-style: none; width: fit-content; }
.stock-near > summary::-webkit-details-marker { display: none; }
.stock-near > summary::after { content: " ▾"; }
.stock-near[open] > summary::after { content: " ▴"; }
.stock-near .near { display: flex; align-items: baseline; gap: 8px; flex-wrap: wrap;
  padding: 4px 0 4px 2px; }
.stock-near .near + .near { border-top: 1px solid var(--color-line-soft); }
.stock-near .near-name { font-weight: 600; }
.stock-near .near-find { display: flex; gap: 6px; align-items: center; padding: 6px 0 4px 2px; }
.stock-near .near-find input { flex: 0 1 320px; font: inherit; padding: 4px 6px; }
.proc-table tr.proc-done td { background: var(--color-good-bg); }
.proc-table tr.proc-done input, .proc-table tr.proc-done select,
.proc-table tr.proc-done textarea { background: transparent; }
.proc-add .block-main input { width: auto; }
/* «Что купить» — наименование позиции: растёт под текст и забирает ширину строки. */
.proc-add .block-main textarea.grow { flex: 1 1 280px; width: auto; }
/* Ссылка-кнопка внутри подсказки: это действие формы, но выглядеть должно ссылкой. */
.linkish { background: none; border: 0; padding: 0; font: inherit; color: var(--color-primary);
  text-decoration: underline; cursor: pointer; }
/* Кнопка «сохранить», спрятанная в начале формы: только чтобы Enter в поле таблицы
   отправлял форму ею, а не первой видимой кнопкой строки. display:none не годится —
   такую кнопку браузер кнопкой по умолчанию не считает. */
.default-submit { position: absolute; width: 1px; height: 1px; padding: 0; border: 0;
  overflow: hidden; clip-path: inset(50%); }

/* --- профиль участника: галочки статуса одной колонкой ------------------------------- */
.doc-field.checks { flex-direction: column; align-items: flex-start; gap: 6px; }
/* Шрифт, рамка и поля — общие с input (правило выше): на бланке многострочное поле не
   должно выглядеть другим элементом, чем однострочное рядом. */
.doc-field textarea { width: 100%; }

/* --- вывод AI-анализа: светофор под полями обеспечений ------------------------------- */
/* Отбивка слева цветом вывода: с доски видно, чем кончился разбор, не читая находок.
   Цвета — те же чернила листа, что у остальных статусов, новых в палитру не заводим. */
.verdict { margin-top: 14px; padding: 10px 12px; border: 1px solid var(--color-line-soft);
  border-left: 3px solid var(--color-ink-muted); background: var(--color-surface); }
.verdict.go { border-left-color: var(--color-good); }
.verdict.caution { border-left-color: var(--color-warn-dot); }
.verdict.stop { border-left-color: var(--color-bad); }
.verdict-head { display: flex; flex-wrap: wrap; align-items: baseline; gap: 8px;
  font-size: var(--text-sm); }
.verdict-head strong { font-weight: 700; font-size: var(--text-sm); }
.verdict.go .verdict-head strong { color: var(--color-good); }
.verdict.caution .verdict-head strong { color: var(--color-warn); }
.verdict.stop .verdict-head strong { color: var(--color-bad); }
.verdict-summary { color: var(--color-ink-muted); font-size: var(--text-sm); }
.verdict-foot { margin-top: 8px; }

/* «Что поменялось» после перепроверки: заметка на полях над выводом. Те же линейки и
   цвета, что у находок, — «было» зачёркнуто, «стало» обычным текстом. */
.recheck { margin: 0 0 10px; padding: 8px 10px; border: 1px dashed var(--color-line);
  background: var(--color-bg); font-size: var(--text-sm); }
.recheck summary { cursor: pointer; font-family: var(--font-mono); font-size: var(--text-xs);
  letter-spacing: .04em; text-transform: uppercase; color: var(--color-ink-muted); }
.recheck-head { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: .04em;
  text-transform: uppercase; color: var(--color-ink-muted); margin: 8px 0 2px; }
.recheck-list { margin: 0; padding: 0; list-style: none; }
.recheck-list li { padding: 4px 0; border-top: 1px solid var(--color-line-soft);
  overflow-wrap: anywhere; }
.recheck-verdict { margin: 0; }
.recheck-verdict s { color: var(--color-ink-muted); }
.recheck .v-go { color: var(--color-good); }
.recheck .v-caution { color: var(--color-warn); }
.recheck .v-stop { color: var(--color-bad); }
.findings-diff li { display: grid; grid-template-columns: auto auto 1fr; gap: 2px 8px;
  align-items: baseline; }
.findings-diff .was, .findings-diff .now { grid-column: 3; }
.findings-diff .was { color: var(--color-ink-muted); }
.diff-tag { font-family: var(--font-mono); font-size: var(--text-xs); text-transform: uppercase;
  letter-spacing: .04em; padding: 0 4px; border: 1px solid var(--color-warn-dot);
  color: var(--color-warn); white-space: nowrap; }
.diff-tag.added { border-color: var(--color-good); color: var(--color-good); }
.diff-tag.removed { border-color: var(--color-line); color: var(--color-ink-muted); }
.lvl { font-family: var(--font-mono); font-size: var(--text-xs); text-transform: uppercase; }
.lvl.green { color: var(--color-good); }
.lvl.yellow { color: var(--color-warn); }
.lvl.red { color: var(--color-bad); }
@media (max-width: 767px) {
  .findings-diff li { grid-template-columns: auto 1fr; }
  .findings-diff .was, .findings-diff .now { grid-column: 1 / -1; }
}

.findings { list-style: none; margin: 8px 0 0; padding: 0; }
.finding { display: grid; grid-template-columns: 10px auto 1fr; gap: 2px 8px;
  align-items: baseline; padding: 5px 0; border-top: 1px solid var(--color-line-soft);
  font-size: var(--text-sm); }
.finding .dot { width: 8px; height: 8px; border-radius: 50%; align-self: center; }
.findings.green .dot { background: var(--color-good); }
.findings.yellow .dot { background: var(--color-warn-dot); }
.findings.red .dot { background: var(--color-bad); }
.finding-topic { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: .04em;
  text-transform: uppercase; color: var(--color-ink-muted); white-space: nowrap; }
/* Заголовок группы: светофор должен читаться и в чёрно-белой печати, и дальтоником. */
.findings-head { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: .04em;
  text-transform: uppercase; margin: 10px 0 0; display: flex; align-items: center; gap: 6px; }
.findings-head .dot { width: 9px; height: 9px; border-radius: 50%; }
.findings-head.green { color: var(--color-good); }
.findings-head.yellow { color: var(--color-warn); }
.findings-head.red { color: var(--color-bad); }
.findings-head.green .dot { background: var(--color-good); }
.findings-head.yellow .dot { background: var(--color-warn-dot); }
.findings-head.red .dot { background: var(--color-bad); }
/* Справочное — без светофора: серая точка, чтобы не читалось как «внимание». */
.findings-head.info { color: var(--color-ink-muted); }
.findings-head.info .dot, .findings.info .dot { background: var(--color-line); }
.finding-detail, .finding-source { grid-column: 3; color: var(--color-ink-muted);
  font-size: var(--text-xs); }
.finding-source { font-family: var(--font-mono); font-size: var(--text-xs); }

/* Условия договора: подпись слева, значение справа — те же линейки, что у находок. */
.terms { display: grid; grid-template-columns: max-content 1fr; gap: 0 12px;
  margin: 6px 0 0; font-size: var(--text-sm); }
.terms dt, .terms dd { margin: 0; padding: 5px 0; border-top: 1px solid var(--color-line-soft); }
.terms dt { font-family: var(--font-mono); font-size: var(--text-xs); letter-spacing: .04em;
  text-transform: uppercase; color: var(--color-ink-muted); }
.terms .finding-source { display: block; color: var(--color-ink-muted); }


@media (max-width: 767px) {
  .finding { grid-template-columns: 10px 1fr; }
  .finding-topic { grid-column: 2; }
  .finding-title, .finding-detail, .finding-source { grid-column: 2; }
  .terms { grid-template-columns: 1fr; }
  .terms dd { border-top: 0; padding-top: 0; }
}

/* Правовые документы: узкая колонка, читаемые абзацы. */
.legal { max-width: 62em; }
.legal h2 { margin: 22px 0 8px; font-size: var(--text-lg); }
.legal h3 { margin: 16px 0 6px; font-size: var(--text-md); }
.legal p, .legal li { font-size: var(--text-sm); line-height: 1.55; }
.legal ol, .legal ul { padding-left: 20px; }
.legal table { margin: 10px 0 16px; }
.foot-legal { display: flex; gap: 14px; flex-wrap: wrap; }
.foot-legal a { color: var(--color-ink); text-decoration: none; }
.foot-legal a:hover { color: var(--color-primary); text-decoration: underline; }


/* Редактор новости в админке. */
.news-edit { display: grid; gap: 16px; max-width: 820px; }
.news-edit label { display: grid; gap: 6px; font-size: var(--text-sm); font-weight: 600; }
.news-edit label .muted { font-weight: 400; }


/* Токен обмена с 1С: выделяется целиком одним кликом и не рвёт узкий экран. */
code.select-all { user-select: all; word-break: break-all; }

/* настройки уведомлений: матрица «событие × канал» */
.notify-matrix td:not(:first-child), .notify-matrix th:not(:first-child) {
  text-align: center; width: 110px; }
.notify-matrix a { text-decoration: none; }

/* анализ проигранных: причина отклонения нашей заявки */
.reject-reason { margin-top: 6px; font-size: var(--text-sm); }
.reject-reason summary { color: var(--color-accent); cursor: pointer; }
.reject-reason p { margin: 6px 0 0; color: var(--color-ink-muted); max-width: 70ch; }

/* проверка заказчика в блоке анализа */
.customer-check { border: 1px solid var(--color-line); border-left-width: 4px; padding: 10px 14px;
  margin: 14px 0; font-size: var(--text-sm); }
.customer-check.green { border-left-color: var(--color-good); background: var(--color-good-bg); }
.customer-check.yellow { border-left-color: var(--color-warn-dot); background: var(--color-warn-bg); }
.customer-check-head { display: flex; align-items: center; gap: 8px; flex-wrap: wrap; }
.customer-check ul { margin: 8px 0 0; padding-left: 18px; color: var(--color-ink-muted); }

/* Чёрный список заказчиков в карточке (core/tenders/blacklist.py). */
.customer-ban { margin: 10px 0; }
.customer-ban-add { margin: 6px 0 4px; }
.customer-ban-add summary { cursor: pointer; }
.customer-ban-add form { display: flex; gap: 8px; margin-top: 6px; flex-wrap: wrap; }
.customer-ban-add input[type="text"] { flex: 1 1 260px; }
.blacklist-table { min-width: 640px; }
/* Источник находки AI-анализа — ссылка на страницу документа с подсвеченной цитатой. */
a.finding-source.quote-link { color: var(--color-ink-muted); text-decoration: underline dotted; }
a.finding-source.quote-link:hover { color: var(--color-primary-press); }

/* Вход и регистрация: форма слева, справа — что даёт пробный период. На телефоне —
   под формой. */
.auth-split { display: grid; grid-template-columns: minmax(0, 640px) minmax(0, 360px);
  gap: var(--space-7); align-items: start; }
.auth-main { min-width: 0; }
.auth-aside { border-left: 3px solid var(--color-primary); padding: var(--space-1) 0 var(--space-1) var(--space-5); }
.auth-aside ul { list-style: none; margin: 0; padding: 0; display: grid; gap: var(--space-3);
  font-size: var(--text-md); }
.auth-aside b { display: block; }
@media (max-width: 767px) {
  .auth-split { grid-template-columns: minmax(0, 1fr); gap: var(--space-6); }
}

/* ── Таблицы (ТЗ 6.2) ───────────────────────────────────────────────────── */
/* Длинная таблица прокручивается внутри своего блока: шапка закреплена сверху, итог —
   снизу, у широких — ещё и первый столбец. Страница при этом не едет вбок на телефоне. */
.table-scroll { max-width: 100%; }
.table-scroll.tall { max-height: 72vh; overflow: auto; border: 1px solid var(--color-line-soft); }
.table-scroll.tall > table { border: 0; }
.table-scroll.tall thead th { position: sticky; top: 0; z-index: 2; background: var(--color-sunken); }
.table-scroll.tall tfoot td { position: sticky; bottom: 0; z-index: 2; background: var(--color-surface);
  box-shadow: inset 0 1px 0 var(--color-ink); }
.table-scroll.pin-first :is(td, th):first-child { position: sticky; left: 0; z-index: 1;
  background: var(--color-surface); }
.table-scroll.pin-first thead th:first-child { z-index: 3; background: var(--color-sunken); }
/* Суммы и количества — по правому краю, цифры одинаковой ширины, без переноса внутри. */
td.num, th.num, .ks-table .num { text-align: right; font-variant-numeric: tabular-nums; }
.money { white-space: nowrap; font-variant-numeric: tabular-nums; }
/* Пустая графа «заполнить вручную» — светлым жёлтым, чтобы её было видно среди заполненных. */
td.cell-manual, .ks-table td.cell-manual { background: var(--color-warn-bg); }
/* Закреплённый первый столбец непрозрачен — но подсветку строки держит. */
.table-scroll.pin-first tr.manual td:first-child { background: var(--color-accent-bg); }
.table-scroll.pin-first tr.loss td:first-child { background: var(--color-bad-bg); }
.table-scroll.pin-first tr.proc-done td:first-child { background: var(--color-good-bg); }

/* ── Кнопки (ТЗ 6.4) ────────────────────────────────────────────────────── */
/* Основная — заливка синью, одна на экран или блок; вторичная — рамкой (.secondary);
   текстовая — .link-btn; опасная — красной рамкой и всегда с подтверждением. */
.btn.danger { background: transparent; color: var(--color-bad); border: 1px solid var(--color-bad); }
.btn.danger:hover { background: var(--color-bad); color: var(--color-on-primary); }
.danger-zone { margin-top: var(--space-4); border: 1px solid var(--color-bad); padding: 10px 16px; }
.danger-zone > summary { cursor: pointer; color: var(--color-bad); font-weight: 600; }
.btn.busy { cursor: progress; }
.long-progress { margin: var(--space-2) 0 0; font-size: var(--text-sm); color: var(--color-ink-muted); }

/* ── Уведомления (ui.js) ────────────────────────────────────────────────── */
.toasts { position: fixed; z-index: 60; right: var(--space-4); bottom: var(--space-4);
  display: flex; flex-direction: column; gap: var(--space-2); max-width: min(420px, calc(100vw - 32px)); }
.toast { display: flex; align-items: center; gap: var(--space-3); padding: var(--space-3) var(--space-4);
  background: var(--color-ink); color: var(--color-dark-ink); font-size: var(--text-sm);
  border-radius: var(--radius-2); box-shadow: var(--shadow-pop); }
.toast > span { flex: 1; min-width: 0; }
.toast.error { background: var(--color-bad-bg); color: var(--color-bad); border: 1px solid var(--color-bad); }
.toast button { background: none; border: 0; color: inherit; cursor: pointer; font: inherit; padding: 4px; }
.toast .toast-undo { font-weight: 600; text-decoration: underline; color: var(--color-dark-link); }
.toast.error .toast-undo { color: var(--color-bad); }

/* ── Окно подтверждения вместо confirm() браузера ───────────────────────── */
.confirm-dialog { max-width: min(460px, calc(100vw - 32px)); padding: var(--space-5);
  border: 1px solid var(--color-ink); border-radius: var(--radius-2); background: var(--color-surface);
  color: var(--color-ink); box-shadow: var(--shadow-pop); }
.confirm-dialog::backdrop { background: var(--color-overlay); }
.confirm-dialog .confirm-text { margin: 0; font-size: var(--text-md); }
.confirm-dialog .btn-row { margin-top: var(--space-5); }

/* ── Зона загрузки файлов (перетаскивание) ──────────────────────────────── */
.dropzone { position: relative; display: flex; flex-direction: column; align-items: flex-start;
  gap: var(--space-1); width: 100%; padding: var(--space-4); border: 1.5px dashed var(--color-line);
  background: var(--color-surface); border-radius: var(--radius-1); cursor: pointer; }
.dropzone:hover, .dropzone.over { border-color: var(--color-primary); background: var(--color-primary-bg); }
.dropzone:focus-within { outline: 2px solid var(--color-primary); outline-offset: 2px; }
.dropzone input[type="file"] { position: absolute; inset: 0; opacity: 0; cursor: pointer; width: 100%; }
.dropzone-title { font-weight: 600; color: var(--color-primary); }
.dropzone-hint { font-size: var(--text-xs); color: var(--color-ink-muted); }
.dropzone-files { font-size: var(--text-sm); color: var(--color-ink); overflow-wrap: anywhere; }
.dropzone-files:empty { display: none; }

/* ── Инструкция «Как это работает» — свёрнута, текст до 720 px ──────────── */
.howto { margin: 0 0 var(--space-5); max-width: var(--width-text); border-left: 3px solid var(--color-line);
  padding-left: var(--space-3); }
.howto > summary { cursor: pointer; color: var(--color-primary); font-size: var(--text-sm); }
.howto > div { padding-top: var(--space-2); color: var(--color-ink-muted); font-size: var(--text-sm); }

/* ── Пустой экран и загрузка ────────────────────────────────────────────── */
.empty-state { max-width: var(--width-text); padding: var(--space-6) var(--space-5);
  border: 1px dashed var(--color-line); background: var(--color-surface); text-align: left; }
.empty-state h2 { margin: 0 0 var(--space-2); font-size: var(--text-lg); }
.empty-state p { margin: 0 0 var(--space-4); color: var(--color-ink-muted); }
.skeleton { display: block; height: 14px; margin: var(--space-2) 0; border-radius: var(--radius-1);
  background: linear-gradient(90deg, var(--color-line-soft), var(--color-sunken), var(--color-line-soft));
  background-size: 200% 100%; animation: skeleton 1.4s ease-in-out infinite; }
@keyframes skeleton { from { background-position: 200% 0; } to { background-position: -200% 0; } }
@media (prefers-reduced-motion: reduce) { .skeleton { animation: none; } }

/* ── Доступность (ТЗ 6.6): цели нажатия на телефоне не меньше 44 px ─────── */
:is(summary, select, .link-btn, .step-btn):focus-visible { outline: 2px solid var(--color-primary);
  outline-offset: 2px; }
@media (max-width: 767px) {
  .btn, .btn.small, select, input[type="text"], input[type="email"], input[type="password"],
  input[type="search"], input[type="number"], input[type="date"] { min-height: 44px; }
  .link-btn, .step-btn { min-width: 44px; min-height: 44px; }
}

/* Нужное только без скрипта (кнопка «Сохранить» у автосохраняемой формы). */
.js .js-hide { display: none; }
.save-state { font-size: var(--text-sm); color: var(--color-good); min-height: 1.5em; }
/* Строка кнопки внутри самого бланка — графой, без внешнего отступа; пустая (кнопка
   спрятана автосохранением, отметки ещё нет) не занимает места. */
form.doc > .btn-row { margin: 0; padding: var(--space-2) var(--space-4); }
.js form.doc > .btn-row:has(> .js-hide):has(> .save-state:empty) { display: none; }
/* Кнопка сохранения длинной формы — у нижнего края экрана, пока форма прокручивается. */
.sticky-save { position: sticky; bottom: 0; z-index: 5; margin: var(--space-5) calc(-1 * var(--space-4)) 0;
  padding: var(--space-3) var(--space-4); background: var(--color-surface);
  border-top: 1px solid var(--color-line); }
.sticky-save .btn:disabled { opacity: .45; cursor: default; }

/* ── Канбан (ТЗ 6.1) ────────────────────────────────────────────────────── */
/* Шапка доски — одна строка: колонки видны сразу, без прокрутки. */
.board-bar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2);
  min-height: var(--height-bar); margin: calc(-1 * var(--space-2)) 0 var(--space-3);
  padding-bottom: var(--space-2); border-bottom: 1px solid var(--color-line-soft); }
.board-bar h1 { font-size: var(--text-xl); margin: 0 var(--space-2) 0 0; }
.board-bar select { font-size: var(--text-sm); padding: 5px 8px; }
.board-bar-gap { flex: 1; }
.board-filters { display: contents; }
.board-bar .board-filters-toggle { display: none; }
/* Сегментный переключатель: радиокнопки, нарисованные полосой. */
.seg { display: inline-flex; border: 1px solid var(--color-line); border-radius: var(--radius-1);
  margin: 0; padding: 0; }
.seg label { position: relative; }
.seg input { position: absolute; opacity: 0; inset: 0; cursor: pointer; }
.seg span { display: block; padding: 5px 10px; font-size: var(--text-sm); cursor: pointer;
  background: var(--color-surface); white-space: nowrap; }
.seg label + label span { border-left: 1px solid var(--color-line); }
.seg input:checked + span { background: var(--color-primary); color: var(--color-on-primary); }
.seg input:focus-visible + span { outline: 2px solid var(--color-primary); outline-offset: 1px; }
/* Выпадающее меню «⋯» — <details>: открывается без скрипта, закрывает его ui.js. */
.menu { position: relative; }
.menu > summary { list-style: none; cursor: pointer; }
.menu > summary::-webkit-details-marker { display: none; }
.menu-list { position: absolute; right: 0; top: calc(100% + 4px); z-index: 40; min-width: 220px;
  display: flex; flex-direction: column; padding: var(--space-1) 0; background: var(--color-surface);
  border: 1px solid var(--color-ink); border-radius: var(--radius-2); box-shadow: var(--shadow-pop); }
.menu-list > a, .menu-list button { display: block; width: 100%; padding: var(--space-2) var(--space-3);
  border: 0; background: none; text-align: left; font: inherit; font-size: var(--text-sm);
  color: var(--color-ink); text-decoration: none; cursor: pointer; }
.menu-list > a:hover, .menu-list button:hover:enabled { background: var(--color-hover); color: var(--color-primary); }
.menu-list button:disabled { color: var(--color-line); cursor: default; }
.menu-list button.danger { color: var(--color-bad); }
.menu-list form { margin: 0; }
.menu-label { display: flex; flex-direction: column; gap: 2px; padding: var(--space-2) var(--space-3);
  font-size: var(--text-xs); color: var(--color-ink-muted); }
.menu-label select { width: 100%; }

/* Колонки шире прежних 220 px — название в три строки читается без обрывков. */
.kanban-col { flex: 0 0 272px; }
.kanban-col-head { display: grid; grid-template-columns: 1fr auto; gap: 0 var(--space-2);
  font-family: var(--font-body); font-size: var(--text-sm); letter-spacing: 0; text-transform: none; }
.kanban-col-title { font-weight: 600; min-width: 0; overflow-wrap: anywhere; }
.kanban-col-sum { grid-column: 1 / -1; font-family: var(--font-mono); font-size: var(--text-xs);
  color: var(--color-ink-muted); font-variant-numeric: tabular-nums; }
.kanban-card { display: flex; flex-direction: column; gap: 6px; }
.kanban-card-no { font-size: var(--text-xs, 12px); color: var(--color-ink-muted); font-variant-numeric: tabular-nums;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.kanban-card:focus-visible { outline: 2px solid var(--color-primary); outline-offset: 1px; }
/* Название — не длиннее трёх строк, целиком — в подсказке. */
.kanban-card-title { font-size: var(--text-sm); line-height: 1.3; display: -webkit-box;
  -webkit-line-clamp: 3; line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.kanban-card-customer { font-size: var(--text-xs); color: var(--color-ink-muted); white-space: nowrap;
  overflow: hidden; text-overflow: ellipsis; }
.kanban-card-row { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; font-size: var(--text-xs); }
.kanban-card-row .kanban-card-price { font-size: var(--text-sm); }
.kanban-card-row .kanban-card-dots { margin: 0; }
.kanban-card-gap { flex: 1; }
.kanban-card.lifted { box-shadow: var(--shadow-pop); position: relative; z-index: 50; opacity: .9; }
.kanban-card-menu > summary { width: 28px; height: 24px; display: grid; place-items: center;
  border-radius: var(--radius-1); color: var(--color-ink-muted); font-size: var(--text-md); }
.kanban-card-menu > summary:hover { background: var(--color-hover); color: var(--color-ink); }
/* Срок — цветом по одному правилу на весь портал: 1–3 дня жёлтый, меньше суток красный.
   Цвет дублируется значком ▲ и словом («через 2 дн.»). */
.due { margin-left: auto; font-weight: 600; color: var(--color-ink-muted); white-space: nowrap; }
.due.warn { color: var(--color-warn); }
.due.bad { color: var(--color-bad); }
.due.gone { color: var(--color-ink-muted); text-decoration: line-through; }
.board-list .due { margin-left: 0; }
/* Светофор разбора — точка; слово — в подсказке и для экранного диктора. */
.light { display: inline-block; width: 10px; height: 10px; border-radius: 50%; flex: none; }
.light-go { background: var(--color-good); }
.light-caution { background: var(--color-warn-dot); }
.light-stop { background: var(--color-bad); }
.light-unknown { background: transparent; box-shadow: inset 0 0 0 1.5px var(--color-ink-muted); }
.avatar { display: inline-grid; place-items: center; width: 22px; height: 22px; border-radius: 50%;
  background: var(--color-primary); color: var(--color-on-primary); font-size: 10px; font-weight: 600; }
.sr-only { position: absolute; width: 1px; height: 1px; overflow: hidden; clip-path: inset(50%);
  white-space: nowrap; }
.board-list th[data-sort] { cursor: pointer; }
.board-list th[data-dir="asc"]::after { content: " ▴"; }
.board-list th[data-dir="desc"]::after { content: " ▾"; }
/* Вкладки этапов — только на телефоне, где видна одна колонка. */
.kanban-tabs { display: none; }
@media (max-width: 767px) {
  .board-bar h1 { flex-basis: 100%; }
  .board-bar-gap { display: none; }
  .js .board-bar .board-filters-toggle { display: inline-flex; }
  /* Кнопки строки растягиваются по высоте соседей — подпись держим по центру, а не у верха. */
  .board-bar > .btn, .board-bar > .board-filters-toggle { display: inline-flex; align-items: center;
    justify-content: center; }
  .js .board-filters:not(.is-open) { display: none; }
  .js .board-filters.is-open { display: flex; flex-wrap: wrap; gap: var(--space-2); flex-basis: 100%; }
  .kanban-tabs { display: flex; gap: 6px; overflow-x: auto; margin: 0 0 var(--space-2);
    padding-bottom: 4px; }
  .kanban-tabs a { flex: none; padding: 6px 10px; font-size: var(--text-sm); text-decoration: none;
    color: var(--color-ink); border: 1px solid var(--color-line-soft);
    border-top: 3px solid var(--stage, var(--color-line)); background: var(--color-surface); }
  .kanban-scroll { display: none; }
  .kanban { scroll-snap-type: x mandatory; }
  .kanban-col { flex: 0 0 calc(100% - 24px); scroll-snap-align: start; }
}
/* Цвет этапа — полоской сверху колонки; название — чернилами: серый этап в шапке
   не читался (контраст ниже 4,5:1). */
.kanban-col .kanban-col-head { color: var(--color-ink); }

/* ══ Каркас портала (ТЗ 4): меню слева, панель сверху, на телефоне — панель снизу ══ */
.in-shell { background: var(--color-bg); }
.shell { display: flex; min-height: 100vh; }
.icon { display: block; flex: none; }

/* ── Левое меню ── */
.side-nav { position: sticky; top: 0; height: 100vh; flex: 0 0 var(--width-nav); width: var(--width-nav);
  display: flex; flex-direction: column; background: var(--color-surface);
  border-right: 1.5px solid var(--color-ink); z-index: 30; }
.side-brand { display: flex; align-items: center; gap: var(--space-2); height: var(--height-bar); flex: none;
  padding: 0 var(--space-4); border-bottom: 1.5px solid var(--color-ink); color: var(--color-ink);
  text-decoration: none; }
.side-brand img { height: 30px; width: auto; }
.side-brand b { display: block; font-family: var(--font-display); font-size: var(--text-xl);
  letter-spacing: .1em; line-height: 1; }
.side-brand small { display: block; font-family: var(--font-mono); font-size: 10.5px;
  color: var(--color-ink-muted); }
.side-close { display: none; }
.side-groups { flex: 1; overflow-y: auto; padding: var(--space-2) 0; }
.nav-group { padding: var(--space-1) 0; }
.nav-group-title { padding: var(--space-2) var(--space-4) var(--space-1); font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--color-ink-muted); }
.nav-item { display: flex; align-items: center; gap: 10px; width: 100%; min-height: 36px;
  padding: 6px var(--space-4); color: var(--color-ink); text-decoration: none; font: inherit;
  font-size: var(--text-sm); background: none; border: 0; text-align: left; cursor: pointer;
  position: relative; }
.nav-item:hover { background: var(--color-hover); color: var(--color-primary); }
.nav-item.active { color: var(--color-primary); font-weight: 600; background: var(--color-primary-bg);
  box-shadow: inset 3px 0 0 var(--color-primary); }
.nav-item.locked { color: var(--color-ink-muted); }
.nav-label { flex: 1; min-width: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.nav-badge { display: inline-flex; align-items: center; gap: 2px; }
.nav-count { font-family: var(--font-mono); font-size: 11px; color: var(--color-ink-muted); }
.nav-count.hot { min-width: 18px; padding: 0 6px; border-radius: 9px; text-align: center;
  background: var(--color-accent); color: var(--color-on-primary); line-height: 18px; }
.side-bottom { flex: none; border-top: 1px solid var(--color-line); padding: var(--space-2) 0; }
.nav-plan { display: block; margin: var(--space-1) var(--space-3) var(--space-2); padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-line-soft); background: var(--color-sunken); color: var(--color-ink);
  text-decoration: none; font-size: var(--text-xs); }
.nav-plan-head { display: flex; justify-content: space-between; gap: var(--space-2); }
.nav-plan-head span { color: var(--color-ink-muted); font-family: var(--font-mono); }
.nav-plan-quota { display: block; color: var(--color-ink-muted); }
.nav-plan-bar { display: block; height: 4px; margin-top: 6px; background: var(--color-line-soft); }
.nav-plan-bar > span { display: block; height: 4px; background: var(--color-primary); }
.nav-collapse { color: var(--color-ink-muted); }

/* Меню само прячется до иконок (класс nav-auto — если человек так выбрал) и раскрывается под мышью
   поверх страницы (nav-peek) — содержимое не сдвигается. Закреплённое — открыто всегда;
   на 768–1199 px закрепить нельзя. */
.nav-auto .nav-pin, html:not(.nav-auto) .nav-unpin { display: flex; }
.nav-pin, .nav-unpin { display: none; }
@media (min-width: 1200px) {
  .nav-auto:not(.nav-peek) .side-nav { flex-basis: var(--width-nav-collapsed); width: var(--width-nav-collapsed); }
  .nav-auto:not(.nav-peek) .side-nav :is(.nav-label, .nav-group-title, .nav-plan, .nav-badge) { display: none; }
  .nav-auto:not(.nav-peek) .side-nav .nav-item { justify-content: center; padding: 8px 0; }
  .nav-auto:not(.nav-peek) .side-nav .nav-count { position: absolute; top: 2px; right: 8px; font-size: 9.5px; }
  .nav-auto:not(.nav-peek) .side-nav .nav-count:not(.hot) { display: none; }
  .nav-auto:not(.nav-peek) .side-brand { justify-content: center; padding: 0; }
}
@media (min-width: 768px) {
  .nav-peek .side-nav { flex-basis: var(--width-nav); width: var(--width-nav);
    margin-right: calc(var(--width-nav-collapsed) - var(--width-nav)); box-shadow: var(--shadow-pop); }
}

/* ── Верхняя панель ── */
.shell-main { flex: 1; min-width: 0; display: flex; flex-direction: column; }
.top-bar { position: sticky; top: 0; z-index: 20; height: var(--height-bar); flex: none;
  display: flex; align-items: center; gap: var(--space-3); padding: 0 var(--space-5);
  background: var(--color-surface); border-bottom: 1.5px solid var(--color-ink); }
.top-gap { flex: 1; }
.quick { position: relative; flex: 1 1 520px; max-width: 560px; margin: 0; }
.quick-field { display: flex; align-items: center; gap: var(--space-2); height: 36px; padding: 0 10px;
  border: 1px solid var(--color-line); border-radius: var(--radius-1); background: var(--color-surface-raised);
  color: var(--color-ink-muted); }
.quick-field:focus-within { border-color: var(--color-primary); outline: 2px solid var(--color-primary-bg); }
.quick-field input { flex: 1; min-width: 0; min-height: 0; border: 0; padding: 0; background: transparent;
  outline: 0; font-size: var(--text-sm); }
.quick-field kbd { font-family: var(--font-mono); font-size: 11px; border: 1px solid var(--color-line-soft);
  padding: 0 5px; border-radius: var(--radius-1); }
.quick-results { left: 0; right: auto; width: 100%; max-height: 60vh; overflow-y: auto; }
.quick-results a { display: flex; flex-direction: column; gap: 1px; }
.quick-results a b { font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.quick-results a span { font-size: var(--text-xs); color: var(--color-ink-muted); }
.quick-results a:focus { background: var(--color-hover); outline: 0; }
.quick-results .quick-take { color: var(--color-primary); font-weight: 600; border-top: 1px solid var(--color-line-soft); }
.icon-btn { position: relative; display: grid; place-items: center; width: 40px; height: 40px;
  border: 0; background: none; color: var(--color-ink); cursor: pointer; border-radius: var(--radius-1); }
.icon-btn:hover { background: var(--color-hover); }
.icon-btn .nav-count { position: absolute; top: 3px; right: 0; font-size: 10px; }
.bell-list { width: min(380px, calc(100vw - 24px)); max-height: 70vh; overflow-y: auto; }
.bell-item { display: flex; flex-direction: column; gap: 2px; padding: var(--space-2) var(--space-3);
  color: var(--color-ink); text-decoration: none; border-bottom: 1px solid var(--color-line-soft); }
.bell-item:hover { background: var(--color-hover); }
.bell-item b { font-size: var(--text-sm); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.bell-item span { font-size: var(--text-xs); color: var(--color-ink-muted); }
.bell-item.deadline span { color: var(--color-warn); font-weight: 600; }
.bell-item.changed span { color: var(--color-accent); }
.bell-empty, .bell-list > .muted { margin: 0; padding: var(--space-3); font-size: var(--text-sm); color: var(--color-ink-muted); }
.account-btn { display: flex; align-items: center; gap: var(--space-2); padding: 4px; border-radius: var(--radius-1); }
.account-btn:hover { background: var(--color-hover); }
.account-name { font-size: var(--text-sm); max-width: 22ch; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.account .avatar { width: 30px; height: 30px; font-size: 12px; }

/* Строка пробника и квоты — одна, под панелью. */
.strip { display: flex; align-items: center; gap: var(--space-3); padding: 6px var(--space-5);
  font-size: var(--text-sm); background: var(--color-primary-bg); color: var(--color-primary-press);
  border-bottom: 1px solid var(--color-primary); }
.strip > span { flex: 1; min-width: 0; }
.strip.warn { background: var(--color-accent-bg); color: var(--color-accent-ink); border-bottom-color: var(--color-accent); }
.strip .icon-btn { width: 28px; height: 28px; color: inherit; }

.shell-content { flex: 1; padding: var(--space-5) var(--space-6) var(--space-7); min-width: 0; }
.shell-content > .lead, .shell-content .legal { max-width: var(--width-text); }
.shell-foot { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); padding: var(--space-3) var(--space-6);
  border-top: 1px solid var(--color-line); font-family: var(--font-mono); font-size: 11px;
  color: var(--color-ink-muted); }
.shell-foot a { color: var(--color-ink); text-decoration: none; }
.shell-foot a:hover { color: var(--color-primary); text-decoration: underline; }
.bottom-bar { display: none; }

/* Шапка гостя и служебных страниц. */
.guest-nav { display: flex; align-items: center; gap: var(--space-4); margin-left: auto; padding: 0 var(--space-4); }
.guest-nav a { color: var(--color-ink); text-decoration: none; font-size: var(--text-sm); }
.guest-nav a:hover { color: var(--color-primary); }
.guest-nav a.enter { color: var(--color-primary); font-weight: 600; }

@media (min-width: 768px) and (max-width: 1199px) {
  html:not(.nav-peek) .side-nav { flex-basis: var(--width-nav-collapsed); width: var(--width-nav-collapsed); }
  html:not(.nav-peek) .side-nav :is(.nav-label, .nav-group-title, .nav-plan, .nav-badge) { display: none; }
  html:not(.nav-peek) .side-nav .nav-item { justify-content: center; padding: 8px 0; }
  html:not(.nav-peek) .side-nav .nav-count { position: absolute; top: 2px; right: 8px; font-size: 9.5px; }
  html:not(.nav-peek) .side-nav .nav-count:not(.hot) { display: none; }
  html:not(.nav-peek) .side-brand { justify-content: center; padding: 0; }
}
@media (max-width: 1199px) {
  .shell .side-nav .nav-collapse { display: none; }
  .shell-content { padding: var(--space-5) var(--space-5) var(--space-7); }
}
@media (max-width: 767px) {
  /* Меню разделов — поверх экрана по «Ещё», с подписями. */
  .side-nav { position: fixed; inset: 0 auto 0 0; width: min(300px, 86vw); flex-basis: auto;
    transform: translateX(-105%); transition: transform .18s ease; box-shadow: var(--shadow-pop); }
  .nav-open .side-nav { transform: none; }
  .side-nav .nav-label { display: block; }
  .side-nav .nav-group-title, .side-nav .nav-plan { display: block; }
  .side-nav .nav-badge { display: inline-flex; }
  .side-nav .nav-item { justify-content: flex-start; padding: 10px var(--space-4); min-height: 44px; }
  .side-nav .nav-count { position: static; }
  .side-nav .nav-count:not(.hot) { display: inline; }
  .side-brand { justify-content: flex-start; padding: 0 var(--space-4); }
  .side-close { display: grid; place-items: center; position: absolute; top: 6px; right: 6px;
    width: 44px; height: 44px; border: 0; background: none; color: var(--color-ink); }
  .top-bar { padding: 0 var(--space-3); gap: var(--space-2); }
  .quick-field kbd, .account-name { display: none; }
  .strip { padding: 6px var(--space-3); font-size: var(--text-xs); }
  .shell-content { padding: var(--space-4) var(--space-4) calc(var(--space-8) + var(--space-5)); }
  .shell-foot { padding: var(--space-3) var(--space-4) calc(var(--space-8) + var(--space-3)); }
  .bottom-bar { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); position: fixed;
    left: 0; right: 0; bottom: 0; z-index: 25; height: 60px; background: var(--color-surface);
    border-top: 1.5px solid var(--color-ink); padding-bottom: env(safe-area-inset-bottom); }
  .bottom-bar > a, .bottom-bar > button { display: flex; flex-direction: column; align-items: center;
    justify-content: center; gap: 2px; min-height: 44px; border: 0; background: none; font: inherit;
    font-size: 11px; color: var(--color-ink); text-decoration: none; cursor: pointer; }
  .bottom-bar > a.active { color: var(--color-primary); font-weight: 600; box-shadow: inset 0 3px 0 var(--color-primary); }
  .guest-nav { gap: var(--space-3); padding: 0 var(--space-3); }
  .guest-nav a:not(.enter) { display: none; }
}
@media (prefers-reduced-motion: reduce) { .side-nav { transition: none; } }

/* Настройки — отдельной страницей со своим списком слева (ТЗ 4.1). Шаблоны раздела
   включают _settings_nav.html первым — сетку из двух колонок строим по нему. */
.shell-content > .settings-nav { display: flex; border: 1px solid var(--color-line-soft);
  background: var(--color-surface); }
/* Колонкой слева — на широком экране; уже 1200 px редакторам (этапы, команда) нужна вся
   ширина, и список ложится полосой сверху. */
@media (min-width: 1200px) {
  .shell-content:has(> .settings-nav) { display: grid; grid-template-columns: 220px minmax(0, 1fr);
    column-gap: var(--space-6); align-content: start; }
  .shell-content:has(> .settings-nav) > * { grid-column: 2; }
  .shell-content > .settings-nav { grid-column: 1; grid-row: 1 / span 999; align-self: start;
    position: sticky; top: calc(var(--height-bar) + var(--space-4)); flex-direction: column;
    padding: var(--space-2) 0; }
}
@media (max-width: 1199px) {
  .shell-content > .settings-nav { flex-direction: row; overflow-x: auto; margin-bottom: var(--space-4); }
  .settings-nav-title { display: none; }
  .settings-nav a { flex: none; white-space: nowrap; }
  .settings-nav a.active { box-shadow: inset 0 -3px 0 var(--color-primary); }
}
.settings-nav-title { margin: 0; padding: var(--space-1) var(--space-4) var(--space-2); font-family: var(--font-mono);
  font-size: 11px; letter-spacing: .08em; text-transform: uppercase; color: var(--color-ink-muted); }
.settings-nav a { padding: 7px var(--space-4); font-size: var(--text-sm); color: var(--color-ink); text-decoration: none; }
.settings-nav a:hover { background: var(--color-hover); color: var(--color-primary); }
.settings-nav a.active { color: var(--color-primary); font-weight: 600; background: var(--color-primary-bg);
  box-shadow: inset 3px 0 0 var(--color-primary); border-bottom: 0; }
.settings-nav a.locked { color: var(--color-ink-muted); }
.quick-results[hidden], .menu-list[hidden] { display: none; }

/* ══ Карточка тендера (ТЗ 5): две колонки, сводка справа закреплена ══════════ */
.card-page { display: flex; flex-direction: column; gap: var(--space-3); }
.crumbs { display: flex; gap: var(--space-4); font-size: var(--text-sm); }
.crumbs a { text-decoration: none; }
.card-head { display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-3) var(--space-5); }
.card-head-main { flex: 1 1 520px; min-width: 0; }
.card-head h1 { margin: 0 0 var(--space-2); overflow-wrap: anywhere; }
.card-head-meta { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-1) var(--space-4);
  font-size: var(--text-sm); color: var(--color-ink-muted); }
.card-number { display: inline-flex; align-items: center; gap: 4px; font-family: var(--font-mono);
  font-size: var(--text-sm); color: var(--color-ink); background: var(--color-surface-raised);
  border: 1px solid var(--color-line-soft); border-radius: var(--radius-1); padding: 1px 6px; cursor: copy; }
.card-number:hover { border-color: var(--color-primary); }
.card-head-side { display: flex; align-items: center; gap: var(--space-3); font-size: var(--text-sm); }
.card-who { display: inline-flex; align-items: center; gap: 6px; }

/* Шкала этапов: пройденные — галочкой, текущий — заливкой цвета этапа. */
.stage-scale { display: flex; flex-wrap: wrap; margin: 0; padding: 0; list-style: none;
  border: 1px solid var(--color-line); background: var(--color-surface); }
.stage-scale li { display: flex; border-right: 1px solid var(--color-line-soft); }
.stage-scale li:last-child { border-right: 0; }
.stage-scale li > span, .stage-scale button { display: block; padding: 8px 14px; font: inherit;
  font-size: var(--text-sm); border: 0; background: none; color: var(--color-ink-muted); cursor: pointer;
  white-space: nowrap; }
.stage-scale form { margin: 0; display: flex; }
.stage-scale button:hover:enabled { background: var(--color-hover); color: var(--color-primary); }
.stage-scale button:disabled { cursor: default; color: var(--color-line); }
.stage-scale li.done, .stage-scale li.done button { color: var(--color-good); }
.stage-scale li.done { background: var(--color-good-bg); }
.stage-scale li.collapsed summary { padding: 8px 14px; font-size: var(--text-sm); color: var(--color-good);
  font-weight: 600; }
.stage-scale li.collapsed .menu-list { left: 0; right: auto; }
.stage-scale li.collapsed .menu-list button { color: var(--color-ink); white-space: nowrap; }
/* Текущий — синью с полоской цвета этапа: серый или жёлтый этап под белым текстом не читался. */
.stage-scale li.current > span { background: var(--color-primary); color: var(--color-on-primary);
  font-weight: 600; cursor: default; box-shadow: inset 0 -3px 0 var(--stage, var(--color-primary)); }
.stage-scale-hint { margin: calc(-1 * var(--space-2)) 0 0; text-align: right; }

.card-cols { display: grid; grid-template-columns: minmax(0, 1fr) 320px; gap: var(--space-5); align-items: start; }
.card-main { min-width: 0; display: flex; flex-direction: column; gap: var(--space-3); }
.card-anchors { position: sticky; top: var(--height-bar); z-index: 10; display: flex; flex-wrap: wrap;
  gap: 2px var(--space-4); padding: var(--space-2) var(--space-3); background: var(--color-surface);
  border: 1px solid var(--color-line-soft); font-size: var(--text-sm); }
.card-anchors a { text-decoration: none; }
.card-main [id] { scroll-margin-top: calc(var(--height-bar) + 52px); }

/* Свёрнутые блоки чужих этапов — строкой с итогом. */
.block-lines { display: flex; flex-direction: column; border: 1px solid var(--color-line-soft);
  background: var(--color-surface); }
.block-line { display: flex; align-items: center; gap: var(--space-2); padding: 7px var(--space-3);
  font-size: var(--text-sm); border-top: 1px solid var(--color-line-soft); }
.block-line:first-child { border-top: 0; }
.block-line b { font-weight: 600; }
.block-line span:last-child { color: var(--color-ink-muted); overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.block-lines.later .block-line { color: var(--color-ink-muted); }
.block-dot { display: inline-block; flex: none; width: 9px; height: 9px; border-radius: 50%;
  border: 1.5px solid var(--color-line); }
.block-dot.done { background: var(--color-good); border-color: var(--color-good); }
.block-dot.work { border-color: var(--color-warn-dot); background: var(--color-warn-bg); }
.block-dot.none { visibility: hidden; }
.stage-block-head h2 { margin: 0; font-family: var(--font-body); font-size: var(--text-md); font-weight: 600;
  text-transform: none; letter-spacing: 0; color: var(--color-ink); }
.stage-block-head { align-items: center; flex-wrap: wrap; }
.block-state { margin-left: auto; font-family: var(--font-mono); font-size: 11px; letter-spacing: .04em;
  text-transform: uppercase; color: var(--color-ink-muted); }
.block-state.done { color: var(--color-good); }
.block-state.work { color: var(--color-warn); }
.stage-block.is-work { border-color: var(--color-ink); }
.stage-actions { margin: 0; }

.card-section { background: var(--color-surface); border: 1px solid var(--color-line-soft); padding: var(--space-3) var(--space-4); }
.card-section > .section-h, .files-head .section-h { margin: 0 0 var(--space-2); }
form.doc.card-fields { max-width: none; border: 0; background: transparent; }
.card-fields .doc-row { padding-left: 0; padding-right: 0; }
.files-box { margin-top: 0; }
.file-list li { flex-wrap: wrap; }
.file-name { min-width: 0; overflow-wrap: anywhere; }
.file-actions { display: inline-flex; align-items: center; gap: var(--space-3); margin-left: auto; font-size: var(--text-sm); }
.file-actions > a { text-decoration: none; }
.file-actions .menu > summary { padding: 0 6px; color: var(--color-ink-muted); }
.card-tabs .tab-bar { display: flex; border-bottom: 1px solid var(--color-line-soft); margin: calc(-1 * var(--space-3)) calc(-1 * var(--space-4)) var(--space-3); }
.card-tabs .tab-bar button { padding: 10px 16px; border: 0; background: none; font: inherit; font-size: var(--text-sm);
  cursor: pointer; color: var(--color-ink); }
.card-tabs .tab-bar button[aria-selected="true"] { color: var(--color-primary); font-weight: 600;
  box-shadow: inset 0 -3px 0 var(--color-primary); }
.feed-h { font-size: var(--text-sm); margin: var(--space-2) 0; }
.activity-feed { list-style: none; margin: 0 0 var(--space-3); padding: 0; font-size: var(--text-sm); }
.activity-feed li { padding: 4px 0; border-bottom: 1px solid var(--color-line-soft); }
.activity-feed .dl-date { font-family: var(--font-mono); font-size: var(--text-xs); color: var(--color-ink-muted); margin-right: 4px; }
.card-chat { margin: 0; border: 0; padding: 0; }

/* Сводка справа. */
.card-summary { position: sticky; top: calc(var(--height-bar) + var(--space-3)); display: flex; flex-direction: column;
  background: var(--color-surface); border: 1px solid var(--color-ink); max-height: calc(100vh - var(--height-bar) - 24px);
  overflow-y: auto; }
.sum-row { margin: 0; display: flex; flex-direction: column; gap: 2px; padding: var(--space-3) var(--space-4);
  border-bottom: 1px solid var(--color-line-soft); font-size: var(--text-sm); }
.sum-row:last-child { border-bottom: 0; }
.sum-label { font-family: var(--font-mono); font-size: 11px; letter-spacing: .06em; text-transform: uppercase;
  color: var(--color-ink-muted); }
.sum-due.warn { background: var(--color-warn-bg); }
.sum-due.bad { background: var(--color-bad-bg); }
.sum-due .sum-left { font-weight: 600; }
.sum-due-body { display: flex; align-items: center; gap: var(--space-3); }
.sum-due-body > div:last-child { display: flex; flex-direction: column; }
.sum-due .tearoff { --due: var(--color-primary); }
.sum-due.warn .tearoff { --due: var(--color-warn); }
.sum-due.bad .tearoff { --due: var(--color-bad); }
.sum-due.warn .sum-left { color: var(--color-warn); }
.sum-due.bad .sum-left { color: var(--color-bad); }
dl.sum-money { display: grid; grid-template-columns: minmax(0, 1fr) auto; gap: 3px var(--space-3); }
dl.sum-money dt { color: var(--color-ink-muted); }
dl.sum-money dt.sum-label { grid-column: 1 / -1; }
dl.sum-money dd { margin: 0; text-align: right; font-variant-numeric: tabular-nums; font-weight: 600; }
dl.sum-money dd:empty { display: none; }
dl.sum-money dd.good { color: var(--color-good); }
dl.sum-money dd.bad { color: var(--color-bad); }
dl.sum-money dd.accent { color: var(--color-accent); }
.verdict-word { display: inline-flex; align-items: center; gap: 6px; font-weight: 600; }
.verdict-word.go { color: var(--color-good); }
.verdict-word.caution { color: var(--color-warn); }
.verdict-word.stop { color: var(--color-bad); }
.customer-line { display: inline-flex; align-items: center; gap: 6px; }
.sum-next .btn { text-align: center; }
.summary-strip { display: none; }

@media (max-width: 1199px) {
  .card-cols { grid-template-columns: minmax(0, 1fr); }
  .card-summary { display: none; }
  /* Сводка — полосой из четырёх чисел и кнопки над блоками. */
  .summary-strip { display: grid; grid-template-columns: repeat(4, minmax(0, 1fr)) auto; align-items: stretch;
    background: var(--color-surface); border: 1px solid var(--color-ink); }
  .ss-cell { display: flex; flex-direction: column; padding: var(--space-2) var(--space-3);
    border-right: 1px solid var(--color-line-soft); font-size: var(--text-xs); min-width: 0; }
  .ss-cell b { font-size: var(--text-sm); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
  .ss-cell.warn { background: var(--color-warn-bg); color: var(--color-warn); }
  .ss-cell.bad { background: var(--color-bad-bg); color: var(--color-bad); }
  .ss-label { font-family: var(--font-mono); font-size: 10.5px; letter-spacing: .06em; text-transform: uppercase;
    color: var(--color-ink-muted); }
  .ss-next { align-self: center; margin: 0 var(--space-3); white-space: nowrap; }
}
@media (max-width: 767px) {
  .summary-strip { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ss-cell:nth-child(2n) { border-right: 0; }
  .ss-cell:nth-child(-n+2) { border-bottom: 1px solid var(--color-line-soft); }
  /* Кнопка следующего шага — у нижнего края, над нижней панелью. */
  .ss-next { position: fixed; left: var(--space-3); right: var(--space-3); bottom: 68px; z-index: 24;
    margin: 0; text-align: center; box-shadow: var(--shadow-pop); }
  /* «⋯» — в строке заголовка справа, а не отдельной строкой: кто ведёт — в сводке. */
  .card-head { flex-wrap: nowrap; gap: var(--space-2); }
  .card-head-main { flex: 1 1 auto; }
  .card-head-side .card-who, .card-head-side > .muted { display: none; }
  .stage-scale { flex-wrap: nowrap; overflow-x: auto; }
  .card-anchors { flex-wrap: nowrap; overflow-x: auto; white-space: nowrap; }
  .file-actions { margin-left: 0; }
  .shell-content:has(.ss-next) { padding-bottom: calc(var(--space-8) + 64px); }
}
/* Добавление даты: на телефоне поля встают друг под другом — в ряд они раздвигали лист. */
.deadline-add { flex-wrap: wrap; }
.deadline-add input[type="datetime-local"] { flex: 1 1 200px; min-width: 0; }

/* ── Расчёт: документы закупки справа, зоны «Смета / ТЗ / Ведомость» слева ────────────
   (portal/templates/calc_upload.html, static/calc_pool.js). На узком экране список
   уходит под форму, а раскладка — кнопками под документами вместо перетаскивания. */
.calc-layout.with-pool { display: grid; grid-template-columns: minmax(0, 640px) minmax(260px, 420px);
  gap: 20px; align-items: start; }
.calc-layout.with-pool form.doc { max-width: none; }
.calc-pool { border: 1px solid var(--color-ink); background: var(--color-surface);
  position: sticky; top: 16px; max-height: calc(100vh - 32px); display: flex; flex-direction: column; }
.calc-pool.over { outline: 2px dashed var(--color-primary); outline-offset: -4px; }
.calc-pool-list { list-style: none; margin: 0; padding: 0; overflow-y: auto; min-height: 0; }
.calc-pool-doc { padding: 8px 16px; border-bottom: 1px solid var(--color-line-soft);
  display: grid; gap: 6px; cursor: grab; user-select: none; }
.calc-pool-doc.unreadable { cursor: default; color: var(--color-ink-muted); }
.calc-pool-doc.placed { background: var(--color-good-bg); }
.calc-pool-doc.dragging { opacity: .5; }
.calc-pool-name { font-size: var(--text-sm); overflow-wrap: anywhere; }
.calc-pool-roles { display: flex; flex-wrap: wrap; gap: 4px; align-items: center; }
.calc-role { font-size: var(--text-xs); padding: 2px 8px; border: 1px solid var(--color-line);
  background: var(--color-surface-raised); color: var(--color-ink); cursor: pointer; }
.calc-role[aria-pressed="true"] { background: var(--color-primary); border-color: var(--color-primary);
  color: var(--color-on-primary); }
.calc-role:disabled { opacity: .4; cursor: not-allowed; }
.calc-drop { min-height: 44px; padding: 6px; border: 1px dashed var(--color-line);
  display: flex; flex-wrap: wrap; gap: 6px; align-items: center; }
.calc-drop.over { border-color: var(--color-primary); background: var(--color-primary-bg); }
.calc-drop.refuse { opacity: .45; }
.calc-drop-empty { font-size: var(--text-xs); color: var(--color-ink-muted); }
.calc-chip ~ .calc-drop-empty { display: none; }
.calc-chip { display: inline-flex; align-items: center; gap: 4px; max-width: 100%;
  padding: 2px 4px 2px 8px; border: 1px solid var(--color-primary); background: var(--color-primary-bg);
  font-size: var(--text-sm); cursor: grab; user-select: none; }
.calc-chip.dragging { opacity: .5; }
.calc-chip-name { overflow-wrap: anywhere; }
.calc-chip-x { border: 0; background: none; padding: 0 4px; font-size: var(--text-lg);
  line-height: 1; cursor: pointer; color: var(--color-ink-muted); }
@media (max-width: 1199px) {
  .calc-layout.with-pool { grid-template-columns: minmax(0, 1fr); }
  .calc-pool { position: static; max-height: none; }
}
