/* Оформление калькулятора заказов.
   Правила из вижна (docs/superpowers/specs/2026-09-03-calculator-hub-design.md, раздел 3.2а):
   - только компьютер, правил для узкого экрана нет вовсе;
   - пять цветовых ролей, зелёного нет: обычная строка без полосы и есть «всё хорошо»;
   - цветные сигналы живут в полосе слева и подписи; фоном сигналить нельзя,
     но приглушать серым то, что заказать нельзя, — можно (см. styles-list.css);
   - строка списка 40 пикселей: 371 позиция — это ~14 экранов.
   Палитра взята от удалённого калькулятора сырья, «витринные» карточки с размытием
   и тяжёлыми тенями НЕ переносим — на списке в 371 строку они заметно тормозят. */

/* Чёрно-белый кабинет — решение владельца 05.09.2026. Цвета из палитры убраны все:
   на экране из 371 строки цвет быстро перестаёт что-либо значить, а печать и слабые
   мониторы его всё равно съедают.
   Из этого следует правило: РАЗЛИЧАТЬ НАДО ФОРМОЙ, А НЕ ЦВЕТОМ. «Нужно заказать» —
   сплошная чёрная полоса, «проблема» — полоса в штриховку, «заказать нельзя» —
   серый фон без полосы. Три разных знака читаются и в чёрно-белом, и на печати. */
:root {
  --bg: #ffffff;
  --surface: #fafafa;
  --border: rgba(0, 0, 0, 0.22);
  /* Линия между позициями. Заметно темнее рамок: именно она отделяет товар от товара,
     и на ней держится «не вписать число в соседнюю строку». */
  --line-strong: rgba(0, 0, 0, 0.45);
  --text: #111111;
  --muted: #5e5e5e;
  --muted-bg: #efefef;
  --hover: rgba(0, 0, 0, 0.05);
  --accent: #111111;
  --accent-strong: #000000;
  --danger: #000000;
  --warn: #6b6b6b;
  --row-h: 40px;
  --sidebar-w: 220px;
}

* { box-sizing: border-box; }

body {
  margin: 0;
  font-family: "Segoe UI", "Segoe UI Variable", system-ui, sans-serif;
  font-size: 14px;
  color: var(--text);
  background: var(--bg);
}

/* ── Экран входа ───────────────────────────────────────────────── */

.auth-gate { display: none; }
body.preauth .auth-gate { display: flex; align-items: center; justify-content: center; min-height: 100vh; }
body.preauth .app { display: none; }
body.authed .auth-gate { display: none; }

.auth-card {
  width: 340px;
  padding: 28px;
  display: flex;
  flex-direction: column;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: 14px;
}

.auth-card h1 { margin: 0; font-size: 24px; }
.auth-hint { margin: 0 0 8px; color: var(--muted); font-size: 13px; }
.auth-card label { font-size: 13px; color: var(--muted); }
.auth-status { margin: 4px 0 0; min-height: 18px; font-size: 13px; color: var(--danger); }
.notice {
  margin: 0 0 8px;
  padding: 8px 10px;
  border-radius: 8px;
  background: var(--muted-bg);
  color: var(--text);
  border-left: 3px solid var(--text);
  font-size: 13px;
}

input, select {
  padding: 8px 10px;
  font: inherit;
  color: var(--text);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 8px;
}

input:focus-visible, select:focus-visible, button:focus-visible, a:focus-visible {
  outline: 2px solid var(--accent);
  outline-offset: 1px;
}

button.primary {
  margin-top: 6px;
  padding: 9px 16px;
  font: inherit;
  color: #fff;
  background: var(--accent);
  border: 1px solid var(--accent-strong);
  border-radius: 8px;
  cursor: pointer;
}

button.primary:hover { background: var(--accent-strong); }
button.primary:disabled { opacity: 0.5; cursor: default; }

button.link {
  padding: 0;
  font: inherit;
  color: var(--muted);
  background: none;
  border: 0;
  text-decoration: underline;
  cursor: pointer;
}

/* ── Каркас приложения ─────────────────────────────────────────── */

.app { display: flex; min-height: 100vh; }

.sidebar {
  position: sticky;
  top: 0;
  align-self: flex-start;
  display: flex;
  flex-direction: column;
  width: var(--sidebar-w);
  min-width: var(--sidebar-w);
  height: 100vh;
  padding: 18px 12px;
  background: var(--surface);
  border-right: 1px solid var(--border);
}

.brand {
  margin: 0 8px 16px;
  font-size: 18px;
  font-weight: 600;
}

.nav-item {
  display: block;
  padding: 9px 12px;
  margin-bottom: 2px;
  color: var(--text);
  text-decoration: none;
  border-radius: 8px;
}

.nav-item:hover { background: var(--hover); }

.nav-item.is-active {
  color: #fff;
  background: var(--accent);
}

.nav-divider { margin: 12px 12px; border-top: 1px solid var(--border); }
.nav-external { color: var(--muted); }

.sidebar-foot {
  margin-top: auto;
  padding: 12px 12px 0;
  border-top: 1px solid var(--border);
  display: flex;
  flex-direction: column;
  gap: 4px;
  font-size: 12px;
  color: var(--muted);
}

.who { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.sidebar-foot .link { align-self: flex-start; font-size: 12px; }

/* ── Правая часть ──────────────────────────────────────────────── */

.content {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-width: 0;
  max-width: 1400px;
  height: 100vh;
  overflow-y: auto;
}

/* Шапка — одной плашкой. Три отдельных прилипающих блока начинают наезжать друг
   на друга при разной высоте, поэтому поиск и фильтры второго этапа встанут сюда же. */
.topbar {
  position: sticky;
  top: 0;
  z-index: 2;
  /* Снизу черты НЕТ: её даёт шапка колонок (.list-head), а две подряд читались как
     пустая полоса между условиями заказа и списком. Владелец 07.09.2026: «верхняя
     плашка очень большая и непонятная, много пустого места». */
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 6px;
  padding: 8px 20px 0;
  background: var(--bg);
}

.section-title { margin: 0; font-size: 18px; font-weight: 600; }

.point-picker { display: flex; align-items: center; gap: 8px; font-size: 13px; color: var(--muted); }
.point-picker select { min-width: 190px; }

/* Прокручивается ВСЯ правая часть, а не только список. Иначе полоса прокрутки живёт
   внутри списка, шапка остаётся снаружи и оказывается на 15 точек шире строк — колонки
   заголовка стоят правее своих колонок, хотя сетка у них одна. Шапка и итог держатся
   на месте через sticky, поэтому внешне ничего не меняется. */
/* Сверху отступа нет вовсе: список начинается сразу под подписями колонок. */
.scroll-area { flex: 1; padding: 0 20px 18px; }

.message {
  margin: 0 0 6px;
  padding: 10px 12px;
  border-radius: 8px;
  font-size: 13px;
  background: var(--muted-bg);
  color: var(--text);
  border-left: 3px solid var(--text);
}

/* Итог — прилипает к низу ВНУТРИ области содержимого. Если сделать «поверх экрана»,
   панель ляжет на сайдбар. */
.bottombar {
  position: sticky;
  bottom: 0;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  padding: 12px 20px;
  background: var(--surface);
  border-top: 1px solid var(--border);
}

/* Поле норматива стоит внутри ячейки расхода — своей колонки у него нет, иначе
   сетка из 371 строки поехала бы ради позиций, которым норматив нужен не всегда. */
.row-norm-input { width: 72px; text-align: right; }

/* Куда уходит заказ — подпись у названия раздела. Приглушённая: это справка, а не
   действие, и спорить за внимание с числами в списке она не должна. */
.section-note { color: var(--muted); font-size: 12px; margin-left: 10px; }

.summary { color: var(--muted); font-size: 13px; }

/* ── Шапка: поиск и фильтры ─────────────────────────────────────── */

/* Элементы идут ПОДРЯД слева, а не растаскиваются по краям. Прежний space-between
   и был главным источником пустоты: в ряду из двух-трёх кнопок между ними зияла
   половина экрана. Выбор точки — единственное, что уезжает вправо. */
.topbar-line {
  display: flex;
  align-items: center;
  gap: 12px;
  justify-content: flex-start;
  flex-wrap: wrap;
}
.topbar-line .point-picker { margin-left: auto; }

.search { flex: 0 0 260px; max-width: 260px; }

.filters { display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }

.chip {
  padding: 5px 11px;
  font: inherit;
  font-size: 13px;
  color: var(--text);
  background: #fff;
  border: 1px solid var(--border);
  border-radius: 999px;
  cursor: pointer;
}

.chip:hover { background: var(--hover); }

.chip.is-active {
  color: #fff;
  background: var(--accent);
  border-color: var(--accent-strong);
}

.shown-count { margin-left: 8px; font-size: 12px; color: var(--muted); }

/* Шапка таблицы — часть той же прилипающей плашки, поэтому её колонки должны
   совпадать с колонками строки: сетка одна и та же. */
/* Ширины подобраны от НАЗВАНИЯ, а не от чисел. В Excel владельца «Наименование» —
   самая широкая колонка листа (45 знаков против 6–12 у остальных), и читается лист
   именно поэтому: сначала понимаешь, ЧТО за товар, потом смотришь цифры. У нас было
   наоборот — служебные колонки занимали 807 пикселей из 1060, названию оставалось
   250, и «Топпинг „Пряная говядина" 10уп*0,3кг» превращалось в многоточие.
   Правило на будущее: новая колонка добавляется за счёт других чисел, не названия.

   Сами ширины и все варианты сетки переехали 10.09.2026 в styles-grid.css — там они
   стоят рядом и читаются вместе. Здесь остались только оформление шапки и строки. */

/* Подписи колонок прижаты к НИЗУ шапки. Иначе двухстрочная подпись «Расход в день /
   будни / выходные» центрируется и отрывается от своего столбца — владелец 07.09.2026:
   «наименования сразу над колой, „в упаковке", „расход", „на складе" тоже сразу
   над числами близко». */
.list-head {
  align-items: end;
  padding: 6px 10px 4px 0;
  font-size: 12px;
  color: var(--text);
  font-weight: 600;
  border-top: 1px solid var(--border);
}

.list-head > span:first-child { grid-column: 2; }
.head-num { text-align: right; }

/* ── Строка списка ──────────────────────────────────────────────── */

.rows { display: flex; flex-direction: column; }

.row {
  min-height: var(--row-h);
  padding-right: 10px;
  border-bottom: 1px solid var(--border);
}

/* Цвет живёт ТОЛЬКО в этой полосе и в подписи под названием.
   Фоном НЕ СИГНАЛИМ — иначе список из 371 строки станет светофором. Серое
   приглушение недоступных позиций — другое дело, оно в styles-list.css. */

/* Числа моноширинные — иначе столбцы пляшут при прокрутке. */
.row-qty {
  width: 100%;
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.row-qty.is-edited { font-weight: 600; }
.row-manual { background: #f4f4f4; }
.row-unit { color: var(--muted); font-size: 13px; }

.list-empty { margin: 18px 0; color: var(--muted); }

/* Ошибочный ввод: не сохраняем и показываем это. Раньше «абв» молча удаляло строку
   в базе, а на экране оставалась видимость введённого. */
.row-qty.is-invalid {
  border-color: var(--danger);
  background: var(--muted-bg);
}

/* Состояние сохранения — в нижней панели, всегда на глазах. */
.save-state { margin-left: auto; margin-right: 16px; font-size: 13px; color: var(--muted); }
.save-state.is-error { color: var(--danger); font-weight: 600; }

/* Сводка «остатки подставились у N из M» — ОДНОЙ строкой и без плашки. Раньше она
   стояла коробкой между подписями колонок и первой позицией, и именно из-за неё шапка
   «не соединялась» со списком (владелец 07.09.2026). Полный текст остаётся в подсказке
   при наведении — обрезается только вид, не знание. */
.hint {
  margin: 0;
  padding: 2px 0 4px;
  font-size: 12px;
  color: var(--muted);
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Атрибут hidden обязан прятать — иначе он молча не работает.
   Причина: у .rows, .filters и .bottombar задан свой display (flex/grid), а он
   сильнее того display:none, который браузер даёт скрытым элементам по умолчанию.
   Поймано глазами 04.09.2026: раздел «Остатки» открывался, а список под ним
   продолжал висеть — при этом в коде elem.hidden честно стоял true. */
[hidden] { display: none !important; }

/* Ссылка-подсказка в полосе кнопок: не действие, а справка, поэтому мелко и приглушённо. */
.link-note { font-size: 12px; color: var(--muted); }

