/* Общая палитра и базовые стили интерфейса.

   Палитра от 10.09.2026. Акцент — синий логотипа (#1f44ac), жёлтый
   логотипа остался фирменным цветом, но не акцентом: на светлом фоне
   он даёт контраст 1,7 при минимуме 4,5 и для текста непригоден.
   Тёмная тема переиспользует основу с операторских экранов АСУ ТП —
   она уже отработана в цеху. Контраст проверен: все пары проходят AA,
   большинство AAA, минимум 5,58.

   Один файл на все страницы: раньше цвета лежали в двух шаблонах,
   и вторая тема означала бы четыре набора переменных вместо двух.

   Тем три состояния, а не два:
     • ничего не выбрано — берётся системная (prefers-color-scheme);
     • data-theme="light" и data-theme="dark" на <html> — выбор человека,
       он сильнее системного.

   Табло (templates/board.html) берёт отсюда палитру и шапку, а вёрстку
   держит свою — крупную, под телевизор.

   Каждый элемент, описанный здесь, показан на витрине /ui (задача 0.9).
   Новый элемент сначала появляется там, потом на рабочем экране: иначе
   витрина через два месяца покажет половину того, что есть. */

:root {
  /* Фирменные цвета логотипа. Одни и те же в обеих темах: акцент
     от темы зависит, а знак предприятия — нет. Жёлтым нельзя красить
     текст на светлом фоне — контраст 1,7 при минимуме 4,5. */
  --brand-blue: #1f44ac;
  --brand-amber: #fabf09;

  --bg: #f2f4f7;
  --panel: #ffffff;
  --panel-alt: #f7f9fb;
  --ink: #14181d;
  --muted: #5c6672;
  --line: #d5dae1;
  --accent: #1f44ac;
  /* Текст на кнопке с акцентом. Не всегда белый: в тёмной теме акцент
     светлый, и белый на нём даёт контраст 2,3 — надпись на основной
     кнопке не читается. */
  --on-accent: #ffffff;
  --accent-soft: #e8eefb;
  --hover: #eef1f6;
  --chip: #e9edf2;
  --error-bg: #fdecea;
  --error-ink: #a4231d;
  --warn-bg: #fdf0cc;
  --warn-ink: #8a5300;
  --ok-bg: #e3f3ea;
  --ok-ink: #0f6b41;
  --scrim: rgba(12, 17, 24, .38);
  --shadow: 0 10px 30px rgba(16, 22, 32, .10);
  --drawer: 260px;

  /* Статусы заказа: принят, в работе, отправлен. Пара «цвет + подложка»,
     потому что на табло они читаются с нескольких метров, и одного
     текста мало. */
  --st-new: #1f44ac;    --st-new-bg: #e8eefb;
  --st-work: #8a5300;   --st-work-bg: #fdf0cc;
  --st-sent: #0f6b41;   --st-sent-bg: #e3f3ea;
}

@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) {
    --bg: #0b1015;
    --panel: #14191f;
    --panel-alt: #181e25;
    --ink: #e5e8ec;
    --muted: #9299a1;
    --line: #262d35;
    --accent: #78adfa;
    --on-accent: #0b1015;
    --accent-soft: #16233a;
    --hover: #1d2229;
    --chip: #21272e;
    --error-bg: #2e1517;
    --error-ink: #ff9a94;
    --warn-bg: #3a2c0f;
    --warn-ink: #f4b93c;
    --ok-bg: #14301f;
    --ok-ink: #48cd8c;
    --scrim: rgba(0, 0, 0, .60);
    --shadow: 0 12px 32px rgba(0, 0, 0, .50);

    --st-new: #78adfa;    --st-new-bg: #16233a;
    --st-work: #f4b93c;   --st-work-bg: #3a2c0f;
    --st-sent: #48cd8c;   --st-sent-bg: #14301f;
  }
}

:root[data-theme="dark"] {
  --bg: #0b1015;
  --panel: #14191f;
  --panel-alt: #181e25;
  --ink: #e5e8ec;
  --muted: #9299a1;
  --line: #262d35;
  --accent: #78adfa;
  --on-accent: #0b1015;
  --accent-soft: #16233a;
  --hover: #1d2229;
  --chip: #21272e;
  --error-bg: #2e1517;
  --error-ink: #ff9a94;
  --warn-bg: #3a2c0f;
  --warn-ink: #f4b93c;
  --ok-bg: #14301f;
  --ok-ink: #48cd8c;
  --scrim: rgba(0, 0, 0, .60);
  --shadow: 0 12px 32px rgba(0, 0, 0, .50);

  --st-new: #78adfa;  --st-new-bg: #16233a;
  --st-work: #f4b93c;   --st-work-bg: #3a2c0f;
  --st-sent: #48cd8c;   --st-sent-bg: #14301f;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  min-height: 100vh;
  background: var(--bg);
  color: var(--ink);
  font: 15px/1.5 -apple-system, "Segoe UI", Roboto, Arial, sans-serif;
}

a { color: var(--accent); }

input[type=text], input[type=password], input[type=search], select {
  padding: 9px 11px;
  font-size: 15px;              /* меньше 16px Safari на телефоне зумит форму */
  color: var(--ink);
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 6px;
}
input:focus, select:focus { outline: 2px solid var(--accent); outline-offset: 1px; }

code {
  padding: 1px 5px;
  background: var(--chip);
  border-radius: 4px;
  font-size: 13px;
}

.panel {
  background: var(--panel);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 22px 24px;
}

h1 { margin: 0 0 6px; font-size: 20px; }
h2 { margin: 0 0 12px; font-size: 16px; }
.sub { margin: 0 0 18px; color: var(--muted); font-size: 14px; }
.muted { color: var(--muted); }

/* Пустое место: раздел ещё не наполнен, поиск ничего не нашёл. */
.soon {
  padding: 14px 16px;
  border: 1px dashed var(--line);
  border-radius: 8px;
  color: var(--muted);
  background: var(--panel-alt);
}


/* --- Кнопки ---
   Одна основная на экран — то действие, ради которого человек пришёл.
   Вторичная — всё остальное. Опасная — то, что убирает или стирает:
   контуром, а не заливкой, чтобы не спорить за внимание с основной. */

.btn {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 9px 14px;
  font: inherit;
  line-height: 1.2;
  color: var(--on-accent);
  background: var(--accent);
  border: 1px solid var(--accent);
  border-radius: 6px;
  text-decoration: none;
  white-space: nowrap;
  cursor: pointer;
}
.btn:hover { filter: brightness(1.08); }
.btn:focus-visible { outline: 2px solid var(--accent); outline-offset: 2px; }
.btn.secondary { color: var(--ink); background: var(--panel); border-color: var(--line); }
.btn.secondary:hover { background: var(--hover); filter: none; }
.btn.danger { color: var(--error-ink); background: none; border-color: var(--error-ink); }
.btn.danger:hover { background: var(--error-bg); filter: none; }


/* --- Поля --- */

/* Поле с подписью над ним. */
.field { display: block; margin-bottom: 14px; font-size: 14px; }
.field > span { display: block; margin-bottom: 5px; color: var(--muted); }
.field input[type=text], .field input[type=password],
.field input[type=search], .field select { width: 100%; }

/* Флажок с подписью справа. */
.check { display: inline-flex; align-items: center; gap: 6px; color: var(--muted); font-size: 14px; }


/* --- Таблица ---
   Своя у системы, а не браузерная: табло стилизует свои ячейки само,
   и общее правило на голый <table> поменяло бы вид экрана в цеху. */

.table { width: 100%; border-collapse: collapse; font-size: 14px; }
.table th, .table td {
  padding: 9px 10px;
  text-align: left;
  border-bottom: 1px solid var(--line);
}
.table th { color: var(--muted); font-weight: 500; }
/* Число не переносится никогда: «2 059 438» рвалось на «2 059» и «438»,
   когда колонке тесно. Разделитель разрядов в `fmt_money` — обычный пробел
   намеренно (его же читают PDF и выгрузки), поэтому запрет живёт здесь,
   в ячейке, а не в формате числа.

   Запрет — только у ячейки (`td`). Заголовок переносится, как и раньше:
   с `th` правило давало «Цена за единицу, ₸» в одну строку — 135 точек
   над числом в 70, и соседние колонки оставались без места (К.11а). */
.table .num { text-align: right; font-variant-numeric: tabular-nums; }
.table td.num { white-space: nowrap; }
.table .right { text-align: right; }
/* Чередование: на широкой таблице глаз теряет строку на полпути. */
.table tbody tr:nth-child(even) td { background: var(--panel-alt); }
.table tbody tr:hover td { background: var(--hover); }
.table tbody tr.selected td { background: var(--accent-soft); }
.table tbody tr.selected td:first-child { box-shadow: inset 3px 0 var(--accent); }


/* --- Метки, чипы, статусы ---
   Метка — пометка при тексте («архив»). Чип — значение само по себе:
   параметр изделия, выбранный фильтр. */

.tag {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 6px;
  font-size: 12px;
  line-height: 1.5;
  color: var(--muted);
  background: var(--chip);
  border-radius: 4px;
}
.chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 3px 10px;
  font-size: 13px;
  color: var(--ink);
  background: var(--chip);
  border-radius: 999px;
}

/* Статус заказа — пара «цвет + подложка» из палитры. Имя не «status»:
   так на табло называется ячейка таблицы, и общее правило сделало бы
   её строчным блоком — вёрстка экрана в цеху поехала бы. */
.order-status {
  display: inline-block;
  padding: 2px 10px;
  font-size: 13px;
  font-weight: 600;
  border-radius: 999px;
  white-space: nowrap;
}
.order-status.st-new  { color: var(--st-new);  background: var(--st-new-bg); }
.order-status.st-work { color: var(--st-work); background: var(--st-work-bg); }
.order-status.st-sent { color: var(--st-sent); background: var(--st-sent-bg); }


/* --- Сообщения --- */

.msg {
  margin: 0 0 16px;
  padding: 10px 12px;
  border-radius: 6px;
  font-size: 14px;
}
.msg.error { color: var(--error-ink); background: var(--error-bg); }
.msg.warn  { color: var(--warn-ink);  background: var(--warn-bg); }
.msg.ok    { color: var(--ok-ink);    background: var(--ok-bg); }

/* Кнопка смены темы — одинаковая на всех страницах, включая вход. */
.theme-toggle {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  font-size: 16px;
  color: var(--muted);
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  cursor: pointer;
}
.theme-toggle:hover { background: var(--hover); color: var(--ink); }
.theme-toggle:focus-visible { border-color: var(--accent); outline: none; }


/* --- Шапка ---
   Одна на все страницы, включая вход и табло, и одной высоты везде
   (задача 0.10). На телевизоре она узкая полоса — принято сознательно:
   крупными остаются заказы. Понадобится крупнее — правка здесь,
   а не второй вариант шаблона. */

.app-header {
  display: flex;
  align-items: center;
  gap: 14px;
  height: 50px;
  flex-shrink: 0;
  padding: 0 16px;
  background: var(--panel);
  border-bottom: 1px solid var(--line);
}
.app-header .logo { display: flex; align-items: center; }
.app-header .logo img { display: block; height: 38px; width: auto; }
.app-header .brand { flex: 1; font-weight: 600; white-space: nowrap; }
.app-header .who {
  display: flex;
  align-items: center;
  gap: 12px;
  color: var(--muted);
  font-size: 14px;
  white-space: nowrap;
}
.app-header .who a { color: var(--muted); }

.burger {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 38px;
  height: 38px;
  font-size: 19px;
  color: var(--ink);
  background: none;
  border: 1px solid transparent;
  border-radius: 8px;
  cursor: pointer;
}
.burger:hover { background: var(--hover); }
.burger:focus-visible { border-color: var(--accent); outline: none; }

/* Часы табло: по ним видно, что экран жив, а по отметке — что данные свежие. */
/* Без переноса: «обновлено 17:31:43» третьей строкой не влезает в высоту шапки. */
.app-header .clock { margin-right: 8px; text-align: right; line-height: 1.25; white-space: nowrap; }
.app-header .clock .time { font-weight: 700; font-variant-numeric: tabular-nums; }
.app-header .clock .upd { color: var(--muted); font-size: 12px; }

/* --- Выдвижная панель разделов --- */

.drawer {
  position: fixed;
  top: 0;
  left: 0;
  z-index: 60;
  width: var(--drawer);
  height: 100%;
  padding: 14px 0;
  font-size: 15px;
  background: var(--panel);
  border-right: 1px solid var(--line);
  box-shadow: var(--shadow);
  transform: translateX(-100%);
  transition: transform .18s ease;
  overflow-y: auto;
}
.drawer .title {
  padding: 6px 18px 12px;
  color: var(--muted);
  font-size: 13px;
  text-transform: uppercase;
  letter-spacing: .04em;
}
.drawer a {
  display: block;
  padding: 10px 18px;
  color: var(--ink);
  text-decoration: none;
  border-left: 3px solid transparent;
}
.drawer a:hover { background: var(--hover); }
.drawer a.active {
  color: var(--accent);
  border-left-color: var(--accent);
  background: var(--accent-soft);
  font-weight: 500;
}
.drawer a .task { display: block; color: var(--muted); font-size: 12px; }
/* Отделяет служебные разделы (витрину) от рабочих. */
.drawer .sep { margin: 8px 18px; border-top: 1px solid var(--line); }

.scrim {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: var(--scrim);
  opacity: 0;
  pointer-events: none;
  transition: opacity .18s ease;
}
body.menu-open .drawer { transform: translateX(0); }
body.menu-open .scrim { opacity: 1; pointer-events: auto; }

/* --------------------------- окно поверх страницы ---------------------------
   Подтверждение перед необратимым (предпросмотр пачки в 1.2) и ввод, который
   не помещается в ячейку (параметры подузла в 2.4). Было описано дважды
   в двух шаблонах — третья копия появилась бы в следующей задаче.

   Своё правило на [hidden] обязательно: стиль автора бьёт [hidden] из таблицы
   браузера, и без него окно висит на экране с первой отрисовки. */
.modal {
  position: fixed;
  inset: 0;
  z-index: 60;
  background: var(--scrim);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 20px;
}
.modal[hidden] { display: none; }

/* Селектор из двух классов намеренно: коробка окна почти всегда ещё
   и .panel, а страницы переопределяют .panel под себя (1200, 1400).
   С одним классом окно раздувалось бы до ширины страницы. */
.modal .modal-box {
  max-width: 640px;
  width: 100%;
  max-height: 82vh;
  overflow: auto;
}
.modal .modal-box h2 { margin-top: 0; }
.modal .modal-box .actions { display: flex; gap: 12px; margin-top: 18px; }
.modal .modal-box .hint { margin: 10px 0 0; font-size: 13px; color: var(--muted); }


/* --- Узкий экран (М.1, ARCHITECTURE.md §3.1) ---

   До этой задачи адаптивных правил в системе не было ни одного: на 390
   точках десять экранов из семнадцати уезжали вбок целиком — вместе
   с шапкой, заголовком и кнопками, потому что таблицы прокручивать было
   нечем. С телефона смотрят все экраны, а КП собирают целиком (§3.1).

   Узкий экран — у́же 768 точек. Всё, что ниже, живёт только здесь:
   на широком не меняется ничего. Правила общие и лежат в одном месте —
   экранов семнадцать, и правило, записанное в одной странице,
   на остальных не появится. */

@media (max-width: 767px) {
  /* Вбок едет таблица, а не страница. Обёртка `.scroll-x` стоит вокруг
     каждой таблицы в шаблонах; на витрине /ui она показана образцом.
     Наименьшей ширины таблице не назначаем: пусть сначала сожмётся сама —
     названия переносятся, числа держит `white-space: nowrap` у `td.num`,
     и прокрутка появляется, только когда сжиматься больше некуда.

     Правило живёт внутри условия ширины, а не снаружи: `overflow-x`
     заводит свой блок форматирования, и отступы внутри обёртки перестают
     схлопываться с соседними. На широком экране это сдвинуло всё,
     что ниже таблицы, на 15 точек — проверено снимками до и после. */
  .scroll-x { overflow-x: auto; -webkit-overflow-scrolling: touch; }
  /* Поля на телефоне — шрифт 16: Safari на iPhone при меньшем увеличивает
     страницу от касания поля и обратно не уменьшает. Проверить это
     на живом iPhone некому, но правило стоит одной строки (§3.1). */
  input[type=text], input[type=password], input[type=search],
  input[type=date], input[type=number], select, textarea {
    font-size: 16px;
    min-height: 44px;
  }

  /* В мелкое пальцем не попасть, а «Перевести в FINAL» и «Удалить
     черновик» стоят рядом. Высота кнопок и полей — не ниже 44.
     Стрелки порядка в таблице позиций — исключение: их берёт М.3. */
  .btn:not(.move-btn), button:not(.move-btn) { min-height: 44px; }
  .btn.small:not(.move-btn), button.small:not(.move-btn) { padding: 9px 12px; }

  /* Шапка обязана помещаться на 360. Уступает имя человека: кто вошёл,
     видно на любом экране раздела, а меню и выход нужны отсюда всегда. */
  .app-header { gap: 10px; padding: 0 10px; }
  .app-header .who { gap: 10px; }
  .app-header .who-name { display: none; }
  .burger { width: 44px; height: 44px; }

  /* Страница у́же, и поля по краям съедают её заметную часть. */
  main { padding: 14px 10px; }
  .panel { padding: 16px 14px; }

  /* Строки поиска и действий над списками переносятся, а не уходят
     за край: «Искать», «Добавить материал», «Выгрузить спецификации».
     Селектор из двух классов — чтобы перебить раскладку страницы:
     её стили подключаются после общих. */
  .panel .head, .panel .head-actions, .panel .filters,
  .panel .tablebar, .panel .actions-top, .panel .pager {
    flex-wrap: wrap;
  }
  .panel .filters input[type=search] { max-width: none; }

  /* Строки полей в формах — цены материала, карточка материала, параметр
     изделия: на узком они встают друг под друга, а не выезжают за край.
     Селекторы длиннее, чем хочется, потому что раскладка страницы
     подключается после общих стилей и при равной силе побеждает её. */
  .panel .row { flex-wrap: wrap; }
  .panel .row .field, .panel .row .narrow-field { flex: 1 1 100%; }

  /* Название объекта на экране расчёта: поле в 320 точек с кнопкой
     «Переименовать» рядом не помещалось, и кнопка уходила за край. */
  .panel .actions-top .rename { flex-wrap: wrap; }
  .panel .actions-top .rename input { width: 100%; }

  /* Поля внутри таблиц — тоже 16: у страниц свои уменьшенные размеры
     (пометка в КП — 13), и они сильнее общего правила выше. */
  .panel .scroll-x .table input, .panel .scroll-x .table select { font-size: 16px; }

  /* Шапка табло: кроме имени уступают название системы — оно рядом
     с логотипом — и отметка обновления под часами. Сами часы остаются:
     по ним видно, что экран жив. */
  .app-header .brand { min-width: 0; overflow: hidden; text-overflow: ellipsis; }
  .app-header .clock .upd { display: none; }

  /* Раздел, свёрнутый на телефоне (М.2). Прячет только это правило
     и только здесь: на широком экране класс `collapsed`, даже если
     остался от узкого, ничего не делает — разделы развёрнуты, как были.
     Заголовок помечен снаружи, если внутри есть ошибка: свёрнутое
     не должно её прятать. */
  .sect.collapsed > .sect-body { display: none; }
  .sect > .sect-head { cursor: pointer; display: flex; align-items: center;
    gap: 8px; min-height: 44px; }
  .sect > .sect-head::after { content: "▾"; margin-left: auto; color: var(--muted); }
  .sect.collapsed > .sect-head::after { content: "▸"; }

  /* --- Позиция расчёта блоком (М.3) ---

     Позиция была строкой таблицы в одиннадцать колонок — 1279 точек
     у черновика: на телефоне её читали, двигая таблицу вбок. Разметка
     осталась одна, таблица: двух наборов полей с одинаковыми именами
     в одной форме быть не может — на сервер ушли бы оба. Меняется только
     раскладка, и только здесь.

     Порядок внутри блока задаёт `order`, а не разметка: первым планом
     идёт то, что человек вводит и за чем пришёл — название, номер, длина,
     количество, цена и сумма; «ещё параметры», раскладка, материалы
     и часы уходят вниз вторым планом, ниже и мельче. */
  .table.positions, .table.positions tbody, .table.positions tfoot,
  .table.positions tr, .table.positions td { display: block; }
  .table.positions thead { display: none; }   /* подписи переехали в ячейки */

  .table.positions tbody tr {
    display: flex; flex-wrap: wrap; gap: 6px 12px; align-items: center;
    padding: 10px; margin-bottom: 8px;
    border: 1px solid var(--line); border-radius: 10px;
  }
  /* Чередование полос на блоках только мешает: блок и так отделён рамкой. */
  .table.positions tbody tr:nth-child(even) td { background: none; }
  .table.positions td { border-bottom: 0; padding: 0; }

  /* Подпись перед значением: без шапки таблицы «1 080 454,11» само
     по себе ничего не говорит. Берётся из `data-label` разметки. */
  .table.positions td[data-label]::before {
    content: attr(data-label) " "; display: block;
    color: var(--muted); font-size: 12px; line-height: 1.3;
  }
  .table.positions td.c-name::before { content: none; }

  .table.positions td.name { order: 1; flex: 1 1 100%; width: auto; }
  .table.positions td.c-no { order: 2; }
  .table.positions td.c-length { order: 3; }
  .table.positions td.c-qty { order: 4; }
  .table.positions td.c-unit { order: 5; }
  .table.positions td.c-total { order: 6; }
  /* Второй план: уходит вниз, подпись в строку со значением и мельче —
     иначе каждая из четырёх ячеек съедает по строке подписи, и позиция
     разрастается на треть экрана телефона. */
  .table.positions td.c-extra { order: 7; }
  .table.positions td.c-layout { order: 8; flex: 1 1 100%; }
  .table.positions td.c-materials { order: 9; }
  .table.positions td.c-hours { order: 10; }
  .table.positions td.c-layout, .table.positions td.c-materials,
  .table.positions td.c-hours { font-size: 12px; }
  .table.positions td.c-layout::before, .table.positions td.c-materials::before,
  .table.positions td.c-hours::before, .table.positions td.c-extra::before {
    display: inline; }
  .table.positions td.c-hint { order: 11; flex: 1 1 100%; }
  .table.positions td.c-actions { order: 12; flex: 1 1 100%; display: flex;
    align-items: center; gap: 20px; }

  /* Ничего не сжимается до нечитаемого (урок К.11): номер показывает
     четыре знака, длина — пять, количество — четыре. */
  .table.positions td { text-align: left; }
  .table.positions input[type=text] { max-width: none; text-align: left; }
  .table.positions td.c-no input.no-input { min-width: 62px; max-width: 62px;
    text-align: left; }
  .table.positions td.c-length input { min-width: 78px; max-width: 78px; }
  .table.positions td.c-qty input { min-width: 66px; max-width: 66px; }
  .table.positions td.c-extra input { min-width: 120px; max-width: none; }
  .table.positions td.name input.label-input { max-width: none; width: 100%; }
  .table.positions td.name select { max-width: none; width: 100%; }

  /* Стрелки порядка: исключение М.1 здесь кончается — палец должен
     попадать. Встают рядом, а не одна над другой: в столбик они дают 88
     точек высоты у каждой позиции. */
  .table.positions .no-cell { justify-content: flex-start; }
  .table.positions .no-cell .move { flex-direction: row; gap: 8px; }
  .table.positions .no-cell .move-btn { min-width: 44px; min-height: 44px;
    font-size: 16px; line-height: 1; justify-content: center; }
  /* «Убрать» не вплотную к «Пересчитать»: рядом стоят «посчитать заново»
     и «выбросить», и промахиваться тут дорого. */
  .table.positions td.c-actions .btn.danger { margin-left: auto; }

  /* Строка с ошибкой — продолжение блока своей позиции, а не отдельная
     карточка: её `tr` идёт следом, поэтому прижимаем её к предыдущему. */
  .table.positions tbody tr.err-note { margin-top: -16px; padding-top: 14px;
    border-top: 0; border-radius: 0 0 10px 10px; }
  .table.positions tbody tr.err-note td { flex: 1 1 100%; }

  /* Отказ и совпадения под строкой добавления (К.13б) — продолжение её
     блока, как строка с ошибкой у позиции. Кнопки совпадений — во всю
     ширину: по ним попадают пальцем. */
  .table.positions tbody tr.add-help { margin-top: -16px; padding-top: 14px;
    border-top: 0; border-radius: 0 0 10px 10px; }
  .table.positions tbody tr.add-help td { flex: 1 1 100%; }
  .table.positions .pick-list { max-width: none; }
  .table.positions .pick { min-height: 44px; }

  /* Итог под блоками: подпись слева, число справа. */
  .table.positions tfoot tr { display: flex; align-items: baseline; gap: 12px;
    padding: 12px; }
  .table.positions td.c-total-label { flex: 1 1 auto; }
  .table.positions td.c-total-sum::before { content: none; }
}
