/* Каркас «Пульса»: раскладка, сайдбар, карточки, заглушки.
   Все цвета и размеры — из tokens.css. */

* { box-sizing: border-box; }

html, body {
  margin: 0;
  height: 100%;
}

body {
  font-family: var(--font-ui);
  font-size: var(--fs-body);
  line-height: 1.5;
  color: var(--ink);
  background: var(--paper);
  -webkit-font-smoothing: antialiased;
}

a { color: var(--pulse); }
a:hover { color: var(--pulse-deep); }

/* --- Раскладка: сайдбар + контент --- */

/* dvh — чтобы на телефоне высоту не воровала съезжающая панель браузера
   (vh оставлен запасным вариантом для старых движков) */
.shell {
  display: grid;
  grid-template-columns: var(--side-w) 1fr;
  min-height: 100vh;
  min-height: 100dvh;
}

/* Сайдбар: тот же фон, что и страница, — единое пространство, граница едва заметна */
.side {
  display: flex;
  flex-direction: column;
  gap: var(--sp-5);
  padding: var(--sp-5) var(--sp-3);
  border-right: 1px solid var(--rule-soft);
  position: sticky;
  top: 0;
  height: 100vh;
  height: 100dvh;
}

.brand {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-1) var(--sp-3);
  text-decoration: none;
  color: var(--ink);
}

.brand-pulse {
  width: 44px;
  height: 20px;
  color: var(--pulse);
  flex: none;
}

.brand-name {
  font-size: var(--fs-h3);
  font-weight: 600;
  letter-spacing: -0.01em;
}

.nav {
  display: flex;
  flex-direction: column;
  gap: 2px;
  flex: 1;
}

.nav-group {
  font-size: var(--fs-caption);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mute);
  padding: var(--sp-4) var(--sp-3) var(--sp-1);
}

.nav-item {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-3);
  min-height: 36px;
  border-radius: var(--r-ctl);
  color: var(--ink-soft);
  text-decoration: none;
  font-weight: 500;
}

a.nav-item:hover {
  color: var(--ink);
  background: var(--rule-soft);
}

.nav-item.is-active {
  color: var(--pulse);
  background: var(--pulse-wash);
}

.nav-item:focus-visible {
  outline: 2px solid var(--pulse);
  outline-offset: 1px;
}

/* Будущие инструменты: видно состав, но кликать нечего.
   Тише активных пунктов, но это всё-таки текст, а не прочерк, — --ink-mute,
   не --ink-ghost (иначе состав инструментов не прочитать). */
.nav-item.is-soon {
  color: var(--ink-mute);
  cursor: default;
  justify-content: space-between;
}

.nav-item.is-soon em {
  font-style: normal;
  font-size: var(--fs-caption);
  color: var(--ink-mute);
  border: 1px solid var(--rule-soft);
  border-radius: 999px;
  padding: 0 var(--sp-2);
  line-height: 18px;
}

.side-foot {
  font-size: var(--fs-caption);
  color: var(--ink-ghost);
  padding: 0 var(--sp-3);
}

/* --- Контентная область --- */

.main {
  padding: var(--sp-6) var(--sp-8) var(--sp-8);
  min-width: 0;
}

.page-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-4);
  margin-bottom: var(--sp-5);
}

.page-head-left {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  min-width: 0;
}

/* Свёрнутый сайдбар — полоска 64px: только логотип-пульс и иконки.
   Полоска фиксирована и ПЛАВНО выезжает до полной ширины при наведении
   (класс side-peek из app.js) — поверх контента, страница не дёргается.
   Геометрия пунктов в обоих состояниях одна (иконки не прыгают),
   меняются только ширина панели и прозрачность подписей.
   ВАЖНО: fixed-сайдбар выпадает из грида, поэтому сетка в mini —
   одна колонка, а место под полоску даёт margin у .main (иначе контент
   сядет в 64px-колонку — уже наступали). */
.shell.side-mini { grid-template-columns: 1fr; }
.shell.side-mini .main { margin-left: 64px; }

.shell.side-mini .side {
  position: fixed;
  top: 0;
  left: 0;
  bottom: 0;
  width: 64px;
  height: auto;
  padding: var(--sp-5) var(--sp-3);
  background: var(--paper);
  overflow: hidden;
  z-index: 60;
  transition: width 0.18s ease, box-shadow 0.18s ease;
}

.shell.side-mini.side-peek .side {
  width: var(--side-w);
  box-shadow: 10px 0 28px rgba(var(--ink-rgb), 0.10);
}

.shell.side-mini .brand { padding: var(--sp-1) 0 var(--sp-1) 2px; }
.shell.side-mini .brand-pulse { width: 36px; transition: width 0.18s ease; }
.shell.side-mini.side-peek .brand-pulse { width: 44px; }

/* Подписи не display:none (иначе не анимируются) — гаснут и не переносятся */
.brand-name,
.nav-item .label,
.nav-group,
.side-user-name,
.side-foot { white-space: nowrap; }

.shell.side-mini:not(.side-peek) .brand-name,
.shell.side-mini:not(.side-peek) .nav-item .label,
.shell.side-mini:not(.side-peek) .nav-group,
.shell.side-mini:not(.side-peek) .side-user-name,
.shell.side-mini:not(.side-peek) .side-foot {
  opacity: 0;
  visibility: hidden;
}

.brand-name, .nav-item .label, .nav-group, .side-user-name, .side-foot {
  transition: opacity 0.15s ease 0.04s, visibility 0.15s;
}

/* Подсписок инструментов РНП: в полоске спрятан, в развёрнутом — дерево */
.shell.side-mini:not(.side-peek) .nav-sub {
  opacity: 0;
  visibility: hidden;
  max-height: 0;
}

.nav-sub {
  display: flex;
  flex-direction: column;
  gap: 2px;
  max-height: 200px;
  overflow: hidden;
  transition: opacity 0.15s ease 0.04s, max-height 0.18s ease, visibility 0.15s;
}

.nav-item-sub {
  min-height: 32px;
  padding-left: 34px;
  font-weight: 400;
}

.nav-item-sub .ni { width: 16px; height: 16px; }

/* На подстранице РНП (тепловая, юнитка) родитель мягко подсвечен —
   в полоске виден только он */
.nav-item.is-sub-active { color: var(--pulse); }

/* Иконки пунктов меню */
.ni {
  width: 20px;
  height: 20px;
  flex: none;
  fill: none;
  stroke: currentColor;
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
}

/* Пользователь внизу сайдбара */
.side-user {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 0 var(--sp-3);
}
.side-user-name {
  flex: 1;
  min-width: 0;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
  font-size: var(--fs-caption);
  color: var(--ink-soft);
}
.side-logout { font-size: var(--fs-h4); }

.page-title {
  margin: 0;
  font-size: var(--fs-h2);
  font-weight: 600;
  letter-spacing: -0.01em;
  text-wrap: balance;
}

.data-status {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-caption);
  color: var(--ink-mute);
  white-space: nowrap;
}

.data-status-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--ink-ghost);
}

.data-status-dot.is-ok { background: var(--gain); }
.data-status-dot.is-warn { background: var(--chart-2); }
.data-status-dot.is-stale { background: var(--loss); }

/* --- Карточки и сетка дашборда --- */

.card {
  background: var(--card);
  border-radius: var(--r-card);
  box-shadow: var(--lift);
  padding: var(--sp-4) var(--sp-5);
  min-width: 0;
}

.card-title {
  margin: 0 0 var(--sp-1);
  font-size: var(--fs-caption);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mute);
}

.grid {
  display: grid;
  gap: var(--sp-4);
}

/* Ряд KPI: первая плитка — герой, шире остальных (6 плиток с прибылью) */
.grid-kpi {
  grid-template-columns: 1.4fr repeat(5, 1fr);
  margin-bottom: var(--sp-4);
}

/* Средний ряд: динамика доминирует */
.grid-mid {
  grid-template-columns: 2fr 1fr;
  margin-bottom: var(--sp-4);
}

.grid-bottom {
  grid-template-columns: 1fr 1fr;
}

/* --- KPI-плитка --- */

.kpi-value {
  font-size: var(--fs-value);
  font-weight: 600;
  letter-spacing: -0.02em;
  font-variant-numeric: tabular-nums;
  line-height: 1.15;
}

.kpi-value.is-empty { color: var(--ink-ghost); }

.kpi-note {
  font-size: var(--fs-caption);
  color: var(--ink-mute);
  margin-top: var(--sp-1);
}

/* День данных в заголовке плитки — не кричит, просто уточняет */
.kpi-when {
  text-transform: none;
  letter-spacing: 0;
  font-weight: 400;
}

/* Дельта к прошлому дню: цвет несёт только она (правило «стрелки, не заливки») */
.kpi-delta {
  font-size: 13px;
  font-weight: 500;
  margin-left: var(--sp-2);
  vertical-align: 3px;
  white-space: nowrap;
}

/* Справка «вчера: N» у плиток за сегодня (день неполный — стрелка врала бы) */
.kpi-prev {
  font-size: var(--fs-caption);
  font-weight: 400;
  color: var(--ink-mute);
  margin-left: var(--sp-2);
  vertical-align: 3px;
  white-space: nowrap;
}

/* Контейнеры графиков ECharts */
.chart-box {
  height: 260px;
  min-width: 0;
}

.chart-box-s { height: 200px; }

/* --- Заглушка блока: тихая пульс-линия + подпись --- */

.placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  min-height: 120px;
  border-radius: var(--r-ctl);
  background: var(--well);
  color: var(--ink-mute);
  font-size: var(--fs-caption);
  text-align: center;
  padding: var(--sp-4);
}

.placeholder svg {
  width: 96px;
  height: 24px;
  color: var(--ink-ghost);
}

.placeholder.is-tall { min-height: 220px; }

/* --- Узкий экран: сайдбар становится верхней полосой --- */

@media (max-width: 900px) {
  .shell, .shell.side-mini { grid-template-columns: 1fr; }

  /* Нейтрализуем полоску и её плавный выезд: тут сайдбар — верхняя полоса.
     Прокручивается только список разделов; логотип и блок пользователя
     закреплены по краям, иначе «Выйти» уезжает за экран (аудит 2026-08-06). */
  .side,
  .shell.side-mini .side {
    position: static;
    width: auto;
    height: auto;
    flex-direction: row;
    align-items: center;
    gap: var(--sp-3);
    padding: var(--sp-2) var(--sp-4);
    border-right: 0;
    border-bottom: 1px solid var(--rule-soft);
    overflow: hidden;
    box-shadow: none;
  }

  .brand { flex: none; }

  .shell.side-mini:not(.side-peek) .brand-name,
  .shell.side-mini:not(.side-peek) .nav-item .label {
    opacity: 1;
    visibility: visible;
  }

  .shell.side-mini:not(.side-peek) .nav-sub,
  .nav-sub {
    opacity: 1;
    visibility: visible;
    max-height: none;
    flex-direction: row;
    overflow: visible;
  }

  .nav-item-sub { padding-left: var(--sp-3); }

  .brand { padding: 0; }
  .shell.side-mini .brand-pulse { width: 44px; }

  .nav {
    flex-direction: row;
    align-items: center;
    gap: var(--sp-1);
    min-width: 0;
    overflow-x: auto;
    /* Растворяющийся правый край — единственный намёк, что список едет
       дальше: полосы прокрутки на телефоне не видно. В маске работает
       только альфа-канал, сам цвет ничего не красит. */
    mask-image: linear-gradient(to right, black calc(100% - 24px), transparent);
    scrollbar-width: none;
  }
  .nav::-webkit-scrollbar { display: none; }

  /* Хвостовой пробел ровно под растворяющийся край: докрутив до конца,
     последний пункт остаётся читаемым, а не тонет в градиенте */
  .nav::after {
    content: '';
    flex: none;
    width: 24px;
  }

  .nav-group { display: none; }
  .side-foot { display: none; }
  .nav-item { white-space: nowrap; }
  .nav-item.is-soon { display: none; }

  /* Имя и выход всегда на экране, у правого края полосы */
  .side-user {
    flex: none;
    padding: 0 0 0 var(--sp-3);
    border-left: 1px solid var(--rule-soft);
  }
  .side-user-name { max-width: 88px; }

  .main { padding: var(--sp-4); }
  .shell.side-mini .main { margin-left: 0; }

  .grid-kpi { grid-template-columns: 1fr 1fr; }
  .grid-mid, .grid-bottom { grid-template-columns: 1fr; }
}

/* --- Палец вместо мыши ---
   Условие по типу указателя, а не по ширине экрана: планшет с клавиатурой
   и ноутбук с сенсорным экраном — разные случаи. Меньше 44px палец не
   ловит: до правки кнопки тулбара были 33px, крестики — 18×21
   (аудит 2026-08-06). На мыши ничего не меняется. */
@media (pointer: coarse) {
  .btn,
  .seg-btn,
  .sort-btn,
  .nav-item,
  .picker-item,
  .picker-list-apply,
  .picker-save-list,
  .picker-reset,
  .draw-row {
    min-height: 44px;
  }

  .btn, .seg-btn { min-width: 44px; }

  .chip-x {
    min-width: 44px;
    min-height: 44px;
  }

  /* Ползунок остаётся 34×20 на вид, но ловит палец на 44px вокруг */
  .sw input { inset: -12px; }

  .ue td.is-edit input,
  .ue td.is-edit select { min-height: 44px; }
}

@media (prefers-reduced-motion: no-preference) {
  .nav-item { transition: background-color 140ms cubic-bezier(0.23, 1, 0.32, 1), color 140ms cubic-bezier(0.23, 1, 0.32, 1); }
}

/* Обещание из DESIGN.md: анимации выключаются, если система просит покоя.
   Раньше под запросом жила только подсветка меню, а выезд сайдбара,
   тумблеры и раскрытие подсписка двигались всегда (аудит 2026-08-06). */
@media (prefers-reduced-motion: reduce) {
  .shell.side-mini .side,
  .shell.side-mini .brand-pulse,
  .nav-sub,
  .brand-name,
  .nav-item .label,
  .nav-group,
  .side-user-name,
  .side-foot,
  .sw-track,
  .sw-thumb {
    transition: none;
  }
}

/* ===== РНП: панель управления и таблица раскладки А ===== */

.toolbar {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: var(--sp-3);
  flex-wrap: wrap;
  margin-bottom: var(--sp-4);
}

.toolbar-label {
  font-size: var(--fs-caption);
  color: var(--ink-mute);
}

.chips {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  flex-wrap: wrap;
  min-height: 32px;
}

.chip-id {
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  color: var(--ink-mute);
}

.chip-x {
  border: 0;
  background: none;
  padding: 0 4px;
  font: inherit;
  color: var(--ink-mute);
  cursor: pointer;
  border-radius: 50%;
}
.chip-x:hover { color: var(--loss); }

.btn {
  border: 1px solid var(--rule);
  border-radius: var(--r-ctl);
  background: var(--card);
  padding: 5px 12px;
  font: inherit;
  font-weight: 500;
  color: var(--ink-soft);
  cursor: pointer;
}
.btn:hover { background: var(--well); color: var(--ink); }
.btn:focus-visible { outline: 2px solid var(--pulse); outline-offset: 1px; }

/* Выпадающий выбор артикулов */

.picker { position: relative; display: inline-block; }

.picker-menu {
  position: absolute;
  top: calc(100% + 6px);
  left: 0;
  z-index: 20;
  width: min(340px, calc(100vw - 48px));
  background: var(--card);
  border-radius: var(--r-card);
  box-shadow: var(--lift), 0 12px 28px rgba(var(--ink-rgb), 0.12);
  padding: var(--sp-2);
}

.is-hidden { display: none; }

.picker-search {
  width: 100%;
  padding: 7px 10px;
  border: 1px solid var(--rule);
  border-radius: var(--r-ctl);
  background: var(--well);
  font: inherit;
  margin-bottom: var(--sp-2);
}
.picker-search:focus-visible { outline: 2px solid var(--pulse); outline-offset: 1px; }

.picker-list { max-height: 300px; overflow-y: auto; }

.picker-item {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 7px 10px;
  border-radius: var(--r-ctl);
  cursor: pointer;
}
.picker-item:hover { background: var(--well); }
.picker-item input { accent-color: var(--pulse); }
.picker-name { flex: 1; }

/* Кнопка выбора артикулов при включённом фильтре: видно и что фильтр
   активен, и сколько выбрано — чипы-простыню убрали (2026-08-06) */
.btn.is-filter-on {
  border-color: var(--pulse);
  color: var(--pulse);
  background: var(--pulse-wash);
  font-weight: 500;
}

/* Кнопка сброса фильтра в попапе */
.picker-reset {
  display: block;
  width: calc(100% - 16px);
  margin: 0 8px var(--sp-2);
  padding: 7px 10px;
  border: 1px solid var(--rule);
  border-radius: var(--r-ctl);
  background: none;
  font: inherit;
  font-size: var(--fs-caption);
  color: var(--ink-soft);
  cursor: pointer;
  text-align: center;
}

.picker-reset:hover {
  border-color: var(--pulse);
  color: var(--pulse);
}

.picker-reset.is-hidden { display: none; }

/* --- Тумблер-ползунок (панель «Вид», фильтр артикулов) --- */

.sw {
  position: relative;
  width: 34px;
  height: 20px;
  flex: none;
  display: inline-block;
}

.sw input {
  position: absolute;
  inset: 0;
  margin: 0;
  opacity: 0;
  cursor: pointer;
}

.sw-track {
  position: absolute;
  inset: 0;
  border-radius: 999px;
  background: var(--ink-ghost);
  transition: background 0.15s ease;
  pointer-events: none;
}

.sw-thumb {
  position: absolute;
  top: 2px;
  left: 2px;
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--card);
  box-shadow: 0 1px 2px rgba(var(--ink-rgb), 0.25);
  transition: transform 0.15s ease;
  pointer-events: none;
}

.sw input:checked ~ .sw-track { background: var(--pulse); }
.sw input:checked ~ .sw-thumb { transform: translateX(14px); }
.sw input:focus-visible ~ .sw-track {
  outline: 2px solid var(--pulse);
  outline-offset: 1px;
}

/* --- Списки артикулов в попапе выбора --- */

.picker-lists {
  border-bottom: 1px solid var(--rule-soft);
  padding: var(--sp-2) var(--sp-2) var(--sp-3);
  margin-bottom: var(--sp-2);
}

.picker-lists-title {
  font-size: var(--fs-caption);
  font-weight: 500;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mute);
  padding: var(--sp-1) 10px var(--sp-2);
}

.picker-lists-empty { padding: 0 10px var(--sp-1); }

.picker-list-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.picker-list-apply {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--sp-2);
  padding: 7px 10px;
  border: 0;
  border-radius: var(--r-ctl);
  background: none;
  font: inherit;
  color: var(--ink);
  text-align: left;
  cursor: pointer;
}

.picker-list-apply:hover { background: var(--well); }

.picker-save-list {
  width: 100%;
  padding: 7px 10px;
  margin-top: var(--sp-1);
  border: 1px dashed var(--rule);
  border-radius: var(--r-ctl);
  background: none;
  font: inherit;
  font-size: var(--fs-caption);
  color: var(--ink-soft);
  cursor: pointer;
  text-align: left;
}

.picker-save-list:hover {
  border-color: var(--pulse);
  color: var(--pulse);
}

/* Переключатель периода */

.seg {
  display: inline-flex;
  border: 1px solid var(--rule);
  border-radius: var(--r-ctl);
  background: var(--card);
  overflow: hidden;
}

/* Соседние группы кнопок — в одной рамке: «дни/недели» и период про одно
   и то же (что показываем по горизонтали), поэтому и держатся вместе.
   Внутренняя граница между группами заметнее, чем между кнопками. */
.seg-pair {
  display: inline-flex;
  border: 1px solid var(--rule);
  border-radius: var(--r-ctl);
  background: var(--card);
  overflow: hidden;
}
.seg-pair > .seg { border: 0; border-radius: 0; }
.seg-pair > .seg + .seg { border-left: 1px solid var(--rule); }
.seg-pair > .seg-btn + .seg-btn { border-left: 1px solid var(--rule-soft); }

/* Выбор сортировки — только для узких экранов, где нет шапки списка */
.sort-mobile { display: none; }

.sort-mobile select {
  border: 1px solid var(--rule);
  border-radius: var(--r-ctl);
  background: var(--card);
  color: var(--ink-soft);
  font: inherit;
  padding: 5px 8px;
  cursor: pointer;
}
.sort-mobile select:focus-visible { outline: 2px solid var(--pulse); outline-offset: 1px; }

/* Кнопка-иконка внутри группы: квадратная, без подписи */
.seg-ico {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  padding: 6px 0;
}

.seg-btn {
  border: 0;
  background: none;
  padding: 6px 12px;
  font: inherit;
  color: var(--ink-soft);
  cursor: pointer;
}
.seg-btn + .seg-btn { border-left: 1px solid var(--rule-soft); }
.seg-btn.is-active { background: var(--pulse-wash); color: var(--pulse); font-weight: 500; }
.seg-btn:focus-visible { outline: 2px solid var(--pulse); outline-offset: -2px; }

/* Сводка и блоки артикулов */

.rnp-summary { grid-template-columns: repeat(3, 1fr); margin-bottom: var(--sp-2); }

.chev { color: var(--ink-mute); flex: none; }

/* Мини-фото товара: в списке выбора артикулов и в липкой планке.
   Фон --well на случай прозрачных углов миниатюры WB. */
.ava {
  width: 24px;
  height: 32px;
  object-fit: cover;
  border-radius: 4px;
  background: var(--well);
  flex: none;
}

/* --- Тепловая карта: таблица на базе .rnp, но ячейки несут заливку --- */

.heat .c-m {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.heat-name {
  display: inline-flex;
  flex-direction: column;
  gap: 1px;
  min-width: 0;
}

.heat-code {
  font-weight: 500;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

.heat td:not(.c-m) { text-align: right; }

/* Итоговая строка «Все артикулы» — суммы/агрегаты по каждому дню */
.heat-row-total td { font-weight: 600; }
.heat-row-total .c-m { background: var(--well); }
.heat-row-total td { border-bottom: 2px solid var(--rule); }

/* Вторая строка ячейки у «Маржа · ДРР»: лежит на залитой клетке,
   поэтому тише размером и весом, но не серым (см. .strip-drr) */
.heat-cell-sub {
  display: block;
  font-size: var(--fs-caption);
  font-weight: 400;
  color: var(--ink-soft);
  line-height: 1.2;
}

.heat-note {
  margin: var(--sp-3) var(--sp-5) 0;
  font-size: var(--fs-caption);
  color: var(--ink-mute);
}

/* Сверка охвата финотчёта (ABC). В норме строка тихая и незаметная — она
   лишь подтверждает, что проверка есть. Красной становится только когда
   деньги реально потерялись: тревога точечная, как и везде (DESIGN.md). */
.abc-leak {
  color: var(--loss);
  background: var(--loss-wash);
  border-radius: var(--r-ctl);
  padding: var(--sp-2) var(--sp-3);
  margin-inline: var(--sp-5);
}

/* --- Липкая шапка раскрытого артикула: планка с названием и датами,
   появляется, когда шапка таблицы уезжает при прокрутке --- */

.rnp-sticky {
  position: fixed;
  top: 0;
  z-index: 40; /* ниже выезжающего сайдбара (60) */
  background: var(--card);
  box-shadow: var(--lift);
  border-radius: 0 0 var(--r-card) var(--r-card);
  overflow: hidden;
}

.rnp-sticky-head {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  border-bottom: 1px solid var(--rule-soft);
  font-size: 13px;
}

.rnp-sticky-title { font-weight: 600; }

.rnp-sticky-head .ava {
  width: 20px;
  height: 26px;
}

.rnp-sticky-scroll { overflow: hidden; }

/* --- Полноэкранный режим таблицы: прячем сайдбар и шапку --- */

.shell.is-full .side,
.shell.is-full .page-head { display: none; }

.shell.is-full {
  grid-template-columns: 1fr;
}

.shell.is-full .main { padding-top: var(--sp-3); }

/* --- Полоса дней. Внутри клетки заказы → прибыль → ДРР, даты — в шапке
   списка, один раз.

   Заливка по заказам убрана 2026-08-07 (вариант «A» из четырёх примерок
   на живом сайте): прямоугольник в каждой клетке перетягивал внимание на
   правую половину строки, а главное — итоги артикула слева. Ряд дней стал
   спокойным хвостом: цифра дня мельче и тише основных, убыточный день
   узнаётся красными цифрами, а не кантом и заливкой. Ценой этого спрос
   больше не читается «гистограммой» — только по числам. --- */

/* --- Список артикулов как таблица (2026-08-07, вариант «A» из трёх
   примерок). Раньше каждый артикул был отдельной карточкой со своими
   подписями и своим рядом дат — 22 копии одного и того же, отчего экран
   читался россыпью блоков. Теперь подписи и даты стоят ОДИН раз в шапке,
   а артикулы идут строками одной сетки: цифры выстраиваются в колонки. --- */

/* Без overflow: hidden — он ломает sticky у шапки списка (она бы уезжала
   вместе со страницей). Скругление углов держат сами края: шапка сверху,
   последняя строка снизу. */
.rnp-list { padding: 0; }
.rnp-list > *:last-child { border-radius: 0 0 var(--r-card) var(--r-card); }

/* Одна сетка на шапку и строки — иначе колонки разъедутся.
   Ширины с запасом под недельный режим: там в тех же колонках стоят
   суммы за 8–12 недель, и на прежних 82px «+1 245 678» налезало на
   соседа (2026-08-07). Правило: колонку меряем по самому длинному
   числу, которое в неё может прийти, а не по типичному. */
.rnp-head,
.rnp-line {
  display: grid;
  grid-template-columns:
    14px 44px minmax(150px, 1.4fr)
    72px 62px 104px 48px 176px
    minmax(0, 4fr) 88px;
  gap: var(--sp-4);
  align-items: center;
  padding: 0 var(--sp-4);
}

/* Даты и подписи остаются на виду при прокрутке длинного списка —
   иначе колонки читать не по чему */
.rnp-head {
  position: sticky;
  top: 0;
  z-index: 5;
  background: var(--card);
  border-radius: var(--r-card) var(--r-card) 0 0;
  border-bottom: 1px solid var(--rule);
  padding-top: var(--sp-2);
  padding-bottom: var(--sp-2);
  align-items: end;
}

.lh {
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-mute);
  white-space: nowrap;
}
.lh.is-num { text-align: right; }

/* Заголовок-сортировка: выглядит как подпись колонки, ведёт себя как
   кнопка. Активная колонка помечена цветом и стрелкой направления. */
.sort-btn {
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
  white-space: nowrap;
}
.sort-btn:hover { color: var(--ink); }
.sort-btn:focus-visible { outline: 2px solid var(--pulse); outline-offset: 2px; }
.sort-btn.is-on { color: var(--pulse); font-weight: 600; }
.sort-arr { margin-left: 2px; }

/* Подпись текущего отрезка: общий заголовок + три мини-подписи под ним */
.lh-now-cap {
  font-size: 10px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ink-mute);
  white-space: nowrap;
}
.lh-now-cap em {
  font-style: normal;
  text-transform: none;
  letter-spacing: 0;
  color: var(--ink-ghost);
}
/* Это подписи колонок, а не прочерки: --ink-ghost давал 1.9:1 и они
   не читались (аудит 2026-08-07) */
.lh-now-cols {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--sp-2);
  font-size: 10px;
  color: var(--ink-mute);
  text-align: right;
}

/* Ноутбук: восьми колонок слева и десяти дней одновременно не бывает.
   Первыми уходят заглушка плана и мини-график переходов — они полезны,
   но не для ежедневного чтения; дни возвращаются с четырёх до семи. */
@media (min-width: 901px) and (max-width: 1500px) {
  .rnp-head,
  .rnp-line {
    grid-template-columns:
      14px 44px minmax(140px, 1.3fr)
      72px 62px 104px 176px
      minmax(0, 4fr);
  }

  .lh.is-plan,
  .lh.is-chart,
  .line-num.is-plan,
  .line-chart { display: none; }
}

/* --- Строка артикула --- */

.rnp-line {
  padding-top: 5px;
  padding-bottom: 5px;
  border-bottom: 1px solid var(--rule-soft);
  cursor: pointer;
  user-select: none;
}
.rnp-line:hover { background: var(--well); }
.rnp-line:focus-visible { outline: 2px solid var(--pulse); outline-offset: -2px; }
.rnp-line.is-open { background: var(--well); }
.rnp-list .rnp-line:last-child { border-bottom: 0; }

.line-photo {
  width: 44px;
  height: 58px;
  border-radius: 4px;
  background: var(--well);
  overflow: hidden;
}
.line-photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

.line-name { min-width: 0; }

.line-title {
  font-size: var(--fs-body);
  font-weight: 600;
  letter-spacing: -0.01em;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Код, остаток и план выкупа — мелкой строкой: бейджам в плотной строке
   места нет, а знать их надо */
.line-meta {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-caption);
  color: var(--ink-mute);
  white-space: nowrap;
  overflow: hidden;
}
.meta-stock { font-variant-numeric: tabular-nums; }
.meta-stock.is-low { color: var(--loss); font-weight: 500; }

.line-num {
  text-align: right;
  font-size: var(--fs-h4);
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* Подпись при числе. На широком экране колонки подписаны шапкой, поэтому
   здесь она не нужна глазу — но нужна тем, кто слушает страницу: без неё
   строка звучит лентой цифр. Прячем визуально, а не от скринридера. */
.num-cap {
  position: absolute;
  width: 1px;
  height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}
.line-num.is-gain { color: var(--gain); }
.line-num.is-loss { color: var(--loss); }
.line-num.is-dim { color: var(--ink-ghost); font-weight: 400; }

/* Текущий отрезок — три числа на розовой подложке «сегодня».
   Между ними полноценный зазор: на «13 0,1% +3 640» четырёх пикселей
   не хватало и числа слипались в одно (2026-08-07). */
.line-now {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  gap: var(--sp-2);
  background: var(--pulse-wash);
  border-radius: 5px;
  padding: 4px var(--sp-3);
}
.line-now .line-num { font-size: 13px; }

/* Плана ещё нет — прочерк того же цвета, что и «нет данных» */
.sum-todo { color: var(--ink-ghost); font-weight: 400; }

.line-chart { color: var(--ink-soft); text-align: right; }
.sum-spark { display: block; margin-left: auto; }
.sum-note { font-size: 10px; color: var(--ink-mute); margin-top: 1px; }

/* --- Раскрытый артикул: таблица под своей строкой --- */

.rnp-open {
  border-bottom: 1px solid var(--rule);
  background: var(--card);
  padding-bottom: var(--sp-2);
}

/* Полоса живёт в ячейке общей сетки: занимает её целиком, клетки тянутся
   до 84px и не сжимаются ниже 60 — лишние дни прячет container query,
   а не сплющивание */
.rnp-strip {
  display: flex;
  justify-content: flex-start;
  min-width: 0;
}

.strip-days {
  display: flex;
  flex: 1;
  min-width: 0;
  gap: 3px;
}

.strip-col {
  display: flex;
  flex-direction: column;
  flex: 1 0 56px;
  max-width: 76px;
  text-align: center;
}

.strip-date {
  font-size: 10px;
  letter-spacing: 0.02em;
  color: var(--ink-mute);
  white-space: nowrap;
  height: 16px;
}

.strip-col.is-today .strip-date { color: var(--pulse); font-weight: 600; }

.strip-cell {
  display: flex;
  flex-direction: column;
  gap: 1px;
  padding: 4px 3px 5px;
}

.strip-cell > span {
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}

/* Иерархия клетки: заказы — главная цифра дня, но тише итогов слева
   (13px против 16px и цвет --ink-soft против чернил) */
.strip-orders {
  font-size: 13px;
  font-weight: 500;
  color: var(--ink-soft);
  line-height: 17px;
}

.strip-profit {
  font-size: 10px;
  font-weight: 500;
  color: var(--gain);
  line-height: 13px;
}

.strip-drr {
  font-size: 10px;
  color: var(--ink-mute);
  line-height: 12px;
}

.strip-cell .is-dim { color: var(--ink-ghost); font-weight: 400; }
.strip-cell .is-loss { color: var(--loss); }

/* Убыточный день: без заливки и канта сигналом остаются сами цифры */
.strip-cell.is-neg .strip-orders { color: var(--loss); }

/* Тесно — режем самые старые дни (они справа), свежие остаются.
   Пороги — по реальной ширине полосы (container query), а не окна:
   сайдбар и полноэкранный режим учитываются сами. Колонка 56px + 3px.
   Шапка списка и строки считают одинаково: сетка у них общая. */
.rnp-strip { container-type: inline-size; }

@container (max-width: 589px) { .strip-days .strip-col:nth-child(n+10) { display: none; } }
@container (max-width: 530px) { .strip-days .strip-col:nth-child(n+9) { display: none; } }
@container (max-width: 471px) { .strip-days .strip-col:nth-child(n+8) { display: none; } }
@container (max-width: 412px) { .strip-days .strip-col:nth-child(n+7) { display: none; } }
@container (max-width: 353px) { .strip-days .strip-col:nth-child(n+6) { display: none; } }
@container (max-width: 294px) { .strip-days .strip-col:nth-child(n+5) { display: none; } }
@container (max-width: 235px) { .strip-days .strip-col:nth-child(n+4) { display: none; } }

/* Таблица: первая колонка и Σ закреплены, скролл по дням внутри карточки */

.rnp-scroll { overflow-x: auto; }

table.rnp {
  border-collapse: separate;
  border-spacing: 0;
  min-width: 100%;
  font-size: var(--fs-body);
  line-height: 1.35;
  font-variant-numeric: tabular-nums;
}

.rnp th, .rnp td {
  padding: 6px 10px;
  text-align: right;
  white-space: nowrap;
  border-bottom: 1px solid var(--rule-soft);
}

.rnp thead th {
  font-size: var(--fs-caption);
  font-weight: 500;
  color: var(--ink-mute);
  border-bottom: 1px solid var(--rule);
}

/* Ярусы строк: главное жирнее, производное тише и с отступом.
   Насмотрено на плотных аналитических таблицах: иерархия веса и цвета
   вместо равных строк, линии светлые, «пустые» значения гаснут. */

.rnp tr.t-hero td { font-weight: 600; }
.rnp tr.t-hero .c-m { color: var(--ink); }

.rnp tr.t-base .c-m { color: var(--ink-soft); }

.rnp tr.t-soft td {
  color: var(--ink-soft);
  padding-top: 4px;
  padding-bottom: 4px;
}
.rnp tr.t-soft .c-m {
  color: var(--ink-mute);
  padding-left: calc(var(--sp-5) + 12px);
}

/* Пустые значения не должны звенеть как данные */
.rnp td.is-dim { color: var(--ink-ghost); }

/* Стрелки динамики к предыдущему дню (по мотивам truestats):
   цвет несут только они, фон ячеек остаётся тихим */
.rnp .arr { font-size: 11px; margin-left: 3px; }
/* Цвета стрелок динамики — общие (РНП, плитки дашборда) */
.arr-g { color: var(--gain); }
.arr-b { color: var(--loss); }
.arr-n { color: var(--ink-ghost); }

/* Колонка «Динамика»: мини-бары за период, хронологически слева направо */
.rnp .c-dyn { width: 64px; min-width: 64px; }
.rnp thead .c-dyn { text-align: right; }
.dyn {
  display: flex;
  align-items: flex-end;
  justify-content: flex-end;
  gap: 1px;
  height: 18px;
}
.dyn span {
  flex: 1 1 2px;
  max-width: 4px;
  min-height: 1px;
  background: var(--ink-ghost);
  border-radius: 1px;
}

/* День недели в шапке дат — второй строкой, тихо */
.rnp thead .dow {
  display: block;
  font-size: 10px;
  line-height: 1.2;
  color: var(--ink-ghost);
  text-transform: lowercase;
}

/* Вести взгляд по 14 колонкам помогает подсветка строки */
.rnp tbody tr:not(.grp):hover td { background: var(--well); }
.rnp tbody tr:not(.grp):hover td.is-today { background: var(--pulse-wash); }

.rnp .c-m {
  position: sticky;
  left: 0;
  z-index: 2;
  width: 176px;
  min-width: 176px;
  background: var(--card);
  text-align: left;
  padding-left: var(--sp-5);
}

.rnp thead .c-m {
  font-size: var(--fs-body);
  font-weight: 600;
  color: var(--ink);
}

.rnp .c-t {
  position: sticky;
  left: 176px;
  z-index: 2;
  background: var(--card);
  border-right: 1px solid var(--rule);
  font-weight: 500;
}

.rnp .is-today { background: var(--pulse-wash); }

/* Заголовок группы — «полка»: фоновая полоса на всю ширину + разрыв сверху,
   чтобы секции читались даже при беглом прокручивании */
.rnp .grp td {
  cursor: pointer;
  user-select: none;
  background: var(--well);
  border-bottom: 0;
  border-top: 8px solid var(--card);
  padding-top: 5px;
  padding-bottom: 5px;
}

.rnp .grp .c-m {
  font-size: var(--fs-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
  background: var(--well);
}

.rnp tbody tr:last-child td { border-bottom: 0; }

/* Название блока — кнопка без вида кнопки: наследует «полку» целиком,
   но сворачивается с клавиатуры, а не только мышью */
.rnp .grp-btn {
  border: 0;
  padding: 0;
  background: none;
  font: inherit;
  color: inherit;
  letter-spacing: inherit;
  text-transform: inherit;
  cursor: pointer;
}
.rnp .grp-btn:focus-visible { outline: 2px solid var(--pulse); outline-offset: 2px; }

.rnp .grp .grp-btn::before { content: '▾ '; color: var(--ink-ghost); }
.rnp tbody.is-closed tr:not(.grp) { display: none; }
.rnp tbody.is-closed .grp .grp-btn::before { content: '▸ '; }

.empty-note { color: var(--ink-mute); }

/* Панель «Вид»: настройка строк таблицы (порядок + вкл/выкл) */

.toolbar-right {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
}

.drawer-backdrop {
  position: fixed;
  inset: 0;
  z-index: 40;
  background: rgba(var(--ink-rgb), 0.28);
}

.drawer {
  position: fixed;
  top: 0;
  right: 0;
  bottom: 0;
  z-index: 41;
  width: min(360px, 92vw);
  display: flex;
  flex-direction: column;
  background: var(--card);
  box-shadow: var(--lift), -16px 0 40px rgba(var(--ink-rgb), 0.14);
  padding: var(--sp-4) var(--sp-4) var(--sp-3);
}

.drawer-head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: var(--sp-2);
}

.drawer-title {
  margin: 0;
  font-size: var(--fs-h4);
  font-weight: 600;
}

.drawer-close { font-size: var(--fs-h3); }

.drawer-body {
  flex: 1;
  overflow-y: auto;
  margin: var(--sp-2) 0;
  border-top: 1px solid var(--rule-soft);
}

.drawer-foot {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding-top: var(--sp-3);
  border-top: 1px solid var(--rule-soft);
}

.drawer-foot-gap { flex: 1; }

.drawer-reset { color: var(--ink-soft); }

.btn-primary {
  background: var(--pulse);
  border-color: var(--pulse);
  color: var(--on-pulse);
}
.btn-primary:hover { background: var(--pulse-deep); color: var(--on-pulse); }

.draw-group-title {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-mute);
  padding: var(--sp-3) var(--sp-2) var(--sp-1);
}
.draw-group.dragging { opacity: 0.45; }

/* Выключенный целиком блок: строки гаснут, но их тумблеры не сбрасываются */
.draw-group-name { flex: 1; }
.draw-group.is-off .draw-row { opacity: 0.4; }

.draw-row {
  display: flex;
  align-items: center;
  gap: var(--sp-2);
  padding: 5px var(--sp-2);
  border-radius: var(--r-ctl);
  background: var(--card);
}
.draw-row:hover { background: var(--well); }
.draw-row.dragging { opacity: 0.45; }
.draw-row input { accent-color: var(--pulse); }

.draw-label { flex: 1; }

.draw-switch {
  border: 1px solid var(--rule-soft);
  border-radius: var(--r-ctl);
  padding: var(--sp-2) var(--sp-2);
}

.handle {
  cursor: grab;
  color: var(--ink-ghost);
  user-select: none;
}

/* Админка */

.admin-card { padding: var(--sp-4) 0 var(--sp-4); }
.admin-card .ue-head { margin-bottom: var(--sp-3); }
.admin-card .ue { width: 100%; }
.ue-status.is-error { color: var(--loss); }

.admin-switch {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  cursor: pointer;
  color: var(--ink-soft);
}
.admin-switch input { accent-color: var(--pulse); }

.admin-actions { text-align: right; }

.admin-add {
  display: flex;
  gap: var(--sp-2);
  flex-wrap: wrap;
  padding: var(--sp-4) var(--sp-5) 0;
  border-top: 1px solid var(--rule-soft);
  margin-top: var(--sp-3);
}
.admin-add .auth-input { flex: 1 1 160px; width: auto; }

/* Страницы входа и первичной настройки */

.auth-page {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 100vh;
  min-height: 100dvh;
  padding: var(--sp-4);
}

.auth-card {
  width: min(360px, 100%);
  padding: var(--sp-8) var(--sp-6) var(--sp-6);
}

.auth-brand {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  color: var(--pulse);
  margin-bottom: var(--sp-5);
}
.auth-brand .brand-pulse { width: 44px; height: 20px; }
.auth-title {
  font-size: var(--fs-h3);
  font-weight: 600;
  color: var(--ink);
  letter-spacing: -0.01em;
}

.auth-note {
  margin: 0 0 var(--sp-4);
  color: var(--ink-soft);
  font-size: var(--fs-body);
}

.auth-label {
  display: block;
  font-size: var(--fs-caption);
  font-weight: 500;
  color: var(--ink-mute);
  margin: var(--sp-3) 0 var(--sp-1);
}

.auth-input {
  width: 100%;
  padding: 9px 12px;
  border: 1px solid var(--rule);
  border-radius: var(--r-ctl);
  background: var(--well);
  font: inherit;
}
.auth-input:focus-visible { outline: 2px solid var(--pulse); outline-offset: 1px; }

.auth-error {
  margin: var(--sp-3) 0 0;
  color: var(--loss);
  font-size: var(--fs-body);
}

.auth-submit {
  width: 100%;
  margin-top: var(--sp-4);
  padding: 9px 12px;
}

@media (max-width: 900px) {
  .rnp-summary { grid-template-columns: 1fr 1fr; }
  .rnp .c-m { width: 132px; min-width: 132px; padding-left: var(--sp-4); }
  .rnp .c-t { left: 132px; }

  /* На телефоне таблицей строку не удержать: сетка складывается в два
     ряда — сверху название и цифры, снизу дни во всю ширину.
     Шапку колонок прячем: подписи возвращаются к самим значениям. */
  .rnp-head { display: none; }

  .rnp-line {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--sp-2) var(--sp-3);
    padding: var(--sp-2) var(--sp-3);
  }
  .rnp-line > .line-photo { width: 40px; height: 52px; }
  /* базис маленький, иначе название требует свою ширину и уносит цифры
     на отдельную строку */
  .rnp-line > .line-name { flex: 1 1 90px; min-width: 0; }

  /* Под названием места на всё не хватает: номер карточки на телефоне
     нужен реже, чем остаток и план выкупа, — он и уходит первым */
  .line-meta { flex-wrap: wrap; row-gap: 0; }
  .line-meta .chip-id { display: none; }
  .rnp-line > .rnp-strip { flex: 1 0 100%; }

  /* План-заглушка, «сегодня» и спарклайн на телефоне не помещаются —
     они остаются на широком экране и в раскрытом артикуле */
  .rnp-line > .line-num.is-plan,
  .rnp-line > .line-now,
  .rnp-line > .line-chart { display: none; }

  .toolbar-right { flex-wrap: wrap; }

  /* Шапки списка тут нет, поэтому сортировка переезжает в тулбар,
     а подписи колонок — к самим числам */
  .sort-mobile {
    display: inline-flex;
    align-items: center;
    gap: var(--sp-2);
    font-size: var(--fs-caption);
    color: var(--ink-mute);
  }

  /* Видимой становится только подпись при числе; «остаток» в мете
     остаётся служебной — там значение и так говорит за себя */
  .line-num > .num-cap {
    position: static;
    width: auto;
    height: auto;
    clip-path: none;
    display: block;
    font-size: 10px;
    font-weight: 400;
    letter-spacing: 0.04em;
    text-transform: uppercase;
    color: var(--ink-mute);
  }
}

/* ===== Юнит-экономика: таблица с редактируемыми ячейками ===== */

.ue-card { padding: var(--sp-4) 0 var(--sp-2); }

.ue-head {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--sp-3);
  padding: 0 var(--sp-5);
  margin-bottom: var(--sp-2);
}

.ue-status { font-size: var(--fs-caption); color: var(--gain); white-space: nowrap; }
.ue-status.is-error { color: var(--loss); }

/* Общая ставка налога — маленькое поле в шапке справочника */
.ue-tax {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-2);
  font-size: var(--fs-caption);
  color: var(--ink-soft);
  white-space: nowrap;
}

.ue-tax input {
  width: 52px;
  padding: 4px 8px;
  border: 1px solid var(--rule);
  border-radius: var(--r-ctl);
  background: var(--card);
  font: inherit;
  color: var(--ink);
  text-align: right;
  font-variant-numeric: tabular-nums;
}

.ue-tax input:focus-visible {
  outline: none;
  border-color: var(--pulse);
}

.ue-scroll { overflow-x: auto; }

table.ue {
  border-collapse: separate;
  border-spacing: 0;
  min-width: 100%;
  font-size: var(--fs-body);
  font-variant-numeric: tabular-nums;
}

.ue th, .ue td {
  border-bottom: 1px solid var(--rule-soft);
  white-space: nowrap;
  text-align: left;
}

.ue th {
  padding: 6px 10px;
  font-size: var(--fs-caption);
  font-weight: 500;
  color: var(--ink-mute);
}

.ue td { padding: 0; }
.ue td.is-auto { padding: 6px 10px; color: var(--ink-soft); }
.ue td.c-id { font-family: var(--font-mono); font-size: 13px; }
.ue th:first-child, .ue td:first-child { padding-left: var(--sp-5); }

/* Редактируемая ячейка: «тихий» инпут — граница видна только при наведении/фокусе */
.ue td.is-edit input {
  width: 100%;
  min-width: 96px;
  border: 1px solid transparent;
  border-radius: 0;
  background: none;
  font: inherit;
  color: var(--ink);
  padding: 6px 10px;
}

/* Текстовым колонкам — больше места: сезон (5), менеджер (6), ЮР лицо (7).
   Статус (4) — выпадающий список, ширина у него своя (см. select ниже). */
.ue td:nth-child(5) input,
.ue td:nth-child(6) input,
.ue td:nth-child(7) input { min-width: 136px; }
.ue td.is-edit input:hover { border-color: var(--rule); }
.ue td.is-edit input:focus-visible {
  outline: none;
  border-color: var(--pulse);
  background: var(--card);
}

.ue td.is-edit select {
  width: 100%;
  min-width: 120px;
  border: 1px solid transparent;
  border-radius: 0;
  background: none;
  font: inherit;
  color: var(--ink);
  padding: 6px 10px;
  cursor: pointer;
}
.ue td.is-edit select:hover { border-color: var(--rule); }
.ue td.is-edit select:focus-visible {
  outline: none;
  border-color: var(--pulse);
  background: var(--card);
}
.ue td.is-num input { text-align: right; }

.ue td.is-loss-wash { background: var(--loss-wash); }
.ue td.is-loss-wash input { color: var(--loss); font-weight: 500; }
.ue td.is-gain-wash { background: var(--gain-wash); }
.ue td.is-gain-wash input { color: var(--gain); font-weight: 500; }

/* --- ABC-анализ: широкая таблица группами колонок, как лист «🔍 ABC» --- */

/* Двухрядная шапка: ряд групп — «полки» (как заголовки блоков РНП),
   ряд колонок — обычные подписи. Границы групп несут вертикальные линии. */
.abc thead .abc-g th {
  text-align: center;
  background: var(--well);
  font-size: var(--fs-caption);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.08em;
  color: var(--ink-soft);
  border-bottom: 0;
}
.abc thead .abc-g .c-m { background: var(--card); }
.abc .gs { border-left: 1px solid var(--rule-soft); }
.abc thead .abc-g th.gs { border-left: 1px solid var(--rule); }

.abc .c-m { width: 232px; min-width: 232px; }

.abc .abc-cat {
  text-align: left;
  color: var(--ink-mute);
  font-size: 13px;
}

/* Паспорт артикула: фото + код + бейджи класса и статуса */
.abc-item { display: flex; align-items: center; gap: var(--sp-2); min-width: 0; }
.abc .ava { width: 30px; height: 40px; }
.abc-name { display: flex; flex-direction: column; gap: 2px; min-width: 0; }
.abc-code {
  font-family: var(--font-mono);
  font-size: 13px;
  overflow: hidden;
  text-overflow: ellipsis;
}
.abc-meta { display: flex; align-items: center; gap: 6px; }

.abc-cls {
  font-family: var(--font-mono);
  font-size: 10px;
  font-weight: 600;
  letter-spacing: 0.06em;
  padding: 1px 5px;
  border-radius: 4px;
  background: var(--well);
  color: var(--ink-soft);
}
.abc-cls.is-top { background: var(--gain-wash); color: var(--gain); }
.abc-cls.is-low { background: var(--loss-wash); color: var(--loss); }

.abc-status { font-size: 10px; }
.abc-status.is-loss-w { color: var(--loss); }
.abc-status.is-gain-w { color: var(--gain); }
.abc-nocost { font-size: 10px; color: var(--ink-mute); border-bottom: 1px dashed var(--rule); }

/* Итог сверху; убыток — красным только там, где минус означает беду */
.abc .abc-total td { background: var(--well); }
.abc td.is-loss { color: var(--loss); }

/* Артикулы без движения за период — видны, но не звенят */
.abc tr.is-idle td { color: var(--ink-mute); }
.abc tr.is-idle .ava { opacity: 0.55; }
.abc tr.is-idle .abc-code { color: var(--ink-mute); }

.abc tr.abc-un td { color: var(--ink-mute); }

/* Тулбар: произвольный период и попап порогов */
.abc-dates { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.abc-date {
  padding: 5px 8px;
  border: 1px solid var(--rule);
  border-radius: var(--r-ctl);
  background: var(--card);
  font: inherit;
  font-size: 13px;
  color: var(--ink);
}
.abc-date:focus-visible { outline: 2px solid var(--pulse); outline-offset: -1px; }
.abc-dash { color: var(--ink-mute); }
.abc-apply { border: 1px solid var(--rule); border-radius: var(--r-ctl); }

.abc-thr { position: relative; display: inline-flex; }
.abc-thr > .seg-btn { border: 1px solid var(--rule); border-radius: var(--r-ctl); }
.abc-thr-pop.is-hidden { display: none; }
.abc-thr-pop {
  position: absolute;
  top: calc(100% + 6px);
  right: 0;
  z-index: 40;
  display: flex;
  flex-direction: column;
  gap: var(--sp-2);
  padding: var(--sp-3);
  background: var(--card);
  border-radius: var(--r-card);
  box-shadow: var(--lift), 0 12px 28px rgba(var(--ink-rgb), 0.12);
  white-space: nowrap;
}
.abc-thr-pop label { display: flex; align-items: center; gap: 6px; font-size: 13px; color: var(--ink-soft); }
.abc-thr-pop input {
  width: 64px;
  padding: 5px 8px;
  border: 1px solid var(--rule);
  border-radius: var(--r-ctl);
  font: inherit;
  text-align: right;
  color: var(--ink);
}
.abc-thr-pop input:focus-visible { outline: 2px solid var(--pulse); outline-offset: -1px; }
.abc-thr-foot { display: flex; justify-content: flex-end; gap: var(--sp-2); }
.abc-thr-foot .seg-btn { border: 1px solid var(--rule); border-radius: var(--r-ctl); }

/* Парето-полоса: тот случай, где заливка и есть смысл блока (правило
   тепловой карты) — интенсивность одного тона по классам, не три цвета */
.abc-pareto { margin-bottom: var(--sp-4); }
.abc-pareto-head {
  display: flex;
  justify-content: space-between;
  gap: var(--sp-3);
  flex-wrap: wrap;
  font-size: var(--fs-caption);
  color: var(--ink-mute);
  margin-bottom: var(--sp-4);
}
.abc-pareto-legend { display: inline-flex; gap: var(--sp-2); align-items: baseline; }
.abc-pareto-legend b {
  font-family: var(--font-mono);
  font-weight: 600;
  color: var(--ink-soft);
  margin-left: var(--sp-2);
}
.pareto-bar { position: relative; height: 18px; margin-top: 4px; }
.pareto-track {
  display: flex;
  height: 100%;
  border-radius: 4px;
  overflow: hidden;
  background: var(--well);
}
.pareto-seg { display: block; height: 100%; min-width: 2px; }
.pareto-seg + .pareto-seg { border-left: 1px solid var(--card); }
.pareto-seg.cls-a { background: rgba(var(--heat), 0.45); }
.pareto-seg.cls-b { background: rgba(var(--heat), 0.24); }
.pareto-seg.cls-c { background: rgba(var(--heat), 0.11); }
.pareto-mark {
  position: absolute;
  top: -3px;
  bottom: -3px;
  width: 0;
  border-left: 1px dashed rgba(var(--ink-rgb), 0.4);
}
.pareto-mark i {
  position: absolute;
  top: -14px;
  left: -9px;
  font-size: 10px;
  font-style: normal;
  color: var(--ink-mute);
}

/* Строка «Не разложено по артикулам»: сумма и состав дублируются в
   закреплённой колонке — их колонки (Маржа, Ч. прибыль) уезжают вправо,
   и без этого строка читалась бы как пустая */
.abc-un-name { display: block; }
.abc-un-sum {
  margin-left: 6px;
  font-weight: 500;
  color: var(--ink-soft);
  font-variant-numeric: tabular-nums;
}
.abc-un-note {
  display: block;
  margin-top: 1px;
  font-size: 10px;
  color: var(--ink-mute);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

/* --- Фильтр по классу ABC: матрица 3×3 (выручка × маржа) ---
   Класс двухбуквенный, и это две независимые оси. Плоский список из девяти
   галочек прятал бы главное — несовпадения («выручки много, маржи нет»),
   поэтому выбор идёт по раскладу, где эти клетки видно глазами. */

.seg-btn.is-filter-on {
  border-color: var(--pulse);
  color: var(--pulse);
  background: var(--pulse-wash);
  font-weight: 500;
}

.abc-cls-pop { min-width: 210px; }

.abc-mx-cap {
  font-size: 10px;
  color: var(--ink-mute);
  margin-bottom: var(--sp-2);
  max-width: 190px;
  white-space: normal;
  line-height: 1.35;
}

.abc-mx {
  display: grid;
  grid-template-columns: 22px repeat(3, 46px);
  gap: 3px;
  align-items: stretch;
}

.abc-mx-corner { display: block; }

.abc-mx-h,
.abc-mx-c {
  border: 1px solid transparent;
  border-radius: var(--r-ctl);
  background: none;
  font: inherit;
  font-variant-numeric: tabular-nums;
  cursor: pointer;
  padding: 4px 0;
}

/* Заголовки строк/столбцов — буквы: тише клеток, но кликабельны
   (берут всю линию одним нажатием) */
.abc-mx-h {
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  font-weight: 600;
  color: var(--ink-mute);
}
.abc-mx-h:hover { color: var(--ink); background: var(--well); }
.abc-mx-h.is-on { color: var(--pulse); }

/* Клетка — число артикулов в классе */
.abc-mx-c {
  background: var(--well);
  color: var(--ink-soft);
  font-weight: 500;
}
.abc-mx-c:hover:not(:disabled) { background: var(--rule); color: var(--ink); }
.abc-mx-c.is-on {
  background: var(--pulse-wash);
  border-color: var(--pulse);
  color: var(--pulse);
}

/* Пустой класс выбирать нечего — гаснет, как прочерк в таблице */
.abc-mx-c.is-empty {
  background: none;
  color: var(--ink-ghost);
  cursor: default;
}

.abc-mx-h:focus-visible,
.abc-mx-c:focus-visible { outline: 2px solid var(--pulse); outline-offset: -2px; }

/* Подпись при «Итого»: сколько артикулов в итоге и по какому отбору */
.abc-total-note {
  display: block;
  margin-top: 1px;
  font-size: 10px;
  font-weight: 400;
  color: var(--ink-mute);
}

/* Выключенная кнопка сегмента («Показать все», когда фильтр и так пуст):
   должна читаться как недоступная, а не как обычная */
.seg-btn:disabled {
  color: var(--ink-ghost);
  cursor: default;
}

/* Заголовок колонки с пояснением: пунктир снизу — единственный намёк,
   что у названия есть расшифровка по наведению (как «нет С/С» в строке) */
.sort-btn.has-tip { border-bottom: 1px dashed var(--rule); }

/* --- Колонка «Куда уходит рубль»: структура выручки полосой ---
   Тот же случай, что тепловая карта: цвет здесь не фон к цифрам, а
   единственное содержимое колонки. Стоит последней, чтобы не разрывать
   ряды чисел (просьба пользователя 2026-08-07). */

.abc .c-str {
  width: 200px;
  min-width: 200px;
  text-align: left;
  padding-left: var(--sp-3);
}
.abc thead .c-str { text-align: left; }

.str { position: relative; display: block; }

.str-bar {
  display: flex;
  height: 14px;
  border-radius: 3px;
  overflow: hidden;
  background: var(--well);
}

/* Разделяет сегменты, не сдвигая их: зазор через тень внутрь, а не gap —
   иначе проценты перестали бы сходиться с шириной */
.str-bar i {
  display: block;
  height: 100%;
  box-shadow: inset -1px 0 0 var(--card);
}
.str-bar i:last-child { box-shadow: none; }

/* Граница выручки: видна только там, где полоса за неё вышла */
.str-tick {
  position: absolute;
  top: -3px;
  bottom: -3px;
  width: 2px;
  background: var(--ink);
}

.abc tbody tr:hover .str-bar i { box-shadow: inset -1px 0 0 var(--well); }

/* Легенда полосы — под таблицей, рядом с остальными пояснениями */
.str-legend {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--sp-1) var(--sp-3);
  margin: var(--sp-3) var(--sp-5) 0;
  font-size: var(--fs-caption);
  color: var(--ink-mute);
}
.str-legend span { display: inline-flex; align-items: center; gap: 5px; }
.str-legend i {
  width: 10px;
  height: 10px;
  border-radius: 2px;
  display: block;
}

/* Хвост полосы за границей выручки — расходы, которые товар не окупил */
.str-over {
  position: absolute;
  right: 0;
  bottom: -3px;
  height: 2px;
  background: var(--loss);
  border-radius: 1px;
}

/* ===== Самовыкупы: журнал, грид ввода, массовая правка ===== */

.sb-card { padding: var(--sp-4) 0 var(--sp-2); }
.sb-pad { padding: 0 var(--sp-5) var(--sp-2); }
.sb-gap { flex: 1; }
.row-wrap { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }

.sb-f {
  display: inline-flex;
  align-items: center;
  gap: var(--sp-1);
  font-size: var(--fs-caption);
  color: var(--ink-mute);
}
.sb-f input, .sb-sel {
  font: inherit;
  font-size: var(--fs-body);
  color: var(--ink);
  background: var(--card);
  border: 1px solid var(--rule);
  border-radius: var(--r-ctl);
  padding: 4px 8px;
}
.btn-mini { padding: 4px 9px; font-size: var(--fs-caption); }

/* Сводка: та же типографика, что у плиток дашборда */
.sb-totals {
  display: flex;
  align-items: center;
  gap: var(--sp-5);
  flex-wrap: wrap;
  padding: 0 var(--sp-5) var(--sp-4);
}
.sb-totals .kpi { display: flex; flex-direction: column; gap: 1px; }
.sb-totals .kpi .l {
  font-size: 10.5px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.sb-totals .kpi .v {
  font-family: var(--font-mono);
  font-size: var(--fs-h3);
  font-weight: 500;
  font-variant-numeric: tabular-nums;
}
.sb-totals .kpi .v.is-bad { color: var(--loss); }

.sb-stat {
  font-size: var(--fs-caption);
  display: inline-flex;
  align-items: center;
  gap: 5px;
}
.sb-stat::before {
  content: '';
  width: 7px;
  height: 7px;
  border-radius: 2px;
  background: currentColor;
}
.sb-stat.is-buy { color: var(--gain); }
.sb-stat.is-ord { color: var(--pulse); }
.sb-stat.is-warn { color: var(--warn); }
.sb-stat.is-err { color: var(--loss); }

.sb-scroll { overflow: auto; max-height: 68vh; }
.sb-grid-scroll { max-height: 58vh; }

.sb-table { border-collapse: collapse; width: 100%; font-size: var(--fs-body); }
.sb-table th, .sb-table td {
  padding: 6px var(--sp-3);
  text-align: left;
  white-space: nowrap;
  border-bottom: 1px solid var(--rule-soft);
}
.sb-table thead th {
  position: sticky;
  top: 0;
  z-index: 1;
  background: var(--card);
  font-size: var(--fs-caption);
  font-weight: 500;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-mute);
  border-bottom: 1px solid var(--rule);
}
.sb-table tbody tr:hover { background: var(--well); }
.sb-table tbody tr.is-err { background: var(--loss-wash); }
.sb-table .is-num { text-align: right; font-family: var(--font-mono); font-variant-numeric: tabular-nums; }
.sb-table .c-date, .sb-table .c-id { font-family: var(--font-mono); }
.sb-table .sb-id { font-family: var(--font-mono); font-size: var(--fs-caption); color: var(--ink-ghost); }
.sb-table .sb-q { max-width: 220px; overflow: hidden; text-overflow: ellipsis; color: var(--ink-soft); }
.sb-none { color: var(--ink-ghost); }
.sb-act { text-align: right; }
.sb-ok { color: var(--gain); }
.sb-warn { color: var(--warn); }
.sb-err { color: var(--loss); }

.sb-chip {
  font-size: 10.5px;
  padding: 1px 7px;
  border-radius: 999px;
  white-space: nowrap;
}
.sb-chip.is-ord { background: var(--pulse-wash); color: var(--pulse); }
.sb-chip.is-buy { background: var(--gain-wash); color: var(--gain); }
.sb-chip.is-bad { background: var(--loss-wash); color: var(--loss); }

/* Грид ввода */
.sb-sheet { border-collapse: separate; border-spacing: 0; font-size: var(--fs-body); }
.sb-sheet th {
  position: sticky;
  top: 0;
  z-index: 2;
  padding: 6px var(--sp-2);
  font-size: var(--fs-caption);
  font-weight: 500;
  letter-spacing: 0.03em;
  text-transform: uppercase;
  color: var(--ink-mute);
  text-align: left;
  white-space: nowrap;
  background: var(--well);
  border-bottom: 1px solid var(--rule);
  border-right: 1px solid var(--rule-soft);
}
.sb-sheet .sb-dot { color: var(--pulse); }
.sb-sheet .sb-fd {
  font: inherit;
  font-size: 11px;
  line-height: 1;
  margin-left: 5px;
  padding: 1px 4px;
  border: 1px solid var(--rule);
  border-radius: 4px;
  background: var(--card);
  color: var(--ink-mute);
  cursor: pointer;
  vertical-align: middle;
}
.sb-sheet .sb-fd:hover { border-color: var(--pulse); color: var(--pulse); }
.sb-sheet td {
  padding: 0;
  border-bottom: 1px solid var(--rule-soft);
  border-right: 1px solid var(--rule-soft);
}
.sb-sheet input {
  font: inherit;
  border: 0;
  background: transparent;
  color: var(--ink);
  padding: 5px var(--sp-2);
  width: 100%;
  min-width: 72px;
  outline: none;
}
.sb-sheet input.is-num {
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
}
.sb-sheet input:focus { background: var(--pulse-wash); box-shadow: inset 0 0 0 1.5px var(--pulse); }
.sb-sheet td.is-bad { background: var(--loss-wash); }
.sb-sheet td.is-soft { background: var(--warn-wash); }
.sb-sheet .sb-rn {
  background: var(--well);
  color: var(--ink-ghost);
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  text-align: center;
  padding: 0 6px;
  user-select: none;
}
.sb-sheet .sb-derived, .sb-sheet .sb-derived-h {
  padding: 5px var(--sp-2);
  font-family: var(--font-mono);
  font-size: var(--fs-caption);
  color: var(--ink-mute);
  white-space: nowrap;
}
.sb-sheet .sb-derived.is-miss { color: var(--loss); }
.sb-sheet .sb-st { padding: 4px var(--sp-2); white-space: nowrap; }

.sb-foot {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  padding: var(--sp-3) var(--sp-5) var(--sp-2);
  border-top: 1px solid var(--rule-soft);
}


/* Правка одной строки */
.sb-edit { width: min(440px, 100vw); }
.sb-edit-body { display: flex; flex-direction: column; gap: var(--sp-3); }
.sb-fld { display: flex; flex-direction: column; gap: 3px; }
.sb-fld > span { font-size: var(--fs-caption); color: var(--ink-mute); }
.sb-fld input, .sb-fld select {
  font: inherit;
  padding: 6px 9px;
  border: 1px solid var(--rule);
  border-radius: var(--r-ctl);
  background: var(--card);
  color: var(--ink);
}

.sb-flash {
  margin-bottom: var(--sp-3);
  padding: 8px var(--sp-4);
  border-radius: var(--r-ctl);
  background: var(--gain-wash);
  color: var(--gain);
  font-size: var(--fs-body);
}

/* Сверка загруженного файла: блоки «что изменится» и «что удалится» */
.sb-block { border-top: 1px solid var(--rule-soft); }
.sb-block-h {
  padding: var(--sp-3) var(--sp-5) var(--sp-2);
  font-size: var(--fs-caption);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.sb-block-h.sb-err { color: var(--loss); }
.sb-diff { display: inline-block; margin-right: var(--sp-3); white-space: nowrap; }
.sb-diff s { color: var(--ink-mute); }
.sb-diff b { font-weight: 500; }
.sb-table td.sb-q { white-space: normal; }

/* Окно «Файл таблицы»: скачать, загрузить, история версий */
/* .drawer-backdrop сам по себе не флекс — он подложка для выезжающей
   панели, которая позиционируется fixed. Окну нужен флекс, иначе оно
   ложится в левый верхний угол. */
/* z-index выше сайдбара (60): у подложки drawer'а он 40, и 64-пиксельная
   полоска сайдбара накрывала левый край окна — на узком экране оно выглядело
   сдвинутым, хотя было отцентровано. */
.sb-modal-back {
  display: flex;
  align-items: center;
  justify-content: center;
  padding: var(--sp-5);
  z-index: 70;
}
/* Крестик окна — крупнее общего .chip-x: в модальном окне это единственный
   способ выйти мышью, и попадать в него должно быть легко. */
.sb-modal .drawer-close {
  font-size: 26px;
  line-height: 1;
  width: 40px;
  height: 40px;
  display: grid;
  place-items: center;
  border-radius: var(--r-ctl);
  margin: -6px -8px -6px 0;
}
.sb-modal .drawer-close:hover { background: var(--well); color: var(--loss); }

.sb-modal {
  background: var(--card);
  border-radius: var(--r-card);
  box-shadow: var(--lift), 0 24px 60px rgba(var(--ink-rgb), 0.18);
  width: min(920px, calc(100vw - 48px));
  max-height: calc(100vh - 64px);
  display: flex;
  flex-direction: column;
  overflow: hidden;
}
.sb-modal-body {
  padding: var(--sp-4) 0 var(--sp-2);
  overflow-y: auto;
  display: flex;
  flex-direction: column;
  gap: var(--sp-4);
}
.sb-actions {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: var(--sp-3);
  padding: 0 var(--sp-5);
}
@media (max-width: 640px) { .sb-actions { grid-template-columns: 1fr; } }
.sb-action {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 3px;
  text-align: left;
  padding: var(--sp-4);
  line-height: 1.4;
}
.sb-action b { font-size: var(--fs-h4); font-weight: 600; }
.sb-action .empty-note, .sb-action span { font-size: var(--fs-caption); }
.sb-action.btn-primary span { color: rgba(255, 255, 255, 0.85); }

.sb-versions { border-top: 1px solid var(--rule-soft); }
.sb-versions-h {
  padding: var(--sp-4) var(--sp-5) var(--sp-2);
  font-size: var(--fs-caption);
  font-weight: 500;
  letter-spacing: 0.06em;
  text-transform: uppercase;
  color: var(--ink-mute);
}
.sb-vchanges { font-family: var(--font-mono); white-space: nowrap; }
.sb-vchanges span { margin-right: 6px; }
.sb-act a.btn-mini { text-decoration: none; display: inline-block; }

/* Комментарий к версии — пишется в момент применения */
.sb-comment {
  display: flex;
  flex-direction: column;
  gap: 3px;
  padding: var(--sp-3) var(--sp-5) 0;
}
.sb-comment > span:first-child { font-size: var(--fs-caption); color: var(--ink-mute); }
.sb-comment input {
  font: inherit;
  padding: 8px 11px;
  border: 1px solid var(--rule);
  border-radius: var(--r-ctl);
  background: var(--card);
  color: var(--ink);
  max-width: 640px;
}
.sb-comment input:focus { outline: 2px solid var(--pulse); outline-offset: 1px; }
