/* ─── Переменные ───────────────────────────────────────────── */
:root {
  --bg:        #04060d;
  --surface:   #0a0f1c;
  --surface2:  #101828;
  --surface3:  #16203a;
  --border:    rgba(56,189,248,.1);
  --border2:   rgba(56,189,248,.22);
  --text:      #e8edf5;
  --muted:     #a3b3cc;
  --dim:       #7e90ae;

  --blue:      #38bdf8;
  --ozon-sky:  #7dd3fc;
  --wb-pink:   #e879f9;
  /* Цена покупателя — везде, где она рисуется линией: «Продажи по периодам»
     и «Реклама, цена покупателя и заказы» в карточке товара. Отдельный
     токен, а не --part-cost: тот фиолетовый значит «себестоимость». */
  --violet:    #a78bfa;
  --blue-glow: rgba(59,130,246,.18);
  --green:     #10b981;
  --green-glow:rgba(16,185,129,.15);
  --red:       #f43f5e;
  --red-glow:  rgba(244,63,94,.12);
  --amber:     #f59e0b;

  /* Статьи — один стандарт на весь сайт: «Маржа», карточка товара, «Стенд»,
     витрина приёмов. Кто ещё их читает: lab-kit.js (COLOR.*) и кнопки-ключи
     графиков (--key). Хардкодить эти цвета в страницах нельзя.

       прибыль — зелёный · себестоимость — фиолетовый · реклама — оранжевый
       комиссия — розово-красный · баллы (СПП) — голубой · логистика — бирюза

     Логистика бирюзовая, а не синяя: синий занят баллами, и в стеке две синие
     статьи слипались. Палитра проверена на этом фоне: соседние сегменты
     различимы и при дальтонизме (ΔE ≥ 8), контраст к подложке ≥ 3:1.
     Менять — только с перепроверкой всей шестёрки. */
  --part-net:  #0d9f76;
  --part-cost: #8b5cf6;
  --part-ad:   #c98500;
  --part-logi: #2aa1b8;
  --part-comm: #e04b63;
  --part-return: #fb7185;
  --part-penalty: #94a3b8;
  --part-rest: #3a4a68;
  --part-spp:  #7dd3fc;

  /* Категориальная палитра — для «кто есть кто», а не «что есть что»: товары в
     донате, схемы в разрезе. Отдельная от статей выше: там зелёный навсегда
     значит прибыль, а здесь цвет — просто ярлык, и смешивать эти два смысла
     нельзя. Порядок фиксированный: слот 1 всегда первому, слот 2 второму, по
     кругу не гоняем. Больше восьми имён цветом не различить — девятый и
     дальше сваливаются в «остальные» (серый --part-rest).

     Набор проверен скриптом validate_palette (навык dataviz) на этом фоне
     (#0a0f1c): полоса светлоты, минимум цветности, разделимость соседних пар
     при дальтонизме (худшая ΔE 8.4 при протанопии), нормальное зрение
     (ΔE 19.3) и контраст к подложке ≥ 3:1 — всё в пределах. Менять цвет
     поодиночке нельзя, только перепроверив весь набор. */
  --cat-1: #3987e5;
  --cat-2: #d95926;
  --cat-3: #199e70;
  --cat-4: #c98500;
  --cat-5: #d55181;
  --cat-6: #008300;
  --cat-7: #9085e9;
  --cat-8: #e66767;

  /* Скруглений в интерфейсе ровно три, и различает их роль, а не размер:
     --r-sm — то, что нажимают и заполняют (кнопки, поля, плашки, подсказки),
     --r-card — карточки, панели и таблицы,
     --r-pill — фильтры и переключатели: круглый торец говорит «выбор из
     ряда», а не «блок с содержимым».

     --r-md/--r-lg/--r-xl оставлены псевдонимами карточного. Обещание
     «скруглений ровно два» до сих пор держалось только в комментарии:
     страницы продолжали звать наследство, и одна и та же по смыслу
     карточка выходила 12px на «Анализе», 14px в «Стенде» и «Остатках»,
     20px у метрики и 26px в «Рекламе» и карточке товара. Старые вызовы
     остаются рабочими и попадают в общий размер; новый код зовёт
     --r-sm / --r-card / --r-pill. */
  --r-sm: 10px;
  --r-card: 12px;
  --r-pill: 999px;

  --r-md: var(--r-card);
  --r-lg: var(--r-card);
  --r-xl: var(--r-card);

  /* Отступы — тоже роли. Раньше поля карточки писались числом на месте, и
     соседние по смыслу блоки получали 12/14/16/18/20/22/24/28px: «Анализ»
     набивал карточку плотнее, чем «Реклама», а панель товара — свободнее
     обеих. Числа ниже — те же, что были у большинства; смысл в том, что
     теперь их одно место.

       --card-pad   карточка с числом или списком
       --panel-pad  крупная панель: заголовок, график, подвал
       --card-gap   зазор между карточками в сетке
       --block-gap  отбивка между разделами страницы */
  --card-pad: 14px 16px;
  --panel-pad: 18px 20px;
  --card-gap: 14px;
  --block-gap: 18px;

  /* Подсказка на графике — один вид на весь сайт. До этого их было десять:
     пять разных подложек (#101828, #0e1420, --surface, --surface2,
     --surface3), шесть радиусов, четыре кегля, а на «WB порог акций»
     Chart.js рисовал вообще свою чёрную плашку по умолчанию. Читают их
     все одинаково, значит и выглядеть они обязаны одинаково: тёмная
     подложка, тонкая голубая рамка, цветной квадрат серии, табличные
     цифры. Значения отсюда берут и CSS-подсказки, и static/chart-theme.js
     (Chart.defaults), и cyberpunk/dashboard.css. */
  --tip-bg: #101828;
  --tip-border: rgba(56, 189, 248, .35);
  --tip-pad: 8px 11px;
  --tip-fs: var(--fs-sm);
  --tip-lh: 1.45;

  /* Размеры текста (--fs-*) переехали в static/chrome-tokens.css: ту же шкалу
     читает общая шапка, а она стоит и на собранном «Обзоре», где style.css
     нет. Файл подключается первым (_base.html) и вклеивается в дашборд при
     сборке — здесь шкалы больше нет, чтобы не было двух. */

  --shadow: 0 4px 24px rgba(0,0,0,.5);
  --shadow-lg: 0 8px 48px rgba(0,0,0,.6);
}

/* ─── Сброс ─────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }

body {
  background-color: var(--bg);
  background-image:
    radial-gradient(120% 70% at 50% -10%, rgba(56, 189, 248, .07), transparent 62%),
    radial-gradient(90% 55% at 88% 4%, rgba(168, 85, 247, .05), transparent 60%);
  background-attachment: fixed;
  color: var(--text);
  font: 13px/1.5 "JetBrains Mono", "SF Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
  min-height: 100vh;
}
button, input, select, textarea, .btn {
  font-family: "JetBrains Mono", "SF Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
}

a { color: var(--blue); text-decoration: none; }
a:hover { color: #60a5fa; }

/* ─── Шапка ─── стили в static/topbar.css: одна шапка на приложение и /cyberpunk. */

/* ─── Контент ─────────────────────────────────────────────────
   Ширина у всех вкладок одна. Исключение ровно одно и названо явно:
   страницы-формы (калькулятор) — им 1440 не нужны, поля растянулись бы
   на весь экран. Раньше каждая вкладка задавала ширину сама (960 в
   калькуляторе, 720 в настройках, 1560 на стенде), и сайт выглядел как
   несколько разных. */
.page { max-width: 1440px; margin: 0 auto; padding: 28px 28px 80px; }
.page--narrow { max-width: 960px; }

/* ─── Заголовок страницы ─────────────────────────────────────── */
.page-header {
  display: flex; align-items: flex-end; justify-content: space-between;
  gap: 16px; margin-bottom: 24px; flex-wrap: wrap;
}
.page-title { font-size: var(--fs-hero); font-weight: 700; color: var(--text); }
.page-sub   { font-size: var(--fs-base); color: var(--muted); margin-top: 4px; }

/* Свежесть данных — под заголовком каждой вкладки, где есть чему устареть.
   Точка отвечает на вопрос раньше, чем прочитан текст: зелёная — данные
   свежие, жёлтая — пора обновить, красная — за ними стоит сходить. */
.page-stamp {
  display: flex; align-items: center; flex-wrap: wrap; gap: 6px;
  margin-top: 6px;
  font-size: var(--fs-sm); color: var(--muted);
}
.page-stamp__dot {
  width: 7px; height: 7px; border-radius: 50%;
  background: var(--green); box-shadow: 0 0 8px var(--green-glow);
}
.page-stamp__dot--warn { background: var(--amber); box-shadow: 0 0 8px rgba(245,158,11,.35); }
.page-stamp__dot--old  { background: var(--red);   box-shadow: 0 0 8px var(--red-glow); }
/* Живая вкладка: данные приходят при открытии, устаревать нечему. */
.page-stamp__dot--live { background: var(--blue); box-shadow: 0 0 8px var(--blue-glow); }
.page-stamp__sep { color: var(--border2); }
.page-stamp__ago { color: var(--dim); }
.page-stamp__ago::before { content: '('; }
.page-stamp__ago::after  { content: ')'; }
.page-stamp.is-pending .page-stamp__dot { opacity: .4; }
.page-stamp__refresh {
  display: inline-flex; align-items: center; gap: 5px;
  margin-left: 4px; padding: 3px 10px;
  border: 1px solid var(--border); border-radius: var(--r-pill);
  background: var(--surface2); color: var(--muted);
  font-size: var(--fs-xs); font-weight: 600; text-decoration: none;
  transition: background .15s, color .15s, border-color .15s;
}
.page-stamp__refresh:hover { background: var(--surface3); color: var(--text); border-color: var(--border2); }

/* ─── Кнопки ─────────────────────────────────────────────────── */
.btn {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 8px 16px; border-radius: var(--r-sm);
  border: 1px solid var(--border2);
  background: var(--surface2);
  color: var(--text); font: inherit; font-size: var(--fs-h3);
  cursor: pointer; white-space: nowrap;
  transition: background .15s, border-color .15s, transform .1s;
}
.btn:hover { background: var(--surface3); border-color: var(--blue); transform: translateY(-1px); }
.btn-primary {
  background: linear-gradient(135deg, #2563eb, #1d4ed8);
  border-color: transparent; color: #fff;
}
.btn-primary:hover { background: linear-gradient(135deg, #3b82f6, #2563eb); border-color: transparent; }

/* ─── Карточки метрик ────────────────────────────────────────── */
.metrics {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(190px, 1fr));
  gap: var(--card-gap);
  margin-bottom: var(--card-gap);
}

/* Заголовок сводки */
.summary-head {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 8px; margin-bottom: 12px;
}
.summary-title { font-size: var(--fs-h2); font-weight: 700; color: var(--text); }
.summary-warn { font-size: var(--fs-base); color: #f59e0b; }
.summary-ok   { font-size: var(--fs-base); color: var(--muted); }
.summary-notices-shell { margin: -4px 0 10px; }
.summary-notices {
  width: fit-content;
  max-width: min(920px, 100%);
  color: var(--muted);
  font-size: var(--fs-sm);
}
.summary-notices summary {
  display: flex;
  align-items: center;
  gap: 8px;
  width: fit-content;
  padding: 4px 8px;
  border: 1px solid rgba(245, 158, 11, .18);
  border-radius: var(--r-sm);
  background: rgba(245, 158, 11, .04);
  color: #d99a25;
  cursor: pointer;
  list-style: none;
}
.summary-notices summary::-webkit-details-marker { display: none; }
.summary-notices summary::after {
  content: '›';
  color: var(--dim);
  transition: transform .15s ease;
}
.summary-notices[open] summary::after { transform: rotate(90deg); }
.summary-notices summary em {
  color: var(--dim);
  font-style: normal;
}
.summary-notices__body {
  margin-top: 6px;
  padding: 7px 10px;
  border-left: 1px solid rgba(245, 158, 11, .28);
  color: var(--dim);
  line-height: 1.45;
}
.summary-notices__body p { margin: 0; }
.summary-notices__body p + p { margin-top: 5px; }
.summary-notices__body b { color: var(--muted); }
/* Единицы в помесячной таблице. Обе величины лежат в ячейке сразу, переключение
   — это CSS-класс на таблице: пересчитывать на клиенте нечего, а при выключенном
   JS таблица остаётся в рублях. */
.months-table .u-pct { display: none; }
.months-table.is-pct .u-rub { display: none; }
.months-table.is-pct .u-pct { display: inline; }
.months-table.is-pct th.u-rub, .months-table.is-pct td.u-rub { display: none; }

/* Окупаемость — плитки-медальоны. Второй вариант подачи (полоса
   «вложено → вернулось») стоял рядом, пока выбирали, и удалён вместе со
   своими стилями. */
.payback-card {
  margin: 0 0 var(--card-gap);
  padding: var(--card-pad);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--surface2);
}
.payback-card__head {
  display: flex; flex-wrap: wrap; gap: 12px 24px;
  align-items: flex-start; justify-content: space-between; margin-bottom: 12px;
}
.payback-card__title { font-size: var(--fs-h3); font-weight: 700; color: var(--text); }
.payback-card__sub { margin-top: 2px; font-size: var(--fs-sm); color: var(--dim); }
.payback-card__totals { display: flex; gap: 22px; }
.payback-card__totals div { display: flex; flex-direction: column; gap: 1px; text-align: right; }
.payback-card__totals b { font-size: var(--fs-h2); font-weight: 700; font-variant-numeric: tabular-nums; }
.payback-card__totals span { font-size: var(--fs-xs); color: var(--dim); }

/* Прибыль и убытки — парой в две колонки. Донат рисуется в колоночной
   пропорции (круг слева, легенда справа), и на всю ширину карточки он
   растягивался пустотой; убыточные плитки, наоборот, спокойно ужимаются
   в сетку 2×N. */
.payback-row {
  display: grid;
  /* Донату шире: его svg нарисован в системе 640 единиц, и в узкой колонке
     он сжимался вместе с подписями — легенда уезжала ниже 10px. */
  grid-template-columns: minmax(0, 1.75fr) minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--card-gap);
  align-items: stretch;
}
.payback-row .payback-card { margin: 0; }
/* Боковые колонки узкие — плитки в них по две в ряд, шесть штук дают три
   ровных ряда вровень с донатом. `grid-auto-rows: 1fr` держит ряды одной
   высоты: без него плитка с длинной подписью растягивала свой ряд, и сетка
   выглядела рваной. */
.payback-card--side .payback-tiles {
  grid-template-columns: repeat(2, minmax(0, 1fr));
  grid-auto-rows: 1fr;
}
.payback-card--side .payback-tile { padding: 10px 12px; }
.payback-card--side .payback-tile__roi { font-size: var(--fs-lead); }
/* Счётчик убытков не должен создавать вторую строку шапки: иначе правая
   сетка начинается ниже соседней. Число и подпись стоят одной компактной
   строкой на уровне заголовка. */
.payback-card--loss .payback-card__totals div {
  flex-direction: row; align-items: baseline; gap: 6px;
}
.payback-card--loss .payback-card__totals b {
  font-size: var(--fs-h3); line-height: 1.2;
}
.payback-card--loss .payback-card__totals span { font-size: var(--fs-xs); }
/* Две подписанные строки вместо безымянной суммы «15 164 ₽ · себес …».
   grid-auto-rows выше держит соседние плитки одинаковой высоты. */
.payback-tile__money {
  display: grid; grid-template-columns: minmax(0, 1fr) auto;
  gap: 2px 8px; margin-top: 2px;
  color: var(--dim); font-size: var(--fs-xs); line-height: 1.25;
}
.payback-tile__money span { overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.payback-tile__money b {
  color: var(--text); font-weight: 600; font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.payback-tile__money b.pos { color: var(--part-net); }
.payback-tile__money b.neg { color: var(--part-comm); }

/* Средний экран: донат во всю ширину, лучшие и худшие — парой под ним. */
@media (max-width: 1360px) {
  .payback-row { grid-template-columns: 1fr 1fr; }
  .payback-row > .payback-card:first-of-type { grid-column: 1 / -1; }
}
@media (max-width: 860px) {
  .payback-row { grid-template-columns: 1fr; }
  .payback-row > .payback-card:first-of-type { grid-column: auto; }
}

/* Донат «На чём держится месяц»: примитив стенда рисует svg с viewBox 640,
   растягиваем его по колонке. */
.payback-donut { margin-top: 2px; }
.payback-donut .lk-svg { width: 100%; height: auto; display: block; }

/* Плитки — теперь только у убыточных */
.payback-tiles {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(170px, 1fr));
  gap: 10px;
}
.payback-tile {
  display: flex; flex-direction: column; gap: 3px;
  padding: 12px 14px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: var(--surface);
  color: inherit; text-decoration: none;
  transition: border-color .15s, transform .1s;
}
.payback-tile:hover { border-color: var(--border2); transform: translateY(-1px); }
/* Расшифровка процента по наведению — тем же приёмом, что подсказки в «пути
   рубля»: постоянной строкой это три числа на каждую плитку, а нужны они
   ровно в тот момент, когда смотришь на конкретный товар. */
.payback-tile { position: relative; }
.payback-tile__hint {
  position: absolute; left: 50%; bottom: calc(100% + 8px);
  transform: translateX(-50%);
  z-index: 6; width: max-content; max-width: 260px;
  padding: var(--tip-pad);
  border: 1px solid var(--tip-border); border-radius: var(--r-sm);
  background: var(--tip-bg); box-shadow: var(--shadow);
  color: var(--dim); font-size: var(--tip-fs); font-style: normal;
  line-height: var(--tip-lh); text-align: left; white-space: nowrap;
  opacity: 0; pointer-events: none; transition: opacity .12s ease;
  /* Подпись — значение в две колонки: числа выстраиваются в столбик и
     сравниваются между собой, а не выискиваются в строке текста. */
  display: grid; grid-template-columns: auto auto; gap: 3px 16px;
}
.payback-tile__hint i {
  grid-column: 1 / -1; margin-bottom: 3px; padding-bottom: 4px;
  border-bottom: 1px solid var(--border);
  color: var(--text); font-style: normal; font-weight: 600;
  font-size: var(--fs-sm);
}
.payback-tile__hint b {
  justify-self: end; color: var(--text); font-weight: 600;
  font-variant-numeric: tabular-nums;
}
.payback-tile__hint b.pos { color: var(--part-net); }
.payback-tile__hint b.neg { color: var(--part-comm); }
.payback-tile:hover .payback-tile__hint { opacity: 1; }
.payback-tile__roi { font-size: var(--fs-hero); font-weight: 700; font-variant-numeric: tabular-nums; line-height: 1.1; }
.payback-tile__name {
  font-size: var(--fs-base); color: var(--text);
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
.payback-tile--loss { border-color: color-mix(in srgb, var(--part-comm) 30%, transparent); }

/* Второй ряд раздела «Когда покупают» — три одинаковые колонки: сезонность,
   дни недели и возвраты. Возвраты уплотнены, чтобы в узкой карточке остались
   и четыре итога, и рейтинг с долей и суммой потерь. */
.analysis-insights .lab-card { align-self: stretch; }
.returns-insight__body { padding-top: 0; }
.returns-card__totals {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px 12px;
  margin-bottom: 10px; padding-bottom: 10px;
  border-bottom: 1px solid var(--border);
}
.returns-card__totals div { display: flex; flex-direction: column; gap: 1px; text-align: left; }
.returns-card__totals b { font-size: var(--fs-h2); font-weight: 700; font-variant-numeric: tabular-nums; }
.returns-card__totals b.neg { color: var(--part-comm); }
.returns-card__totals span { font-size: var(--fs-xs); color: var(--dim); }
.returns-insight .lk-rank__row { text-decoration: none; color: inherit; }
.returns-insight .lk-rank__row:has(.lk-rank__extra) {
  gap: 5px;
  /* Числовые колонки фиксированы: иначе «4 из 16» и «3 из 9» оставляли
     полосе разное место, и шкалы начинались и заканчивались лесенкой. */
  grid-template-columns: 16px minmax(0, 1.35fr) minmax(36px, .8fr) 68px 110px;
}
.returns-insight .lk-rank__label i { display: none; }
.returns-insight .lk-rank__extra { font-size: 10px; }
.returns-insight .lk-rank__row:hover .lk-rank__label { color: var(--blue); }

/* Детальная разбивка */
/* ─── Путь рубля: из выручки в прибыль ────────────────────────────────────
   Строка = шаг расчёта, полоса = доля от выручки, цвет — тот же, что у
   сегмента этой статьи в графике по месяцам. Пришло на смену плоской сетке
   «подпись — число»: в ней не читались ни порядок вычетов, ни их вес. */
.flow {
  display: grid;
  grid-template-columns: minmax(620px, 1.55fr) minmax(330px, .75fr);
  gap: 1px;
  background: var(--border);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  overflow: hidden;
  margin-bottom: 20px;
}
/* Запас по вертикали — под подсказки крайних строк: они всплывают по центру
   строки, а карточка обрезает всё, что вылезло за неё. */
.flow__steps { background: var(--surface); padding: 7px 16px; }
.flow__row {
  display: flex; align-items: center; gap: 10px;
  padding: 6px 0; font-size: var(--fs-base);
  border-bottom: 1px dashed var(--border);
}
.flow__row:last-child { border-bottom: none; }
.flow__sign  { flex: 0 0 10px; color: var(--dim); }
/* Подпись фиксированной ширины, полоса забирает весь остаток — та же раскладка,
   что у воронки на вкладке «Графики» (gallery.css, .gal-funnel__row). Пока имя
   тянулось вместе с полосой, на широком экране от полосы оставался огрызок. */
.flow__name  { position: relative; flex: 0 0 160px; min-width: 0; color: var(--muted); }
.flow__bar   {
  flex: 1; height: 6px; border-radius: 3px;
  background: rgba(255, 255, 255, .06); overflow: hidden;
}
.flow__bar i {
  display: block; height: 100%; border-radius: 3px;
  background: var(--tone, var(--blue));
  box-shadow: 0 0 10px -2px var(--tone, var(--blue));
}

/* Пояснение к строке — по наведению, а не второй строкой под каждым именем:
   десять подписей подряд превращали расчёт в сплошной текст. Всплывает справа
   от имени и по центру строки — так подсказка не вылезает за карточку
   (у .flow стоит overflow: hidden) ни сверху, ни снизу. */
.flow__hint {
  position: absolute;
  left: calc(100% + 14px);
  top: 50%;
  transform: translateY(-50%);
  z-index: 5;
  width: max-content;
  max-width: 260px;
  padding: var(--tip-pad);
  border-radius: var(--r-sm);
  background: var(--tip-bg);
  border: 1px solid var(--tip-border);
  box-shadow: var(--shadow);
  font-size: var(--tip-fs);
  font-style: normal;
  line-height: var(--tip-lh);
  color: var(--muted);
  opacity: 0;
  pointer-events: none;
  transition: opacity .12s ease;
}
.flow__row:hover .flow__hint { opacity: 1; }
.flow__val {
  flex: 0 0 132px; text-align: right; white-space: nowrap;
  font-variant-numeric: tabular-nums; color: var(--tone, var(--text));
}
.flow__share {
  flex: 0 0 48px; text-align: right; font-size: var(--fs-base);
  font-variant-numeric: tabular-nums; color: var(--dim);
}

.flow__row[data-part="buyer"] { --tone: var(--blue); }
.flow__row[data-part="spp"] { --tone: var(--part-spp); }
.flow__row[data-part="gross"] { --tone: var(--blue); }
.flow__row[data-part="commission"] { --tone: var(--part-comm); }
.flow__row[data-part="logistics"] { --tone: var(--part-logi); }
.flow__row[data-part="penalties"] { --tone: var(--dim); }
.flow__row[data-part="other"] { --tone: var(--part-rest); }
.flow__row[data-part="ozon"] { --tone: var(--muted); }
.flow__row[data-part="ad"] { --tone: var(--part-ad); }
.flow__row[data-part="cost"] { --tone: var(--part-cost); }
/* Прибыль — промежуточный итог: тем же зелёным, что остаток, но приглушённо,
   чтобы итоговая строка внизу оставалась главной. */
.flow__row[data-part="profit"] { --tone: var(--part-net); opacity: .92; }
.flow__row[data-part="net"] { --tone: var(--part-net); }
.flow__row--loss                   { --tone: var(--red); }

/* Состав строки выше, а не следующий шаг расчёта: отступ и вертикаль слева
   говорят «это внутри», чтобы источники выручки не читались как вычеты. */
.flow__row--part .flow__name {
  padding-left: 14px;
  border-left: 1px solid var(--border);
  font-size: var(--fs-base);
}
.flow__row--part .flow__val,
.flow__row--part .flow__share { font-size: var(--fs-base); }
.flow__row--part .flow__bar { opacity: .75; }

/* Итоги — сплошная линия и вес: взгляд должен цепляться за них, а не за
   вычеты между ними. */
.flow__row--total { border-bottom-style: solid; }
.flow__row--total .flow__name,
.flow__row--total .flow__val { color: var(--text); font-weight: 700; }
.flow__row--net .flow__val { color: var(--tone); font-size: var(--fs-h2); }

/* ROI дописан к пути рубля последней строкой. Доли от выручки в нём нет, а
   пустая дорожка читалась бы как «ноль» — гасим её, оставив место под колонку,
   чтобы число встало в один столбец с остальными. */
.flow__row--metric .flow__bar { background: none; }
.flow__row--metric .flow__val { color: var(--tone); font-weight: 700; }

.flow__economy {
  display: flex;
  flex-direction: column;
  /* Обе колонки начинаются с одной высоты: заголовок блока — по строке
     «Выручка» слева. Раньше блок прижимался к низу (по строке ROI), и сверху
     оставалась дыра в треть карточки. Отступ считается от левой колонки:
     .flow__steps даёт 7px, первая строка — ещё 6px. */
  justify-content: flex-start;
  min-width: 0;
  padding: 13px 26px 20px;
  background: var(--surface);
}
.flow__economy-title {
  font-size: var(--fs-sm);
  font-weight: 700;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--text);
}
.flow__economy-sub {
  margin-top: 3px;
  font-size: var(--fs-xs);
  color: var(--dim);
}
.economy-card {
  margin-top: 10px;
  padding: 10px 12px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .018);
}
.economy-card__label,
.economy-mini > span {
  display: block;
  color: var(--muted);
  font-size: var(--fs-xs);
}
.economy-card strong,
.economy-mini strong {
  color: var(--part-net);
  font-variant-numeric: tabular-nums;
}
.economy-card > strong {
  display: block;
  margin-top: 3px;
  font-size: var(--fs-hero);
}
.economy-card small,
.economy-mini small {
  display: block;
  margin-top: 2px;
  color: var(--dim);
  font-size: var(--fs-xs);
  line-height: 1.35;
}
.economy-card--loss strong,
.economy-mini--loss strong { color: var(--red); }
.economy-card__pair {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-top: 3px;
}
.economy-card__pair strong { color: var(--part-ad); font-size: var(--fs-hero); }
.economy-card__pair span { color: var(--muted); font-size: var(--fs-xs); }
/* Порог — цветом остатка, как засечка на шкале: он про то, где остаток
   обнулится, а не про рекламу. */
.economy-card__pair span b { color: var(--part-net); font-weight: 700; }
/* Реклама перешагнула порог — тогда красное само число, а не только «запас
   ДРР» в соседней плитке. */
.economy-card--over .economy-card__pair strong { color: var(--red); }
.economy-meter {
  position: relative;
  height: 7px;
  margin-top: 7px;
  border-radius: 4px;
  background: rgba(255, 255, 255, .06);
}
.economy-meter i {
  display: block;
  width: var(--current);
  height: 100%;
  border-radius: inherit;
  background: var(--part-ad);
  box-shadow: 0 0 10px -2px var(--part-ad);
}
.economy-meter b {
  position: absolute;
  top: -3px;
  left: var(--limit);
  width: 2px;
  height: 13px;
  border-radius: 1px;
  background: var(--part-net);
}
.economy-split {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 8px;
  margin-top: 7px;
}
.economy-mini {
  min-width: 0;
  padding: 8px 10px;
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  background: rgba(255, 255, 255, .018);
}
.economy-mini strong {
  display: block;
  margin-top: 3px;
  font-size: var(--fs-h2);
}

@media (max-width: 1180px) {
  .flow { grid-template-columns: minmax(0, 1fr); }
  .flow__economy { padding: 18px; }
}

/* На узком экране полосы не помещаются, а колонки съезжают за край карточки:
   подпись занимает всю строку, число с долей уходят под неё вправо. */
@media (max-width: 720px) {
  .flow__steps { padding: 4px 14px; }
  .flow__row { flex-wrap: wrap; gap: 3px 10px; }
  .flow__sign, .flow__bar { display: none; }
  .flow__name { flex: 1 1 100%; }
  .flow__val { flex: 0 0 auto; margin-left: auto; }
  .flow__share { flex: 0 0 auto; min-width: 42px; }
  .economy-split { grid-template-columns: 1fr; }
  /* На телефоне наведения нет, а места справа от имени — тоже: возвращаем
     пояснение обычной строкой под именем. */
  .flow__hint {
    position: static;
    transform: none;
    display: block;
    max-width: none;
    margin-top: 2px;
    padding: 0;
    border: none;
    background: none;
    box-shadow: none;
    color: var(--dim);
    opacity: 1;
  }
}

/* Сравнение по месяцам */
.months-title { font-size: var(--fs-h2); font-weight: 700; color: var(--text); margin-bottom: 10px; }
/* Подзаголовок таблицы под графиками: набран как заголовки карточек графиков
   (капитель), чтобы в блоке был один главный заголовок и одинаковые мелкие. */
.months-title--sub {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 18px;
  font-size: var(--fs-sm); letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted);
}
/* Переключатель единиц внутри подзаголовка набран обычным текстом: капитель и
   разрядка заголовка на кнопках «₽ / % от выручки» читаются плохо. */
.months-title--sub .months-chart__switch { letter-spacing: normal; text-transform: none; }

/* ─── Столбики по месяцам ─────────────────────────────────────────────────
   Стоят над таблицей: сначала видно форму года, потом читаются точные числа.
   Столбец — выручка месяца, разобранная на части; кнопки-ключи включают
   нужные, переключатель ₽/% меняет единицы. Блок при этом не перерисовывается. */
.months-chart {
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--surface);
  padding: var(--card-pad);
  margin-bottom: 12px;
}
/* Тот же график внутри чужой карточки: рамку, фон и отступы уже дала она.
   Так «Реклама, цена покупателя и заказы» в товаре выглядит как на «Анализе»,
   но сидит в панели карточки наравне с соседями. */
.months-chart--bare {
  border: 0; background: none; padding: 0; margin-bottom: 0;
}
.months-chart__head {
  display: flex; align-items: center; justify-content: space-between;
  flex-wrap: wrap; gap: 8px 14px; margin-bottom: 10px;
}
.months-chart__title {
  font-size: var(--fs-sm); font-weight: 700; letter-spacing: .1em;
  text-transform: uppercase; color: var(--muted);
}
.months-chart__switch { display: flex; gap: 4px; }
.months-chart__btn {
  padding: 5px 12px; border-radius: var(--r-sm);
  border: 1px solid var(--border); background: transparent;
  color: var(--dim); font: inherit; font-size: var(--fs-base);
  cursor: pointer; transition: color .15s, border-color .15s, background .15s;
}
.months-chart__btn:hover { color: var(--text); border-color: var(--border2); }
.months-chart__btn.is-active {
  color: var(--blue); border-color: var(--border2);
  background: rgba(56, 189, 248, .10);
}

/* Ключи стека — они же легенда: цвет сегмента живёт здесь, в --key, и график
   читает его отсюда. Двух списков цветов (CSS + JS) быть не должно —
   разъезжаются. */
.months-chart__keys { display: flex; flex-wrap: wrap; gap: 6px; margin-bottom: 12px; }
.months-chart__key {
  display: inline-flex; align-items: center; gap: 7px;
  padding: 5px 11px; border-radius: var(--r-pill);
  border: 1px solid var(--border); background: transparent;
  color: var(--dim); font: inherit; font-size: var(--fs-base);
  cursor: pointer; transition: color .15s, border-color .15s, background .15s;
}
.months-chart__key::before {
  content: ''; width: 9px; height: 9px; border-radius: 3px;
  background: var(--key, var(--dim)); opacity: .3; transition: opacity .15s;
}
.months-chart__key:hover { color: var(--text); border-color: var(--border2); }
.months-chart__key[aria-pressed="true"] {
  color: var(--text); border-color: var(--border2); background: var(--surface2);
}
.months-chart__key[aria-pressed="true"]::before { opacity: 1; }
/* Ключ, которого в этом срезе нет (например «Прочее» у товара, где весь
   расход разложился по двум кнопкам), прячется совсем. `display` из класса
   перебивает браузерное [hidden] — возвращаем ему силу. */
.months-chart__key[hidden] { display: none; }

/* Цвета — общие с «путём рубля» выше (--part-*), чтобы статья везде
   выглядела одинаково. */
.months-chart__key[data-part="net"]        { --key: var(--part-net); }
.months-chart__key[data-part="cost"]       { --key: var(--part-cost); }
.months-chart__key[data-part="ad"]         { --key: var(--part-ad); }
.months-chart__key[data-part="logistics"]  { --key: var(--part-logi); }
.months-chart__key[data-part="commission"] { --key: var(--part-comm); }
.months-chart__key[data-part="refunds"]    { --key: var(--part-return); }
.months-chart__key[data-part="penalties"]  { --key: var(--part-penalty); }
.months-chart__key[data-part="gross"]      { --key: var(--part-rest); }  /* «прочее» — фон */
.months-chart__key[data-part="spp"]        { --key: var(--part-spp); }
/* Только у «Рубля покупателя»: «Ozon себе» — те же сборы площадки, что и
   комиссия, поэтому её цвет. «Прочее» — тот же серо-синий, что и остаток
   столбца в графике выше. */
.months-chart__key[data-part="ozon"]       { --key: var(--part-comm); }
.months-chart__key[data-part="other"]      { --key: var(--part-rest); }
/* Только у «Рекламы, цены покупателя и заказов» в карточке товара: цена
   продавца — нейтральный потолок, цена покупателя под ней синяя, и разрыв
   между ними читается как скидка. Голубой (--part-spp) тут занять нельзя:
   он значит «баллы», а баллы здесь и есть этот разрыв, своей линии у них
   нет. Правила общие, потому что общий и график: карточка берёт ту же
   разметку `.months-chart`. */
.months-chart__key[data-part="price"]      { --key: var(--muted); }
/* Цена покупателя фиолетовая: ровно так её рисуют «Продажи по периодам»
   выше, а синий там занят столбиками «продано» — одна величина, один цвет
   на всю карточку. Синей она была до того, и в подсказке сливалась со
   строкой скидки Ozon, которая голубая (--part-spp, цвет баллов). */
.months-chart__key[data-part="paid"]       { --key: var(--violet); }
/* Полосы заказов — подложка, а не пятая величина. Тон уведён к фону
   намеренно: в один шаг с «ценой продавца» они читались как закрашенный
   разрыв между линиями, то есть как размер скидки. */
.months-chart__key[data-part="qty"]        { --key: color-mix(in srgb, var(--part-rest) 72%, var(--bg)); }
/* Только у «Рекламы по дням» в карточке товара: тот же расход, что и статья
   --part-ad выше, разложенный по кнопкам кабинета. Трафареты держат её цвет —
   это основная кнопка и основная часть столбика; вывод в топ синий, потому
   что синий на сайте означает сторону площадки, а ВВТ и есть место в её
   выдаче. «Прочее» — тот же фоновый серо-синий, что и остаток столбца
   в графиках «Анализа». */
.months-chart__key[data-part="adTraf"]     { --key: var(--part-ad); }
.months-chart__key[data-part="adTop"]      { --key: var(--blue); }
.months-chart__key[data-part="adRest"]     { --key: var(--part-rest); }
/* Только у «Сколько заказ едет до покупателя»: схема — это и линия дней, и
   столбец заказов, поэтому цвет один на обе величины, а ключ гасит их разом.
   Синий у склада Ozon неслучайно: FBO — их логистика, и синий на сайте везде
   означает сторону площадки. */
.months-chart__key[data-part="fbo"]        { --key: var(--blue); }
.months-chart__key[data-part="fbs"]        { --key: var(--violet); }

/* Chart.js меряет холст по родителю — высоту задаём здесь, не атрибутом. */
.months-chart__canvas { position: relative; height: 260px; }
/* Разрез «на штуку» выше остальных: четыре линии в рублях и полосы заказов
   на второй шкале в 260px слипались в одну ленту. */
.months-chart__canvas--tall { height: 320px; }
.months-chart__note {
  margin-top: 10px; max-width: 92ch;
  font-size: var(--fs-sm); line-height: 1.55; color: var(--dim);
}
.months-note { font-size: var(--fs-base); font-weight: 400; color: var(--muted); }

/* Платная история: строка размыта и не выделяется — цифры в ней всё равно
   подставные, настоящие на клиент не уходят. */
.paywall-note { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
                font-size: var(--fs-base); color: var(--text); background: var(--surface2);
                border: 1px solid var(--border2); border-left: 2px solid var(--blue);
                border-radius: var(--r-sm); padding: 9px 12px; margin-bottom: 10px; }
/* Переключатель предпросмотра — только у владельца, поэтому неброский. */
.paywall-preview { display: flex; align-items: center; gap: 10px; flex-wrap: wrap;
                   font-size: var(--fs-sm); color: var(--muted); margin-bottom: 10px; }
.locked-row td { filter: blur(4px); user-select: none; opacity: .75; }
.locked-row td:first-child { filter: none; opacity: .55; }
@media (prefers-reduced-motion: no-preference) {
  .locked-row:hover td { filter: blur(3.4px); }
}
.months-wrap { margin-bottom: 24px; max-height: none; }
.months-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--fs-h3); }
.months-table thead th {
  padding: 10px 8px; background: var(--surface2); color: var(--muted);
  font-size: var(--fs-xs); font-weight: 700; text-transform: uppercase; letter-spacing: .03em;
  /* Переносим по словам, как в главной таблице: «Обр. логистика» и «Чистая
     прибыль» в одну строку не помещаются и раньше обрезались. */
  text-align: right; white-space: normal; overflow-wrap: normal;
  line-height: 1.3; vertical-align: bottom;
  border-bottom: 2px solid var(--border2);
  position: sticky; top: var(--thead-top); z-index: 10;
}
.months-table thead th.l { text-align: left; }
.months-table tbody td { padding: 10px 12px; text-align: right; white-space: nowrap; border-bottom: 1px solid var(--border); }
.months-table tbody td.l { text-align: left; }
.months-table tbody tr:hover td { background: var(--surface2); }
.months-table tbody tr:last-child td { border-bottom: none; }
.metric {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  padding: var(--panel-pad);
  position: relative; overflow: hidden;
  transition: border-color .2s;
}
.metric:hover { border-color: var(--border2); }
.metric::before {
  content: "";
  position: absolute; inset: 0;
  opacity: 0;
  transition: opacity .2s;
  border-radius: inherit;
}
.metric.blue::before  { background: var(--blue-glow); }
.metric.green::before { background: var(--green-glow); }
.metric.red::before   { background: var(--red-glow); }
.metric:hover::before { opacity: 1; }

.metric-label {
  font-size: var(--fs-sm); font-weight: 600;
  text-transform: uppercase; letter-spacing: .07em;
  color: var(--muted); margin-bottom: 10px;
}
.metric-value {
  font-size: var(--fs-display); font-weight: 800; line-height: 1;
  color: var(--text);
}
.metric-value.pos { color: var(--green); }
.metric-value.neg { color: var(--red); }
.metric-value.blue { color: var(--blue); }
.metric-sub {
  font-size: var(--fs-sm); color: var(--muted); margin-top: 6px;
}
.metric-accent {
  position: absolute; right: 18px; top: 18px;
  font-size: var(--fs-hero); opacity: .08;
}

/* ─── Панель фильтров ───────────────────────────────────────────
   Один прямоугольник вместо россыпи кнопок. Раньше период, календарь,
   «Обновить», охват, тумблер вложенного и цена смолы лежали в общем
   flex-wrap с тремя `margin-left: auto`: строка ломалась там, где
   придётся, и на каждой ширине экрана по-своему — читалось как случайно
   рассыпанные элементы.

   Теперь у панели постоянный смысл по строкам: сверху «когда» (период и
   его календарь), снизу «по каким числам» (охват, что считаем вложенным,
   цена смолы). У каждой группы подпись, поэтому не нужно догадываться,
   что означает пара кнопок без заголовка. */
.filters {
  display: flex;
  flex-direction: column;
  margin-bottom: var(--block-gap);
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: var(--surface);
}
.filters__row {
  display: flex; align-items: center; flex-wrap: wrap;
  gap: 8px 16px;
  padding: 9px 12px;
}
.filters__row + .filters__row { border-top: 1px solid var(--border); }
/* Группа — подпись и её орган управления: они не должны разъезжаться при
   переносе строки. */
.filters__group { display: inline-flex; align-items: center; gap: 8px; min-width: 0; }
.filters__group--end { margin-left: auto; }
.filters__label {
  font-size: var(--fs-xs); font-weight: 700; letter-spacing: .08em;
  text-transform: uppercase; color: var(--dim); white-space: nowrap;
}
.filters__note { font-size: var(--fs-xs); color: var(--dim); white-space: nowrap; }

/* Сегментированный переключатель: выбор из ряда — одна деталь с общей
   рамкой, а не пять отдельных пилюль с зазорами между ними. */
.seg {
  display: inline-flex; align-items: center; gap: 2px;
  padding: 3px; border-radius: var(--r-pill);
  background: var(--surface2); border: 1px solid var(--border);
}
.seg > .period-btn {
  border: 1px solid transparent; background: none; padding: 5px 12px;
}
.seg > .period-btn:hover { background: var(--surface3); border-color: transparent; }
.seg > .period-btn.active { background: var(--blue); color: #fff; border-color: transparent; }

/* ─── Выбор периода ─────────────────────────────────────────── */
.period-bar {
  display: flex; align-items: center; gap: 6px; margin-bottom: 18px; flex-wrap: wrap;
}
.period-btn {
  display: inline-flex; align-items: center; justify-content: center;
  line-height: 1;
  padding: 6px 14px; border-radius: var(--r-pill); font-size: var(--fs-base); font-weight: 600;
  border: 1px solid var(--border); background: var(--surface2);
  color: var(--muted); text-decoration: none;
  transition: background .15s, color .15s, border-color .15s;
}
.period-btn:hover { background: var(--surface3); color: var(--text); border-color: var(--border2); }
.period-btn.active { background: var(--blue); color: #fff; border-color: transparent; }
/* «Обновить» — та же кнопка, но не выбор периода: отодвинута от него (в
   панели это делает .filters__group--end) и со значком. Переехала сюда из
   шапки, где отбирала место у списка вкладок. */
.period-btn--refresh { gap: 7px; }
/* `.period-note` здесь больше нет: период карточки товара теперь выбирают, а
   не читают, и его границы показывает `.filters__note` в самой панели. */

/* Календарь произвольного периода */
.period-calendar {
  display: inline-flex; align-items: center; gap: 6px;
  padding: 4px 8px; border-radius: var(--r-pill);
  border: 1px solid var(--border); background: var(--surface2);
}
.period-calendar.active { border-color: var(--blue); }
.period-calendar span { color: var(--muted); }
.period-calendar input[type="date"] {
  background: var(--surface); border: 1px solid var(--border); border-radius: var(--r-sm);
  color: var(--text); font-size: var(--fs-base); padding: 3px 6px;
  color-scheme: dark;
}
.period-calendar button {
  padding: 4px 12px; border-radius: var(--r-pill); border: none; cursor: pointer;
  background: var(--blue); color: #fff; font-size: var(--fs-base); font-weight: 600;
}

/* ─── Панель поиска/фильтра ──────────────────────────────────── */
.toolbar {
  display: flex; gap: 10px; align-items: center;
  margin-bottom: 16px; flex-wrap: wrap;
}
.search-box {
  position: relative; flex: 1; min-width: 220px; max-width: 340px;
}
.search-box input {
  width: 100%; padding: 8px 12px 8px 34px;
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-sm); color: var(--text); font: inherit; font-size: var(--fs-h3);
  transition: border-color .15s;
}
.search-box input:focus { outline: none; border-color: var(--blue); }
.search-box svg { position: absolute; left: 10px; top: 50%; transform: translateY(-50%); color: var(--muted); }
.filter-select {
  padding: 8px 12px; background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-sm); color: var(--text); font: inherit; font-size: var(--fs-h3);
  cursor: pointer;
}
.filter-select:focus { outline: none; border-color: var(--blue); }
.toolbar-count { font-size: var(--fs-base); color: var(--muted); margin-left: auto; }

/* ─── Таблица ────────────────────────────────────────────────── */
/* Обёртки, которые сами прокручиваются, забирают шапку себе: липнуть через
   них к меню нельзя — sticky считается от ближайшего прокручиваемого предка,
   а не от окна. Внутри коробки это и не нужно: её верхний край и так на
   виду. Любая новая прокручиваемая обёртка вокруг таблицы должна объявить
   `--thead-top: 0px` — иначе шапка уедет вверх вместе со строками. */
.table-wrap,
.table-outer { --thead-top: 0px; }

.table-wrap {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  overflow: auto;
  max-height: calc(100vh - 280px);
}

/* Вид полосы прокрутки общий для всего приложения и задаётся в
   chrome-tokens.css. Здесь остаётся только геометрия таблиц. */

/* Контейнер для таблицы продаж */
.table-outer {
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  overflow: auto;
  max-height: calc(100vh - 220px);
}
.sales-table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--fs-h3); }
.sales-table thead th {
  padding: 11px 12px;
  background: var(--surface2);
  color: var(--muted); font-size: var(--fs-sm); font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  text-align: right; white-space: nowrap;
  border-bottom: 2px solid var(--border2);
  position: sticky; top: var(--thead-top); z-index: 20;
}
.sales-table thead th.l { text-align: left; }
.sales-table tbody td {
  padding: 11px 12px;
  text-align: right; white-space: nowrap;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
.sales-table tbody td.l { text-align: left; }
.sales-table tbody tr:last-child td { border-bottom: none; }

/* Строки-детали */
tr.month-detail { transition: background .12s; }
tr.month-detail:hover td { background: var(--surface2); }
tr.month-detail.loss td { background: rgba(244,63,94,.05); }
tr.month-detail.loss:hover td { background: rgba(244,63,94,.10); }
tr.row-hidden { display: none; }

/* Итоговые строки месяца */
tr.month-subtotal { cursor: pointer; }
tr.month-subtotal td {
  background: var(--surface2);
  border-top: 2px solid var(--border2);
  border-bottom: 2px solid var(--border2);
  font-weight: 700; color: var(--text);
}
tr.month-subtotal:hover td { background: var(--surface3); }
tr.month-subtotal:first-child td { border-top: none; }

/* ─── Артикул: клик копирует ────────────────────────────────────────────
   Поведение общее для всех вкладок (static/copy-id.js), поэтому и вид
   один: пунктир снизу как обещание «с этим можно что-то сделать», курсор
   copy, подтверждение всплывает у самого курсора. */
.copy-id {
  cursor: copy; border-bottom: 1px dashed var(--border2);
  transition: color .15s, border-color .15s;
}
.copy-id:hover { color: var(--blue); border-bottom-color: var(--blue); }

.copy-flash {
  position: fixed; z-index: 200; transform: translate(-50%, -160%);
  padding: 5px 10px; border-radius: var(--r-sm);
  background: var(--surface3); border: 1px solid var(--blue);
  color: var(--text); font-size: var(--fs-sm); white-space: nowrap;
  box-shadow: var(--shadow); pointer-events: none;
  opacity: 0; transition: opacity .12s;
}
.copy-flash.is-on { opacity: 1; }
.copy-flash--bad { border-color: var(--red); color: var(--red); }

/* Иконка сворачивания */
.toggle-icon {
  display: inline-block;
  font-size: var(--fs-xs); color: var(--muted);
  margin-right: 6px;
  transition: transform .18s;
  user-select: none;
}
.toggle-icon.collapsed { transform: rotate(-90deg); }
/* Замок вместо стрелки: закрытый подпиской месяц разворачивать нечем —
   продажи внутри него на страницу не приезжают вовсе. */
.toggle-icon--lock { font-size: var(--fs-sm); opacity: .8; }
.month-subtotal.locked-row { cursor: default; }

table { width: 100%; border-collapse: separate; border-spacing: 0; font-size: var(--fs-h3); table-layout: fixed; }
/* Фиксированная ширина столбца Товар в главной таблице */
#t th:first-child, #t td:first-child { width: 220px; min-width: 220px; max-width: 220px; }
/* Шестнадцать столбцов на 1200px — это 65px на каждый: боковые поля по 12px
   съедали треть клетки, «КОМИССИЯ» переносилась посреди слова, а суммы вроде
   −182 965 ₽ наезжали на соседа. Поля ужимаем, а таблице даём минимальную
   ширину — она и так лежит в прокручиваемой обёртке (.table-outer), и лучше
   пролистать её вбок, чем читать «ОБР. ЛО» и обрубленные числа. */
#t { min-width: 1330px; }
#t th, #t td { padding-left: 6px; padding-right: 6px; }
#t thead th { letter-spacing: .02em; }

/* Шапка переносится по словам, а не обрезается: столбцы фиксированной ширины
   (table-layout: fixed), и длинные названия — «Обр. логистика», «Чистая
   прибыль» — при nowrap показывались огрызками вроде «ОБР. ЛО». Числа в
   ячейках по-прежнему в одну строку. */
thead th {
  padding: 11px 12px;
  background: var(--surface2);
  color: var(--muted); font-size: var(--fs-xs); font-weight: 700;
  text-transform: uppercase; letter-spacing: .06em;
  /* Переносим только по пробелам: разрыв посреди слова давал «ПОСЛЕДНЯ / Я
     ПРОДАЖА». Слову, которое не влезает целиком, даёт место min-width таблицы. */
  text-align: right; white-space: normal; overflow-wrap: normal;
  line-height: 1.3; vertical-align: bottom;
  border-bottom: 1px solid var(--border);
  cursor: pointer; user-select: none;
  position: sticky; top: var(--thead-top); z-index: 20;
}
thead th.l { text-align: left; }
thead th:hover { color: var(--text); }
thead th.sort-asc::after  { content: " ↑"; color: var(--blue); }
thead th.sort-desc::after { content: " ↓"; color: var(--blue); }

tbody td {
  padding: 11px 12px;
  text-align: right; white-space: nowrap;
  border-bottom: 1px solid var(--border);
  vertical-align: middle;
}
tbody td.l { text-align: left; }

tbody tr { transition: background .12s; cursor: pointer; }
tbody tr:hover td { background: var(--surface2); }
tbody tr:last-child td { border-bottom: none; }
tbody tr.loss td { background: rgba(244,63,94,.05); }
tbody tr.loss:hover td { background: rgba(244,63,94,.10); }

/* Строка, себестоимость которой только что сохранилась. Перезагрузка возвращает
   на то же место, и без отметки непонятно, применилось ли что-нибудь. Гаснет
   сама, анимацией, — таймер на снятие класса тут был бы лишней деталью. */
tbody tr.is-saved td { animation: saved-flash 2.5s ease-out; }
@keyframes saved-flash {
  from { background: rgba(16, 185, 129, .22); }
  to   { background: transparent; }
}
@media (prefers-reduced-motion: reduce) {
  tbody tr.is-saved td { animation: none; background: rgba(16, 185, 129, .12); }
}

tbody tr.month-subtotal td {
  background: var(--surface2);
  border-top: 2px solid var(--border2);
  border-bottom: 2px solid var(--border);
  font-weight: 700;
}
tbody tr.month-subtotal td:first-child { color: var(--text); }
tbody tr.month-subtotal:hover td { background: var(--surface2); }

.product-name {
  font-weight: 600; color: var(--text); display: block; max-width: 340px;
  overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}
/* Артикул слева, поле себестоимости — прижато вправо. Пока поле просто шло
   за артикулом, оно стояло на своём месте в каждой строке: артикулы разной
   длины, и колонка «себес» получалась рваной. */
.product-meta {
  display: flex; align-items: center; gap: 8px;
  font-size: var(--fs-sm); color: var(--muted); margin-top: 2px;
}
/* Артикул уступает место полю, а не выдавливает его из колонки: цифры не
   переносятся, и без min-width: 0 длинный артикул тащил поле за край. */
.product-offer {
  min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
}

/* Запасной маски на CSS здесь больше нет. Она красила текст прозрачным и
   рисовала поверх безномерное «Товар», то есть поверх подмены из
   privacy-mode.js: в таблице «Анализа» все строки становились одинаковыми, а
   «Товар 7» из соседних блоков не с чем было сопоставить. Прятать название
   осталось одному месту — скрипту, он же держит нумерацию. */

/* Себестоимость правится прямо в строке списка: поле маленькое и тихое,
   пока в него не целятся. Клик по нему не должен открывать карточку —
   это снимает onclick в шаблоне. */
.cost-inline { display: inline-flex; align-items: center; gap: 4px; margin-left: auto; flex: none; }
.cost-inline-input {
  width: 58px; padding: 2px 6px;
  border: 1px solid transparent; border-radius: var(--r-sm);
  background: var(--surface2); color: var(--text);
  font: inherit; font-size: var(--fs-sm); text-align: right;
  outline: none; transition: border-color .15s, background .15s;
}
.cost-inline-input::placeholder { color: var(--dim); }
.cost-inline-unit { color: var(--dim); font-size: var(--fs-xs); }
.cost-inline-input:hover { border-color: var(--border); }
.cost-inline-input:focus { border-color: var(--blue); background: var(--surface3); }
.cost-inline-save {
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface2); color: var(--muted);
  font-size: var(--fs-sm); line-height: 1; padding: 3px 6px; cursor: pointer;
  opacity: 0; transition: opacity .15s, color .15s, border-color .15s;
}
.cost-inline:hover .cost-inline-save,
.cost-inline:focus-within .cost-inline-save { opacity: 1; }
.cost-inline-save:hover { color: var(--blue); border-color: var(--border2); }
/* Пока сохранение летит на сервер. Поле не блокируем — ответ приходит быстрее,
   чем успеваешь набрать следующее число, а заблокированное поле сбрасывало бы
   курсор. Достаточно показать, что запрос в пути. */
.cost-inline.is-saving .cost-inline-input { border-color: var(--blue); opacity: .6; }

/* Цветные значения */
.pos  { color: var(--green); }
.neg  { color: var(--red);   }
.muted-val { color: var(--muted); }

/* Бейдж маржи */
.badge {
  display: inline-block; padding: 2px 8px; border-radius: var(--r-pill);
  font-size: var(--fs-base); font-weight: 700;
}
.badge.pos { background: var(--green-glow); color: var(--green); border: 1px solid rgba(16,185,129,.25); }
.badge.neg { background: var(--red-glow);   color: var(--red);   border: 1px solid rgba(244,63,94,.25); }

/* Дельта комиссии */
.delta { font-size: var(--fs-sm); margin-left: 4px; }

/* Итоговая строка */
tfoot td {
  padding: 11px 12px; text-align: right; white-space: nowrap;
  background: var(--surface2);
  border-top: 2px solid var(--border2);
  font-weight: 700; color: var(--text);
}
tfoot td.l { text-align: left; }

/* ─── Карточка товара ─────────────────────────────────────────── */
.back-link {
  display: inline-flex; align-items: center; gap: 6px;
  font-size: var(--fs-h3); color: var(--muted); margin-bottom: 20px;
  transition: color .15s;
}
.back-link:hover { color: var(--text); }

.product-hero {
  background: linear-gradient(135deg, var(--surface) 0%, var(--surface2) 100%);
  border: 1px solid var(--border);
  border-radius: var(--r-xl);
  padding: 28px 32px;
  margin-bottom: 20px;
  display: flex; justify-content: space-between; align-items: flex-start; gap: 32px;
  flex-wrap: wrap;
}
.hero-name { font-size: var(--fs-hero); font-weight: 700; line-height: 1.3; max-width: 680px; }
/* Переименование — у самого названия, а не отдельной формой внизу страницы. */
.hero-name-row { display: flex; align-items: center; gap: 10px; }
.hero-rename {
  flex: none; display: inline-flex; padding: 5px;
  border: 1px solid var(--border); border-radius: var(--r-sm);
  background: var(--surface2); color: var(--muted);
  cursor: pointer; opacity: .55;
  transition: opacity .15s, color .15s, border-color .15s;
}
.hero-name-row:hover .hero-rename { opacity: 1; }
.hero-rename:hover { color: var(--blue); border-color: var(--border2); }
.hero-rename-form { display: flex; gap: 8px; align-items: center; flex-wrap: wrap; }
/* display у классов перебивает браузерное [hidden] — возвращаем ему силу. */
.hero-name-row[hidden], .hero-rename-form[hidden] { display: none; }
.hero-rename-form input[name="name"] {
  min-width: 280px; padding: 7px 11px;
  border: 1px solid var(--border2); border-radius: var(--r-sm);
  background: var(--surface2); color: var(--text);
  font: inherit; font-size: var(--fs-h2); font-weight: 700; outline: none;
}
.hero-rename-form input[name="name"]:focus { border-color: var(--blue); }
.hero-meta { font-size: var(--fs-base); color: var(--muted); margin-top: 8px; }
.hero-stats { display: flex; gap: 24px; flex-shrink: 0; align-items: flex-start; }
.hero-stat { text-align: right; }
.hero-stat-label { font-size: var(--fs-sm); color: var(--muted); text-transform: uppercase; letter-spacing: .07em; }
.hero-stat-value { font-size: var(--fs-display); font-weight: 800; line-height: 1.1; margin-top: 4px; }

/* Воронка */
.funnel {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px;
  margin: 16px 0;
}
.funnel-step {
  background: var(--surface2); border: 1px solid var(--border);
  border-radius: var(--r-sm); padding: 12px 16px;
  min-width: 130px;
}
.funnel-step.accent {
  background: linear-gradient(135deg, rgba(59,130,246,.15), var(--surface2));
  border-color: rgba(59,130,246,.3);
}
.funnel-step.result {
  background: linear-gradient(135deg, rgba(16,185,129,.15), var(--surface2));
  border-color: rgba(16,185,129,.3);
}
.funnel-step.result.bad {
  background: linear-gradient(135deg, rgba(244,63,94,.12), var(--surface2));
  border-color: rgba(244,63,94,.3);
}
.funnel-label { font-size: var(--fs-sm); color: var(--muted); margin-bottom: 5px; }
.funnel-value { font-size: var(--fs-lead); font-weight: 700; }
.funnel-op { color: var(--dim); font-size: var(--fs-lead); font-weight: 300; flex-shrink: 0; }

/* Панели */
.panel {
  background: var(--surface); border: 1px solid var(--border);
  border-radius: var(--r-card); padding: var(--panel-pad); margin-bottom: var(--block-gap);
}
.panel-title { font-size: var(--fs-h2); font-weight: 700; margin-bottom: 16px; color: var(--text); }

/* Форма себестоимости */
.cost-form {
  display: flex; gap: 10px; align-items: flex-end; flex-wrap: wrap; margin-top: 16px;
}
.cost-form label { font-size: var(--fs-base); color: var(--muted); display: block; margin-bottom: 5px; }
.cost-form input {
  padding: 8px 12px; background: var(--surface2); border: 1px solid var(--border);
  border-radius: var(--r-sm); color: var(--text); font: inherit; font-size: var(--fs-h3); width: 140px;
}
.cost-form input:focus { outline: none; border-color: var(--blue); }

.note { font-size: var(--fs-base); color: var(--muted); margin-top: 12px; line-height: 1.6; }
.note b { color: var(--text); }

/* ─── Утилиты ─────────────────────────────────────────────────── */
.monospace { font-family: "SF Mono", "Consolas", monospace; }

.resin-form {
  display: flex; gap: 8px; align-items: center; flex-wrap: wrap;
  margin-bottom: 16px;
  padding: 10px 12px;
  background: var(--surface);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
}
.resin-form.active { border-color: var(--blue); }
.resin-label { font-size: var(--fs-base); font-weight: 700; color: var(--text); }
.resin-form input[type="text"] {
  width: 120px; padding: 8px 10px;
  background: var(--surface2); border: 1px solid var(--border);
  border-radius: var(--r-sm); color: var(--text); font: inherit; font-size: var(--fs-h3);
}
.resin-form input[type="text"]:focus { outline: none; border-color: var(--blue); }
.resin-form button {
  padding: 8px 12px; border-radius: var(--r-sm); border: none; cursor: pointer;
  background: var(--blue); color: #fff; font-size: var(--fs-base); font-weight: 700;
}
.resin-note { font-size: var(--fs-base); color: var(--muted); }

/* Цена смолы — управляющий элемент панели фильтров, а не всплывающее окно.
   Раньше блок висел `position: fixed` в правом верхнем углу и на «Марже»
   ложился поверх карточки ROI, а на узком экране — поверх таблицы. Теперь
   он стоит в панели: то же место в глазах, но ничего не закрывает. */
.floating-resin {
  display: inline-flex; align-items: center; gap: 6px;
  min-width: 0;
}
.floating-resin input[type="text"] {
  width: 78px;
  min-width: 0;
  padding: 5px 9px;
  background: var(--surface2);
  border: 1px solid var(--border);
  border-radius: var(--r-sm);
  color: var(--text);
  font: inherit;
  font-size: var(--fs-base);
}
.floating-resin.active input[type="text"] { border-color: var(--blue); }
.floating-resin input[type="text"]:focus { outline: none; border-color: var(--blue); }
.floating-resin button {
  padding: 5px 12px;
  border: none;
  border-radius: var(--r-pill);
  cursor: pointer;
  background: var(--blue);
  color: #fff;
  font-size: var(--fs-sm);
  font-weight: 700;
}

/* На узком экране панель и так переносится — подсказка о том, что цена
   работает во всей аналитике, там только мешает. */
@media (max-width: 1100px) {
  .filters__group--end { margin-left: 0; }
  .floating-resin .filters__note { display: none; }
}


/* ═══ Неон: материал карточек, типографика, эффекты ═══════════
   Раньше это лежало отдельным файлом neon-theme.css поверх базы —
   дизайн один, файл теперь тоже один. Секция намеренно идёт последней:
   она перекрывает базовые правила выше. Логика (появление, count-up,
   spotlight) — в static/neon-theme.js, шапка — в static/topbar.css. */

/* Зерно — снимает пластиковость градиента. */
.fx-grain {
  position: fixed;
  inset: -50%;
  z-index: 0;
  pointer-events: none;
  opacity: .045;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='220' height='220'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='.85' numOctaves='3'/%3E%3C/filter%3E%3Crect width='220' height='220' filter='url(%23n)'/%3E%3C/svg%3E");
  animation: fx-grain-shift 6s steps(6) infinite;
}
@keyframes fx-grain-shift {
  0% { transform: translate(0, 0); }
  20% { transform: translate(-4%, 3%); }
  40% { transform: translate(3%, -4%); }
  60% { transform: translate(-3%, -3%); }
  80% { transform: translate(4%, 2%); }
  100% { transform: translate(0, 0); }
}
.page { position: relative; z-index: 2; }

.btn { padding: 7px 10px; font-size: var(--fs-xs); }

.page-title {
  text-transform: uppercase;
  letter-spacing: .04em;
  text-shadow: 0 0 14px rgba(56, 189, 248, .5), 0 0 40px rgba(56, 189, 248, .22);
}

/* ---------- карточки ---------- */
.metric,
.stat-card,
.table-card,
.summary,
.months-wrap {
  position: relative;
  border: 1px solid var(--border);
  border-radius: var(--r-card);
  background: linear-gradient(180deg, rgba(16, 24, 40, .9), rgba(10, 15, 28, .9));
  box-shadow: inset 0 0 24px rgba(56, 189, 248, .05);
  transform: translateY(var(--fx-ty, 0px)) scale(var(--fx-scale, 1));
  transition: transform .5s cubic-bezier(.16, 1, .3, 1), border-color .3s, box-shadow .35s;
}
.metric { --fx-light: var(--ozon-sky); overflow: hidden; }
.stat-card, .table-card, .summary, .months-wrap { --fx-light: var(--blue); }
.metric:hover,
.stat-card:hover {
  --fx-ty: -4px;
  --fx-scale: 1.008;
  border-color: var(--border2);
}

/* Угловые «скобки» — подпись Neon Grid. */
.metric::after,
.stat-card::after {
  content: "";
  position: absolute;
  inset: 5px;
  border: 1px solid var(--fx-light);
  border-radius: 6px;
  opacity: .16;
  transition: opacity .3s;
  pointer-events: none;
  clip-path: polygon(0 0, 22px 0, 22px 1px, 1px 1px, 1px 22px, 0 22px, 0 100%, 22px 100%, 22px calc(100% - 1px), 1px calc(100% - 1px), 1px calc(100% - 22px), 0 calc(100% - 22px));
}
.metric:hover::after,
.stat-card:hover::after { opacity: .34; }

/* Spotlight под курсором — координаты ставит neon-theme.js. */
.metric::before,
.stat-card::before,
.table-card::before {
  content: "";
  position: absolute;
  inset: 0;
  z-index: 0;
  border-radius: inherit;
  pointer-events: none;
  opacity: 0;
  transition: opacity .3s;
  background:
    radial-gradient(260px circle at var(--fx-mx, 50%) var(--fx-my, 50%),
      color-mix(in srgb, var(--fx-light) 26%, transparent), transparent 62%),
    radial-gradient(700px circle at var(--fx-mx, 50%) var(--fx-my, 50%),
      color-mix(in srgb, var(--fx-light) 12%, transparent), transparent 75%);
}
.metric:hover::before,
.stat-card:hover::before { opacity: 1; }
.table-card:hover::before { opacity: .5; }
.metric > *, .stat-card > * { position: relative; z-index: 1; }

/* Рейка канала и светящаяся кромка — их вставляет neon-theme.js. */
.fx-rail {
  position: absolute;
  left: 0;
  top: 0;
  bottom: 0;
  width: 2px;
  background: linear-gradient(180deg, var(--fx-light), transparent);
  opacity: .5;
  pointer-events: none;
}
.metric:hover > .fx-rail { opacity: 1; }
.fx-edge {
  position: absolute;
  left: 0;
  right: 0;
  top: 0;
  height: 2px;
  z-index: 2;
  border-radius: inherit;
  pointer-events: none;
  overflow: hidden;
  background: linear-gradient(90deg,
    transparent 0%,
    color-mix(in srgb, var(--fx-light) 30%, transparent) 38%,
    var(--fx-light) 50%,
    color-mix(in srgb, var(--fx-light) 30%, transparent) 62%,
    transparent 100%);
  background-size: 260% 100%;
  background-repeat: no-repeat;
  background-position: 150% 0;
  filter: drop-shadow(0 0 6px var(--fx-light));
  opacity: 0;
  transition: opacity .2s;
}
.metric:hover > .fx-edge,
.stat-card:hover > .fx-edge,
.table-card:hover > .fx-edge {
  opacity: 1;
  animation: fx-sheen 1.2s cubic-bezier(.22, .61, .36, 1) both;
}
@keyframes fx-sheen {
  from { background-position: 150% 0; }
  to { background-position: -50% 0; }
}

/* ---------- типографика ---------- */
.metric-label,
.stat-label,
.bd-label {
  font-size: var(--fs-xs);
  font-weight: 600;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--muted);
}
.metric-value,
.stat-value {
  font-size: var(--fs-display);
  font-weight: 700;
  letter-spacing: -.02em;
  font-variant-numeric: tabular-nums;
  text-shadow: 0 0 22px color-mix(in srgb, currentColor 40%, transparent);
}
.metric-sub, .stat-sub { font-size: var(--fs-xs); color: var(--dim); }
.bd-val, td, th { font-variant-numeric: tabular-nums; }

/* ---------- таблицы ---------- */
/* Шапка липнет у всех таблиц — иначе на длинном списке пролистал десяток
   строк и уже не помнишь, что за число в шестом столбце. Место парковки —
   `--thead-top` (chrome-tokens.css): по умолчанию низ меню, внутри
   прокручиваемой коробки — её собственный край. */
table thead th,
.months-table thead th,
.wb-table thead th {
  position: sticky;
  top: var(--thead-top);
  z-index: 3;
  background: rgba(9, 14, 26, .92);
  backdrop-filter: blur(8px);
  border-bottom: 1px solid var(--border2);
  text-transform: uppercase;
  letter-spacing: .1em;
  font-size: var(--fs-xs);
  color: var(--muted);
}
tbody tr {
  transition: background .12s, color .12s;
}
tbody tr:hover td,
.months-table tbody tr:hover td {
  background: linear-gradient(90deg, rgba(56, 189, 248, .09), rgba(56, 189, 248, .015));
  color: #eaf9ff;
}

/* Строки выезжают по одной при появлении — класс ставит neon-theme.js. */
.fx-row {
  opacity: 0;
  transform: translateX(-12px);
  transition: opacity .5s cubic-bezier(.16, 1, .3, 1), transform .5s cubic-bezier(.16, 1, .3, 1),
    background .12s, color .12s;
}
.fx-row.fx-in { opacity: 1; transform: none; }

/* ---------- кнопки и бейджи ---------- */
.btn {
  border-radius: var(--r-sm);
  letter-spacing: .06em;
  text-transform: uppercase;
  font-size: var(--fs-sm);
  transition: border-color .2s, color .2s, background .2s, transform .2s;
}
.btn:hover { border-color: var(--border2); color: var(--blue); transform: translateY(-1px); }
.view-btn, .boost-badge {
  border-radius: var(--r-sm);
  font-variant-numeric: tabular-nums;
}

/* ---------- появление блоков ---------- */
.fx-reveal {
  opacity: 0;
  --fx-ty: 18px;
  --fx-scale: .99;
  transition: opacity .7s cubic-bezier(.16, 1, .3, 1), transform .7s cubic-bezier(.16, 1, .3, 1);
}
.fx-reveal.fx-in { opacity: 1; --fx-ty: 0px; --fx-scale: 1; }

@media (prefers-reduced-motion: reduce) {
  .fx-grain { display: none; }
  .fx-reveal, .fx-row { opacity: 1; transform: none; transition: none; }
  .metric, .stat-card { transition: none; }
  .fx-edge { animation: none; }
}

/* ─── Фокус с клавиатуры ─────────────────────────────────────
   Поля выше гасят outline у :focus, чтобы рамка не вспыхивала от клика мышью.
   Заодно пропадал и фокус при обходе табом: по странице нельзя было
   ориентироваться с клавиатуры вообще. :focus-visible браузер ставит только
   при клавиатурной навигации — кольцо видит тот, кому оно нужно, и не видит
   тот, кто кликает.

   !important тут намеренно: правило должно пережить любое `:focus { outline:
   none }` в CSS отдельных вкладок. Иначе фокус пропадёт снова — и незаметно
   для того, кто правил только свою страницу. */
:focus-visible {
  outline: 2px solid var(--blue) !important;
  outline-offset: 2px;
}
