/* Таблица калькулятора заказов (ZK-58): карточка с прокруткой внутри, короткая шапка,
   строка от 54px, состояния строки, поля и меню «⋯».
   Ширины колонок строит zakaz-columns.js в переменную --zakaz-cols, порядок — --ord-<key>. */

/* Область списка: таблица (и на планшете стоя — карточка позиции справа) занимает остаток высоты. */
.work { flex: 1; min-height: 0; display: flex; }
.table-card {
  --table-grid-line: oklch(0.70 0.01 80);
  /* Сетка: сверху полоса загрузки (если есть), ниже таблица. */
  flex: 1; min-height: 0; display: grid; grid-template-columns: minmax(0, 1fr); grid-template-rows: auto minmax(0, 1fr); margin: 0 var(--page-x); border: 1px solid var(--table-grid-line); border-bottom: 0;
  border-radius: 12px 12px 0 0; background: var(--surface); overflow: hidden;
}
.table-scroll { grid-row: 2; min-width: 0; min-height: 0; overflow: auto; position: relative; font-variant-numeric: tabular-nums; }

/* ── Шапка ──────────────────────────────────────────────────────── */

.thead {
  position: sticky; top: 0; z-index: 5; background: var(--surface-sunk); border-bottom: 1px solid var(--table-grid-line);
  white-space: nowrap;
}
.list-head, .row { display: grid; grid-template-columns: var(--zakaz-cols); /* ширины — zakaz-columns.js */ }
.list-head { height: 40px; font-size: 12.5px; font-weight: 500; color: var(--ink-2); touch-action: none; }
.list-head > span {
  position: relative; display: flex; align-items: center; min-width: 0; padding: 0 10px; overflow: hidden;
  cursor: grab; user-select: none;
}
.list-head > span.head-num { justify-content: flex-end; }
.list-head > .col-num { justify-content: flex-end; padding: 0 8px; }
.list-head > .col-name { padding: 0 12px; }
body.set-simple .list-head > .col-name { padding: 0 16px; }
.list-head > .col-reserve, .list-head > .col-fact { padding: 0 8px; }
.list-head > .col-need { padding: 0 8px; }
body.set-simple .list-head > .col-need { padding: 0 12px; }
.list-head > .col-order { padding: 0 12px; color: oklch(0.22 0.015 60); font-weight: 600; }
.list-head > .col-order:has(.clear-order-head) { flex-direction: column; align-items: flex-end; justify-content: center; gap: 0; }
.clear-order-head { border: 0; padding: 0; background: none; color: var(--ink-soft); font-size: 10px; line-height: 13px; text-decoration: underline; cursor: pointer; white-space: nowrap; }
.clear-order-head:hover, .clear-order-head:focus-visible { color: var(--bad-ink); }
.list-head > .col-incoming, .list-head > .col-incoming2, .list-head > .col-incoming3 {
  display: block; padding: 4px 6px; white-space: normal; text-align: right; line-height: 1.2; font-size: 12px;
}
.list-head .head-sub { font-size: 11.5px; color: var(--ink-mute); font-weight: 400; }
.list-head .head-sub.link { color: var(--link); }
.list-head > .col-menu { cursor: default; }
.list-head .col-resize { position: absolute; top: 0; right: -3px; width: 7px; height: 100%; cursor: col-resize; z-index: 2; }
.list-head > span.is-drop-target { box-shadow: inset 2px 0 0 var(--focus); }
.list-head > span.is-active-col { color: var(--focus); }
.list-head .rate-sub { display: block; font-size: 11.5px; color: var(--ink-mute); font-weight: 400; }
.list-head > .col-rate { flex-direction: column; align-items: flex-end; justify-content: center; line-height: 1.2; }

/* Порядок колонок: переменные --ord-<key> раздаёт zakaz-columns.js на контейнер. */
.list-head > .col-num, .row > .row-num { order: var(--ord-num, 1); }
.list-head > .col-code, .row > .row-code { order: var(--ord-code, 2); }
.list-head > .col-name, .row > .row-name-box { order: var(--ord-name, 1); }
.list-head > .col-stock, .row > .row-stock { order: var(--ord-stock, 4); }
.list-head > .col-rate, .row > .row-rate { order: var(--ord-rate, 5); }
.list-head > .col-pack, .row > .cell-pack { order: var(--ord-pack, 6); }
.list-head > .col-fact, .row > .cell-fact { order: var(--ord-fact, 7); }
.list-head > .col-reserve, .row > .cell-reserve { order: var(--ord-reserve, 8); }
.list-head > .col-needqty, .row > .row-needqty { order: var(--ord-needqty, 10); }
.list-head > .col-need, .row > .row-need { order: var(--ord-need, 11); }
.list-head > .col-order, .row > .cell-order { order: var(--ord-order, 12); }
.list-head > .col-incoming, .row > .cell-incoming { order: var(--ord-incoming, 13); }
.list-head > .col-incoming2, .row > .cell-incoming2 { order: var(--ord-incoming2, 14); }
.list-head > .col-menu, .row > .row-menu-cell { order: var(--ord-menu, 99); }

/* ── Строка ─────────────────────────────────────────────────────── */

.rows { min-width: 0; }
.row {
  min-height: var(--row-h); border-bottom: 1px solid var(--table-grid-line); overflow-wrap: anywhere; background: transparent;
  scroll-margin-top: var(--reveal-top, 70px); scroll-margin-bottom: var(--reveal-bottom, 12px);
}
.row > * { min-width: 0; display: flex; align-items: center; }
.row > .row-num { justify-content: flex-end; padding: 0 8px; font-size: 12.5px; color: var(--ink-mute); }
.row > .row-code { padding: 0 10px; font: 400 12px var(--mono); color: var(--ink-soft); }
.row > .row-name-box { flex-direction: column; align-items: stretch; justify-content: center; gap: 3px; padding: 6px 12px; }
body.set-simple .row > .row-name-box { padding: 6px 16px; }
.row-name-line { display: flex; min-width: 0; }
.row-name { flex: 1; min-width: 0; font-weight: 500; }
body:not(.is-touch) .row-name-line > .row-consumable-action { flex: none; width: auto; min-width: 0; max-width: 100%; height: 20px; overflow: hidden; padding: 0 2px; font-size: 0; white-space: nowrap; }
body:not(.is-touch) .row-name-line > .row-consumable-action::after { content: attr(data-label); font-size: 11px; }
.row-name-text { border-radius: 3px; }
.row.is-hit .row-name-text { background: var(--search-hit); }
.row-note { display: flex; flex-wrap: wrap; align-items: center; gap: 4px 8px; min-width: 0; font-size: 12.5px; line-height: 17px; }
.zone-tag {
  flex: none; padding: 0 5px; border-radius: 4px; font: 500 10.5px/17px var(--mono); letter-spacing: .03em;
  background: var(--zone-dry-bg); color: var(--zone-dry);
}
.zone-tag.is-cold { background: var(--zone-cold-bg); color: var(--zone-cold); }
.zone-tag.is-frost { background: var(--zone-frost-bg); color: var(--zone-frost); }
.off-tag { flex: none; padding: 0 6px; border-radius: 5px; border: 1px dashed oklch(0.72 0.012 60); color: var(--ink-2); line-height: 15px; }
.broken-text { flex: 0 1 auto; min-width: 0; color: var(--bad-ink); font-weight: 500; }
.fix-link { flex: none; padding: 0; border: 0; background: none; font-size: 12.5px; font-weight: 500; color: var(--link); text-decoration: underline; text-underline-offset: 2px; }
/* «Едет 22.09», а дата прошла (zakaz-sent.js ставит is-overdue): жёлтым с пунктиром — поставка,
   похоже, приехала, пора «приехало». Стиль пропал в ZK-58 вместе с styles-list.css, вернул ZK-60. */
.list-head .is-overdue > span:first-child { color: var(--warn-ink); border-bottom: 1px dotted currentColor; }
.warn-text { flex: none; max-width: 100%; color: var(--warn-ink); font-weight: 500; }
.note-text { min-width: 0; color: oklch(0.45 0.014 60); }
.note-text:empty { display: none; }

.row > .row-stock { justify-content: flex-end; gap: 4px; padding: 0 10px; color: var(--ink); font-size: 13.5px; font-weight: 600; }
.row > .row-stock.is-consumable { flex-wrap: wrap; gap: 2px; padding-inline: 4px; font-size: 11.5px; }
.row-consumable-stock-value { min-width: 0; }
.row > .row-stock.is-text { color: var(--ink-3); }
.row > .row-stock.is-minus { color: var(--bad-num); }
.row > .row-stock.is-shelf { color: var(--ink-3); text-decoration: line-through; }
.cell-unit { font-size: 11.5px; color: var(--ink-mute); }
.row > .row-rate { justify-content: flex-end; padding: 0 10px; color: var(--ink-2); }
.row > .row-needqty { justify-content: flex-end; gap: 4px; padding: 0 10px; color: var(--ink); font-size: 14px; font-weight: 600; }
.row > .row-needqty.is-need { font-weight: 600; }
.row > .row-needqty.is-need .cell-unit { font-weight: 400; }
.row > .row-needqty.is-dash { color: var(--ink-3); }
.row > .row-need { justify-content: flex-end; padding: 0 6px 0 8px; color: var(--ink); font-size: 13.5px; font-weight: 600; }
body.set-simple .row > .row-need { padding: 0 12px; }
.row > .row-need.is-zero, .row > .row-need.is-dash { color: var(--ink-3); }
.row > .row-need.has-spike { flex-direction: column; justify-content: center; gap: 0; cursor: pointer; }
.spike-badge { border: 0; background: none; padding: 2px 10px; color: var(--warn-ink); font: inherit; font-size: 11px; line-height: 14px; cursor: help; }
.spike-badge:focus-visible { outline: 2px solid var(--warn-ink); outline-offset: -2px; border-radius: 3px; }
.row-stats b.has-spike, .tc-cell b.has-spike { display: inline-flex; flex-direction: column; align-items: center; cursor: pointer; }
.spike-tip { position: fixed; z-index: 200; max-width: min(280px, calc(100vw - 16px)); padding: 9px 12px; border-radius: 8px; background: var(--ink); color: white; font-size: 12px; line-height: 1.4; box-shadow: 0 4px 16px #0003; pointer-events: none; }

/* Один стандарт табличного выравнивания: коды и названия слева; индекс и все
   количества — по центру своей колонки. Центрируется вся пара «число + единица»,
   а не каждый span отдельно. Карточки телефона и планшета стоя имеют свой вид. */
body:not(.touch-phone):not(.touch-portrait) .table-card .list-head > :is(.col-num, .head-num) {
  justify-content: center; align-items: center; padding-inline: 4px; text-align: center;
}
body:not(.touch-phone):not(.touch-portrait) .table-card .list-head > :is(.col-rate, .col-order) {
  align-items: center;
}
body:not(.touch-phone):not(.touch-portrait) .table-card .list-head > :is(.col-incoming, .col-incoming2, .col-incoming3) {
  display: grid; place-items: center; padding: 2px 4px; text-align: center;
}
body:not(.touch-phone):not(.touch-portrait) .table-card .row > :is(.row-num, .row-stock, .row-rate, .row-needqty, .row-need, .cell) {
  justify-content: center; padding-inline: 4px; text-align: center;
}
body:not(.touch-phone):not(.touch-portrait) .table-card .row-qty { width: 100%; max-width: 100%; padding-inline: 3px; text-align: center; }
/* У закрытой позиции «На складе 0 шт» укладывается в две строки посередине
   узкой колонки «Расчёт», сохраняя пояснение и единицу. */
body:not(.touch-phone):not(.touch-portrait) .table-card .row > .row-needqty.is-stock-caption {
  display: block; align-content: center; white-space: normal; line-height: 1.15; font-size: 12px;
}
body:not(.touch-phone):not(.touch-portrait) .table-card .row-needqty.is-stock-caption .cell-unit { margin-left: 3px; }

/* Все границы таблицы одинаковые, в том числе после скрытия и перестановки колонок. */
.list-head > span, .row > * { border-left: 1px solid var(--table-grid-line); }

/* ── Поля ───────────────────────────────────────────────────────── */

.row > .cell { justify-content: flex-end; padding: 0 8px; position: relative; }
.row-qty {
  width: 42px; height: 28px; padding: 0 6px; border-radius: 6px; border: 1px solid transparent;
  background: transparent; text-align: right; color: inherit; outline: none; font-variant-numeric: tabular-nums;
}
/* Тихое поле показывает рамку, только когда мышь над ним самим, а не над строкой (макет). */
.row-qty:hover:not(:read-only):not(:disabled) { border-color: var(--line-strong); }
.row-qty:focus { border-color: var(--focus); background: var(--pop); }
.row-qty.row-pack-input, .row-qty.row-incoming { width: 56px; }
.row-qty.row-pack-input { color: var(--ink-soft); }
.row-qty.row-incoming { color: var(--ink); font-size: 14px; font-weight: 600; }
.row-qty.row-reserve { width: 44px; }
.row-qty.row-reserve::placeholder { color: oklch(0.75 0.01 60); }
.row-qty.row-manual { width: 58px; }
.row-qty.row-manual.has-value { border-color: oklch(0.8 0.06 75); background: oklch(0.975 0.025 85); font-weight: 600; }
.row-qty.row-norm-input { width: 64px; }
.row-qty.is-invalid, .tc-edit input.is-invalid { border-color: var(--bad) !important; background: oklch(0.97 0.02 28); }
.row-qty:disabled, .row-qty:read-only { cursor: default; }

.row > .cell-order { padding: 0 10px; gap: 6px; }
body.set-simple .row > .cell-order { padding: 0 12px; }
body.set-noTare .row > .cell-order { padding: 0 10px 0 12px; }
.row-qty.row-order {
  width: 64px; height: 32px; padding: 0 9px; border-radius: 7px; border: 1px solid var(--line-strong);
  background: oklch(0.998 0.001 80); font-weight: 500;
}
.row-qty.row-order:focus { box-shadow: var(--focus-ring); border-color: var(--focus); }
/* Пустое «Итого» на компьютере — белое, без прочерка (макет); прочерк виден только в степпере телефона. */
.row-qty.row-order::placeholder { color: transparent; }
body.touch-phone .row-qty.row-order::placeholder { color: var(--ink-3); }
.order-dash { display: none; color: oklch(0.62 0.01 60); }
.order-unit { width: 18px; font-size: 11.5px; color: var(--ink-3); }

/* ── Состояния строки ───────────────────────────────────────────── */

/* Заполнена: в «Итого» есть число. */
.row.is-ordered { background: var(--ok-row); }
.row.is-ordered > .cell-order { background: var(--ok-band); }
.row.is-ordered .row-qty.row-order { background: var(--ok-input); border-color: var(--ok); color: var(--ok-ink); font-weight: 700; }
.row.is-ordered .order-unit { color: oklch(0.38 0.08 150); }
/* Не заказываем: выводится, нет в пиццерии, не возят. Поля «Итого» нет — прочерк. */
.row.is-retiring, .row.is-blocked { background: var(--off-row); }
.row.is-retiring .row-name, .row.is-blocked .row-name,
.row.is-retiring > .row-stock, .row.is-blocked > .row-stock,
.row.is-retiring > .row-rate, .row.is-blocked > .row-rate,
.row.is-retiring .row-qty, .row.is-blocked .row-qty { color: var(--ink-3); }
.row:is(.is-stock-retired, .is-stop-confirmed) { background: var(--off-row); }
.row:is(.is-stock-retired, .is-stop-confirmed) .row-name, .row:is(.is-stock-retired, .is-stop-confirmed) > .row-stock,
.row:is(.is-stock-retired, .is-stop-confirmed) > .row-rate, .row:is(.is-stock-retired, .is-stop-confirmed) .row-qty,
.row:is(.is-stock-retired, .is-stop-confirmed) > .row-needqty { color: var(--ink-3); }
.row:is(.is-stock-retired, .is-stop-confirmed) .row-qty.row-order { background: var(--off-row); border-color: var(--line); }
.row.is-retiring .row-qty.row-order, .row.is-blocked .row-qty.row-order { display: none; }
.row.is-retiring .order-dash, .row.is-blocked .order-dash { display: inline; }
/* Данные сломаны: штриховка в ячейке «№» (ВЗ) или полоской слева у названия. */
.row.is-problem > .row-num { background: var(--stripe); }
body.set-simple .row.is-problem > .row-name-box,
.row.is-problem > .row-num[hidden] ~ .row-name-box { background: var(--stripe) left / 5px 100% no-repeat; }
/* Курсор: синяя рамка по краю и лёгкий синий фон — поверх любого состояния. Только когда курсор в поле:
   открытое меню «⋯» строку не подсвечивает (макет vz/04). */
.row:has(.row-qty:focus) { background: var(--focus-row); box-shadow: inset 0 0 0 2px var(--focus); }
/* Вспышка при переходе по метке (1,4 с). */
.row.is-flash { background: var(--flash) !important; }

/* ── Меню «⋯» ───────────────────────────────────────────────────── */

.row > .row-menu-cell { justify-content: center; }
.row-menu-btn {
  width: 28px; height: 28px; border: 0; border-radius: 7px; background: transparent; color: var(--ink-mute);
  font-size: 16px; line-height: 1;
}
.row-menu-btn:hover, .row-menu-btn.is-open { background: var(--hover); color: var(--ink); }
.row-phone-menu-btn { display:none; }
body:not(.is-touch) .row-menu-btn { border: 1px solid var(--line-btn); border-radius: 7px; font-size: 18px; color: var(--ink-2); }
.list-head > .col-menu { justify-content: center; font-size: 12px; color: var(--ink-2); }
body:not(.is-touch) .off-tag.is-action { cursor: pointer; }
body:not(.is-touch) .off-tag.is-action:hover { border-color: var(--ink-2); color: var(--ink-strong); }
.row-menu { right: 44px; width: 250px; padding: 6px; border-radius: 12px; box-shadow: var(--shadow-menu); z-index: 20; }
.row-menu-name { padding: 6px 10px 2px; font-size: 12px; font-weight: 600; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.row-menu-sub { padding: 2px 10px 4px; font-size: 11.5px; color: var(--ink-soft); }
.row-menu button {
  display: block; width: 100%; padding: 8px 10px; border: 0; border-radius: 8px; background: transparent; text-align: left;
}
.row-menu button:hover:not(:disabled) { background: var(--hover-menu); }
.row-menu button:disabled { color: var(--ink-3); cursor: default; }
.row-menu .is-strong { font-weight: 500; }
.row-menu .is-danger { color: var(--bad-ink); }
.row-menu .pop-sep { margin: 4px 6px; }
.row-menu { max-height: calc(100vh - 32px); overflow-y: auto; }
.row-norm-editor { padding: 8px 4px 0; border-top: 1px solid var(--line-group); margin-top: 6px; }
.row-norm-editor label { display: block; padding: 0 6px; font-size: 13px; }
.norm-edit-input { display: block; width: 100%; min-height: 40px; margin: 6px 0; padding: 8px; border: 1px solid var(--line-btn); border-radius: 7px; }
.norm-edit-input.is-invalid { border-color: var(--bad-ink); }
.norm-edit-error { padding: 4px 6px; font-size: 12px; color: var(--bad-ink); }

.list-empty { padding: 48px 16px; text-align: center; color: var(--ink-2); margin: 0; }
.list-after { display: flex; align-items: center; gap: 10px; padding: 14px 16px; color: var(--ink-2); font-size: 13px; }
.list-after .btn-dashed { height: 30px; border-color: oklch(0.8 0.012 80); color: var(--ink-strong); }
/* ZK-60: «+ Добавить позиции из остатков» прилипает к низу таблицы — видна без прокрутки списка
   (живой вход 29.09: «не вижу кнопки», у напитков она стояла после 21 строки). Телефон — без
   прилипания: там внизу своя панель действия (styles-phone.css). */
body:not(.touch-phone) .list-after {
  position: sticky; bottom: 0; left: 0; z-index: 4;
  background: var(--surface); border-top: 1px solid var(--line-strong);
}
/* Строка, куда ушёл курсор (Enter, Tab, стрелки), не прячется под прилипшую кнопку: прокрутка держит отступ. */
body.set-simple:not(.touch-phone) #tableScroll { scroll-padding-bottom: 64px; }

/* ── Узкий ноутбук (окно уже таблицы): «Итого к заказу» и всё правее прилипает к правому краю ──
   Таблице ВЗ нужно ~980 точек, на ноутбуке 1024 рядом с меню — 740: без этого главное поле уезжало
   за край (ревью ZK-58, 29.09). Прилипает весь хвост от «Итого» до «⋯» (отступы --sr-<key> считает
   zakaz-columns.js), остальные колонки уезжают под него целиком, у края хвоста — тень, пока под ним
   что-то есть. На широком экране хвост и так на своём месте. Фон свой — под ним проезжают соседи. */
body:not(.is-touch) :is(.row > .cell-order, .list-head > .col-order) { position: sticky; right: var(--sr-order, auto); z-index: 2; }
body:not(.is-touch) :is(.row > .cell-incoming, .list-head > .col-incoming) { position: sticky; right: var(--sr-incoming, auto); z-index: 2; }
body:not(.is-touch) :is(.row > .cell-incoming2, .list-head > .col-incoming2) { position: sticky; right: var(--sr-incoming2, auto); z-index: 2; }
body:not(.is-touch) :is(.row > .row-menu-cell, .list-head > .col-menu) { position: sticky; right: var(--sr-menu, auto); z-index: 2; }
body:not(.is-touch) .list-head > :is(.col-order, .col-incoming, .col-incoming2, .col-incoming3, .col-menu) { background: var(--surface-sunk); }
body:not(.is-touch) .row > :is(.cell-order, .cell-incoming, .cell-incoming2, .cell-incoming3, .row-menu-cell) { background-color: var(--surface); }
body:not(.is-touch) .row.is-ordered > :is(.cell-incoming, .cell-incoming2, .cell-incoming3, .row-menu-cell) { background-color: var(--ok-row); }
body:not(.is-touch) .row.is-ordered > .cell-order { background-color: var(--ok-band); }
body:not(.is-touch) .row:is(.is-retiring, .is-blocked, .is-stock-retired, .is-stop-confirmed) > :is(.cell-order, .cell-incoming, .cell-incoming2, .cell-incoming3, .row-menu-cell) { background-color: var(--off-row); }
body:not(.is-touch) #zakazList .row.is-range > :is(.cell-order, .cell-incoming, .cell-incoming2, .cell-incoming3, .row-menu-cell):not(.is-sel-cell) { background-color: var(--focus-row); }
/* Курсор, вспышка «Перейти к» — и на прилипших ячейках (второй круг ревью 29.09). */
body:not(.is-touch) .row:has(.row-qty:focus) > :is(.cell-order, .cell-incoming, .cell-incoming2, .cell-incoming3, .row-menu-cell):not(.is-sel-cell) { background-color: var(--focus-row); }
body:not(.is-touch) .row.is-flash > :is(.cell-order, .cell-incoming, .cell-incoming2, .cell-incoming3, .row-menu-cell) { background-color: var(--flash); }
@media (max-width: 1120px) {
  body:not(.is-touch) .table-card :is(.row, .list-head) > :is(.cell-order, .cell-incoming, .cell-incoming2,
    .cell-incoming3, .row-menu-cell, .col-order, .col-incoming, .col-incoming2, .col-incoming3, .col-menu) {
    position: relative; right: auto; z-index: auto;
  }
}
.list-head > .col-incoming3, .row > .cell-incoming3 { order: var(--ord-incoming3, 15); }
body:not(.is-touch) :is(.row > .cell-incoming3, .list-head > .col-incoming3) { position: sticky; right: var(--sr-incoming3, auto); z-index: 2; }

body:not(.is-touch) .last-order { flex: 0 0 100%; min-width: 0; max-width: 100%; order: -1; color: var(--ink-2); font-size: 12px; font-weight: 500; line-height: 1.25; }
.row:is(.is-retiring, .is-blocked) > .row-needqty.is-reserve { white-space: normal; font-size: 12px; color: var(--ink-3); }
.row-need, .row-needqty { cursor: help; }

body:not(.is-touch) .row:has(.last-order) { min-height: 72px; }

.list-head > .col-needqty { white-space: normal; text-align: right; line-height: 1.15; font-size: 11.5px; }

/* Серые строки принимают клавиатурный фокус, но readOnly не разрешает запись. */
body:not(.is-touch) .row:is(.is-retiring, .is-blocked) .row-order { display: block; }
body:not(.is-touch) .row:is(.is-retiring, .is-blocked) .order-dash { display: none; }
