/* Базовый слой макета: сброс, шапка, кнопки, формы, общие состояния экрана.
 *
 * Токены живут отдельно (`tokens.css`) и перенесены из `ui-design.md` дословно —
 * пересказ развёл бы облик и вёрстку молча. Экранные стили пишут дорожки в своих
 * файлах; здесь только то, что общее для всех экранов.
 */

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--color-bg);
  color: var(--color-text-primary);
  font-family: var(--font-ui);
  font-size: var(--font-size-base);
  line-height: var(--line-height-ui);
}

a { color: var(--color-link); text-decoration: none; }
/* `.btn`-ссылки исключены явно: `a:hover` иначе побеждает собственный цвет кнопки в каскаде
 * (специфичность (0,1,1) выше базового `.btn--primary` (0,1,0), а `.btn--primary:hover`
 * переопределяет только фон) — текст сливается с фоном при наведении на primary-кнопку,
 * плюс кнопке достаётся подчёркивание, которого у неё быть не должно (находка основателя
 * 2026-09-17, «Настроить» на списке групп). Дефект класса: касается любой ссылки-кнопки. */
a:not(.btn):hover { color: var(--color-link-hover); text-decoration: underline; }

:focus-visible {
  outline: 3px solid var(--color-focus-ring);
  outline-offset: 2px;
}

/* Движение отключается целиком, без исключений. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after { animation: none !important; transition: none !important; }
}

/* ── шапка ──────────────────────────────────────────────────────────────── */

.shell {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky-header);
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: 0 var(--space-5);
  height: 56px;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}

.shell__brand {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--font-size-md);
  font-weight: 700;
  color: var(--color-text-primary);
}
.shell__brand:hover { text-decoration: none; color: var(--color-text-primary); }
.shell__logo { flex: none; width: 32px; height: 32px; }
.shell__logo rect { fill: var(--color-link); }
.shell__logo text { fill: #fff; font-size: var(--font-size-sm); font-weight: 700; font-family: var(--font-ui); }

.shell__nav { display: flex; gap: var(--space-2); }

.shell__link {
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--color-text-secondary);
}
.shell__link:hover { background: var(--color-surface-sunken); text-decoration: none; }
.shell__link.is-active { color: var(--color-link); font-weight: 600; }

.shell__user {
  margin-left: auto;
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-width: 0;
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

.shell__client {
  max-width: 200px;
  padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-sm);
  background: var(--color-surface-sunken);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.shell__menu { position: relative; min-width: 0; }
.shell__menu-summary {
  max-width: 220px;
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  cursor: pointer;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.shell__menu-summary:hover { background: var(--color-surface-sunken); }

.shell__menu-panel {
  position: absolute;
  right: 0;
  top: 100%;
  min-width: 240px;
  padding: var(--space-2);
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  box-shadow: var(--shadow-dropdown);
}

.shell__menu-item {
  display: block;
  width: 100%;
  padding: var(--space-2) var(--space-3);
  border: 0;
  border-radius: var(--radius-sm);
  background: transparent;
  color: var(--color-text-secondary);
  font: inherit;
  text-align: left;
  cursor: pointer;
}
.shell__menu-item:hover { background: var(--color-surface-sunken); text-decoration: none; }
.shell__menu-item.is-active { color: var(--color-link); font-weight: 600; }
.shell__menu-sep { margin: var(--space-2) 0; border: 0; border-top: 1px solid var(--color-border); }

/* ── раскладка страницы ─────────────────────────────────────────────────── */

.page {
  max-width: var(--bp-desktop);
  margin: 0 auto;
  padding: var(--space-5);
}

.page__title {
  margin: 0 0 var(--space-4);
  font-size: var(--font-size-lg);
  font-weight: 600;
}

.page__subtitle {
  margin: calc(var(--space-2) * -1) 0 var(--space-4);
  color: var(--color-text-secondary);
  font-size: var(--font-size-sm);
}

.crumbs {
  margin-bottom: var(--space-3);
  font-size: var(--font-size-sm);
  color: var(--color-text-secondary);
}

/* Шапка страницы: заголовок слева, действие справа. Живёт здесь, а не в
 * `document.css`, потому что её носят два экрана — документ (§5.4) и настройка
 * направления (§5.6), а `document.css` подключён только к первому: на странице
 * группы правило не действовало вовсе, кнопка вставала обычным потоком, и
 * следующий абзац с отрицательным верхним отступом (`.page__subtitle`) наезжал
 * на неё (находка основателя 2026-09-09). */
.page-header {
  display: flex;
  align-items: flex-start;
  justify-content: space-between;
  gap: var(--space-4);
  margin-bottom: var(--space-2);
}
.page-header .page__title { margin: 0; max-width: 70%; }

/* Шапка экрана с подзаголовком (`ui-design.md` §4.14 PageHeader): заголовок и под ним
 * подзаголовок в одной колонке. Отступ под блоком — модификатор, а не правка `.page-header`:
 * на экране документа и настройки потока подзаголовок подтянут к шапке отрицательным полем,
 * и общий отступ 24px разорвал бы их. */
.page-header--spaced { margin-bottom: var(--space-5); }
.page-header__text { min-width: 0; }
.page-header__text .page__title { max-width: none; }
.page-header__text .page__subtitle { max-width: 72ch; margin: var(--space-1) 0 0; }

/* ── кнопки ─────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-2);
  min-height: var(--hit-size-button);
  padding: 0 var(--space-4);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  color: var(--color-text-primary);
  font: inherit;
  cursor: pointer;
  transition: background var(--duration-hover), border-color var(--duration-hover);
}
.btn:hover { border-color: var(--color-link); }

.btn--primary {
  background: var(--color-link);
  border-color: var(--color-link);
  color: #fff;
}
.btn--primary:hover { background: var(--color-link-hover); }

.btn--ghost { border-color: transparent; background: transparent; color: var(--color-link); }
.btn--danger { border-color: var(--color-error-border); color: var(--color-error-text); }

.btn--sm {
  min-height: var(--hit-size-icon);
  padding: 0 var(--space-3);
  font-size: var(--font-size-sm);
}

.btn:disabled { opacity: .45; cursor: not-allowed; }
.btn:disabled:hover { border-color: var(--color-border-strong); }
.btn--primary:disabled:hover { background: var(--color-link); border-color: var(--color-link); }

.btn--icon {
  min-height: var(--hit-size-icon);
  width: var(--hit-size-icon);
  padding: 0;
}

/* ── формы ──────────────────────────────────────────────────────────────── */

.field { display: flex; flex-direction: column; gap: var(--space-1); margin-bottom: var(--space-4); }
.field__label { font-size: var(--font-size-sm); color: var(--color-text-secondary); }
.field__hint { font-size: var(--font-size-xs); color: var(--color-text-secondary); }
.field__error { font-size: var(--font-size-sm); color: var(--color-error-text); }
.field--narrow { max-width: 160px; }
.field--invalid .input { border-color: var(--color-error-border); }

/* Группа полей — `fieldset` с `legend`, а не `span`: экранный читатель объявляет группу. */
fieldset.field { border: 0; padding: 0; margin: 0 0 var(--space-4); min-width: 0; }
fieldset.field > legend { padding: 0; margin-bottom: var(--space-1); }

.input, .select, .textarea {
  min-height: var(--hit-size-button);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border-strong);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  font: inherit;
  color: inherit;
}
.textarea { min-height: 88px; resize: vertical; }
.input:hover, .select:hover, .textarea:hover { border-color: var(--color-text-muted); }
.input:focus, .select:focus, .textarea:focus { border-color: var(--color-link); }
.input:disabled, .select:disabled, .textarea:disabled { opacity: .45; cursor: not-allowed; }

/* Строка выбора для чекбокса: цель клика — вся строка, а не квадрат 13px. `:has` — улучшение:
 * без него выбранная строка просто не подсвечена, действие работает. Группа из Django
 * (`{{ form.rights }}`) выводит свои `<label>`, поэтому адрес правила — `label` внутри
 * `.check-list`, а не имя класса, которого у виджета нет. */
.check-list { display: flex; flex-direction: column; gap: var(--space-2); }
.check-list > div { margin: 0; }
.check, .check-list label {
  display: flex;
  align-items: center;
  gap: var(--space-3);
  min-height: var(--hit-size-button);
  padding: var(--space-2) var(--space-3);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  background: var(--color-surface);
  cursor: pointer;
}
.check input[type="checkbox"], .check-list input[type="checkbox"] {
  flex: none;
  width: 16px;
  height: 16px;
  margin: 0;
  accent-color: var(--color-link);
}
.check:hover, .check-list label:hover { background: var(--color-surface-sunken); border-color: var(--color-border-strong); }
.check:has(input:checked), .check-list label:has(input:checked) {
  border-color: var(--color-link);
  background: color-mix(in srgb, var(--color-link) 10%, var(--color-surface));
}
.check:has(input:focus-visible), .check-list label:has(input:focus-visible) {
  outline: 3px solid var(--color-focus-ring);
  outline-offset: 2px;
}

/* ── карточки и панели ──────────────────────────────────────────────────── */

.card {
  background: var(--color-surface);
  border: 1px solid var(--color-border);
  border-radius: var(--radius-md);
  padding: var(--space-4);
  margin-bottom: var(--space-4);
}

.card__title {
  margin: 0 0 var(--space-3);
  font-size: var(--font-size-md);
  font-weight: 600;
}

/* Карточка с таблицей: шапка таблицы упирается в рамку, скругление не торчит. */
.card--flush { padding: 0; overflow: hidden; }
/* Форма — читаемая ширина строки, прижата влево вместе с заголовком. */
.card--form { max-width: 640px; }
.card--form .state--error { margin-bottom: var(--space-4); }

/* Заголовок блока страницы: меньше заголовка экрана (`--font-size-lg`), одним размером для всех. */
.section-title {
  margin: var(--space-6) 0 var(--space-3);
  font-size: var(--font-size-md);
  font-weight: 600;
}

/* ── таблица данных (`ui-design.md` §4.14 DataTable) ──────────────────────── */

.table-wrap { overflow-x: auto; }
.table { width: 100%; min-width: 720px; border-collapse: collapse; font-size: var(--font-size-sm); }
.table th {
  padding: var(--space-2) var(--space-3);
  background: var(--color-surface-sunken);
  border-bottom: 1px solid var(--color-border);
  color: var(--color-text-secondary);
  font-size: var(--font-size-xs);
  font-weight: 600;
  text-align: left;
  white-space: nowrap;
}
.table td { padding: var(--space-3); border-bottom: 1px solid var(--color-border); vertical-align: middle; }
.table tbody tr:last-child td { border-bottom: 0; }
.table code { font-family: var(--font-quote); font-size: var(--font-size-xs); white-space: nowrap; }
.table__label { font-weight: 600; }
.table__rights { max-width: 220px; }
.table__num { white-space: nowrap; font-variant-numeric: tabular-nums; }
.table__actions { width: 1%; text-align: right; white-space: nowrap; }
.table form { margin: 0; }
/* Неактивная строка — цветом, не прозрачностью: прозрачность роняет контраст текста. */
.table tr.is-inactive td, .table tr.is-inactive .table__label { color: var(--color-text-secondary); }

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip: rect(0 0 0 0);
  white-space: nowrap;
}

.sunken {
  background: var(--color-surface-sunken);
  border-radius: var(--radius-sm);
  padding: var(--space-3);
}

/* ── пять состояний экрана ──────────────────────────────────────────────── */

.state {
  padding: var(--space-7) var(--space-5);
  text-align: center;
  color: var(--color-text-secondary);
}
.state__title { font-size: var(--font-size-md); color: var(--color-text-primary); margin-bottom: var(--space-2); }
.state__hint { font-size: var(--font-size-sm); color: var(--color-text-secondary); }
.state > p { margin: 0; }
.state > .state__title { margin-bottom: var(--space-2); }
.state .btn { margin-top: var(--space-3); }
.card > .state { padding: var(--space-5) var(--space-4); }
.state--sm, .card > .state--sm { padding: var(--space-4); }

.state--error {
  background: var(--color-error-bg);
  border: 1px solid var(--color-error-border);
  border-radius: var(--radius-md);
  color: var(--color-error-text);
  text-align: left;
  padding: var(--space-4);
}

.state--partial {
  background: var(--color-warning-bg);
  border: 1px solid var(--color-warning-border);
  border-radius: var(--radius-md);
  color: var(--color-warning-text);
  text-align: left;
  padding: var(--space-3) var(--space-4);
  margin-bottom: var(--space-4);
}

/* Notice: абзацы внутри блока без внешних отступов браузера, кроме расстояния между ними. */
.state--partial > p, .state--error > p { margin: 0 0 var(--space-3); }
.state--partial > :last-child, .state--error > :last-child { margin-bottom: 0; }

/* Одноразовый показ токена (`ui-design.md` §4.14 TokenReveal): только оформление. */
.token-reveal { max-width: 640px; border-left-width: 4px; }
.token-reveal__lead { font-weight: 600; }
.token-reveal .field__label { margin-top: var(--space-3); }
.token-reveal .field__hint { margin-top: var(--space-3); }
.token-value {
  margin: 0;
  padding: var(--space-3);
  background: var(--color-surface);
  border: 1px solid var(--color-warning-border);
  border-radius: var(--radius-sm);
  font-family: var(--font-quote);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-quote);
  color: var(--color-text-primary);
  white-space: pre-wrap;
  word-break: break-all;
}

/* Загрузка: мерцающие полосы вместо спиннера — видно, сколько всего будет. */
.skeleton {
  height: 64px;
  margin-bottom: var(--space-2);
  border-radius: var(--radius-md);
  background: linear-gradient(90deg, var(--color-surface-sunken) 25%, var(--color-border) 37%, var(--color-surface-sunken) 63%);
  background-size: 400% 100%;
  animation: shimmer var(--duration-shimmer) ease-in-out infinite;
}
@keyframes shimmer { from { background-position: 100% 0; } to { background-position: -100% 0; } }

/* ── всплывающее сообщение ──────────────────────────────────────────────── */

.toast {
  position: fixed;
  left: 50%;
  bottom: var(--space-6);
  transform: translate(-50%, 16px);
  z-index: var(--z-toast);
  padding: var(--space-3) var(--space-5);
  border-radius: var(--radius-md);
  background: var(--color-text-primary);
  color: #fff;
  box-shadow: var(--shadow-modal);
  opacity: 0;
  transition: opacity var(--duration-panel), transform var(--duration-panel);
}
.toast.is-visible { opacity: 1; transform: translate(-50%, 0); }

/* ── бейджи, общие для экранов ──────────────────────────────────────────── */

.badge {
  display: inline-flex;
  align-items: center;
  gap: var(--space-1);
  padding: 2px var(--space-2);
  border-radius: var(--radius-sm);
  font-size: var(--font-size-xs);
  border: 1px solid transparent;
  white-space: nowrap;
}

/* «Действует», «в порядке» — токены успеха (решение основателя 2026-10-01). Не канал ответа на
 * признак (`.badge--yes`): смыслы разведены, `ui-design.md` §3. */
.badge--success { background: var(--color-success-bg); border-color: var(--color-success-border); color: var(--color-success-text); }

.badge--platform { background: var(--color-surface-sunken); color: var(--color-text-secondary); }
.badge--rejected { background: var(--color-rejected-bg); border-color: var(--color-rejected-border); color: var(--color-rejected-text); }
.badge--signal { background: var(--color-surface-sunken); color: var(--color-text-primary); border-color: var(--color-border-strong); }

/* Характеристика — факт закупщика (предмет, марка стали, давление), не наш вывод:
 * баллов не даёт, поэтому не делит канал с `.badge--signal` (признак — наш вывод,
 * даёт баллы). Контур без заливки: спокойнее `.badge--signal`, не претендует на
 * «сработало». `как-это-работает.md`, «Две разные вещи, которые легко перепутать». */
.badge--characteristic { background: transparent; border-color: var(--color-border-strong); color: var(--color-text-secondary); }

/* Знак «передано в CRM» — общий для карточки (`procurement.css`, кнопка выгрузки)
 * и строки Потока (`flow.css`): один и тот же факт, показанный в двух местах,
 * красится одним классом, а не двумя копиями стиля. Спокойный цвет — красный
 * держится только за системным сбоем (`ui-design.md` §3). */
.badge--sent {
  background: var(--color-success-bg, var(--color-surface-sunken));
  border: 1px solid var(--color-success-border, var(--color-border));
  color: var(--color-success-text, var(--color-text-primary));
}

/* Закупка вне правового поля РФ (`intake.ProcurementLawKind.FOREIGN`) — решение
 * основателя 2026-09-17: не прятать, а пометить там, где человек решает. Токен
 * --color-warning-*: требует внимания человека, не является ошибкой и не отсевом
 * (`ui-design.md` §3) — юрисдикция не портит закупку, только меняет применимое право. */
.badge--foreign { background: var(--color-warning-bg); border-color: var(--color-warning-border); color: var(--color-warning-text); }

/* Ответ на признак: три самостоятельных канала. «Не смогли» — ещё и пунктиром,
   чтобы различие не держалось на одном цвете. */
.badge--yes { color: var(--color-answer-yes); border-color: var(--color-answer-yes); }
.badge--no { color: var(--color-answer-no); border-color: var(--color-answer-no); }
.badge--unknown {
  background: var(--color-answer-unknown-bg);
  border: 1px dashed var(--color-answer-unknown-border);
  color: var(--color-answer-unknown-border);
}

.score {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 38px;
  height: 26px;
  padding: 0 var(--space-2);
  border-radius: var(--radius-sm);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.score--low { color: var(--color-score-low); background: var(--color-surface-sunken); }
.score--mid { color: var(--color-score-mid); background: var(--color-warning-bg); }
.score--high { color: #fff; background: var(--color-score-high); }

.quote {
  font-family: var(--font-quote);
  font-size: var(--font-size-sm);
  line-height: var(--line-height-quote);
  background: var(--color-surface-sunken);
  border-left: 3px solid var(--color-border-strong);
  padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
}

.muted { color: var(--color-text-muted); }
.secondary { color: var(--color-text-secondary); }
.nowrap { white-space: nowrap; }

/* ── адаптив до --bp-tablet ─────────────────────────────────────────────────
 * Литерал 768px: `var(--bp-tablet)` внутри условия @media не работает — браузер
 * молча отбрасывает правило, и адаптив «есть» только в тексте. */
@media (max-width: 768px) {
  .card--form, .token-reveal { max-width: 100%; }
}
