/* Единая система оформления приёмки Silver.

   Взята за основу дизайн-система соседнего проекта «Потребность»
   (https://potrebnost.sl-sl.ru/ui/) по решению Vadim'а 22.08.2026. Причина
   не в экономии: палитра, радиус и семья шрифтов у нас уже совпадали
   дословно, а менеджеры Silver работают в обоих сервисах — один язык
   интерфейса им дешевле двух похожих.

   Что взято оттуда без изменений: токены цвета и типографики, сетка,
   таблицы, формы, кнопки, сообщения, пилюли состояния. Что заменено —
   предметная часть: вместо дефицита и свежести источников здесь УИН,
   бирки, партии и статусы строк поставки.

   Три правила, которые здесь важнее вкуса:

   1. Смысловых цветов ровно четыре, и каждый отвечает на свой вопрос:
      зелёный — сделано; охра — ждёт решения человека; кирпич — отказ;
      синий (--hand) — «это поправил человек». Последний нужен именно нам:
      приёмщица правит данные поставщика, и её правку нельзя путать с
      замечанием системы.
   2. Цифры, которые сравнивают глазами, — моноширинные и табличные. УИН
      шестнадцать знаков, вес до тысячных, сумма до копейки; столбец обязан
      читаться столбцом.
   3. `color-scheme` объявлен намеренно: без него на тёмной теме нативные
      элементы (полосы прокрутки, календарь) остаются светлыми, и иконка
      пропадает на тёмном поле.

   Шрифты — свои, не с Google: стенд стоит на российском сервере, а
   приёмщица работает на складской машине. Чужой домен может не открыться,
   и тогда весь текст поедет на подменном шрифте.
*/

/* Дизайн-система «Потребность» — silver & silver.
   Решение Vadim'а 22.08.2026: единый стиль для всех страниц potrebnost.sl-sl.ru,
   родственный статусной странице sklad.sl-sl.ru (тот же шрифтовой набор, та же
   палитра, та же острая геометрия). Обоснование каждого решения — docs/design-system.md.

   Этот файл — единственный источник стилей проекта. Ни одна страница не заводит
   своих цветов и своих шрифтов: страница, которой чего-то не хватает, добавляет
   компонент сюда, а не пишет локальный <style>. */

/* ───────────────────────── ТОКЕНЫ ───────────────────────── */

:root{
  /* Нативные виджеты — календарь в поле даты, стрелка списка, полосы
     прокрутки — берут вид отсюда. Без этого на тёмной теме они остаются
     светлыми, и иконка календаря пропадает на тёмном поле. */
  color-scheme:light;

  /* Поверхности. Фон тёплый серо-зелёный, а не белый: белый лист под таблицей
     на 3000 строк выжигает глаз за смену. */
  --ground:#F5F5F2;
  --panel:#FFFFFF;
  --panel-2:#FAFAF7;      /* шапка таблицы, закреплённая колонка, вторичная плоскость */
  --edge:#DFDFD8;         /* видимая граница */
  --edge-2:#EDEDE7;       /* внутренняя линейка таблицы — тише границы */

  /* Чернила с зелёным уклоном — родня фону, а не нейтральный серый из коробки. */
  --ink:#1B1D1B;
  --ink-2:#5C6159;
  --ink-3:#8A8F86;

  /* Состояние. Три канала, каждый со своей приглушённой землёй. */
  --done:#2E6E4E;   --done-soft:#E4EFE8;   /* сделано, в норме, поступило */
  --ahead:#A8791F;  --ahead-soft:#F6EEDC;  /* впереди, предупреждение, устарело */
  --risk:#96382B;   --risk-soft:#F7E7E3;   /* риск, отказ источника, дефицит */

  /* Четвёртый канал — «здесь вмешался человек». Отдельная ось: закупщик обязан
     отличать «система предупреждает» от «я это поправил», а зелёный, охра и
     кирпич уже заняты состоянием. */
  --hand:#3A5A78;   --hand-soft:#E8EEF4;

  --font-sans:"IBM Plex Sans",system-ui,-apple-system,"Segoe UI",sans-serif;
  --font-serif:"IBM Plex Serif",Georgia,"Times New Roman",serif;
  --font-mono:"IBM Plex Mono",ui-monospace,"SFMono-Regular",Menlo,monospace;

  --r:2px;                /* острый угол — инструмент, а не приложение */
  --row:36px;             /* высота строки таблицы, комфортная */
  --row-compact:28px;
  --wrap:1120px;
}

@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]){
    color-scheme:dark;
    --ground:#131513;
    --panel:#1E211E;      /* поднято от исходных #1B1E1B: на таблице с волосяной
                             сеткой панель на #131513 сливалась с фоном */
    --panel-2:#242823;
    --edge:#333833;       /* поднято от #2E332E по той же причине */
    --edge-2:#282D28;
    --ink:#EDEFEA; --ink-2:#A9AFA4; --ink-3:#767D73;
    --done:#6FBF90;  --done-soft:#1E2C24;
    --ahead:#D8A94B; --ahead-soft:#2B2519;
    --risk:#D98576;  --risk-soft:#2E1D19;
    --hand:#8FB6D8;  --hand-soft:#1B2733;
  }
}

:root[data-theme="dark"]{
  color-scheme:dark;
  --ground:#131513; --panel:#1E211E; --panel-2:#242823;
  --edge:#333833; --edge-2:#282D28;
  --ink:#EDEFEA; --ink-2:#A9AFA4; --ink-3:#767D73;
  --done:#6FBF90;  --done-soft:#1E2C24;
  --ahead:#D8A94B; --ahead-soft:#2B2519;
  --risk:#D98576;  --risk-soft:#2E1D19;
  --hand:#8FB6D8;  --hand-soft:#1B2733;
}

/* ───────────────────────── ОСНОВА ───────────────────────── */

*{box-sizing:border-box}

body{
  margin:0;
  background:var(--ground);
  color:var(--ink);
  font-family:var(--font-sans);
  font-size:15px;
  line-height:1.55;
  -webkit-font-smoothing:antialiased;
}

.wrap{
  max-width:var(--wrap);
  margin:0 auto;
  padding:32px 22px 64px;
  display:flex; flex-direction:column; gap:32px;
}
.wrap--wide{max-width:1600px}   /* экран расчёта: таблица шире текста */

a{color:inherit; text-decoration-color:var(--ink-3); text-underline-offset:2px}
a:hover{text-decoration-color:var(--hand)}

:focus-visible{
  outline:2px solid var(--hand);
  outline-offset:2px;
  border-radius:var(--r);
}

@media (prefers-reduced-motion:reduce){
  *{animation-duration:.01ms !important; animation-iteration-count:1 !important;
    transition-duration:.01ms !important}
}

/* ───────────────────────── ТИПОГРАФИКА ───────────────────────── */

/* Надзаголовок: моношириной, разрядкой и капителью. Единственная роль —
   сказать, где ты находишься, не занимая места заголовка. */
.eyebrow{
  font-family:var(--font-mono); font-size:11.5px; font-weight:500;
  letter-spacing:.14em; text-transform:uppercase; color:var(--ink-3);
}

h1{
  font-family:var(--font-serif); font-weight:600;
  font-size:clamp(26px,4vw,40px); line-height:1.14; margin:6px 0 0;
  text-wrap:balance; letter-spacing:-.01em;
}
h2{
  font-family:var(--font-serif); font-size:19px; font-weight:600;
  margin:0 0 12px; padding-bottom:8px; border-bottom:1px solid var(--edge);
  text-wrap:balance;
}
h3{font-family:var(--font-sans); font-size:15px; font-weight:600; margin:0}

/* Антиква — только заголовок страницы и заголовок раздела. Внутри таблиц и
   форм её нет никогда: на плотной сетке она читается как опечатка. */

.lede{margin:14px 0 0; max-width:62ch; color:var(--ink-2)}
p{margin:0 0 12px; max-width:70ch}
p:last-child{margin-bottom:0}
small,.small{font-size:13px; color:var(--ink-2)}
.micro{font-family:var(--font-mono); font-size:11px; letter-spacing:.08em;
       text-transform:uppercase; color:var(--ink-3)}

/* Любое количество в системе — моноширинное, с табличными цифрами и по правому
   краю. На тысячах строк это разница между «читается» и «не читается». */
.num,td.num,th.num{
  font-family:var(--font-mono); font-variant-numeric:tabular-nums;
  text-align:right; letter-spacing:-.01em;
}
.figure{text-align:right; line-height:1}
.figure b{
  display:block; font-family:var(--font-mono); font-weight:600;
  font-size:clamp(48px,8vw,80px); color:var(--done);
  letter-spacing:-.03em; font-variant-numeric:tabular-nums;
}
.figure span{font-family:var(--font-mono); font-size:12px; color:var(--ink-3);
             letter-spacing:.1em; text-transform:uppercase}

/* ───────────────────────── ШАПКА ПРИЛОЖЕНИЯ ───────────────────────── */

.topbar{
  background:var(--panel); border-bottom:1px solid var(--edge);
  position:sticky; top:0; z-index:30;
}
.topbar__in{
  max-width:1600px; margin:0 auto; padding:10px 22px;
  display:flex; flex-wrap:wrap; gap:10px 22px; align-items:center;
}
.wordmark{
  font-family:var(--font-mono); font-size:13px; font-weight:600;
  letter-spacing:.08em; text-transform:uppercase; white-space:nowrap;
}
.wordmark span{color:var(--ink-3); font-weight:400}
.topnav{display:flex; flex-wrap:wrap; gap:4px 16px; font-size:14px}
.topnav a{text-decoration:none; color:var(--ink-2); padding:3px 0;
          border-bottom:2px solid transparent}
.topnav a:hover{color:var(--ink)}
.topnav a[aria-current="page"]{color:var(--ink); font-weight:600;
                               border-bottom-color:var(--ink)}

/* ───────────────────────── ПАНЕЛИ И СЕТКИ ───────────────────────── */

.panel{background:var(--panel); border:1px solid var(--edge); border-radius:var(--r);
       padding:18px 20px}
.panel--flush{padding:0; overflow:hidden}

/* `minmax(300px,…)` требует окна от 344 px и на 320 вылезает за край —
   поймано при переводе экранов приёмки 22.08.2026. `min(300px,100%)`
   даёт колонке сжаться до ширины экрана вместо переполнения. */
.cols{display:grid; grid-template-columns:repeat(auto-fit,minmax(min(300px,100%),1fr)); gap:26px}

/* Счётчики: сетка на волосяных линиях — фон просвечивает в зазор 1px, рамок
   рисовать не нужно. */
.counts{
  display:grid; grid-template-columns:repeat(auto-fit,minmax(140px,1fr));
  gap:1px; background:var(--edge); border:1px solid var(--edge);
  border-radius:var(--r); overflow:hidden;
}
.count{background:var(--panel); padding:14px 16px}
.count b{display:block; font-family:var(--font-mono); font-size:24px; font-weight:600;
         font-variant-numeric:tabular-nums; letter-spacing:-.02em}
.count span{font-size:12px; color:var(--ink-2)}
.count.is-risk b{color:var(--risk)}
.count.is-ahead b{color:var(--ahead)}
.count.is-done b{color:var(--done)}
/* Плитка на весь остаток строки: длинное число не должно ломаться пополам,
   пока рядом пустует полсетки. Одна плитка на экран, и только там, где число
   длинное, — не свойство всех .count. */
.count--wide{grid-column:1/-1}

/* Заполнитель последней строки. Плиток бывает нечётное число, и на двух
   столбцах рядом с последней светится пустая ячейка цвета кромки — сетка
   держит хайрлайны фоном, и «пусто» выглядит как серый блок. Псевдоэлемент
   идёт последним элементом сетки и закрывает ровно этот остаток при любом
   числе столбцов. Виден на осмотре 23.08.2026, экран завершения на 390 px. */
.counts::after{content:""; background:var(--panel)}

/* ───────────────────────── ПАНЕЛЬ ПАРАМЕТРОВ ───────────────────────── */

.toolbar{
  background:var(--panel); border:1px solid var(--edge); border-radius:var(--r);
  padding:14px 16px; display:flex; flex-wrap:wrap; gap:14px 18px; align-items:flex-end;
}
.toolbar .field{margin:0}
.toolbar__spacer{flex:1 1 auto}

/* ───────────────────────── ФОРМЫ ───────────────────────── */

/* Атрибут hidden сильнее любых display у классов (.field, .btn): иначе скрытые
   поля «Покрытие 2/3» видны всегда (red-team 07.10.2026). */
[hidden]{display:none !important}
.field{display:flex; flex-direction:column; gap:5px; margin:0 0 16px; max-width:26rem}
.field--narrow{max-width:11rem}
.field--wide{max-width:44rem}

.field > label{
  font-family:var(--font-mono); font-size:11px; font-weight:500;
  letter-spacing:.1em; text-transform:uppercase; color:var(--ink-3);
}

input[type=text],input[type=email],input[type=number],input[type=date],
input[type=search],select,textarea{
  font-family:var(--font-sans); font-size:15px; color:var(--ink);
  background:var(--panel); border:1px solid var(--edge); border-radius:var(--r);
  padding:8px 10px; width:100%; max-width:100%; min-height:38px;
}
/* Количества вводятся моноширинным — то же начертание, что в таблице, иначе
   введённое число выглядит чужим рядом с расчётным. */
input[type=number],input.num{font-family:var(--font-mono);
                             font-variant-numeric:tabular-nums; text-align:right}
textarea{min-height:90px; resize:vertical}
select{
  /* Список берёт ширину по самому длинному пункту и распирает страницу —
     проверено на соседнем проекте: пункт с именем поставщика растянул экран
     до 1338px. Ширину ограничиваем здесь, один раз. */
  text-overflow:ellipsis;
}
input:disabled,select:disabled,textarea:disabled{
  background:var(--panel-2); color:var(--ink-3); cursor:not-allowed;
}
::placeholder{color:var(--ink-3); opacity:1}

.hint{font-size:12.5px; color:var(--ink-3)}
.field.is-invalid input,.field.is-invalid select,.field.is-invalid textarea{
  border-color:var(--risk);
}
.field .error{font-size:12.5px; color:var(--risk)}

/* Поле, которое человек изменил, помечается той же осью, что и правленая
   ячейка таблицы, — чтобы правка читалась одинаково везде. */
.is-edited input,input.is-edited{
  border-left:3px solid var(--hand); background:var(--hand-soft);
}

/* ───────────────────────── КНОПКИ ───────────────────────── */

.btn{
  font-family:var(--font-sans); font-size:14px; font-weight:600; line-height:1;
  padding:10px 16px; min-height:38px; border-radius:var(--r);
  border:1px solid var(--edge); background:var(--panel); color:var(--ink);
  cursor:pointer; display:inline-flex; align-items:center; gap:8px;
  white-space:nowrap;
}
.btn:hover{background:var(--panel-2)}
.btn:active{transform:translateY(1px)}
.btn:disabled{opacity:.45; cursor:not-allowed; transform:none}

/* Основное действие залито чернилами, а не акцентом: акцент в этой системе
   означает «человек вмешался», и кнопка не должна его занимать. */
.btn--primary{background:var(--ink); border-color:var(--ink); color:var(--ground)}
.btn--primary:hover{background:var(--ink-2); border-color:var(--ink-2)}
.btn--ghost{background:transparent; border-color:transparent; color:var(--ink-2)}
.btn--ghost:hover{background:var(--panel-2); color:var(--ink)}
.btn--danger{background:var(--risk-soft); border-color:var(--risk); color:var(--risk)}
.btn--sm{font-size:13px; padding:6px 10px; min-height:30px}

/* На телефоне палец не попадает в 30px — цель не меньше 44px. */
@media (max-width:640px){
  .btn{min-height:44px; padding:12px 18px}
  .btn--sm{min-height:38px}
}

/* ───────────────────────── ПЛАШКИ СОСТОЯНИЯ ───────────────────────── */

.pill{
  display:inline-flex; align-items:center; gap:5px;
  font-family:var(--font-mono); font-size:10.5px; font-weight:500;
  letter-spacing:.07em; text-transform:uppercase;
  padding:3px 7px; border-radius:var(--r); border:1px solid transparent;
  white-space:nowrap;
}
.pill--done{background:var(--done-soft); color:var(--done); border-color:var(--done)}
.pill--ahead{background:var(--ahead-soft); color:var(--ahead); border-color:var(--ahead)}
.pill--risk{background:var(--risk-soft); color:var(--risk); border-color:var(--risk)}
.pill--hand{background:var(--hand-soft); color:var(--hand); border-color:var(--hand)}
.pill--muted{background:var(--panel-2); color:var(--ink-3); border-color:var(--edge)}

/* ───────────────────────── СООБЩЕНИЯ ───────────────────────── */

.alert{
  border:1px solid var(--edge); border-left:3px solid var(--ink-3);
  border-radius:var(--r); padding:12px 16px; background:var(--panel);
  overflow-wrap:anywhere;
}
.alert h3{margin:0 0 4px}
.alert p{margin:0; font-size:13.5px; color:var(--ink-2)}
.alert--warn{border-left-color:var(--ahead); background:var(--ahead-soft)}
.alert--risk{border-left-color:var(--risk); background:var(--risk-soft)}
.alert--done{border-left-color:var(--done); background:var(--done-soft)}

.empty{
  border:1px dashed var(--edge); border-radius:var(--r);
  padding:36px 24px; text-align:center; color:var(--ink-2);
}
.empty strong{display:block; color:var(--ink); margin-bottom:6px}

/* ───────────────────────── ТАБЛИЦА ДАННЫХ ───────────────────────── */

/* Широкое едет внутри своего контейнера, страница вбок не уезжает никогда. */
.table-wrap{
  overflow-x:auto; overflow-y:visible;
  border:1px solid var(--edge); border-radius:var(--r); background:var(--panel);
  max-width:100%;
  /* Тень у того края, за которым ещё есть содержимое. Без неё на телефоне
     таблица выглядит просто обрезанной: осмотр 23.08.2026 показал столбец
     «РАЗ…» у края экрана и ни намёка, что его можно долистать.
     `local` у первых двух слоёв — они едут вместе с содержимым и «съедают»
     тень, когда доехали до края; `scroll` у вторых — они стоят на месте. */
  background-image:
    linear-gradient(to right, var(--panel) 40%, transparent),
    linear-gradient(to left,  var(--panel) 40%, transparent),
    linear-gradient(to right, rgba(0,0,0,.10), transparent 14px),
    linear-gradient(to left,  rgba(0,0,0,.10), transparent 14px);
  background-repeat:no-repeat;
  background-size:32px 100%, 32px 100%, 14px 100%, 14px 100%;
  background-position:0 0, 100% 0, 0 0, 100% 0;
  background-attachment:local, local, scroll, scroll;
}

/* Закреплённая шапка имеет смысл только внутри собственного вертикального
   прокрутчика: при прокрутке всей страницы она прилипает к краю окна и
   уходит под шапку сайта. Экран расчёта использует этот вариант. */
.table-wrap--tall{max-height:calc(100vh - 230px); overflow-y:auto}

table.data{border-collapse:separate; border-spacing:0; width:100%; font-size:13.5px}

/* Таблица, в ячейках которой предложения, а не числа. Без нижней границы
   ширины `width:100%` ужимает столбцы до одного слова в строке, и на 390 px
   получается стена вертикального текста: `overflow-x:auto` при этом молчит,
   потому что таблица честно уложилась в контейнер. Осмотр 23.08.2026 —
   экран поставки, таблица замечаний входного контроля. Нижняя граница
   возвращает столбцам читаемую ширину и включает боковую прокрутку. */
table.data--text{min-width:32rem}

table.data th{
  position:sticky; top:0; z-index:2;
  background:var(--panel-2); color:var(--ink-3);
  font-family:var(--font-mono); font-size:10.5px; font-weight:500;
  letter-spacing:.07em; text-transform:uppercase; text-align:left;
  padding:8px 10px; border-bottom:1px solid var(--edge); white-space:nowrap;
}
table.data th.num{text-align:right}

table.data td{
  padding:0 10px; height:var(--row);
  border-bottom:1px solid var(--edge-2); vertical-align:middle;
}
table.data tbody tr:last-child td{border-bottom:none}
table.data tbody tr:hover td{background:var(--panel-2)}

/* Артикул закреплён слева: при 20 колонках прокрутка вправо иначе оставляет
   человека наедине с числами без имени строки. */
table.data .sticky-col{
  position:sticky; left:0; z-index:1;
  background:var(--panel); border-right:1px solid var(--edge);
  font-family:var(--font-mono); font-weight:600; white-space:nowrap;
}
table.data tbody tr:hover .sticky-col{background:var(--panel-2)}
table.data th.sticky-col{z-index:3; background:var(--panel-2)}

/* Плотный режим — не украшение: на трёх тысячах строк это четверть экрана. */
[data-density="compact"] table.data td{height:var(--row-compact)}
[data-density="compact"] table.data{font-size:12.5px}

/* Ячейка «Заказ» — единственное место, где человек переписывает машину.
     Считанное системой — тихое. Поправленное — с меткой на своей оси. */
table.data td.is-edited{
  background:var(--hand-soft);
  box-shadow:inset 3px 0 0 var(--hand);
  font-weight:600;
}
table.data tr.is-top .sticky-col{box-shadow:inset 3px 0 0 var(--done)}

/* Строка размера под артикулом — сдвиг и тихий цвет, а не отдельная таблица. */
table.data tr.is-child .sticky-col{padding-left:26px; font-weight:400; color:var(--ink-2)}

/* Ссылка «как получено число» — слово, а не иконка «i»: за ней целый разбор
   расчёта, и человек должен это понимать до нажатия. */
.explain-link{
  font-family:var(--font-mono); font-size:10.5px; letter-spacing:.06em;
  text-transform:uppercase; color:var(--ink-3); text-decoration:none;
  border-bottom:1px dotted var(--ink-3); white-space:nowrap;
}
.explain-link:hover{color:var(--hand); border-bottom-color:var(--hand)}

/* Разбор числа: пары «показатель → значение», значения моношириной. */
.explain{display:grid; grid-template-columns:max-content minmax(0,1fr); gap:4px 16px;
         margin:0; font-size:13.5px}
.explain dt{color:var(--ink-2)}
.explain dd{margin:0; font-family:var(--font-mono); font-variant-numeric:tabular-nums;
            overflow-wrap:anywhere}

/* ───────────────────────── СТАТУСНЫЕ СТРАНИЦЫ ───────────────────────── */

.head{display:grid; grid-template-columns:minmax(0,1fr) auto; gap:30px; align-items:end}
@media (max-width:640px){
  .head{grid-template-columns:1fr}
  .figure{text-align:left}
}

.rail{display:flex; gap:5px; flex-wrap:wrap}
.stage{
  flex:1 1 92px; min-width:92px; background:var(--panel);
  border:1px solid var(--edge); border-top:3px solid var(--edge);
  border-radius:var(--r); padding:11px 11px 13px;
  display:flex; flex-direction:column; gap:3px;
}
.stage.is-done{border-top-color:var(--done); background:var(--done-soft)}
.stage.is-ahead{border-top-color:var(--ahead)}
.stage code{font-family:var(--font-mono); font-size:13px; font-weight:600; color:var(--ink)}
.stage small{font-size:11.5px; color:var(--ink-2); line-height:1.35}
.stage em{font-family:var(--font-mono); font-style:normal; font-size:10.5px;
          letter-spacing:.08em; text-transform:uppercase; margin-top:2px}
.stage.is-done em{color:var(--done)}
.stage.is-ahead em{color:var(--ahead)}

.list{list-style:none; margin:0; padding:0; display:flex; flex-direction:column; gap:11px}
.list li{display:grid; grid-template-columns:16px minmax(0,1fr); gap:10px; align-items:baseline}
.list strong{font-weight:600}
.list p{margin:2px 0 0; font-size:13.5px; color:var(--ink-2); max-width:none}
.tick{font-family:var(--font-mono); font-size:13px; color:var(--done); font-weight:600}
.dot{font-family:var(--font-mono); font-size:13px; color:var(--ahead); font-weight:600}
.bang{font-family:var(--font-mono); font-size:13px; color:var(--risk); font-weight:600}

.next{display:flex; flex-direction:column; gap:12px}
.block{background:var(--panel); border:1px solid var(--edge);
       border-left:3px solid var(--ahead); border-radius:var(--r); padding:14px 16px}
.block h3{display:flex; justify-content:space-between; gap:12px; align-items:baseline}
.block h3 span{font-family:var(--font-mono); font-size:11px; letter-spacing:.08em;
               text-transform:uppercase; color:var(--ink-3); white-space:nowrap}
.block p{margin:6px 0 0; font-size:13.5px; color:var(--ink-2)}
.block.heavy{border-left-color:var(--risk)}

.risks{background:var(--risk-soft); border:1px solid var(--edge);
       border-radius:var(--r); padding:18px 20px}
.risks h2{border-bottom-color:var(--edge)}

footer{border-top:1px solid var(--edge); padding-top:16px; font-size:12.5px; color:var(--ink-3)}
footer code{font-family:var(--font-mono)}

/* ───────────────────────── СЛУЖЕБНОЕ ───────────────────────── */

.stack{display:flex; flex-direction:column; gap:12px}
.row{display:flex; flex-wrap:wrap; gap:10px; align-items:center}
.sr-only{position:absolute; width:1px; height:1px; padding:0; margin:-1px;
         overflow:hidden; clip:rect(0 0 0 0); white-space:nowrap; border:0}

/* `code` без собственного правила остаётся шрифтом браузера: разметка
   опиралась на моноширинность, и после замены системы значения поехали.
   Здесь же — перенос длинных значений: sha256 в журнале растягивал
   таблицу шире экрана. */
code{font-family:var(--font-mono); font-variant-numeric:tabular-nums; font-size:.94em;
  overflow-wrap:anywhere}

/* Шапка делила место между заголовком и ОДНИМ соседом — третий элемент
   уезжал во второй ряд. Пусть подписи живут своей строкой. */
.head{flex-wrap:wrap}

/* ─────────── предметное: приёмка поставок ─────────── */

/* Бирка и УИН. Шестнадцать цифр читают и сверяют глазами весь день,
   поэтому здесь моноширинный шрифт и лёгкий разряд между знаками. */
.uin,.article{font-family:var(--font-mono); font-variant-numeric:tabular-nums; letter-spacing:.03em}

/* Поле сканирования. Сканер работает как клавиатура: поле само держит
   фокус, и приёмщице не приходится щёлкать мышью между бирками. */
.scan-field input{font-family:var(--font-mono); font-size:19px; letter-spacing:.06em; padding:11px 13px}

/* Шесть статусов строки поставки (спека §6.2). Конечных два — «Готов» и
   «Исключена»; «Требует разбора» и «Ошибка» временные, из них есть выход. */
.pill--ready{background:var(--done-soft); border-color:var(--done); color:var(--done)}
.pill--review,.pill--repeat{background:var(--ahead-soft); border-color:var(--ahead); color:var(--ahead)}
.pill--error,.pill--excluded{background:var(--risk-soft); border-color:var(--risk); color:var(--risk)}

/* Правка приёмщицы — синим, отдельно от замечаний системы. */
.edited{color:var(--hand)}
.edited-mark{background:var(--hand-soft); border-left:3px solid var(--hand); padding:2px 8px; border-radius:var(--r)}

/* Кандидаты. Фотография — главный инструмент сверки: реквизитов для
   сравнения почти нет (вес заполнен у 0,1 % карточек), и два похожих
   кольца различают глазами. Снимок обязан быть крупным и не ломать 320 px. */
.cards{display:grid; grid-template-columns:repeat(auto-fill,minmax(min(230px,100%),1fr)); gap:14px}
.card-photo{aspect-ratio:1; width:100%; object-fit:contain; background:var(--panel-2);
  border:1px solid var(--edge); border-radius:var(--r)}
.card-nophoto{aspect-ratio:1; display:flex; align-items:center; justify-content:center;
  text-align:center; font-size:12.5px; color:var(--ink-3); background:var(--panel-2);
  border:1px dashed var(--edge); border-radius:var(--r); padding:10px}

/* Экран выбора карточки — сетка 5 × 2 по ТЗ заказчика (Олег, 25.09.2026,
   задача 2775): десять окон на экран, в окне верхняя половина — фото,
   нижняя — четыре реквизита и две кнопки. Сверка целиком — в окне
   «Подробнее» (<dialog>) поверх сетки. До 25.09 здесь был список строк со
   значками ✓/≠; заказчик назвал значки непонятными, а раскрытие не
   помещалось на экран его ноутбука (~1280 × 600 полезной высоты).

   Высота фото привязана к высоте окна браузера (vh): сетка обязана
   влезать в экран по вертикали, а ширина у окна и так есть. */
.wrap--pick{max-width:1600px; padding:6px 18px 24px; gap:5px}
.wrap--pick > .head{display:flex; flex-wrap:wrap; align-items:baseline; gap:4px 16px}
.wrap--pick > .head h1{font-size:20px; margin:0}
.wrap--pick > .head .eyebrow{margin:0; max-width:none}
.wrap--pick .hand{line-height:1.4; padding:3px 10px}
.wrap--pick .hand-title,.wrap--pick .hand-line{font-size:12px; line-height:1.4}
.wrap--pick > .alert{padding-top:3px; padding-bottom:3px; font-size:13.5px; max-width:none}
.wrap--pick > .tip{margin:0}
.pick-rule{margin:0}
.pick-count{margin:2px 0 0; font-size:13.5px; max-width:none}
.pick-count .pick-h2{font-size:15px}
.hand{border:1px solid var(--edge); border-left:3px solid var(--ahead); background:var(--panel);
  border-radius:var(--r); padding:4px 12px; margin:0;
  position:sticky; top:52px; z-index:2}   /* под липкой шапкой; эталон виден, пока листаешь сетку */
.hand-title{display:inline; font-family:var(--font-sans); font-size:12px; margin:0 6px 0 0; padding:0; border:0;
  text-transform:uppercase; letter-spacing:.04em; color:var(--ink-3)}
.hand-title + .hand-line{display:inline}
.hand-line{margin:0; max-width:none; font-size:13.5px; line-height:1.55}

.pick-grid{display:grid; grid-template-columns:repeat(5,minmax(0,1fr)); gap:6px}
section.panel.pick{padding:4px; margin:0; display:flex; flex-direction:column; gap:3px; min-width:0}
.pick-thumb{position:relative; height:clamp(84px, calc(50vh - 232px), 300px)}
.card-thumb{width:100%; height:100%; object-fit:contain; background:var(--panel-2);
  border:1px solid var(--edge-2); border-radius:var(--r); display:block}
.thumb-empty{display:flex; width:100%; height:100%; align-items:center; justify-content:center;
  text-align:center; font-size:11.5px; color:var(--ink-3); background:var(--panel-2);
  border:1px dashed var(--edge); border-radius:var(--r); padding:4px}
.pick-marks{position:absolute; top:3px; left:3px; right:3px; display:flex; flex-wrap:wrap; gap:3px}
.pick-marks .pill{font-size:10.5px; padding:0 5px; line-height:1.5; white-space:normal}
.pick-facts{display:grid; grid-template-columns:auto minmax(0,1fr); gap:0 6px; margin:0;
  font-size:12.5px; line-height:1.35}
.pick-facts dt{color:var(--ink-3); font-size:11.5px; white-space:nowrap; cursor:default}
.pick-facts dd{margin:0; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.pick-facts dd.article{font-weight:600}
.pick-act{display:flex; gap:4px; margin-top:auto}
.pick-act form{margin:0; flex:1}
.pick-act .btn{width:100%; min-height:26px; padding:3px 6px; font-size:12.5px}
.pick-act .pick-open{flex:1}

/* «Подробнее» — карточка на весь экран: крупное фото слева, справа таблица
   расхождений и реквизиты. На 1280 × 650 помещается без прокрутки таблицы. */
.pick-dialog{width:min(1280px, 96vw); max-width:none; max-height:94vh; padding:10px 14px 12px;
  border:1px solid var(--edge); border-radius:var(--r); background:var(--panel); color:var(--ink)}
.pick-dialog::backdrop{background:rgba(20,22,20,.55)}
.pick-dialog__head{display:grid; grid-template-columns:auto minmax(0,1fr) auto; gap:12px;
  align-items:baseline; margin-bottom:8px}
.pick-dialog__head h2{font-size:17px; margin:0; padding:0; border:0}
.pick-dialog__head p{margin:0; max-width:none; overflow:hidden; text-overflow:ellipsis; white-space:nowrap}
.pick-close{font-size:18px; min-height:32px; padding:2px 10px}
.pick-detail{display:grid; grid-template-columns:minmax(0,5fr) minmax(0,6fr); gap:16px}
.pick-detail .field{margin:0}
.pick-detail .card-photo{width:100%; height:min(76vh, 640px); object-fit:contain; aspect-ratio:auto}
.pick-detail .card-nophoto{height:min(40vh, 320px); aspect-ratio:auto}
.pick-body h3{margin:0 0 4px}
.pick-body .table-wrap + h3{margin-top:10px}

@media (max-width:1100px){
  .pick-grid{grid-template-columns:repeat(4,minmax(0,1fr))}
}
@media (max-width:760px){
  .hand{position:static}   /* на телефоне плашка в три экрана — липкой она закрыла бы сетку */
  .pick-grid{grid-template-columns:repeat(2,minmax(0,1fr))}
  .pick-thumb{height:150px}
  .pick-act{flex-direction:column}
  .pick-dialog{width:100vw; max-height:100dvh; height:100dvh; margin:0; padding:8px 10px}
  .pick-dialog__head{grid-template-columns:minmax(0,1fr) auto}
  .pick-dialog__head p{grid-column:1 / -1; grid-row:2; white-space:normal}
  .pick-detail{grid-template-columns:minmax(0,1fr)}
  .pick-detail .card-photo{height:auto; max-height:50vh}
  .pick-dialog .pill{white-space:normal}   /* «сравнить не с чем» — в две строки, а не за край */
}

/* ─────────── подсказки на экранах и страница справки ─────────── */

/* Подсказка тихая по замыслу: закрытая — это строка ростом с текст рядом,
   с кружком «?» вместо кричащей плашки. Лишняя подсказка над очевидным
   раздражает сильнее, чем её отсутствие, и заметная рамка вокруг каждой
   превратила бы экран приёмки в стену объяснений.

   <details>/<summary> — нативные, без единой строки JavaScript: раскрытие
   работает мышью, пальцем, с клавиатуры и при выключенном JS. Раскрытое
   тело уходит вниз своим потоком, сетку не трогает и ничего не перекрывает:
   прыгает только то, что ниже, и ровно на свою высоту. */
.tip{max-width:70ch; margin:0 0 14px}
.tip > summary{
  display:inline-flex; align-items:center; gap:7px;
  cursor:pointer; list-style:none;
  font-size:13px; color:var(--ink-3); padding:2px 0;
}
/* Стрелка-треугольник браузера здесь лишняя — её роль играет кружок «?».
   Двумя правилами: `list-style` снимает её в Firefox, псевдоэлемент — в
   вебките. */
.tip > summary::-webkit-details-marker{display:none}
.tip > summary::before{
  content:"?"; flex:none;
  width:15px; height:15px; border-radius:50%;
  border:1px solid var(--ink-3);
  font-family:var(--font-mono); font-size:10px; font-weight:600; line-height:1;
  display:inline-flex; align-items:center; justify-content:center;
}
.tip > summary:hover,.tip[open] > summary{color:var(--ink)}
/* Тело — с отбивкой волосяной линейкой, а не панелью: линейка говорит
   «это про то, что выше» и не спорит с панелями экрана за внимание. */
.tip__body{
  margin:4px 0 0 7px; padding:2px 0 2px 15px;
  border-left:1px solid var(--edge);
  font-size:13.5px; color:var(--ink-2);
}
.tip__body p{margin:0 0 6px; max-width:none}
.tip__body p:last-child{margin-bottom:0}

/* Шапка приложения прилипшая: без этого отступа переход по якорю ставил бы
   заголовок раздела ровно под неё, и приёмщица читала бы справку со второго
   абзаца. */
.help-section{scroll-margin-top:84px}
.help-short{color:var(--ink-2)}

/* Оглавление в колонках по ширине, а не по числу: `columns:16rem` сам даёт
   одну колонку на телефоне и две-три на ноутбуке, и горизонтальной прокрутки
   не возникает ни при какой ширине окна. */
.help-toc ul{columns:16rem; column-gap:26px; list-style:none; margin:0; padding:0}
.help-toc li{break-inside:avoid; padding:3px 0; font-size:13.5px}

/* ─────────── экран партии: восемь зон по макету заказчика ───────────
   Олег, 25.09.2026 (задача 2775): все блоки партии — на одном экране, без
   прокрутки страницы. Сетка 3 × 3, пропорции столбцов и строк — из его
   файла «Изменение макета приёмки.xlsx». Если содержимое зоны длиннее её
   клетки, прокручивается сама зона. Главные кнопки зон (выбор карточки,
   «Завершить партию», «К комплектам») стоят вверху своих зон — их видно
   без прокрутки и на ноутбуке 1280 × 650.

   Узкое окно (< 1000 px) — зоны идут столбцом, страница прокручивается как
   раньше: восемь клеток на телефоне не поместить. */
.zones{display:flex; flex-direction:column; gap:12px}
.zone{position:relative; min-width:0; background:var(--panel); border:1px solid var(--edge);
  border-radius:var(--r); padding:10px 12px}
.zone:empty{display:none}
.zones h1{margin:0}
.zones h2{margin:0 0 6px; padding-bottom:4px}
.zones h2:not(:first-child){margin-top:10px}
.zones p{margin:0 0 6px}
.zones .field{margin:0 0 6px; gap:2px; max-width:none}
.zones .row{margin-top:4px}
.zones .tip{margin:0 0 6px}
.zones .cols{display:grid; grid-template-columns:minmax(0,1fr) minmax(0,1fr); gap:4px 12px}
.zones .table-wrap + .table-wrap{margin-top:8px}
.zone-lead{margin:0 0 6px}
.zones .cond{border:1px dashed var(--edge); padding:4px 8px; margin:8px 0 0; border-radius:var(--r)}
.zones .cond > summary{cursor:pointer}
.zones .cond > summary h2{display:inline; font-size:.95em; margin:0; padding:0; border:0}
.zones .cond[open] > summary{margin-bottom:6px}

@media (min-width:1000px){
  body.page-batch{height:100vh; display:flex; flex-direction:column; overflow:hidden;
    font-size:clamp(12px,0.78vw + 3px,14.5px)}
  .page-batch .topbar{position:static}
  .page-batch .topbar__in{max-width:none; padding:4px 16px; flex-wrap:nowrap; gap:18px}
  .page-batch .topnav{flex-wrap:nowrap; white-space:nowrap}
  /* Имя вошедшего переносится, а не выталкивает страницу вбок: у
     администратора в меню лишний пункт «Админка», и на 1280 длинное имя
     давало прокрутку вбок на 41 px (замер 26.09.2026). */
  .page-batch .who{white-space:normal; min-width:0; text-align:right; margin-left:auto}
  .wrap--batch{flex:1; min-height:0; width:100%; max-width:none; padding:8px 12px 10px; display:block}
  .zones{
    height:100%; display:grid; gap:8px;
    grid-template-columns:minmax(0,1.13fr) minmax(0,1fr) minmax(0,1fr);
    grid-template-rows:auto minmax(0,1.2fr) minmax(0,1fr);
    grid-template-areas:
      "z1 z23 z23"
      "z4 z5 z6"
      "z4 z7 z8";
  }
  .zone{min-height:0; overflow:auto}
  .zone:empty{display:block}
  .z1{grid-area:z1} .z23{grid-area:z23} .z4{grid-area:z4}
  .z5{grid-area:z5} .z6{grid-area:z6} .z7{grid-area:z7} .z8{grid-area:z8}
  .z56{grid-column:2 / 4; grid-row:2}
  .zone.z1,.zone.z23{padding:6px 12px}
  .z23{display:flex; flex-direction:column; justify-content:center}
  /* Зоны 7 и 8 (Олег, 26.09.2026): заголовки на одной высоте — обе зоны
     начинаются сверху; кнопки «Перенести УИН» и «К комплектам →» на одной
     высоте — обе прижаты к низу своей зоны. Строка сетки у них общая,
     поэтому низ совпадает. */
  .z7,.z8{display:flex; flex-direction:column}
  .z7 > form{flex:1 0 auto; display:flex; flex-direction:column}
  .zones .row--bottom{margin-top:auto; padding-top:4px}
  /* На 1280 × 650 зона 7 была выше своей клетки на 20 px, и кнопка
     «Перенести УИН» уезжала под прокрутку ниже «К комплектам →». */
  .z7 .tip{margin:0}
  .z7 .field{margin:0 0 2px}
  .z7 .row--bottom{padding-top:2px}
  .z7 .field label{line-height:1.15}
  .zones h1{font-size:clamp(20px,1.7vw,30px)}
  .zones h2{font-size:clamp(14px,1vw,17px)}
  .zones .hint{font-size:.88em}
  .z1 p.hint{max-width:none; font-size:.82em; line-height:1.4; margin:2px 0 4px}
  .z1 .tip{margin:0}
  .zones table.data{font-size:.93em}
  .zones table.data td,.zones table.data th{padding:2px 7px; height:auto; white-space:nowrap}
  .zones table.data th{padding:4px 7px}
  .zones .z5 table.data,.zones .z6 table.data{font-size:.85em}
  .zones .z5 table.data td + td,.zones .z6 table.data td,.zones .z6 table.data th{white-space:normal}
  .zones .field input,.zones .field select{padding:3px 6px; min-height:0; font-size:1em}
  .zones .btn{padding:5px 12px; min-height:0; font-size:.93em}
  .zones .btn--zone-act{font-size:1.05em; padding:8px 16px; width:12.5em; justify-content:center}
  .z6 td input:not([type]){width:100%; min-width:6em}
  .zones .alert{padding:4px 10px; font-size:.9em; max-width:none; margin:0 0 6px}
  /* Список кандидатов: столбец «сравнить и выбрать» не имеет права уехать
     за край зоны — это действие строки. Узкие отступы и перенос длинных
     названий дают ему место на 1280. */
  .zones .z5 table.data th,.zones .z5 table.data td{padding-left:4px; padding-right:4px}
  .zones .z5 table.data th,.zones .z6 table.data th,.zones .z7 table.data th{letter-spacing:0; white-space:normal}
  .zones .z6 table.data th,.zones .z6 table.data td,.zones .z7 table.data th,.zones .z7 table.data td{padding-left:4px; padding-right:4px}
  .zones .z7 table.data td{white-space:normal; overflow-wrap:anywhere}
  .zones .z7 table.data{font-size:.85em}
  .zones .z6 .pill{white-space:normal}
  .zones .z5 table.data td:last-child{min-width:5.5em}
}

/* Переход «К комплектам» с экрана партии ведёт на якорь kits-batch-<id>
   (флажок партии в «Собрать комплект»). Отступ ставит строку ближе к
   середине экрана, а не под прилипшую шапку (просьба Олега, 25.09.2026). */
[id^="kits-batch-"]{scroll-margin-top:40vh}

/* ─────────── экран партии: эстетика по цветному макету Олега ───────────
   26.09.2026, задача 2775 (сообщение 814137). Всё ограничено .page-batch
   .zones: общая шапка и остальные экраны не меняются.

   Одна гарнитура — Golos Text (файлы в fonts.css, со своего сервера).
   Моноширинный Plex здесь больше не нужен: цифры УИН и сумм держат столбик
   за счёт tabular-nums — у Golos все цифры одной ширины. Иерархия по
   функции: номер партии крупнее всего, заголовки зон жирные, пояснения и
   подписи таблиц — мелко. */
.page-batch .zones{--r:8px}
.page-batch .zones,.page-batch .zones *{font-family:"Golos Text",system-ui,-apple-system,"Segoe UI",sans-serif;
  font-variant-numeric:tabular-nums}
.page-batch .zones h1{font-weight:700; letter-spacing:-.01em}
.page-batch .zones h2{font-weight:700}
.page-batch .zones .hint{font-weight:400}
.page-batch .zones .eyebrow,.page-batch .zones label,.page-batch .zones table.data th{
  font-weight:600; letter-spacing:.04em; font-size:.78em}
.page-batch .zones .btn{font-weight:600}

/* Заливка зон — как на макете: изделия и шапка партии сиреневые, старинка
   розовая, вставки новинки зелёные. Остальные зоны белые. Внутренние
   таблицы прозрачные, чтобы зона читалась одним цветом. */
.page-batch .z1,.page-batch .z4{background:#e6e6fd}
.page-batch .z5{background:#fde6e6}
.page-batch .z6{background:#e6fde6}
@media (prefers-color-scheme:dark){
  :root:not([data-theme="light"]) .page-batch .z1,:root:not([data-theme="light"]) .page-batch .z4{background:#23233a}
  :root:not([data-theme="light"]) .page-batch .z5{background:#3a2323}
  :root:not([data-theme="light"]) .page-batch .z6{background:#233a23}
}
:root[data-theme="dark"] .page-batch .z1,:root[data-theme="dark"] .page-batch .z4{background:#23233a}
:root[data-theme="dark"] .page-batch .z5{background:#3a2323}
:root[data-theme="dark"] .page-batch .z6{background:#233a23}
:root[data-theme="dark"] .btn--gray{background:#3a3d3a; border-color:#4a4e4a}
@media (prefers-color-scheme:dark){:root:not([data-theme="light"]) .btn--gray{background:#3a3d3a; border-color:#4a4e4a}}
.page-batch .z1 .table-wrap,.page-batch .z4 .table-wrap,.page-batch .z5 .table-wrap,.page-batch .z6 .table-wrap,
.page-batch .z4 table.data,.page-batch .z5 table.data,.page-batch .z6 table.data,
.page-batch .z4 table.data th,.page-batch .z5 table.data th,.page-batch .z6 table.data th{background:transparent}

/* Верхняя полоса: три равные части — серая «Продолжить сканирование»,
   статус, главное действие (зелёное «Закрыть партию» или красное «Вернуть
   в работу»). Обе кнопки во всю ширину своей трети, поэтому одного размера. */
.strip{display:grid; grid-template-columns:repeat(3,minmax(0,1fr)); gap:12px; align-items:center}
.strip__part{min-width:0}
.strip__part--status{text-align:center}
.strip__part form{margin:0}
.page-batch .zones .btn--strip{text-decoration:none; width:100%; justify-content:center; font-size:1.1em; padding:12px 14px; white-space:normal}
/* Олег 28.09 (2775): серая кнопка возврата к сканированию в шапке «Комплектов» — компактная, как на странице партии */
.head__scan{grid-column:1 / -1; justify-self:start; text-decoration:none; justify-content:center; font-size:1.05em; padding:10px 22px}
.btn--gray{background:#d9d9d6; border-color:#c4c4c0; color:var(--ink)}
.btn--gray:hover{background:#cacac6}
.btn--go{background:var(--done); border-color:var(--done); color:var(--panel)}
.btn--go:hover{filter:brightness(1.1); background:var(--done)}
.btn--stop{background:var(--risk); border-color:var(--risk); color:var(--panel)}
.btn--stop:hover{filter:brightness(1.1); background:var(--risk)}
.page-batch .z23 .alert{margin:6px 0 0}

/* Размер 1С поштучно в списке изделий партии (2775, 01.10.2026). */
form.size-row { display: flex; gap: 4px; align-items: center; margin: 0; }
form.size-row input { width: 4.5em; min-width: 0; padding: 2px 4px; }
form.batch-size-all { margin-top: 16px; }
form.size-row .btn { padding: 2px 8px; min-height: 0; }

/* Комплекты: комплект 1С у старинки и строки разбора (2775, 30.09.2026) */
table.data tr.is-kit-conflict td{background:var(--risk-soft)}
table.data tr.is-kit-conflict td:first-child{box-shadow:inset 3px 0 0 var(--risk)}
td.kit-1c small{color:var(--ink-2)}

/* Возврат поставщику: ответ на скан читается с вытянутой руки — кладовщик
   держит изделие и смотрит, в какую стопку его положить. */
.vozvrat-otvet{max-width:none}
.vozvrat-nomer{font-size:44px; font-weight:700; line-height:1.1; margin:2px 0 6px}

/* Страница поставок по макету Олега (2775, 09.10.2026): экран 1920 × 1080 не
   прокручивается; слева заведение поставки, справа карточки, длинный список
   прокручивается внутри своей области. Ниже 1000 px — прежняя лента: форма,
   потом список. Приём тот же, что у экрана партии (.page-batch). */
.postavki__spisok{margin-top:24px}
@media (min-width:1000px){
  body.page-postavki{height:100vh; display:flex; flex-direction:column; overflow:hidden}
  .page-postavki .topbar{position:static}
  .wrap--postavki{flex:1; min-height:0; width:100%; max-width:1600px; padding:20px 22px 16px; gap:14px}
  .postavki{flex:1; min-height:0; display:grid; gap:24px;
    grid-template-columns:minmax(300px,26rem) minmax(0,1fr)}
  .postavki__forma,.postavki__spisok{min-height:0; overflow-y:auto}
  .postavki__spisok{margin-top:0; padding-right:6px}
}

/* Страница ввода поставки по макету Олега (2775, 15.10.2026): экран не
   прокручивается, у каждой области своё место. Слева управление (узкая), в
   середине контроль и корректировка (широкая), справа сверху подготовка к
   приёмке, снизу постприёмка; длинное прокручивается внутри своей области.
   Уже 1280 px — прежняя лента в том же порядке. Приём тот же, что у страницы
   поставок (.page-postavki). */
.vvod{display:flex; flex-direction:column; gap:32px}
.vvod__oblast{display:flex; flex-direction:column; gap:20px; min-width:0}
/* Область прокручивается сама, блоки внутри не сжимаются: иначе flex срезал
   таблицу реквизитов до четырёх строк без прокрутки (замер 15.10). */
.vvod__oblast > *{flex-shrink:0}
.vvod__oblast > h2, .vvod__oblast section > h2, .vvod__oblast summary h2{margin-top:0}
details.redkoe > summary{cursor:pointer; list-style:none}
details.redkoe > summary::-webkit-details-marker{display:none}
details.redkoe > summary h2{display:inline-block}
details.redkoe > summary h2::before{content:"▸ "; color:var(--ink-3)}
details.redkoe[open] > summary h2::before{content:"▾ "}
@media (min-width:1280px){
  body.page-vvod{height:100vh; display:flex; flex-direction:column; overflow:hidden}
  .page-vvod .topbar{position:static}
  .wrap--vvod{flex:1; min-height:0; width:100%; max-width:none; padding:16px 22px 14px; gap:10px}
  .vvod{flex:1; min-height:0; display:grid; gap:14px 26px;
    grid-template-columns:minmax(240px,19rem) minmax(0,1.5fr) minmax(0,1fr);
    grid-template-rows:minmax(0,1fr) minmax(0,1fr);
    grid-template-areas:"upr kontrol podg" "upr kontrol post"}
  .vvod__oblast{min-height:0; overflow-y:auto; padding-right:6px}
  .vvod__upr{grid-area:upr}
  .vvod__kontrol{grid-area:kontrol}
  .vvod__podg{grid-area:podg}
  .vvod__post{grid-area:post; border-top:1px solid var(--edge); padding-top:12px}
  .vvod__upr .head{grid-template-columns:1fr; gap:6px}
  .vvod__upr h1{font-size:30px}
  /* Левая колонка — ряд шагов: кнопки обязаны быть видны на 1920 × 1080 без
     прокрутки, поэтому справочное в ней — плотнее, чем на остальных экранах. */
  .vvod__upr{gap:12px; font-size:14px}
  /* Когда сообщений слева много (отложено, комплекты, оповещение, ГИИС), колонка
     листается, и завершение уходило под сгиб даже на 1920 (замер red-team 15.10).
     Строка завершения прилипает к низу колонки и видна при любой длине. */
  .vvod__itog{position:sticky; bottom:0; background:var(--ground); padding:8px 0 2px; margin-top:auto}
  .vvod__upr .alert{padding:8px 12px; font-size:13px; line-height:1.4}
  .vvod__upr table.data td{height:26px; font-size:12.5px}
  .vvod__upr h2{font-size:16px; margin-bottom:6px; padding-bottom:4px}
  .vvod__upr p{margin:0}
}

/* Модуль Г (2866): снимок 1С и главное фото WB рядом на экране партии.
   Высота ограничена: зона 5 прокручивается внутри, а фото не должны вытеснить
   из неё кнопки отметки. */
.foto-g{display:flex; flex-direction:column; gap:8px; margin-top:12px}
.foto-g__pair{display:grid; grid-template-columns:1fr 1fr; gap:12px}
.foto-g figure{margin:0; display:flex; flex-direction:column; gap:4px; min-width:0}
.foto-g img{width:100%; height:200px; object-fit:contain; background:var(--panel-2); display:block}
.foto-g__empty{height:200px; display:flex; align-items:center; justify-content:center; text-align:center;
  background:var(--panel-2); color:var(--ink); font-size:13px; padding:8px}
.foto-g figcaption{font-size:13px}
