/* Оформление панели каталога. Единственное место, где живут цвета и размеры.
 *
 * До 10.09.2026 палитра была скопирована в одиннадцать файлов — 22 блока
 * `:root`. Правка цвета требовала восьми правок, и восьмую забывали: класс
 * `.chk` был описан только в одном файле, а использовался в двух, и на экране
 * цен стеблей две галочки фильтра стояли без стилей вовсе.
 *
 * ## Акцент
 *
 * Был `#ECBDD9` — розовый с карточки для клиента. Как заливка он читается,
 * а **как линия его нет**: 1,63:1 на белом при норме 3:1. От этого у главной
 * кнопки не было видимого края, подсветка кандидата на мосту не отличалась
 * от покоя, а полоса прогресса сливалась с дорожкой. В тёмной теме тот же
 * цвет даёт 11,16:1 и работает — ломался он только на светлой.
 *
 * Теперь `#9B2C6F` — **тот же тон розы** (324° против 325°), доведённый до
 * рабочей насыщенности: 7,04:1 на белом. В тёмной теме акцентом остаётся
 * прежний `#ECBDD9`, там он хорош.
 *
 * Правило, которое избавляет от исключений: **`--accent-fg` всегда равен
 * `--bg`.** Белое на тёмной розе в светлой теме, почти-чёрное на пастели
 * в тёмной.
 *
 * ## Цвет кнопки = последствие
 *
 * В панели три класса действий, и раньше все три были одного пастельного
 * цвета — самое опасное выглядело самым мягким пятном на экране, а опасность
 * компенсировалась красным абзацем сверху, который никто не читает.
 *
 *   .btn           чтение         пересчитать, обновить
 *   .btn--primary  обратимое      скрыть букет, вернуть, завести
 *   .btn--commit   необратимое    коды товара, цена на витрину, цена стебля
 *
 * ## Три семантических цвета выровнены по весу
 *
 * Было 5,02–8,31 — жёлтый и красный кричали сильнее зелёного, и экран
 * выглядел пёстрым не из-за числа плашек, а из-за неравного веса.
 * Стало 6,33 / 6,57 / 6,60 на светлой и 8,92 / 9,79 / 9,84 на тёмной.
 */

:root {
  --bg: #FFFFFF;
  --surface: #F5F0F3;
  --surface-2: #FCFAFB;
  --fg: #3D3238;
  --muted: #6F646A;
  --fg-off: #A0949A;
  --line: #E7DFE3;
  --line-strong: #9C8E96;
  --accent: #9B2C6F;
  --accent-fg: #FFFFFF;
  --accent-tint: #FBEEF5;
  --good: #0E6B39;      --good-bg: #E9F6EE;
  --warn: #8A5300;      --warn-bg: #FDF3E2;
  --bad:  #B42318;      --bad-bg:  #FEF0EE;
  --focus: #9B2C6F;

  --r-xs: 4px;  --r-sm: 8px;  --r-md: 12px;  --r-lg: 16px;  --r-pill: 999px;
  /* Ширина следует типу содержимого, а не стремлению всё выровнять:
     таблице нужен размах, абзацу — предел, иначе строка в 150 знаков
     и глаз теряет начало следующей. */
  --w-table: 1440px;
  --w-form: 720px;
  --w-text: 720px;
}

@media (prefers-color-scheme: dark) {
  :root {
    --bg: #17141A;
    --surface: #251E24;
    --surface-2: #1C181B;
    --fg: #EDE7EA;
    --muted: #A69BA1;
    --fg-off: #7D6C76;
    --line: #332B31;
    --line-strong: #77646F;
    --accent: #ECBDD9;
    --accent-fg: #17141A;
    --accent-tint: #2B1F27;
    --good: #5DD48D;    --good-bg: #132E1F;
    --warn: #F0B44A;    --warn-bg: #332714;
    --bad:  #FF9A8F;    --bad-bg:  #3A1F1D;
    --focus: #ECBDD9;
  }
}

* { box-sizing: border-box }

body {
  margin: 0;
  background: var(--bg);
  color: var(--fg);
  font: 15px/1.45 system-ui, -apple-system, "Segoe UI", Roboto,
        "Helvetica Neue", Arial, sans-serif;
}

/* Весов ровно три: 400 / 600 / 700. Было 550, 600, 650, 700 — на SF в macOS
   650 рисуется отдельным начертанием, на Segoe UI в Windows тем же, что 700,
   и один экран выглядел по-разному на разных машинах. */
h1 { margin: 0; font-size: 18px; line-height: 1.25; font-weight: 700; letter-spacing: -.01em }
h2 { margin: 32px 0 12px; font-size: 15px; line-height: 1.3; font-weight: 700 }
small { font-size: 12px }
.dim { color: var(--muted) }
.mono { font: 12px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace }

/* Правило экрана — не плашка. Оно не меняется никогда и читается один раз
   в жизни; полный текст живёт в подтверждении той кнопки, которую жмут. */
.rule { padding: 8px 20px; font-size: 13px; color: var(--muted); max-width: var(--w-text) }
.rule a, .rule summary { color: var(--accent); font-weight: 600; cursor: pointer }
.rule details { display: inline }
.rule details p { margin: 8px 0 0; color: var(--muted) }

/* ---------------------------------------------------------- полоса статуса */

.status {
  display: flex; gap: 14px; align-items: center; flex-wrap: wrap;
  padding: 12px 20px; background: var(--surface); font-size: 13px;
}
.status .grow { flex: 1 }
.status.on { box-shadow: inset 3px 0 0 var(--good) }
.status.off { box-shadow: inset 3px 0 0 var(--bad) }
.dot { width: 6px; height: 6px; border-radius: var(--r-pill); display: inline-block;
  margin-right: 6px; vertical-align: middle; background: var(--muted) }
.dot.ok { background: var(--good) }
.dot.warn { background: var(--warn) }
.dot.bad { background: var(--bad) }

/* ------------------------------------------------------------------ плашки */

/* Два уровня, не четыре. Левая линия важнее заливки: на тёмной теме подложки
   дают 1,2 к фону, и смысл несёт цвет текста, а линия читается одинаково
   в обеих темах и не превращает экран в набор цветных прямоугольников. */
.note {
  padding: 12px 16px; border-radius: var(--r-sm); margin-bottom: 16px;
  font-size: 14px; background: var(--surface); color: var(--fg);
  box-shadow: inset 3px 0 0 var(--muted); max-width: var(--w-text);
}
.note b { font-weight: 600 }
.note.good { box-shadow: inset 3px 0 0 var(--good) }
.note.warn { box-shadow: inset 3px 0 0 var(--warn) }
.note.bad  { box-shadow: inset 3px 0 0 var(--bad) }
/* Громкая — привилегия единственного блокирующего сообщения на экране. */
.note.loud.good { background: var(--good-bg); color: var(--good) }
.note.loud.warn { background: var(--warn-bg); color: var(--warn) }
.note.loud.bad  { background: var(--bad-bg);  color: var(--bad) }
.note.wide { max-width: none }

/* ------------------------------------------------------------------ кнопки */

.btn {
  font: inherit; font-size: 15px; font-weight: 600; min-height: 40px;
  padding: 8px 16px; border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--bg); color: var(--fg); cursor: pointer;
}
.btn:hover { background: var(--surface) }
.btn--primary { background: var(--accent); color: var(--accent-fg);
  border-color: var(--accent); padding: 12px 20px; font-weight: 700 }
.btn--primary:hover { filter: brightness(1.08) }
.btn--commit { background: var(--bad); color: var(--bg);
  border-color: var(--bad); padding: 12px 20px; font-weight: 700 }
.btn--commit:hover { filter: brightness(1.08) }
.btn--ghost { border-color: transparent; background: none; color: var(--muted);
  font-weight: 400; min-height: 0; padding: 4px 8px }
.btn--ghost:hover { color: var(--fg); background: none; text-decoration: underline }
.btn--sm { font-size: 13px; padding: 4px 12px; min-height: 0; font-weight: 600 }
/* Выключенная кнопка — не прозрачность: на красной заливке она даёт
   нечитаемое розовое пятно, а на розовой превращает главную кнопку в фон. */
.btn:disabled, .btn[disabled] {
  background: var(--surface); color: var(--fg-off); border-color: var(--line);
  cursor: not-allowed; filter: none;
}
/* Причина, по которой кнопка выключена, стоит рядом с ней, а не абзацем выше. */
.why-off { font-size: 13px; color: var(--muted) }

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

/* ------------------------------------------------------------------- поля */

input[type=text], input[type=search], input[type=number], input[type=password],
select, textarea {
  font: inherit; font-size: 15px; padding: 8px 12px;
  border: 1px solid var(--line); border-radius: var(--r-sm);
  background: var(--bg); color: var(--fg);
}
input:focus, select:focus { border-color: var(--accent) }
input.num-in { width: 104px; text-align: right; font-variant-numeric: tabular-nums }
input.num-in.set { border-color: var(--accent) }

/* --------------------------------------------------------- чипы и счётчики */

/* Форма несёт смысл: таблетка значит «на меня можно нажать». Счётчик,
   на который нажать нельзя, — прямоугольник. */
.stat { display: inline-block; background: var(--surface); border-radius: var(--r-xs);
  padding: 4px 12px; font-size: 12px; color: var(--muted); font-weight: 600 }
.stat b { color: var(--fg); font-weight: 600 }
.chip { display: inline-flex; gap: 7px; align-items: center; cursor: pointer;
  background: var(--bg); border: 1px solid var(--line); border-radius: var(--r-pill);
  padding: 4px 12px; font-size: 13px; color: var(--fg) }
.chip:hover { background: var(--surface) }
.chip.on { background: var(--accent-tint); border-color: var(--accent) }
.chip input { width: auto; margin: 0 }
.tag { font-size: 12px; padding: 2px 7px; border-radius: var(--r-xs);
  background: var(--surface); color: var(--muted); white-space: nowrap }
.tag.warn { background: var(--warn-bg); color: var(--warn); font-weight: 600 }
.tag.accent { background: var(--accent-tint); color: var(--fg); font-weight: 600 }

/* ---------------------------------------------------------------- вкладки */

.tabs { display: flex; gap: 8px; padding: 16px 20px 0; flex-wrap: wrap }
.tab { font: inherit; font-size: 13px; padding: 4px 12px; cursor: pointer;
  border: 1px solid var(--line); border-radius: var(--r-pill);
  background: var(--bg); color: var(--fg); min-height: 0 }
.tab:hover { background: var(--surface) }
.tab.on { background: var(--accent); border-color: var(--accent);
  color: var(--accent-fg); font-weight: 600 }

/* --------------------------------------------------------------- таблица */

.scroll { overflow-x: auto }
table { border-collapse: collapse; width: 100% }
th {
  font-size: 12px; font-weight: 600; color: var(--muted); text-align: left;
  padding: 8px 12px; background: var(--surface);
  border-bottom: 1px solid var(--line-strong);
  position: sticky; top: 0; z-index: 1;
}
td { padding: 8px 12px; font-size: 14px; vertical-align: top }
/* Зебра ИЛИ построчные линии — что-то одно, иначе таблица выглядит
   миллиметровкой. Оставлена зебра. */
tbody tr:nth-child(even) { background: var(--surface-2) }
tbody tr:hover { background: var(--surface) }
/* Отмеченная строка обязана отличаться от той, под которой мышь: на экране
   цен стеблей отметка означает отправку цены на витрину. */
tbody tr.on, tbody tr.on:hover { background: var(--accent-tint);
  box-shadow: inset 2px 0 0 var(--accent) }
.num, th.num { text-align: right; white-space: nowrap; width: 1%;
  font-variant-numeric: tabular-nums; font-weight: 600 }
td.nm { font-weight: 600; width: 100% }
td.sub, .sub { font-size: 12px; font-weight: 400; color: var(--muted) }
/* Одна вертикальная линия на таблицу — делит «что это» и «сколько». */
.split, th.split { border-left: 1px solid var(--line) }
.u { color: var(--muted); font-weight: 400 }
.why { font-size: 13px; color: var(--muted); font-weight: 400 }

/* ----------------------------------------------------------------- разное */

.wrap { padding: 16px 20px 40px; max-width: var(--w-table) }
.wrap.form { max-width: var(--w-form) }
.bar { display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  padding: 16px 20px; max-width: var(--w-table) }
.acts { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; margin: 16px 0 }
.stats { display: flex; gap: 8px; flex-wrap: wrap; padding: 16px 20px 0;
  max-width: var(--w-table) }
.box { border: 1px solid var(--line); border-radius: var(--r-md);
  padding: 12px; background: var(--surface) }
code { font: 12px/1.4 ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  background: var(--surface); padding: 1px 5px; border-radius: var(--r-xs) }
kbd { border: 1px solid var(--line); border-bottom-width: 2px; border-radius: var(--r-xs);
  padding: 0 5px; font: inherit; font-size: 11px; background: var(--bg) }
@media (max-width: 700px) {
  .wrap, .bar, .stats { padding-left: 16px; padding-right: 16px }
  .status, .rule { padding-left: 16px; padding-right: 16px }
}

/* --------------------------------------------- состояние строки в таблице */

/* Значок статуса строки: «запишем», «мёртвая зона», «заморожено тестом».
   Прямоугольник, а не таблетка: нажать на него нельзя. */
.state { font-size: 12px; padding: 2px 8px; border-radius: var(--r-xs);
  white-space: nowrap; font-weight: 600; background: var(--surface); color: var(--muted) }
.state.go   { background: var(--good-bg); color: var(--good) }
.state.hold { background: var(--warn-bg); color: var(--warn) }
.state.no   { background: var(--bad-bg);  color: var(--bad) }
.state.idle { background: var(--surface); color: var(--muted); font-weight: 400 }

.up   { color: var(--good); font-weight: 600 }
.down { color: var(--bad);  font-weight: 600 }

/* Клавиша внутри кнопки берёт её цвета: на розовой заливке `kbd` со своим
   фоном выглядел тёмным прямоугольником — заплаткой поверх кнопки. */
.btn kbd { border-color: currentColor; background: transparent; color: inherit; opacity: .75 }


/* ─── Оболочка: боковое меню и колонка содержимого ──────────────────────────
   Строка из тринадцати ссылок наверху не помещалась на телефон и не говорила,
   где ты находишься. 22.09.2026 владелец не смог найти экран цен Flowwow —
   он был в той строке, четвёртой слева. Меню с разделами это чинит. */
/* Раскладку включает наличие самого меню, а не класс на body: страница
   входа меню не имеет и остаётся обычной. Копировать эти правила в каждый
   экран нельзя — 22.09.2026 я так и сделала на витрине, и следующий экран
   скопировал бы их снова. */
body:has(> .side) { display: flex; flex-direction: row; margin: 0; min-height: 100vh; }
.col { flex: 1 1 auto; min-width: 0; display: flex; flex-direction: column; }

/* Шапка страницы: слева имя и счётчики, справа действия и одна главная цифра. */
.page { display: flex; align-items: flex-start; justify-content: space-between;
        gap: 16px; padding: 18px 20px 14px; border-bottom: 1px solid var(--line);
        flex: 0 0 auto; }
.page h1 { margin: 0 0 4px; font-size: 22px; font-weight: 700; letter-spacing: -0.015em; }
.page .sub { color: var(--muted); font-size: 13px; }
.page .sub b { color: var(--fg); font-weight: 600; }
.page-right { display: flex; flex-direction: column; align-items: flex-end;
              gap: 10px; flex: 0 0 auto; }
.page-act { display: flex; gap: 8px; flex-wrap: wrap; justify-content: flex-end; }
.page-kpi { text-align: right; flex: 0 0 auto; }
.page-kpi .l { font-size: 10px; letter-spacing: .08em; text-transform: uppercase;
               color: var(--fg-off); }
.page-kpi .v { font-size: 26px; font-weight: 700; letter-spacing: -0.02em; }

/* Кнопка «Фильтры» нужна только на узком экране. */
.fbtn { display: none; }

@media (max-width: 860px) {
  body:has(> .side) { display: block; }
  .col { display: block; }
  .page { flex-direction: column; gap: 10px; padding: 14px; }
  .page h1 { font-size: 20px; }
  .page-right { align-items: stretch; width: 100%; }
  .page-act { justify-content: flex-start; }
  .page-kpi { text-align: left; }
  .fbtn { display: inline-flex; }
}

.side {
  width: 216px; flex: 0 0 216px; background: var(--side-bg); color: var(--side-fg);
  display: flex; flex-direction: column; padding: 16px 0; overflow-y: auto;
}
.side .brand {
  display: flex; align-items: center; gap: 10px; padding: 0 16px 16px;
  font-weight: 700; font-size: 15px;
}
.side .ava {
  width: 28px; height: 28px; border-radius: 50%; background: var(--accent);
  color: var(--accent-fg); display: grid; place-items: center; font-size: 13px;
}
.side .grp {
  padding: 14px 16px 5px; font-size: 10.5px; letter-spacing: .09em;
  color: var(--side-grp); text-transform: uppercase;
}
.side a {
  display: block; padding: 8px 16px; color: var(--side-fg); text-decoration: none;
  font-size: 14px; border-left: 3px solid transparent;
}
.side a:hover { background: rgba(255,255,255,.06); }
.side a.here {
  background: var(--side-on); color: #fff; font-weight: 600;
  border-left-color: var(--accent);
}
:root { --side-bg: #2A1F26; --side-fg: #D9CDD4; --side-grp: #9B8A94;
        --side-on: rgba(155,44,111,.30); }

/* На телефоне меню ложится полосой сверху. Прокрутка вбок — у самой полосы,
   а не у страницы: горизонтальная прокрутка страницы считается дефектом. */
@media (max-width: 860px) {
  .side {
    width: auto; flex: none; flex-direction: row; align-items: center;
    padding: 0; overflow-x: auto; overflow-y: hidden; gap: 0;
    -webkit-overflow-scrolling: touch;
  }
  .side .brand, .side .grp { display: none; }
  .side a { white-space: nowrap; padding: 12px 14px; border-left: 0;
            border-bottom: 3px solid transparent; }
  .side a.here { border-left: 0; border-bottom-color: var(--accent); }
  /* Короткое меню (смена на `flo`, курьер) обязано влезть целиком: пункт
     за правым краем ничем себя не выдаёт. С «Сборкой» у смены четыре пункта,
     и при полях по 14 px «Загрузка» на 320 px уезжала за край. С «С витрины»
     (22.10.2026) пунктов пять: в 375 px они ещё встают в строку, уже — вторая
     строка, а не прокрутка. */
  .side:not(:has(> a:nth-of-type(6))) { flex-wrap: wrap; }
  .side:not(:has(> a:nth-of-type(6))) a { flex: 1 1 auto; padding: 12px 6px;
            text-align: center; }
}
