/* Кабинет продавца. Светлая тема.
   Все цвета/отступы/шрифты — только через переменные :root. Хардкод цветов ниже запрещён.
   После правки — бампнуть STATIC_VERSION в app/config.py. */

:root {
  --color-bg: #f4f5f7;
  --color-surface: #ffffff;
  --color-surface-2: #f8f9fb;
  --color-border: #e3e6eb;
  --color-text: #1d2330;
  --color-muted: #6b7384;
  --color-accent: #005bff;
  --color-accent-hover: #0049cc;
  --color-accent-soft: #e8f0ff;
  --color-on-accent: #ffffff;
  --color-error: #d92d20;
  --color-error-soft: #fdecea;
  --color-ok: #12875a;
  --color-ok-soft: #e4f5ec;
  --color-warn: #b25e00;
  --color-warn-soft: #fff4d6;
  --color-placeholder: #e3e6eb;
  /* «План-факт»: строки как в таблице плана — остатки тёмные, месяц жёлтый, итоги зелёные, недобор розовый */
  --pf-stock-bg: #20242c;
  --pf-stock-text: #f1f3f6;
  --pf-stock-muted: #9aa3b2;
  --pf-month-bg: #fff3b0;
  --pf-month-text: #3a3000;
  --pf-hdr-bg: #e8f0ff;
  --pf-sum-bg: #e9f4e6;
  --pf-gap-bg: #fdecea;
  --pf-now-bg: #eef4ff;
  --pf-api: #005bff;
  --pf-api-on-dark: #8fb4ff;
  --pf-manual: #b25e00;
  --pf-formula: #8a93a3;
  /* Категории — те же цвета, что у .supply-cat--* в «Запасе» */
  --pf-cat-vip: #00ff00;
  --pf-cat-combat: #00ffff;
  --pf-cat-border: #cccccc;
  --pf-cat-new: #ffff00;
  --pf-cat-drain: #ff0000;
  --pf-on-cat-muted: rgba(0, 0, 0, 0.62);
  /* Рамка ручного поля — как у полей «Запаса», чуть темнее сетки, чтобы поле читалось среди её линий */
  --pf-input-border: #c4c9d2;
  /* Ячейки гипотезы по результату: проверяем — серый, сработала — зелёный, не сработала — красный */
  --pf-hyp-wait: #eceef2;
  /* Сработала / не сработала — ярко, чтобы читалось с одного взгляда (владелец 18.10.2026) */
  --pf-hyp-yes: #6fdc8c;
  --pf-hyp-no: #f4877f;
  --color-shadow: rgba(20, 30, 50, 0.08);
  --color-overlay: rgba(20, 30, 50, 0.45);
  /* Шапка залита цветом площадки (--mp-accent приходит из настроек площадки) */
  --mp-on-accent: #ffffff;
  --mp-layer: rgba(255, 255, 255, 0.16);
  --mp-layer-hover: rgba(255, 255, 255, 0.1);
  --mp-divider: rgba(255, 255, 255, 0.35);

  --radius: 10px;
  --radius-sm: 6px;
  --space-1: 4px;
  --space-2: 8px;
  --space-3: 12px;
  --space-4: 16px;
  --space-5: 24px;
  --space-6: 32px;
  --font-sans: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;
  --font-mono: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;
  --font-size: 14px;
  --nav-height: 56px;
  /* одна высота для всех однострочных контролов и кнопок */
  --control-height: 38px;
  --page-max: 1280px;
  --thumb: 56px;
}

* { box-sizing: border-box; }
[x-cloak] { display: none !important; }

html, body { margin: 0; }
body {
  background: var(--color-bg);
  color: var(--color-text);
  font: var(--font-size)/1.45 var(--font-sans);
  -webkit-font-smoothing: antialiased;
}
a { color: var(--color-accent); text-decoration: none; }
a:hover { text-decoration: underline; }
h1 { font-size: 22px; margin: 0; }
h2 { font-size: 16px; margin: 0 0 var(--space-3); }
/* h3 и абзацы жили на браузерных отступах (по 16px сверху и снизу): заголовок, пояснение под ним
   и таблица читались как три оторванных друг от друга куска. Держим их одной группой — воздух
   остаётся между блоками, а не внутри блока. */
h3 { font-size: 15px; margin: var(--space-5) 0 var(--space-1); }
p { margin: 0 0 var(--space-3); }
h2 + p, h3 + p { margin-top: 0; }
.summary { margin-top: var(--space-2); }
/* Счётчик в заголовке — справка, а не часть названия раздела: жирным остаётся только число */
h3 .muted { font-weight: 400; }
.muted { color: var(--color-muted); }
.mono { font-family: var(--font-mono); font-size: 13px; }
.nowrap { white-space: nowrap; }

/* ---------- шапка ---------- */
.topnav {
  position: sticky; top: 0; z-index: 50;
  background: var(--color-surface);
  border-bottom: 1px solid var(--color-border);
}
/* Шапка целиком в цвете площадки: юрлица разные, и перепутать, чьи деньги на экране, нельзя */
.topnav--mp {
  background: var(--mp-accent, var(--color-accent));
  border-bottom-color: transparent;
  color: var(--mp-on-accent);
}
.topnav__inner {
  max-width: var(--page-max); margin: 0 auto; padding: 0 var(--space-4);
  height: var(--nav-height);
  display: flex; align-items: center; gap: var(--space-4);
}
.topnav__brand {
  font-weight: 700; font-size: 16px; color: var(--color-text);
  /* На цветной шапке — белым: синий на синем не читается */
  white-space: nowrap; overflow: hidden; text-overflow: ellipsis; max-width: 220px;
}
.topnav__brand:hover { text-decoration: none; }

/* Переключатель площадок. Цвет приходит из настроек площадки (--mp-accent на body):
   Ozon и Wildberries — разные юрлица, и перепутать, чьи цифры на экране, нельзя. */

.mp-switch__button {
  display: flex; align-items: center; gap: var(--space-2);
  background: none; border: 0; cursor: pointer; padding: var(--space-1) var(--space-2);
  border-radius: var(--radius-2); max-width: none;
}
.mp-switch__button:hover { background: var(--color-surface-2); }
.mp-switch__store { font-weight: 700; }
.mp-switch__name {
  font-weight: 600; font-size: 13px;
  color: var(--mp-accent, var(--color-accent));
  border-left: 1px solid var(--color-border); padding-left: var(--space-2);
}
.mp-switch__menu { min-width: 240px; }
.mp-switch__item { display: flex; align-items: center; gap: var(--space-2); }
.mp-switch__item small { display: block; color: var(--color-muted); font-size: 12px; }
.mp-switch__item.is-active { font-weight: 600; background: var(--color-surface-2); }
.mp-switch__dot {
  width: 10px; height: 10px; border-radius: 50%; flex: none;
  background: var(--mp-item, var(--color-accent));
}
.topnav__tabs {
  list-style: none; margin: 0 auto; padding: 0;
  display: flex; gap: var(--space-1);
}
.topnav__tabs a, .topnav__link {
  display: block; padding: var(--space-2) var(--space-3);
  border-radius: var(--radius-sm);
  color: var(--color-muted); white-space: nowrap;
}
.topnav__tabs a:hover, .topnav__link:hover { background: var(--color-surface-2); color: var(--color-text); text-decoration: none; }
.topnav__tabs a.is-active, .topnav__link.is-active { background: var(--color-accent-soft); color: var(--color-accent); font-weight: 600; }

/* Всё содержимое цветной шапки — белым, подложки полупрозрачные, чтобы работать с любым цветом */
.topnav--mp .topnav__tabs a,
.topnav--mp .topnav__link,
.topnav--mp .topnav__user,
.topnav--mp .topnav__burger,
.topnav--mp .topnav__brand { color: var(--mp-on-accent); }
.topnav--mp .topnav__tabs a:hover,
.topnav--mp .topnav__link:hover,
.topnav--mp .topnav__user:hover,
.topnav--mp .mp-switch__button:hover { background: var(--mp-layer-hover); color: var(--mp-on-accent); }
.topnav--mp .topnav__tabs a.is-active,
.topnav--mp .topnav__link.is-active { background: var(--mp-layer); color: var(--mp-on-accent); }
.topnav--mp .mp-switch__name { color: var(--mp-on-accent); border-left-color: var(--mp-divider); }
/* Своя светлая заливка на цветной шапке превратила бы белый текст в белое пятно */
.topnav--mp .topnav__user { background: transparent; border-color: var(--mp-divider); }
.topnav__right { display: flex; align-items: center; gap: var(--space-2); }
.topnav__user {
  border: 1px solid var(--color-border); background: var(--color-surface);
  border-radius: var(--radius-sm); padding: var(--space-2) var(--space-3);
  font: inherit; color: var(--color-text); cursor: pointer; white-space: nowrap;
  max-width: 180px; overflow: hidden; text-overflow: ellipsis;
}
.topnav__burger { display: none; }

.dropdown { position: relative; }
.dropdown__menu {
  position: absolute; right: 0; top: calc(100% + var(--space-1));
  min-width: 180px; padding: var(--space-1);
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius); box-shadow: 0 8px 24px var(--color-shadow);
}
.dropdown__menu a, .dropdown__menu button {
  display: block; width: 100%; text-align: left;
  padding: var(--space-2) var(--space-3); border: 0; background: none;
  border-radius: var(--radius-sm); color: var(--color-text); font: inherit; cursor: pointer;
}
.dropdown__menu a:hover, .dropdown__menu button:hover { background: var(--color-surface-2); text-decoration: none; }
.dropdown__menu form { margin: 0; }

/* ---------- страница ---------- */
.page { max-width: var(--page-max); margin: 0 auto; padding: var(--space-5) var(--space-4) var(--space-6); }
.page--center { min-height: 100vh; display: grid; place-items: center; }
.page-head { display: flex; align-items: center; justify-content: space-between; gap: var(--space-4); flex-wrap: wrap; margin-bottom: var(--space-4); }
.page-head--flush { margin-bottom: 0; }
.page-head__side { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; }

.card {
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius); padding: var(--space-5); margin-bottom: var(--space-4);
}
.grid-2 { display: grid; grid-template-columns: repeat(auto-fit, minmax(320px, 1fr)); gap: var(--space-4); align-items: start; }
.grid-2 > .card { margin-bottom: 0; }

.empty { text-align: center; padding: 80px var(--space-4); }
.empty__icon { font-size: 48px; margin-bottom: var(--space-3); }
.empty h1 { margin-bottom: var(--space-2); }

.login { width: 100%; max-width: 360px; }
.login__title { margin-bottom: var(--space-1); }

/* ---------- формы и кнопки ---------- */
.form { display: flex; flex-direction: column; gap: var(--space-3); }
.form--inline { flex-direction: row; flex-wrap: wrap; align-items: flex-end; }
.form > .btn { align-self: flex-start; }
/* В строчной форме кнопка стоит в один ряд с полями, а не над ними */
.form--inline > .btn { align-self: flex-end; }
.form > .btn--block { align-self: stretch; }
/* Действия под таблицей. У .table-scroll своего отступа нет, и кнопка прилипала к последней строке —
   читалось как часть строки, а не как действие над отмеченным. Отступ тот же, что между карточками. */
.form--after-table { margin-top: var(--space-4); }
.field { display: flex; flex-direction: column; gap: var(--space-1); }
.field > span { font-size: 13px; color: var(--color-muted); }
.field__hint { font-size: 12px; color: var(--color-muted); }

input[type=text], input[type=password], input[type=search], input[type=number], input[type=date], input[type=file], select, textarea {
  font: inherit; color: var(--color-text);
  background: var(--color-surface);
  border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  padding: var(--space-2) var(--space-3); min-height: var(--control-height);
}
/* Высота задаётся явно: у select и input[type=date] своя внутренняя раскладка,
   с одним только min-height они выходили на 2-3px ниже текстовых полей в том же ряду. */
input[type=text], input[type=password], input[type=search], input[type=number], input[type=date], select {
  height: var(--control-height);
}
input:focus, select:focus, textarea:focus { outline: 2px solid var(--color-accent-soft); border-color: var(--color-accent); }
input:disabled { background: var(--color-surface-2); color: var(--color-muted); }

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: var(--space-1);
  font: inherit; font-weight: 500; white-space: nowrap;
  min-height: var(--control-height); padding: var(--space-2) var(--space-4);
  border: 1px solid var(--color-border); border-radius: var(--radius-sm);
  background: var(--color-surface); color: var(--color-text); cursor: pointer;
}
.btn:hover { background: var(--color-surface-2); text-decoration: none; }
.btn--primary { background: var(--color-accent); border-color: var(--color-accent); color: var(--color-on-accent); }
.btn--primary:hover { background: var(--color-accent-hover); }
.btn--ghost { border-color: transparent; background: none; }
.btn--sm { min-height: 28px; padding: var(--space-1) var(--space-2); font-size: 13px; }
.btn--block { width: 100%; }
.btn[disabled], .btn.htmx-request { opacity: .6; pointer-events: none; }
.btn .spinner { display: none; }
.btn.htmx-request .spinner, form.htmx-request button[type=submit] .spinner { display: inline-block; }
form.htmx-request button[type=submit] { opacity: .6; pointer-events: none; }
.spinner {
  width: 12px; height: 12px; border-radius: 50%;
  border: 2px solid currentColor; border-right-color: transparent;
  animation: spin .7s linear infinite;
}
@keyframes spin { to { transform: rotate(360deg); } }

.alert { padding: var(--space-3) var(--space-4); border-radius: var(--radius-sm); margin-bottom: var(--space-3); }
.alert--error { background: var(--color-error-soft); color: var(--color-error); }
.alert--ok { background: var(--color-ok-soft); color: var(--color-ok); }
.alert--warn { background: var(--color-warn-soft); color: var(--color-warn); }

/* Галочки доступа к вкладкам в таблице пользователей */
.perm-grid { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-3); max-width: 340px; }
.perm { display: inline-flex; align-items: center; gap: 6px; font-size: 13px; white-space: nowrap; cursor: pointer; }
.perm input { margin: 0; }

.badge {
  display: inline-block; padding: 1px var(--space-2); border-radius: 999px;
  font-size: 12px; background: var(--color-surface-2); color: var(--color-muted);
  border: 1px solid var(--color-border); white-space: nowrap;
}
.badge--ok { background: var(--color-ok-soft); color: var(--color-ok); border-color: transparent; }
.badge--accent { background: var(--color-accent-soft); color: var(--color-accent); border-color: transparent; }

.meta { display: grid; grid-template-columns: max-content 1fr; gap: var(--space-1) var(--space-4); margin: 0; }
.meta dt { color: var(--color-muted); }
.meta dd { margin: 0; }

/* ---------- таблицы ---------- */
.table { width: 100%; border-collapse: collapse; }
.table th {
  text-align: left; font-weight: 500; font-size: 12px; color: var(--color-muted);
  padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--color-border); white-space: nowrap;
}
.table td { padding: var(--space-2) var(--space-3); border-bottom: 1px solid var(--color-border); vertical-align: middle; }
.table tr.is-dim td { color: var(--color-muted); }
.actions { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.table .num { text-align: right; white-space: nowrap; }
.table .center { text-align: center; }

/* ---------- тосты ---------- */
.toasts {
  position: fixed; right: var(--space-4); bottom: var(--space-4); z-index: 100;
  display: flex; flex-direction: column; gap: var(--space-2); max-width: min(420px, calc(100vw - 32px));
}
.toast {
  padding: var(--space-3) var(--space-4); border-radius: var(--radius);
  background: var(--color-surface); border: 1px solid var(--color-border);
  box-shadow: 0 8px 24px var(--color-shadow); cursor: pointer;
  border-left: 4px solid var(--color-muted);
  animation: toast-in .15s ease-out;
}
.toast--error { border-left-color: var(--color-error); }
.toast--ok { border-left-color: var(--color-ok); }
.toast--warn { border-left-color: var(--color-warn); }
@keyframes toast-in { from { transform: translateY(8px); opacity: 0; } }

/* ---------- модалка ---------- */
.modal { position: fixed; inset: 0; z-index: 80; background: var(--color-overlay); display: grid; place-items: center; padding: var(--space-4); }
.modal__box { background: var(--color-surface); border-radius: var(--radius); padding: var(--space-5); width: 100%; max-width: 720px; max-height: 90vh; overflow: auto; }
.modal__head { display: flex; justify-content: space-between; align-items: center; margin-bottom: var(--space-3); }

/* ---------- себестоимость ---------- */
.tiles { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-3); margin-bottom: var(--space-4); }
.tile {
  display: block; background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius); padding: var(--space-4); color: var(--color-text);
}
.tile:hover { text-decoration: none; }
.tile__value { font-size: 24px; font-weight: 700; margin-top: var(--space-1); white-space: nowrap; }
.tile__label { color: var(--color-muted); font-size: 13px; }
.tile--warn { border-color: var(--color-warn); background: var(--color-warn-soft); }
.tile--warn .tile__value { color: var(--color-warn); }
a.tile:hover { box-shadow: 0 0 0 2px var(--color-accent-soft); }
a.tile--warn:hover { box-shadow: 0 0 0 2px var(--color-warn); }
.tile--err { border-color: var(--color-error); background: var(--color-error-soft); }
.tile--err .tile__value { color: var(--color-error); }
a.tile--err:hover { box-shadow: 0 0 0 2px var(--color-error); }
.tile.is-active { box-shadow: 0 0 0 2px var(--color-accent); }

.toolbar { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; margin-bottom: var(--space-3); }
.toolbar input[type=search] { flex: 1 1 260px; }
.toolbar__spacer { flex: 1; }
/* Второй ряд фильтра: кнопки конкретных складов внутри выбранной группы (FBS) */
.toolbar__row { flex: 1 1 100%; display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.seg { display: inline-flex; border: 1px solid var(--color-border); border-radius: var(--radius-sm); overflow: hidden; background: var(--color-surface); }
.seg label { padding: var(--space-2) var(--space-3); color: var(--color-muted); border-right: 1px solid var(--color-border); white-space: nowrap; cursor: pointer; }
.seg label:last-child { border-right: 0; }
.seg label:hover { background: var(--color-surface-2); }
.seg label:has(input:checked) { background: var(--color-accent-soft); color: var(--color-accent); font-weight: 600; }
.seg label:has(input:focus-visible) { outline: 2px solid var(--color-accent); outline-offset: -2px; }
.seg input { position: absolute; opacity: 0; pointer-events: none; }

.costs-table { background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius); overflow: hidden; }
.costs-table .table td { padding-top: var(--space-2); padding-bottom: var(--space-2); }
.costs-table th a { color: inherit; }
.th-sort { color: inherit; text-decoration: none; white-space: nowrap; }
.th-sort:hover { color: var(--color-accent); }
.th-sort.is-active { color: var(--color-text); }
.row--nocost .product-row td:first-child { box-shadow: inset 4px 0 0 var(--color-warn); }
.row--archived td { color: var(--color-muted); }
.thumb {
  width: var(--thumb); height: var(--thumb); border-radius: var(--radius-sm);
  object-fit: cover; background: var(--color-placeholder); display: block;
}
.product-name { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; max-width: 460px; }
.cost-value {
  border: 1px dashed transparent; background: none; font: inherit; font-weight: 600;
  color: var(--color-text); padding: var(--space-1) var(--space-2); border-radius: var(--radius-sm); cursor: pointer; white-space: nowrap;
}
.cost-value:hover { border-color: var(--color-border); background: var(--color-surface-2); }
.cost-edit { display: flex; flex-wrap: wrap; gap: var(--space-1); align-items: center; }
.cost-edit input[name=cost] { width: 110px; text-align: right; }
.cost-edit input[type=date] { width: 140px; }
.cost-edit input[name=note] { width: 140px; }
.upcoming { display: block; font-size: 12px; color: var(--color-muted); }
/* «В пути»: под заголовком колонки — подпись, что именно в ней лежит */
.th-hint { display: block; font-size: 11px; font-weight: 400; line-height: 1.2; color: var(--color-muted); margin-top: 2px; }
.stock-table th.num .th-hint { max-width: 120px; margin-left: auto; }
.chevron { transition: transform .15s; display: inline-block; }
.chevron.is-open { transform: rotate(90deg); }
.history-row > td { background: var(--color-surface-2); }
.history { font-size: 13px; padding: var(--space-1) 0; max-width: 640px; }
.history__title { font-weight: 600; margin-bottom: var(--space-2); }
.history__item { padding: var(--space-2) 0; border-bottom: 1px solid var(--color-border); }
.history__item:last-child { border-bottom: 0; }
.history__item.is-past { color: var(--color-muted); }
.history__main { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.history__date { min-width: 96px; }
code { font-family: var(--font-mono); font-size: 12px; background: var(--color-surface-2); padding: 1px var(--space-1); border-radius: var(--radius-sm); }
.alert ul { margin: var(--space-2) 0 0; padding-left: var(--space-5); }
.list-footer { padding: var(--space-3); text-align: center; color: var(--color-muted); }

.preview-stats { display: flex; flex-wrap: wrap; gap: var(--space-3); margin-bottom: var(--space-3); }
.diff-up { color: var(--color-error); }
.diff-down { color: var(--color-ok); }

.htmx-indicator { opacity: 0; transition: opacity .2s; }
.htmx-request .htmx-indicator, .htmx-request.htmx-indicator { opacity: 1; }

/* ---------- мобильная вёрстка ---------- */
@media (max-width: 960px) {
  .topnav__burger {
    display: inline-flex; margin-left: auto; font-size: 20px;
    background: none; border: 0; color: var(--color-text); cursor: pointer; padding: var(--space-2);
  }
  .topnav__tabs {
    display: none; position: absolute; top: var(--nav-height); left: 0; right: 0;
    flex-direction: column; background: var(--color-surface);
    border-bottom: 1px solid var(--color-border); padding: var(--space-2) var(--space-4); margin: 0;
  }
  .topnav--mp .topnav__tabs { background: var(--mp-accent, var(--color-accent)); border-bottom-color: transparent; }
  .topnav__tabs.is-open { display: flex; }
  .topnav__right { margin-left: 0; }
  .tiles { grid-template-columns: repeat(2, 1fr); }
}

@media (max-width: 720px) {
  .hide-sm { display: none; }
  .page { padding: var(--space-4) var(--space-3) var(--space-6); }
  .card { padding: var(--space-4); }
  .topnav__brand { max-width: 140px; }
  .mp-switch__store { max-width: 90px; overflow: hidden; text-overflow: ellipsis; }
  .tile__value { font-size: 20px; }
  .seg { flex-wrap: wrap; }
  .seg label { flex: 1 1 auto; text-align: center; border-bottom: 1px solid var(--color-border); }
  .toolbar select, .toolbar .combo__input { flex: 1 1 100%; }

  /* Таблица → карточки */
  .table--cards thead { display: none; }
  .table--cards, .table--cards tbody, .table--cards tr, .table--cards td { display: block; width: 100%; }
  .table--cards tr { border-bottom: 1px solid var(--color-border); padding: var(--space-3); }
  .table--cards td { border: 0; padding: var(--space-1) 0; }
  .table--cards td[data-label]::before {
    content: attr(data-label); display: block; font-size: 12px; color: var(--color-muted);
  }
  .table--cards td.no-label::before { content: none; }

  .table--cards tbody { display: block; }
  .costs-table .table--cards tr.product-row {
    display: grid; gap: var(--space-1) var(--space-3); align-items: start;
    grid-template-columns: var(--thumb) 1fr auto;
    grid-template-areas: "thumb name name" "thumb offer toggle" "thumb cost toggle" ". stock stock" ". date date";
  }
  .costs-table .product-row td { padding: 0; }
  .costs-table .product-row td::before { display: none; }
  .costs-table .cell-thumb { grid-area: thumb; }
  .costs-table .cell-name { grid-area: name; }
  .costs-table .cell-offer { grid-area: offer; }
  .costs-table .cell-cost { grid-area: cost; }
  .costs-table .cell-stock { grid-area: stock; font-size: 13px; }
  .costs-table .product-row td.cell-stock::before { content: 'По складу: '; display: inline; font-size: 12px; }
  .costs-table .cell-date { grid-area: date; font-size: 12px; color: var(--color-muted); }
  .costs-table .product-row td.cell-date::before { content: 'Изменена: '; display: inline; font-size: 12px; }
  .costs-table .cell-toggle { grid-area: toggle; align-self: center; }
  .costs-table .history-row td { padding: var(--space-2) var(--space-3); }
  .row--nocost .product-row { box-shadow: inset 4px 0 0 var(--color-warn); }
  .row--nocost td:first-child { box-shadow: none; }
  .cost-edit input[name=cost], .cost-edit input[type=date], .cost-edit input[name=note] { flex: 1 1 100%; width: 100%; }
  .product-name { max-width: none; }
}

/* ---------- мой склад ---------- */
/* Липнут под шапкой сайта. На «Моём складе» вкладок 11, а таблицы длинные: без этого
   «История изменений» уезжает за верх экрана и найти её нельзя — на ней живёт откат правок. */
.subtabs {
  display: flex; flex-wrap: wrap; gap: var(--space-1);
  margin-bottom: var(--space-4); border-bottom: 1px solid var(--color-border);
  position: sticky; top: var(--nav-height); z-index: 40;
  background: var(--color-bg); padding-top: var(--space-2);
}
@media (max-width: 720px) {
  /* Вкладки липкие, а на телефоне их десяток: в четыре строки они съели бы пол-экрана.
     Держим одну строку со сдвигом вбок. Правило обязано стоять ниже базового: специфичность
     та же, и медиазапрос выше по файлу базовое не перебил бы. */
  .subtabs { flex-wrap: nowrap; overflow-x: auto; scrollbar-width: none; }
  .subtabs::-webkit-scrollbar { display: none; }
}
/* Вложенный переключатель под рядом вкладок (пока это «Счета ФФ» / «Отправления FBS» внутри FBS).
   Рисуется сегментом, а не второй строкой подчёркиваний: два одинаковых ряда сливаются в один. */
.stock-subnav { margin-bottom: var(--space-4); }
.subtabs:has(+ .stock-subnav) { margin-bottom: var(--space-3); }
.subtabs a { padding: var(--space-2) var(--space-3); color: var(--color-muted); border-bottom: 2px solid transparent; margin-bottom: -1px; white-space: nowrap; }
.subtabs a:hover { color: var(--color-text); text-decoration: none; }
.subtabs a.is-active { color: var(--color-accent); border-bottom-color: var(--color-accent); font-weight: 600; }
.table-scroll { overflow-x: auto; }
.is-clickable { cursor: pointer; }
.is-clickable:hover td { background: var(--color-surface-2); }
.qty-neg { color: var(--color-error); font-weight: 600; }
.qty-pos { color: var(--color-ok); }
.row--negative td:first-child { box-shadow: inset 4px 0 0 var(--color-error); }
/* Себестоимость посчитана не до конца: часть сумм ещё не внесена */
.row--incomplete td:first-child,
.batch--incomplete td:first-child { box-shadow: inset 4px 0 0 var(--color-warn); }
.row--warn td { background: var(--color-warn-soft); }
/* Товары внутри накладной в «Остатки → По накладным»: раскрываются под строкой накладной */
.row--sub td { background: var(--color-bg); }
.row--sub td:first-child { padding-left: var(--space-5); }
.warn-text { color: var(--color-warn); font-size: 13px; }
.badge--warn { background: var(--color-warn-soft); color: var(--color-warn); border-color: transparent; }
.badge--error { background: var(--color-error-soft); color: var(--color-error); border-color: transparent; }
.modal__box--wide { max-width: 1100px; }
.stock-product__head { display: flex; gap: var(--space-3); align-items: center; margin-bottom: var(--space-2); }
.stock-product__head h2 { margin: 0; }
.stock-table td.num, .stock-table th.num { min-width: 72px; }
/* Колонки складов в «Остатках» — по центру: заголовок стоит ровно над своей цифрой. «Итого» и
   «Стоимость» остаются по правому краю, иначе разряды сумм не встают друг под другом.
   Только на широком экране: в карточках на телефоне значения идут столбиком слева */
@media (min-width: 721px) {
  .stock-table td.col-wh, .stock-table th.col-wh { text-align: center; min-width: 0; }
  .stock-table th.col-wh { line-height: 1.25; }
  /* То же для колонок с датой и сроком в разрезе «По накладным» */
  .stock-table td.col-mid, .stock-table th.col-mid { text-align: center; }
}
/* Строка заголовков таблиц липнет под шапкой (и под вкладками склада), как закреплённая строка
   в Excel: таблицы длинные, и к середине уже не видно, какая колонка что значит. Классы ставит
   app.js. Sticky не работает внутри overflow-контейнера, поэтому обёрткам таблицы скролл меняем
   на clip (углы режутся так же, но обёртка перестаёт быть скролл-контейнером) — и только когда
   таблица влезает по ширине: иначе clip отрезал бы её боковой скролл. Уже 1024px не липнем вовсе */
@media (min-width: 1024px) {
  /* !important — служебный класс от JS: у .stage, .card и прочих обёрток свой overflow ниже по файлу
     с той же специфичностью, и он перебивал clip. Обёртка оставалась скролл-контейнером, и заголовок
     лип к ней, а не к окну: висел на 144px ниже верха карточки поверх строк (07.10.2026) */
  .sticky-clip { overflow: clip !important; }
  .table--sticky-head > thead th {
    position: sticky; top: var(--sticky-top, var(--nav-height)); z-index: 30;
    background: var(--color-surface); box-shadow: inset 0 -1px 0 var(--color-border);
  }
}
/* Таблица в своей рамке со скроллом в обе стороны — для широких таблиц, где общий липкий заголовок
   (.table--sticky-head) не работает: ему нужен clip у обёртки, а clip отрезал бы боковой скролл.
   «Поставки на Ozon» шириной зависят от числа кластеров и на ноутбуке не влезают (15.10.2026).
   Заголовок липнет к верху рамки, рамка — не выше окна под шапкой, так что он всегда на экране.
   Вычитаем нижний отступ main.page (--space-6): иначе в конце страницы верх рамки уезжает под вкладки */
@media (min-width: 1024px) {
  .table-frame {
    overflow: auto;
    max-height: calc(100vh - var(--sticky-top, var(--nav-height)) - var(--space-6));
  }
  .table-frame > .table > thead th {
    position: sticky; top: 0; z-index: 3;
    background: var(--color-surface-2); box-shadow: inset 0 -1px 0 var(--color-border);
  }
}
.select-batch { width: 100%; min-width: 260px; }
.new-batch { display: flex; flex-wrap: wrap; gap: .35rem; margin-top: .35rem; }
.new-batch input { flex: 1 1 8rem; min-width: 0; }
/* Ручка перемещения строки в редакторе документа. touch-action: none — иначе палец на ручке скроллит
   страницу и перетащить строку нечем */
.drag-cell { width: 28px; padding-right: 0; }
.drag-handle {
  border: 0; background: none; padding: var(--space-1); line-height: 1; cursor: grab;
  color: var(--color-muted); font-size: 16px; touch-action: none; border-radius: var(--radius-sm);
}
.drag-handle:hover { color: var(--color-text); background: var(--color-surface-2); }
.drag-handle:active { cursor: grabbing; }
.row--dragging td { background: var(--color-accent-soft); box-shadow: inset 0 0 0 1px var(--color-accent); }
.row--dragging td:first-child { box-shadow: inset 3px 0 0 var(--color-accent); }
/* Пока тащим — курсор «схвачено» по всей странице и никакого выделения текста */
body.is-dragging { user-select: none; cursor: grabbing; }
body.is-dragging .drag-handle { cursor: grabbing; }
/* Названия товаров у Ozon в сотню символов: без потолка список растягивается по самому длинному
   и выталкивает штуки за правый край таблицы */
.select-offer { width: 100%; min-width: 220px; max-width: 420px; }
.input-qty { width: 96px; text-align: right; }
input.input-qty.is-invalid { border-color: var(--color-error); }
.error-text { display: block; font-size: 12px; color: var(--color-error); }
/* Подсказка под полем штук не должна растягивать колонку и выталкивать «Убрать» за край карточки */
.waybill-lines .error-text, .waybill-lines .upcoming { max-width: 260px; margin-left: auto; white-space: normal; }
/* Пересорт. Под списком товара висит артикул, и при выравнивании по середине поля этой ячейки уезжали
   выше соседних — строка выглядела кривой. Выравниваем всё по верху: поля встают в одну линию, а подписи
   свисают под ними. Текст без поля (цена, прочерк) — высотой поля, чтобы стоять на той же линии.
   Колонок много, и на узком экране таблица листается вбок (решение владельца 01.10.2026): каждому полю —
   своя колонка, а не стопка в одной ячейке. Название товара сужено — артикул под списком его дублирует,
   а партии отдано место под номер накладной целиком: по нему и выбирают */
.table--regrade td { vertical-align: top; }
/* Заголовки — все по центру колонки (решение владельца 01.10.2026): вперемешку слева и справа они не
   читались как один ряд. Числа в ячейках при этом остаются по правому краю — так разряды встают друг
   под другом, и 1 000 от 100 000 отличается с первого взгляда */
.table--regrade thead th, .table--regrade thead th.num { text-align: center; }
.table--regrade td > .cell-text { display: inline-block; line-height: var(--control-height); }
.table--regrade .select-offer { min-width: 180px; max-width: 240px; }
.table--regrade .select-batch { min-width: 250px; }
.table--regrade select[name=line_reason] { min-width: 210px; }
.table--regrade select[name=line_cost] { min-width: 245px; }
/* Крестик высотой поля — иначе он висит выше линии, на которой стоят поля строки */
.table--regrade td.row-remove .btn { height: var(--control-height); }
@media (min-width: 721px) {
  .table--regrade td.row-remove, .table--regrade th.row-remove {
    position: sticky; right: 0; background: var(--color-surface);
  }
}
/* Счёт ФФ: в строке два длинных списка, и таблица выезжает за карточку. Колонку с «✕» держим
   у правого края, иначе удалить строку можно только домотав горизонтальный скролл */
@media (min-width: 721px) {
  .ff-lines td.row-remove, .ff-lines th.row-remove {
    position: sticky; right: 0; background: var(--color-surface);
  }
}
/* Переезд — под «Куда относим», только для строк «подготовка переезда» */
.ff-lines select[name=line_transfer] { display: block; width: 100%; margin-top: 6px; }
.ff-total td { border-bottom: 0; }
@media (max-width: 720px) {
  .ff-lines tfoot { display: block; }
  .ff-total__label, .ff-total td.row-remove { display: none !important; }
}
/* Выпадающие списки с поиском (static/select-search.js). Настоящий select скрыт, но не display: none —
   иначе браузер не покажет подсказку required. Выбранный пункт — подсказка поля: тёмная, пока не печатают */
.combo-native { position: absolute; width: 1px; height: 1px; opacity: 0; pointer-events: none; }
input.combo__input { padding-right: 32px; text-overflow: ellipsis; cursor: pointer;
  background-image: linear-gradient(45deg, transparent 50%, var(--color-muted) 50%),
    linear-gradient(135deg, var(--color-muted) 50%, transparent 50%);
  background-position: calc(100% - 17px) 50%, calc(100% - 12px) 50%;
  background-size: 5px 5px; background-repeat: no-repeat; }
input.combo__input::placeholder { color: var(--color-text); opacity: 1; }
input.combo__input:focus { cursor: text; }
input.combo__input:focus::placeholder { color: var(--color-muted); }
input.combo__input.is-invalid { border-color: var(--color-error); }
.combo__list { position: fixed; z-index: 90; list-style: none; margin: 0; padding: var(--space-1) 0; overflow-y: auto;
  border: 1px solid var(--color-border); border-radius: var(--radius-sm); background: var(--color-surface);
  box-shadow: 0 4px 12px var(--color-shadow); }
.combo__list[hidden] { display: none; }
.combo__list li { padding: 6px var(--space-3); cursor: pointer; font-size: 14px; line-height: 1.35; }
.combo__list li.is-active { background: var(--color-accent-soft); }
.combo__list li.is-picked { font-weight: 600; }
.combo__list li.combo__empty { cursor: default; color: var(--color-muted); }

/* Накладные и ПЭК: одна стадия пути груза = одна карточка со своей таблицей
   и своими действиями внизу. Действия рядом с данными, к которым относятся. */
.stage {
  background: var(--color-surface); border: 1px solid var(--color-border);
  border-radius: var(--radius); margin-bottom: var(--space-4); overflow: hidden;
}
.stage__head {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: var(--space-3); padding: var(--space-4) var(--space-4) var(--space-3);
}
.stage__title { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-2); margin: 0; }
.stage__hint { margin: var(--space-1) 0 0; color: var(--color-muted); font-size: 13px; }
.stage__count { color: var(--color-muted); font-size: 13px; font-weight: 400; }
/* Блок 1 накладных: строка, товар которой уже на складе карго в Китае */
.china-row:has(.china-arrived:checked) td { background: var(--color-ok-soft); }
.china-arrived { width: 18px; height: 18px; cursor: pointer; }
.stage__empty { margin: 0; padding: 0 var(--space-4) var(--space-4); color: var(--color-muted); }
.stage__subtitle { font-size: 14px; margin: var(--space-4) var(--space-4) var(--space-2); }
.stage .table tbody tr:last-child td { border-bottom: 0; }
.stage .table th:first-child, .stage .table td:first-child { padding-left: var(--space-4); }
.stage .table th:last-child, .stage .table td:last-child { padding-right: var(--space-4); }
/* Действия — сразу под шапкой стадии: при длинной таблице кнопки не должны уезжать за экран */
.stage__actions {
  display: flex; flex-wrap: wrap; align-items: flex-start; gap: var(--space-3); padding: var(--space-4);
  background: var(--color-surface-2); border-bottom: 1px solid var(--color-border);
}
/* Раскрывашка с архивом идёт сразу за таблицей или кнопкой действий над ней.
   Без верхнего отступа она слипалась с кнопкой и читалась как одна с ней плашка.
   Отступ тот же, что между карточками. */
.stage--archive { padding: 0; margin-top: var(--space-4); }
.stage__summary { padding: var(--space-4); cursor: pointer; font-weight: 600; }
.stage__summary::marker { color: var(--color-muted); }
.stage__archive { border-top: 1px solid var(--color-border); padding-bottom: var(--space-3); }
.step-badge {
  display: inline-flex; align-items: center; justify-content: center;
  width: 22px; height: 22px; border-radius: 50%;
  background: var(--color-accent-soft); color: var(--color-accent);
  font-size: 12px; font-weight: 700;
}

/* Внутри стадии: поля и кнопка, к которой они относятся, лежат в одной рамке,
   иначе кнопки перемешиваются с чужими полями. */
.action-group {
  display: grid; gap: var(--space-3);
  /* группы делят строку, пока каждой хватает ~360px; дальше переносятся */
  flex: 1 1 360px;
  padding: var(--space-3) var(--space-4) var(--space-4);
  border: 1px solid var(--color-border); border-radius: var(--radius);
  background: var(--color-surface);
}
.action-group__head { display: flex; flex-wrap: wrap; align-items: baseline; gap: var(--space-2); }
.action-group__title { font-weight: 600; }
.action-group__hint { color: var(--color-muted); font-size: 13px; }
.action-group__body { display: flex; flex-wrap: wrap; align-items: flex-end; gap: var(--space-3); }
.action-group__foot { display: flex; }
.action-group .field--text input { width: 200px; }
.action-group .field--date input { width: 150px; }

@media (max-width: 720px) {
  .action-group__body .field { flex: 1 1 100%; }
  .action-group .field--text input, .action-group .field--date input { width: 100%; }
  .action-group__foot .btn { width: 100%; }
  .stage__head, .stage__actions, .stage__summary { padding: var(--space-3); }
  .stage__subtitle { margin-left: var(--space-3); margin-right: var(--space-3); }
  .stage .table th:first-child, .stage .table td:first-child { padding-left: var(--space-3); }
}
.paste summary { cursor: pointer; color: var(--color-accent); margin-bottom: var(--space-2); }
.paste textarea { width: 100%; font-family: var(--font-mono); font-size: 13px; }
.stock-doc h2 { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.stock-doc .meta { margin-bottom: var(--space-4); }
.doc-note { white-space: pre-line; margin-right: var(--space-2); }
.doc-note-edit { display: flex; flex-direction: column; gap: var(--space-1); max-width: 520px; }
.doc-note-edit .toolbar { margin: 0; }

@media (max-width: 720px) {
  .select-batch, .select-offer { min-width: 0; max-width: none; }
  .input-qty { width: 100%; }
  .modal__box { padding: var(--space-4); }
}
.section-title { margin: var(--space-5) 0 var(--space-3); }
.grid-2 + .card { margin-top: var(--space-4); }

/* Справочники «Мой склад»: названия в таблицах стоят по одной линии с полями формы над ними,
   а кнопки удаления — у правого края, одинаково во всех таблицах вкладки */
@media (min-width: 721px) {
  .ref-table th:first-child, .ref-table td:first-child { padding-left: 0; }
  /* Отступ справа — чтобы кнопка не липла к краю карточки */
  .ref-table th:last-child, .ref-table td:last-child:not(.list-footer) {
    padding-right: calc(var(--space-6) + var(--space-2)); width: 1%; white-space: nowrap; text-align: right;
  }
}
/* Таблица складов стоит колонками под формой «Добавить склад»: поле названия и «Переименовать» —
   под «Названием» и «Видом», вид склада — под «Фулфилментом», выбор фулфилмента — под «Названием в Ozon».
   Ширины общие для формы и таблицы, поэтому раскладка у таблицы фиксированная, иначе браузер
   раздал бы свободное место по колонкам и линии разошлись бы. */
.ref-wh { --wh-name: 200px; --wh-kind: 200px; --wh-op: 170px; --wh-ozon: 200px; --wh-gap: var(--space-6); }
.ref-rename { display: grid; grid-template-columns: 1fr auto; align-items: center; column-gap: var(--space-3); row-gap: var(--space-1); }
/* width: 0 + min-width: 100% — подпись «в Ozon: …» переносится по ширине поля, а не раздвигает его */
.ref-rename__note { width: 0; min-width: 100%; }
.ref-rename > .btn { justify-self: start; }
@media (min-width: 721px) {
  .ref-wh__form { column-gap: var(--wh-gap); }
  .ref-wh__name { width: var(--wh-name); }
  .ref-wh__kind { width: var(--wh-kind); }
  .ref-wh__op { width: var(--wh-op); }
  .ref-wh__ozon { width: var(--wh-ozon); }
  .ref-wh__form .field input, .ref-wh__form .field select { width: 100%; }
  .ref-wh .ref-table { table-layout: fixed; }
  .ref-wh .ref-table th:not(:last-child), .ref-wh .ref-table td:not(:last-child) { padding-left: 0; padding-right: var(--wh-gap); }
  .ref-wh .ref-table th:nth-child(1) { width: calc(var(--wh-name) + var(--wh-kind) + 2 * var(--wh-gap)); }
  .ref-wh .ref-table th:nth-child(2) { width: calc(var(--wh-op) + var(--wh-gap)); }
  .ref-wh .ref-table th:nth-child(3) { width: calc(var(--wh-ozon) + var(--wh-gap)); }
  .ref-wh .ref-table th:last-child { width: calc(var(--space-6) * 5); }
  .ref-wh .ref-table td:nth-child(3) select, .ref-wh .ref-table td:nth-child(3) .combo__input { width: 100%; }
  .ref-rename { grid-template-columns: var(--wh-name) auto; column-gap: var(--wh-gap); }
  .ref-rename input { width: 100%; }
}

/* ---------------------------------------------------------------- Руководство
   Статьи раздела «Руководство». Главное здесь — снимок экрана с номерами: кружки
   позиционируются в процентах от картинки, поэтому переснятый экран не ломает разметку,
   а подписи остаются текстом и читаются на телефоне под картинкой. */

/* Раздел свёрнут по умолчанию: шесть строк оглавления видно целиком, без прокрутки */
.guide-section { padding: 0; }
.guide-section + .guide-section { margin-top: var(--space-3); }
.guide-section__head {
  display: flex; align-items: center; gap: var(--space-3);
  padding: var(--space-4) var(--space-5);
  cursor: pointer; list-style: none; user-select: none;
  border-radius: var(--radius);
}
.guide-section__head::-webkit-details-marker { display: none; }
.guide-section__head:hover { background: var(--color-surface-2); }
.guide-section__num {
  flex: 0 0 32px; height: 32px;
  border-radius: var(--radius-sm);
  background: var(--color-accent-soft); color: var(--color-accent);
  font: 700 15px/32px var(--font-sans); text-align: center;
}
.guide-section__title { font-size: 17px; font-weight: 600; flex: 1 1 auto; }
.guide-section__count { color: var(--color-muted); font-size: 14px; white-space: nowrap; }
/* Стрелка: вниз — раздел свёрнут, вверх — раскрыт */
.guide-section__head::after {
  content: '▾'; color: var(--color-muted); font-size: 14px; transition: transform .15s ease;
}
.guide-section[open] > .guide-section__head::after { transform: rotate(180deg); }
.guide-section[open] > .guide-section__head { border-bottom: 1px solid var(--color-border); border-radius: var(--radius) var(--radius) 0 0; }

.guide-list { list-style: none; margin: 0; padding: var(--space-4) var(--space-5); display: grid; gap: var(--space-3); }
.guide-list li { padding-bottom: var(--space-3); border-bottom: 1px solid var(--color-border); }
.guide-list li:last-child { padding-bottom: 0; border-bottom: 0; }
.guide-list a { font-weight: 600; }
.guide-list__num { color: var(--color-muted); font-variant-numeric: tabular-nums; margin-right: var(--space-2); }
.guide-route { font-size: 13px; margin-top: var(--space-1); }
.guide-back { margin-bottom: var(--space-3); display: flex; gap: var(--space-2); align-items: baseline; flex-wrap: wrap; }
.guide-article__num { color: var(--color-muted); font-size: 14px; font-variant-numeric: tabular-nums; }

/* В карточке статьи список «Рядом» лежит внутри и своих отступов не требует */
.guide-article .guide-list { padding: 0; }

.guide-article { max-width: 860px; }
.guide-article h1 { margin-top: 0; }
.guide-article h2 { margin-top: var(--space-6); }
.guide-article p { margin: 0 0 var(--space-3); }
.guide-article blockquote {
  margin: 0 0 var(--space-4);
  padding: var(--space-3) var(--space-4);
  background: var(--color-surface-2);
  border-left: 3px solid var(--color-accent);
  border-radius: 0 var(--radius-sm) var(--radius-sm) 0;
}
.guide-steps { margin: 0 0 var(--space-4); padding-left: var(--space-5); }
.guide-steps li { margin-bottom: var(--space-2); }
.guide-bullet { padding-left: var(--space-4); position: relative; }
.guide-bullet::before { content: '—'; position: absolute; left: 0; color: var(--color-muted); }
.guide-open { margin-top: var(--space-5); }

.shot { margin: var(--space-5) 0 var(--space-6); }
.shot__frame {
  position: relative;
  border: 1px solid var(--color-border);
  border-radius: var(--radius);
  overflow: hidden;
  line-height: 0;
  background: var(--color-surface-2);
}
.shot__frame img { width: 100%; display: block; }
.shot__mark {
  position: absolute;
  transform: translate(-50%, -50%);
  width: 32px; height: 32px;
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-on-accent);
  font: 700 16px/32px var(--font-sans);
  text-align: center;
  box-shadow: 0 0 0 4px rgba(0, 91, 255, 0.22), 0 2px 8px var(--color-shadow);
}
.shot__legend { list-style: none; margin: var(--space-3) 0 0; padding: 0; display: grid; gap: var(--space-2); }
.shot__legend li { display: flex; gap: var(--space-3); align-items: flex-start; line-height: 1.5; }
.shot__legend b {
  flex: 0 0 24px; height: 24px;
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-on-accent);
  font: 700 13px/24px var(--font-sans);
  text-align: center;
}

@media (max-width: 720px) {
  .shot__mark { width: 24px; height: 24px; font-size: 13px; line-height: 24px; box-shadow: 0 0 0 3px rgba(0, 91, 255, 0.22); }
}

/* ---------------------------------------------------------------- Аналитика */
.toolbar { display: flex; align-items: center; gap: var(--space-3); flex-wrap: wrap; margin-bottom: var(--space-4); }
.seg--links a { padding: var(--space-2) var(--space-3); color: var(--color-muted); border-right: 1px solid var(--color-border); white-space: nowrap; }
.seg--links a:last-child { border-right: 0; }
.seg--links a:hover { background: var(--color-surface-2); text-decoration: none; }
.seg--links a.is-active { background: var(--color-accent-soft); color: var(--color-accent); font-weight: 600; }

.chips { display: flex; flex-wrap: wrap; gap: var(--space-1); margin-bottom: var(--space-4); }
.chip {
  padding: var(--space-1) var(--space-3); border: 1px solid var(--color-border);
  border-radius: 999px; background: var(--color-surface); color: var(--color-muted);
  font-size: 13px; cursor: pointer;
}
.chip:hover { background: var(--color-surface-2); }
.chip.is-active { background: var(--color-accent-soft); border-color: var(--color-accent); color: var(--color-accent); font-weight: 600; }

/* Сетка плиток: порядок задаётся CSS-свойством order по рангу выбранной метрики */
.tiles--metric { display: flex; flex-wrap: wrap; }
.tiles--metric .tile { flex: 1 1 200px; max-width: 260px; }
.tile--sku { display: flex; flex-direction: column; gap: 2px; }
.tile__value--empty { font-size: 15px; font-weight: 400; color: var(--color-muted); }
.tile__sku { margin-top: auto; padding-top: var(--space-2); color: var(--color-muted); font-size: 11px; }
.sparkline { display: block; width: 100%; height: 28px; margin-top: var(--space-1); color: var(--color-accent); }
.sparkline--flat { color: var(--color-muted); }

.tile__expenses { margin-top: var(--space-2); font-size: 12px; }
.tile__expenses summary { color: var(--color-muted); cursor: pointer; }
.tile__expenses summary:hover { color: var(--color-text); }
.tile__expenses dl { margin: var(--space-2) 0 0; display: grid; gap: 2px; }
.tile__expenses div { display: flex; justify-content: space-between; gap: var(--space-2); }
.tile__expenses dt { color: var(--color-muted); }
.tile__expenses dd { margin: 0; white-space: nowrap; }
.tile__expenses .is-muted dd { color: var(--color-muted); }

.tile--total { border-color: var(--color-accent); }
.modal__metrics, .modal__expenses { display: grid; gap: var(--space-3); margin: var(--space-3) 0; }
.modal__metrics > div { display: grid; gap: 2px; padding-bottom: var(--space-3); border-bottom: 1px solid var(--color-border); }
.modal__metrics dt, .modal__expenses dt { color: var(--color-muted); font-size: 13px; }
.modal__metrics dd { margin: 0; font-size: 20px; font-weight: 700; }
.modal__metrics dd small { font-weight: 400; font-size: 12px; margin-left: var(--space-2); }
.modal__expenses { gap: 2px; }
.modal__expenses > div { display: flex; justify-content: space-between; gap: var(--space-3); }
.modal__expenses dd { margin: 0; }

/* Вкладка «Карта»: заливка строки показывает вес кластера */
.cluster-bar { display: inline-block; width: 60px; height: 8px; margin-right: var(--space-2);
  border-radius: 4px; background: var(--color-border); position: relative; overflow: hidden; vertical-align: middle; }
.cluster-bar::after { content: ''; position: absolute; inset: 0 auto 0 0; width: var(--w, 0%); background: var(--color-accent); }

/* Кнопки рядом с полем с подписью встают по нижнему краю — на одну линию с самим полем */
.toolbar--bottom { align-items: flex-end; }
/* «Передача товара»: кнопка под строками — по левому краю полей в ячейках и с зазором от таблицы */
.loan-lines__add { margin-top: var(--space-3); padding-left: var(--space-3); }

/* «Новая закупка»: шапка — сетка 4 колонки × 2 ряда, чтобы «Отмеченным строкам» и его кнопки стояли
   ровно под полями (дата / байер / оплачено / комментарий) и не вылезали за их правый край */
.purchase-head {
  display: grid; grid-template-columns: minmax(0, 12rem) repeat(3, minmax(0, 16rem));
  gap: var(--space-3); align-items: end; margin-bottom: var(--space-4);
}
.purchase-head__tool { align-self: center; justify-self: start; }
/* Класс select-search.js переносит на своё поле ввода — растягиваем его, а не скрытый select */
.purchase-head__fill { width: 100%; }
.purchase-head__value { width: 8rem; }
@media (max-width: 720px) { .purchase-head { grid-template-columns: 1fr; } }
/* Первая колонка строк закупки — без отступа слева: поле артикула встаёт под «Дату заказа» и «＋ Строка» */
@media (min-width: 721px) {
  .table--purchase th:first-child, .table--purchase td:first-child { padding-left: 0; }
}

/* «Планёрка» → «Приходы»: товар и его приходы в одной сетке колонок, каждый товар — отдельная карточка */
.arrivals-tiles { grid-template-columns: repeat(4, 1fr); }
.arrivals-toolbar { display: grid; grid-template-columns: repeat(4, 1fr); gap: var(--space-3); margin-bottom: var(--space-4); }
.arrivals-toolbar input[type=search] { grid-column: span 2; width: 100%; }
.arrivals-toolbar__side { display: flex; align-items: center; gap: var(--space-3); grid-column: span 2; }
@media (max-width: 1100px) {
  .arrivals-tiles, .arrivals-toolbar { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 720px) {
  .arrivals-tiles, .arrivals-toolbar { grid-template-columns: 1fr; }
  .arrivals-toolbar input[type=search], .arrivals-toolbar__side { grid-column: auto; }
}
.tile__sub { color: var(--color-muted); font-size: 12px; margin-top: 2px; }
.arrivals-table { border-collapse: separate; border-spacing: 0; min-width: 980px; }
/* Отступ между карточками товаров: строка-распорка в начале каждой карточки, кроме первой */
.arrivals-gap td { height: var(--space-3); padding: 0; background: none; border: 0; }
.arrivals-table > tbody:first-of-type .arrivals-gap { display: none; }
/* Номер и ручка перетаскивания в одной ячейке */
.arrivals-num { white-space: nowrap; }
.arrivals-handle { margin-right: 2px; }
.arrivals-card.is-dragged .arrivals-product td { background: var(--color-accent-soft); border-color: var(--color-accent); }
.arr-c-n { width: 64px; } .arr-c-qty { width: 72px; } .arr-c-date { width: 118px; } .arr-c-sup { width: 150px; }
.arr-c-wb { width: 180px; } .arr-c-stage { width: 190px; } .arr-c-eta { width: 150px; }
.arrivals-table td { border-bottom: 0; }
/* Строка товара — светлая шапка карточки (светлее фона страницы), шапка колонок и приходы — на белом */
.arrivals-product td { background: var(--color-surface-2); padding-top: var(--space-3); padding-bottom: var(--space-3);
  border-top: 1px solid var(--color-border); vertical-align: middle; }
.arrivals-product td:first-child { border-left: 1px solid var(--color-border); border-top-left-radius: var(--radius); }
.arrivals-product td:last-child { border-right: 1px solid var(--color-border); border-top-right-radius: var(--radius); }
/* Свёрнутая карточка и товар без приходов — одна строка, рамка закрывается снизу */
.arrivals-card:not(.is-open) .arrivals-product td { border-bottom: 1px solid var(--color-border); }
.arrivals-card:not(.is-open) .arrivals-product td:first-child { border-bottom-left-radius: var(--radius); }
.arrivals-card:not(.is-open) .arrivals-product td:last-child { border-bottom-right-radius: var(--radius); }
.arrivals-none .arrivals-product td { opacity: .6; }
/* Наведение на свёрнутый товар — чуть темнее, чтобы было видно, что он раскрывается */
.arrivals-product.is-clickable:hover td { background: var(--color-border); }
.arrivals-num { font-weight: 600; color: var(--color-muted); text-align: center; }
.arrivals-title { display: flex; align-items: center; gap: var(--space-3); }
.arrivals-title .product-name { font-weight: 600; }
.arrivals-label { color: var(--color-muted); font-size: 12px; }
.arrivals-big { font-size: 17px; font-weight: 700; white-space: nowrap; }
.arrivals-stage { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); }
.arrivals-more { font-size: 12px; margin-top: 2px; }
.arrivals-toggle { border: 0; background: none; cursor: pointer; color: var(--color-muted); font-size: 18px; line-height: 1; padding: var(--space-1); }
.arrivals-toggle span { display: inline-block; transition: transform .15s; transform: rotate(180deg); }
.arrivals-toggle span.is-open { transform: none; }
.arrivals-head td { background: var(--color-surface); color: var(--color-muted); font-size: 12px;
  padding-top: var(--space-2); padding-bottom: var(--space-2); border-top: 1px solid var(--color-border); }
.arrivals-line td { background: var(--color-surface); color: var(--color-text); font-variant-numeric: tabular-nums;
  border-top: 1px solid var(--color-border); }
.arrivals-line td[rowspan] { vertical-align: middle; }
.arrivals-head td:first-child, .arrivals-line td:first-child { border-left: 1px solid var(--color-border); }
.arrivals-head td:last-child, .arrivals-line td:last-child, .arrivals-line td[rowspan]:last-child { border-right: 1px solid var(--color-border); }
/* Низ карточки — у последней строки последнего прихода */
.arrivals-card > tr:last-child td { border-bottom: 1px solid var(--color-border); }
.arrivals-card > tr:last-child td:first-child { border-bottom-left-radius: var(--radius); }
.arrivals-span-end td[rowspan] { border-bottom: 1px solid var(--color-border); }
/* У последней строки объединённого прихода последняя ячейка — дата закупки, угол карточки не её */
.arrivals-card > tr.arrivals-joined:last-child td:last-child { border-bottom-right-radius: 0; }
.arrivals-card > tr:last-child td:last-child, .arrivals-span-end td[rowspan]:last-child { border-bottom-right-radius: var(--radius); }
/* Закупки одной накладной: скобка слева — приедут вместе */
.arrivals-joined td:nth-child(2) { box-shadow: inset 3px 0 0 var(--color-accent); }

/* «Планёрка» → «Запас». Цвета категорий — как в таблице владельца (15.10.2026): вип #00ff00, боевой #00ffff, приграничный #cccccc */
.supply-table td { vertical-align: middle; }
.supply-table th, .supply-table td { padding-left: var(--space-2); padding-right: var(--space-2); }
.supply-table th.num { white-space: normal; }
.supply-table th.num.nowrap { white-space: nowrap; }
/* По центру: заголовки в две строки и числа под ними читаются одной колонкой (просьба владельца 15.10) */
/* .table.supply-table — сильнее общего «.table .num { text-align: right }» */
.table.supply-table th, .table.supply-table td { text-align: center; vertical-align: middle; }
.table.supply-table th:nth-child(2), .table.supply-table td:nth-child(2) { text-align: left; }
.supply-card.is-dragged td { background: var(--color-accent-soft); }
.supply-table .supply-input, .supply-weeks .supply-input { width: 60px; text-align: center; padding: 0 var(--space-2); }
.supply-cat { border-radius: var(--radius-sm); border: 1px solid var(--color-border); padding: 2px var(--space-2); }
select.supply-cat { height: var(--control-height); padding: 0 var(--space-1); width: 136px; }
.supply-cat--vip { background: #00ff00; border-color: #00b300; }
.supply-cat--combat { background: #00ffff; border-color: #00b3b3; }
.supply-cat--border { background: #cccccc; border-color: #999999; }
.supply-cat--new { background: #ffff00; border-color: #b3b300; }
.supply-cat--drain { background: #ff0000; border-color: #b30000; }
/* Строка с категорией целиком в её цвете, перекрывая серый фон фактических колонок; без категории — белая */
.table.supply-table tr.supply-row > td { background: var(--color-surface); }
.table.supply-table tr.supply-row--vip > td { background: #00ff00; }
.table.supply-table tr.supply-row--combat > td { background: #00ffff; }
.table.supply-table tr.supply-row--border > td { background: #cccccc; }
.table.supply-table tr.supply-row--new > td { background: #ffff00; }
.table.supply-table tr.supply-row--drain > td { background: #ff0000; }
/* Заголовок с подсказкой: пунктир и курсор «?» — иначе про title никто не догадается */
.supply-table th.has-tip { cursor: help; text-decoration: underline dotted; text-underline-offset: 3px; }
/* Поля ввода в цветной строке — в цвет строки и с рамкой, как у списка категорий: видно, что значение можно менять */
.supply-row--vip .supply-input { background: #00ff00; border-color: #00b300; }
.supply-row--combat .supply-input { background: #00ffff; border-color: #00b3b3; }
.supply-row--border .supply-input { background: #cccccc; border-color: #999999; }
.supply-row--new .supply-input { background: #ffff00; border-color: #b3b300; }
.supply-row--drain .supply-input { background: #ff0000; border-color: #b30000; }
/* На ярком фоне категорий обычный серый текст теряется — в цветных строках он темнее */
.supply-row--vip .muted, .supply-row--combat .muted, .supply-row--border .muted, .supply-row--new .muted, .supply-row--drain .muted,
.supply-row--vip .arrivals-num, .supply-row--combat .arrivals-num, .supply-row--border .arrivals-num, .supply-row--new .arrivals-num, .supply-row--drain .arrivals-num { color: rgba(0, 0, 0, 0.62); }
/* Оранжевые недели и красный дефицит на зелёном и бирюзовом не читаются — там они тёмно-красные и жирные */
.supply-row--vip .warn-text, .supply-row--combat .warn-text, .supply-row--border .warn-text, .supply-row--new .warn-text,
.supply-row--vip .supply-deficit, .supply-row--combat .supply-deficit, .supply-row--border .supply-deficit, .supply-row--new .supply-deficit { color: #a50000; font-weight: 700; }
.supply-row--vip .supply-ok, .supply-row--combat .supply-ok, .supply-row--border .supply-ok, .supply-row--new .supply-ok { color: #00500f; font-weight: 700; }
/* На красном «Сливе» тёмно-красный дефицит и тёмно-зелёный ноль не читаются — белым */
.supply-row--drain .warn-text, .supply-row--drain .supply-deficit, .supply-row--drain .supply-ok { color: #ffffff; font-weight: 700; }
.supply-deficit { color: var(--color-error); font-weight: 600; }
.supply-row--short td:first-child { box-shadow: inset 3px 0 0 var(--color-warn); }
/* Сортировка кликом по заголовку — временная, на этом экране. Пока она включена, ручку ⠿ прячем:
   перетаскивание в отсортированном виде переписало бы общий ручной порядок */
.supply-table th[data-sort] { cursor: pointer; user-select: none; }
.supply-table th[data-sort][aria-sort=ascending]::after { content: ' ▲'; }
.supply-table th[data-sort][aria-sort=descending]::after { content: ' ▼'; }
.supply-table.is-sorted .arrivals-handle { display: none; }
.supply-sort-bar { display: flex; justify-content: flex-end; margin-bottom: var(--space-2); }
.supply-weeks__row { display: flex; align-items: center; justify-content: space-between; gap: var(--space-2); margin-top: var(--space-1); }
.supply-weeks .supply-input { width: 56px; }
.supply-ok { color: var(--color-ok); }
/* Фактические колонки «Запаса» — справочные, их не вводят: приглушённый фон отделяет их от плана */
.supply-table .supply-fact { background: var(--color-surface-2); }
.supply-total td { font-weight: 700; border-top: 2px solid var(--color-border); background: var(--color-surface); }

/* «Планёрка» → «Поставки на Ozon»: товар × кластер. Первая колонка прилипает при прокрутке вбок */
.fbo-tiles { grid-template-columns: repeat(4, 1fr); }
.fbo-toolbar { display: flex; flex-wrap: wrap; align-items: center; gap: var(--space-3); margin-bottom: var(--space-2); }
.fbo-toolbar .seg { display: inline-flex; border: 1px solid var(--color-border); border-radius: var(--radius-sm); overflow: hidden; background: var(--color-surface); }
.fbo-toolbar .seg a { padding: 0 var(--space-4); line-height: var(--control-height); color: var(--color-text); }
.fbo-toolbar .seg a:hover { text-decoration: none; background: var(--color-surface-2); }
.fbo-toolbar .seg a.is-active { background: var(--color-accent); color: var(--color-on-accent); }
.fbo-search { display: flex; gap: var(--space-2); flex: 1 1 280px; }
.fbo-search input[type=search] { flex: 1; }
.fbo-clusters summary { cursor: pointer; color: var(--color-accent); }
.fbo-clusters__list { display: grid; grid-template-columns: repeat(auto-fill, minmax(220px, 1fr)); gap: var(--space-1) var(--space-4);
  margin-top: var(--space-2); padding: var(--space-3); background: var(--color-surface); border: 1px solid var(--color-border); border-radius: var(--radius-sm); }
.fbo-clusters__list label { display: flex; gap: var(--space-2); align-items: center; }
.table.fbo-table th, .table.fbo-table td { text-align: center; vertical-align: middle; padding-left: var(--space-2); padding-right: var(--space-2); }
.fbo-table th.num { white-space: nowrap; }
/* Три липкие колонки: «№», «Товар» и «Себест.» (в развёрнутом товаре — подписи строк раскладки).
   Ширина первых двух фиксирована: от неё отсчитывается, где прилипает следующая */
.fbo-table { --fbo-num: 56px; --fbo-first: 240px; }
.table.fbo-table .fbo-sticky0 { position: sticky; left: 0; z-index: 1; background: var(--color-surface);
  width: var(--fbo-num); min-width: var(--fbo-num); max-width: var(--fbo-num); padding-left: var(--space-1); padding-right: var(--space-1); }
.table.fbo-table .fbo-sticky { position: sticky; left: var(--fbo-num); z-index: 1; background: var(--color-surface); text-align: left;
  width: var(--fbo-first); min-width: var(--fbo-first); max-width: var(--fbo-first); white-space: normal; }
.table.fbo-table .fbo-sticky2 { position: sticky; left: calc(var(--fbo-num) + var(--fbo-first)); z-index: 1;
  background: var(--color-surface); box-shadow: 1px 0 0 var(--color-border); }
/* Угол «Товар» липнет в обе стороны и должен лежать поверх липкой колонки строк. Селектор с .table —
   иначе z-index: 1 из правила выше перебивает, и при прокрутке строки наезжают на заголовок */
.table.fbo-table thead .fbo-sticky0, .table.fbo-table thead .fbo-sticky, .table.fbo-table thead .fbo-sticky2 { background: var(--color-surface-2); z-index: 4; }
.table.fbo-table .fbo-total .fbo-sticky0, .table.fbo-table .fbo-total .fbo-sticky, .table.fbo-table .fbo-total .fbo-sticky2 { background: var(--color-surface-2); }
.fbo-table .fbo-sticky .badge { margin-top: var(--space-1); }
.fbo-row:hover > td, .fbo-row:hover > td.fbo-sticky0, .fbo-row:hover > td.fbo-sticky, .fbo-row:hover > td.fbo-sticky2 { background: var(--color-surface-2); }
.fbo-table th.fbo-cl { writing-mode: vertical-rl; transform: rotate(180deg); text-align: left; height: 130px; padding: var(--space-2) var(--space-1); font-weight: 500; }
.fbo-table .fbo-grp { border-left: 2px solid var(--color-border); }
.fbo-c { padding: var(--space-1) 2px; min-width: 34px; }
.fbo-c span { display: inline-block; min-width: 28px; padding: 3px 0; border-radius: 4px; }
.fbo-table th.fbo-cl--off { color: var(--color-muted); font-weight: 400; }
.fbo-heat { background: color-mix(in srgb, var(--color-accent) calc(var(--w, 0) * 40% + 10%), transparent); font-weight: 600; }
.fbo-zero { color: var(--color-border); }
.fbo-send { font-weight: 700; color: var(--color-accent); }
.table.fbo-table td.fbo-msg { text-align: left; color: var(--color-error); white-space: normal; }
.fbo-card.is-dragged td, .fbo-card.is-dragged td.fbo-sticky0, .fbo-card.is-dragged td.fbo-sticky, .fbo-card.is-dragged td.fbo-sticky2 { background: var(--color-accent-soft); }
.fbo-table .supply-input { width: 52px; text-align: center; padding: 0 var(--space-1); }
.fbo-table .supply-input.is-default { color: var(--color-muted); }
/* Развёрнутый товар: строки раскладки под колонками кластеров, подписи — в колонке «Себест.» */
.table.fbo-table .fbo-detail > td, .table.fbo-table .fbo-detail > th { background: var(--color-surface-2); border-top: 0;
  border-bottom: 0; padding-top: 3px; padding-bottom: 3px; font-size: 13px; }
/* Ячейки на все строки раскладки (rowspan) кончаются вместе с последней — им та же линия снизу */
.table.fbo-table .fbo-detail--last > td, .table.fbo-table .fbo-detail--last > th,
.table.fbo-table .fbo-detail > td[rowspan] { border-bottom: 1px solid var(--color-border); }
.table.fbo-table .fbo-detail--first > td, .table.fbo-table .fbo-detail--first > th { padding-top: var(--space-3); }
.table.fbo-table .fbo-detail--last > td, .table.fbo-table .fbo-detail--last > th { padding-bottom: var(--space-3); }
.table.fbo-table .fbo-detail > th.fbo-detail__label { text-align: right; font-weight: 500; color: var(--color-muted); white-space: nowrap; }
.table.fbo-table td.fbo-detail__note { vertical-align: top; white-space: normal; color: var(--color-muted); font-size: 13px; }
.fbo-detail__val { white-space: nowrap; }
.table.fbo-table td.fbo-off { vertical-align: middle; color: var(--color-muted); }
.fbo-off span { writing-mode: vertical-rl; transform: rotate(180deg); white-space: nowrap; min-width: 0; padding: 0; }
.fbo-total td { font-weight: 700; background: var(--color-surface-2); }
.fbo-by-cluster td.fbo-items-start { white-space: normal; border-left: 1px solid var(--color-border); }
.fbo-by-cluster th.fbo-items-start { border-left: 1px solid var(--color-border); }
.fbo-by-cluster .fbo-cluster__head { vertical-align: top; }
.fbo-by-cluster tbody.fbo-cluster + tbody.fbo-cluster { border-top: 2px solid var(--color-border); }
.fbo-by-cluster .fbo-cluster__toggle td { padding-top: var(--space-1); padding-bottom: var(--space-1); }
@media (max-width: 760px) {
  .fbo-tiles { grid-template-columns: repeat(2, 1fr); }
  .fbo-table { --fbo-num: 48px; --fbo-first: 160px; }
}

/* --- «Планёрка» → «План-факт» -------------------------------------------------------------------
   Широкая сетка как лист «Озон план»: своя прокрутка, слева закреплены «Период» и «Общее», шапка с
   товарами липнет сверху. Ширины колонок A/B — переменные: от них считается отступ второй колонки. */
.pf-toolbar .pf-year { display: inline-flex; align-items: center; gap: var(--space-2); font-weight: 600; }
.pf-toolbar .pf-year select { height: var(--control-height); font-weight: 700; }
.pf-legend { display: flex; flex-wrap: wrap; gap: var(--space-1) var(--space-4); align-items: center; }
.pf-dot { display: inline-block; width: 8px; height: 8px; border-radius: 50%; margin-right: var(--space-1); vertical-align: 1px; flex: none; }
.pf-dot--api { background: var(--pf-api); }
.pf-dot--manual { background: var(--pf-manual); }
.pf-dot--formula { background: var(--pf-formula); }

/* Окно таблицы — вся высота экрана под вкладками, за вычетом нижнего отступа страницы (.page, --space-6): докрутили
   страницу до конца — верх окна встаёт ровно под вкладки, и строка с товарами (липкая внутри окна) на виду
   (владелец 18.10.2026). position: sticky тут не работает: окно — последний элемент, прилипнуть ему некуда,
   и при прокрутке до конца страницы его верх с товарами уезжал под вкладки. Под окном поэтому ничего нет */
/* --pf-a 192: «Отстающие товары по плану» встаёт в одну строку */
.pf-frame { --pf-a: 192px; --pf-b: 112px; overflow: auto;
  max-height: calc(100vh - var(--sticky-top, var(--nav-height)) - var(--space-6)); min-height: 320px;
  /* Рамка по всему краю — цветом месяца, как полосы между товарами: без неё таблица выглядела незаконченной,
     будто уходит выше (владелец 18.10.2026). Рамка на окне, а не на ячейках — при прокрутке стоит на месте */
  border: 4px solid var(--pf-month-bg); border-radius: var(--radius); background: var(--color-surface); }
.pf-table { border-collapse: separate; border-spacing: 0; font-size: 12.5px; font-variant-numeric: tabular-nums; }
.pf-table th, .pf-table td { border-right: 1px solid var(--color-border); border-bottom: 1px solid var(--color-border);
  padding: 2px 6px; white-space: nowrap; height: 26px; text-align: right; font-weight: 400; }
.pf-table .pf-a, .pf-table .pf-b { position: sticky; z-index: 2; background: var(--color-surface); }
.pf-table .pf-a { left: 0; width: var(--pf-a); min-width: var(--pf-a); max-width: var(--pf-a); text-align: left;
  white-space: normal; line-height: 1.2; }
.pf-table .pf-b { left: var(--pf-a); min-width: var(--pf-b); font-weight: 600; color: var(--color-text); }
.pf-table thead th { position: sticky; top: 0; z-index: 3; background: var(--color-surface); vertical-align: bottom; }
.pf-table thead th.pf-a, .pf-table thead th.pf-b { z-index: 4; font-weight: 600; }
/* Шапка товара — две строки: название (не влезло — многоточие, целиком в подсказке) и «схема + категория» */
.pf-table thead th.pf-prod { text-align: center; white-space: normal; line-height: 1.2; padding: 4px 30px 4px 8px; border-top: 4px solid var(--color-border); }
.pf-prod__name { font-weight: 700; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pf-prod__meta { display: flex; justify-content: center; align-items: center; gap: var(--space-2); margin-top: 3px; flex-wrap: wrap; }
.pf-prod__sub { color: var(--color-muted); font-size: 11.5px; font-weight: 400; }
.pf-prod__scheme { color: var(--pf-api); font-size: 12px; }
/* Ближайшая поставка под названием товара — одна строка; просроченный прогноз — красным */
.pf-arr { margin-top: 3px; font-size: 12px; font-weight: 400; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.pf-arr b { font-weight: 700; }
.pf-arr .is-late { color: var(--color-error); font-weight: 600; }
.pf-table thead th[class*='pf-cat--']:not(.pf-cat--none) .pf-arr .is-late { color: inherit; text-decoration: underline; }
/* На заливке категории (как строки «Запаса») серый текст сливается — темнее, как у .supply-row--* .muted */
.pf-table thead th[class*='pf-cat--']:not(.pf-cat--none) .pf-prod__sub { color: var(--pf-on-cat-muted); }
/* select.supply-cat из «Запаса» задаёт высоту 38 px — без .pf-table select здесь она побеждала */
.pf-table select.pf-catsel { height: 22px; min-height: 0; padding: 0 var(--space-1); font-size: 12px; font-weight: 600; width: auto; }
.pf-table thead th.pf-cat--vip { border-top-color: var(--pf-cat-vip); background: var(--pf-cat-vip); }
.pf-table thead th.pf-cat--combat { border-top-color: var(--pf-cat-combat); background: var(--pf-cat-combat); }
.pf-table thead th.pf-cat--border { border-top-color: var(--pf-cat-border); background: var(--pf-cat-border); }
.pf-table thead th.pf-cat--new { border-top-color: var(--pf-cat-new); background: var(--pf-cat-new); }
.pf-table thead th.pf-cat--drain { border-top-color: var(--pf-cat-drain); background: var(--pf-cat-drain); }
/* Синяя метка схемы на красном «Сливе» не читается — белая */
.pf-table thead th.pf-cat--drain .pf-prod__scheme { color: #ffffff; }

.pf-stock td, .pf-stock th, .pf-stock .pf-a, .pf-stock .pf-b { background: var(--pf-stock-bg); color: var(--pf-stock-text);
  border-color: var(--pf-stock-bg); font-weight: 600; height: 34px; }
/* Подпись — сверху, место под неё — ровно на две строки: числа встают в один уровень, даже если подпись в одну
   строку («на FBO»), а у соседа — в две («в пути на Ozon») */
/* Подписи — сверху по центру, цифры — снизу в одну линию, сколько бы строк ни заняла подпись (владелец 26.10.2026).
   Высоту ячейки задаёт самая длинная подпись, цифра прижата к низу и место под неё оставлено отступом */
/* :not(.pf-b) — ячейка «Остатки» закреплена слева (sticky), relative её открепил бы */
.pf-table .pf-stock td:not(.pf-b) { vertical-align: top; position: relative; padding-bottom: 20px; }
/* Цифры по центру, как подписи (владелец 26.10.2026): разряды разделены пробелом, читается и без выравнивания вправо */
.pf-stock .pf-stock-v { position: absolute; left: 6px; right: 6px; bottom: 3px; text-align: center; }
/* «—» — в таблице плана не заполнено (не ноль): тише цифр */
.pf-stock .pf-stock-na { color: var(--pf-stock-muted); cursor: help; }
.pf-stock td i { display: block; text-align: center; font-style: normal; font-weight: 500; font-size: 10px; line-height: 1.1;
  color: var(--pf-stock-muted); white-space: normal; }
.pf-live { font-size: 10px; font-weight: 700; text-transform: uppercase; letter-spacing: .04em; color: var(--pf-api); }
.pf-stock .pf-live { color: var(--pf-api-on-dark); }

.pf-mrow td, .pf-mrow th, .pf-mrow .pf-a, .pf-mrow .pf-b { background: var(--pf-month-bg); color: var(--pf-month-text); }
/* Строка месяца — она же строка остатков: тёмная, а ячейка с месяцем жёлтая, чтобы месяцы находились глазом */
.pf-toggle { cursor: pointer; }
/* Месяцы подряд сливались в один тёмный лист — светлая полоса цвета фона отделяет каждый (владелец 18.10.2026) */
.pf-table tr.pf-toggle > th, .pf-table tr.pf-toggle > td { border-top: 3px solid var(--color-bg); }
.pf-toggle:focus-visible { outline: 2px solid var(--color-accent); outline-offset: -2px; }
.pf-table .pf-stock.pf-toggle th.pf-month-name { background: var(--pf-month-bg); color: var(--pf-month-text); font-size: 15px;
  font-weight: 700; vertical-align: middle; }
.pf-table .pf-stock.pf-toggle td.pf-stock-label { vertical-align: middle; font-weight: 600; text-align: left; }
/* .pf-table td задаёт nowrap — без .pf-table td здесь заголовок не переносился и держал колонку широкой */
.pf-table td.pf-colhead { font-size: 11px; font-weight: 600; text-align: center; vertical-align: middle; white-space: normal; line-height: 1.1; }
/* Ширины колонок — по самым длинным значениям, заголовок переносится в две строки (владелец 18.10.2026).
   Классы стоят и на строке остатков: без них у свёрнутых месяцев (строки заголовков нет) колонки сжимались.
   min-width обязателен: width в широкой таблице Chrome считает пожеланием и сжимает пустые колонки до 17 px.
   Таблица шире экрана, и без ширин браузер растягивал каждую колонку по заголовку в одну строку.
   Нижние границы: поля ввода (ширина колонки минус 8 px под «12,7%», «1 200»; уже — срезалась рамка), «цена 1 877 ₽» в строке «Неделя» у «Факт сумм» */
.pf-table td.pf-col--drr { width: 72px; min-width: 72px; }
.pf-table td.pf-col--plan_sum { width: 80px; min-width: 80px; }
.pf-table td.pf-col--plan_qty { width: 68px; min-width: 68px; }
.pf-table td.pf-col--fact_qty { width: 52px; min-width: 52px; }
.pf-table td.pf-col--fact_sum { width: 84px; min-width: 84px; }
.pf-table td.pf-col--done { width: 80px; min-width: 80px; }
.pf-table td.pf-col--margin { width: 68px; min-width: 68px; }
.pf-table td.pf-col--mpct { width: 76px; min-width: 76px; }
.pf-table td.pf-col--ozon_stock { width: 64px; min-width: 64px; }
.pf-tog { display: inline-grid; place-items: center; width: 18px; height: 18px; margin-right: var(--space-2);
  border: 1.5px solid currentColor; border-radius: 4px; font: 700 14px/1 var(--font-mono); vertical-align: -3px; }

.pf-hdr td, .pf-hdr th, .pf-hdr .pf-a, .pf-hdr .pf-b { background: var(--pf-hdr-bg); }
.pf-hdr .pf-a, .pf-hdr .pf-b { font-weight: 600; }
/* Подсвечена прошлая неделя — её разбираем на планёрке (владелец 27.10.2026) */
.pf-week.is-review td, .pf-week.is-review th, .pf-week.is-review .pf-a, .pf-week.is-review .pf-b { background: var(--pf-now-bg); }
.pf-sum td, .pf-sum th, .pf-sum .pf-a, .pf-sum .pf-b { background: var(--pf-sum-bg); }
.pf-sum--gap td, .pf-sum--gap th, .pf-sum--gap .pf-a, .pf-sum--gap .pf-b { background: var(--pf-gap-bg); }
/* Строки гипотез — тем же цветом, что итоги месяца (владелец 18.10.2026); ячейки с результатом красятся поверх */
.pf-hyprow td, .pf-hyprow th, .pf-hyprow .pf-a, .pf-hyprow .pf-b { background: var(--pf-sum-bg); }

/* Цифры из кабинета — обычным цветом: синие приходилось разглядывать (планёрка 26.10.2026).
   Откуда цифра — видно по точке в заголовке колонки и по подсказке ячейки */
.pf-table td.is-neg { color: var(--color-error); }
/* Перевыполнение плана в итогах месяца — зелёным (недобор — красным, .is-neg) */
.pf-table td.is-pos { color: var(--color-ok); }
.pf-edit { padding: 0 !important; }
.pf-table input.pf-in[type=text] { text-align: right; display: block; width: calc(100% - 8px); min-width: 0; height: 22px; min-height: 0;
  margin: 2px 4px; padding: 0 var(--space-1); font: inherit; color: var(--color-text); background: var(--color-surface);
  border: 1px solid var(--pf-input-border); border-radius: var(--radius-sm); box-shadow: none; }
.pf-table input.pf-in[type=text]:hover { background: var(--color-surface-2); }
.pf-table input.pf-in[type=text]:focus { outline: 2px solid var(--color-accent-soft); border-color: var(--color-accent); background: var(--color-surface); }

.pf-add { display: flex; flex-wrap: wrap; gap: var(--space-2); align-items: center; }
.pf-add__label { display: inline-flex; align-items: center; gap: var(--space-2); font-size: 13px; color: var(--color-muted); }
.pf-add select { min-width: 280px; max-width: 100%; height: var(--control-height); }
/* Гипотезы — в данных товара за месяц, под итогами (решение владельца 18.10.2026) */
.pf-hyphead td, .pf-hyphead th, .pf-hyphead .pf-a, .pf-hyphead .pf-b { background: var(--pf-hdr-bg); font-weight: 600; font-size: 11.5px; }
.pf-hyphead td, .pf-hyprow td { text-align: left; }
.pf-hyphead td.num, .pf-hyprow td.num { text-align: center; }
.pf-table td.pf-hyp-text { text-align: left; white-space: normal; line-height: 1.3; }
.pf-hyp-plus { color: var(--color-muted); }
.pf-table input.pf-hyp-in[type=text] { display: block; width: calc(100% - 8px); min-width: 0; height: 22px; min-height: 0;
  margin: 2px 4px; padding: 0 var(--space-1); font: inherit; color: var(--color-text); background: var(--color-surface);
  border: 1px solid var(--pf-input-border); border-radius: var(--radius-sm); box-shadow: none; }
.pf-table input.pf-hyp-in[type=text]:hover { background: var(--color-surface-2); }
.pf-table input.pf-hyp-in[type=text]:focus { outline: 2px solid var(--color-accent-soft); border-color: var(--color-accent); background: var(--color-surface); }
.pf-table .pf-res { height: 22px; min-height: 0; padding: 0 var(--space-2); font-size: 12px; margin: 0 var(--space-1); }
.pf-table td.pf-hyp--wait { background: var(--pf-hyp-wait); }
.pf-table td.pf-hyp--yes { background: var(--pf-hyp-yes); }
.pf-table td.pf-hyp--no { background: var(--pf-hyp-no); }
/* Ячейка гипотезы закрашена целиком: поле пояснения и список результата — цветом строки, рамка остаётся */
.pf-table td[class*='pf-hyp--'] input.pf-hyp-edit[type=text], .pf-table td[class*='pf-hyp--'] .pf-res {
  background: transparent; color: var(--color-text); border-color: rgba(0, 0, 0, 0.22); }
.pf-table input.pf-hyp-edit[type=text] { text-overflow: ellipsis; display: block; width: calc(100% - 8px); min-width: 0; height: 22px; min-height: 0;
  margin: 2px 4px; padding: 0 var(--space-1); font: inherit; color: var(--color-text); background: var(--color-surface);
  border: 1px solid var(--pf-input-border); border-radius: var(--radius-sm); box-shadow: none; }
.pf-table input.pf-hyp-edit[type=text]:focus { outline: 2px solid var(--color-accent-soft); border-color: var(--color-accent); background: var(--color-surface); }

/* Граница между товарами — жёлтая полоса цвета месяца (владелец 18.10.2026). Первая ячейка товара в любой строке идёт
   сразу за узким столбцом предыдущего (.pf-stub, скрыт, но в разметке) — ей и рисуем полосу слева */
.pf-table .pf-stub + td, .pf-table .pf-stub + th { border-left: 4px solid var(--pf-month-bg); }
/* Та же полоса между «Общее» и первым товаром. td/th в селекторе — чтобы перебить border-color строк остатков */
.pf-table td.pf-b, .pf-table th.pf-b { border-right: 4px solid var(--pf-month-bg); }
/* Скрытый товар: вместо его колонок — узкий столбец с «+» (правила display ставит app.js, planfactGrid) */
.pf-table .pf-stub { display: none; width: 30px; min-width: 30px; max-width: 30px; padding: 0; text-align: center; }
.pf-table thead th.pf-stub-head { vertical-align: top; padding: var(--space-2) 0; border-top: 4px solid var(--color-border); }
.pf-stub-name { display: inline-block; writing-mode: vertical-rl; transform: rotate(180deg); font-size: 11px; font-weight: 600;
  max-height: 150px; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; margin-top: var(--space-2); }
.pf-unhide, .pf-hide { display: inline-grid; place-items: center; width: 20px; height: 20px; padding: 0; border: 1.5px solid currentColor;
  border-radius: 4px; background: transparent; color: inherit; font: 700 14px/1 var(--font-mono); cursor: pointer; }
.pf-unhide:hover, .pf-hide:hover { color: var(--color-accent); }
.pf-table thead th.pf-prod { position: sticky; }
.pf-hide { position: absolute; top: 4px; right: 6px; }
/* Процентные поля (ДРР, Факт мрж): знак «%» стоит в правом краю ячейки сам, в поле — только число (владелец 18.10.2026) */
.pf-table td.pf-pct { position: relative; }
.pf-table td.pf-pct::after { content: '%'; position: absolute; right: 10px; top: 50%; transform: translateY(-50%);
  color: var(--color-muted); font-size: 12px; pointer-events: none; }
.pf-table td.pf-pct input.pf-in[type=text] { padding-right: 16px; }
/* Подпись к полю «план на месяц» в строке «Неделя»; доля месячного плана в поле недели — серой подсказкой */
.pf-table td.pf-month-plan-label { font-size: 10.5px; line-height: 1.1; white-space: normal; color: var(--color-muted); }
.pf-table input.pf-in[type=text]::placeholder { color: var(--color-muted); opacity: 1; }
.pf-toolbar { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: var(--space-3); margin-bottom: var(--space-3); }
/* Цена в строке «Неделя»: «цена» / «300 ₽», правее — «с 23.09» / «2 изм.»; дата открывает окно истории */
.pf-table td.pf-price { line-height: 1.15; }
.pf-price__label { display: block; font-size: 10.5px; opacity: .75; }
.pf-price__since { border: 0; background: none; padding: 0; font: inherit; color: var(--pf-api); text-align: right; cursor: pointer;
  text-decoration: underline dotted; text-underline-offset: 2px; }
.pf-price__since:hover { color: var(--color-accent-hover); }
.pf-modal-note { margin: var(--space-3) 0 0; font-size: 12px; }
.pf-res { height: 30px; border-radius: 999px; padding: 0 var(--space-2); font-weight: 600; border: 1px solid var(--color-border); }
.pf-res--yes { background: var(--color-ok-soft); color: var(--color-ok); border-color: var(--color-ok-soft); }
.pf-res--no { background: var(--color-error-soft); color: var(--color-error); border-color: var(--color-error-soft); }
.pf-res--wait { background: var(--color-surface-2); color: var(--color-muted); }
@media (max-width: 860px) {
  .pf-frame { --pf-a: 110px; --pf-b: 92px; max-height: 70vh; }
}
