:root {
    --color-bg: #f4f5f7;
    --color-surface: #ffffff;
    --color-text: #1f2430;
    --color-muted: #6b7280;
    --color-accent: #2563eb;
    --color-accent-soft: #eef2ff;
    --color-error: #dc2626;
    --color-error-soft: #fee2e2;
    --color-ok: #16a34a;
    --color-ok-soft: #dcfce7;
    --color-warn: #b45309;
    --color-warn-soft: #fef3c7;
    --color-return: #9333ea;
    --color-return-soft: #f3e8ff;
    --color-ads-cpc: #0891b2;
    --color-ads-cpo: #d97706;
    --color-border: #e5e7eb;
    --color-border-strong: #d1d5db;
    --color-on-accent: #ffffff;
    --radius: 8px;
    --font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Arial, sans-serif;
}

* { box-sizing: border-box; }

body {
    margin: 0;
    font-family: var(--font-sans);
    background: var(--color-bg);
    color: var(--color-text);
}

[x-cloak] { display: none !important; }

a { color: var(--color-accent); text-decoration: none; }
a:hover { text-decoration: underline; }

/* ---- Шапка ---- */
.topnav {
    position: sticky;
    top: 0;
    z-index: 50;
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    /* Раньше 12px 24px — над этим ещё была отдельная строка topnav__brand ("Мой кабинет"),
       из-за неё шапка была в два ряда. Плашку убрали (решение пользователя 2026-08-26:
       "убери саму плашку строку сузь в высоту"), а вертикальный паддинг заодно сжали — шапка
       теперь один невысокий ряд, больше места под полезный контент ниже. */
    padding: 8px 24px;
    background: var(--color-surface);
    border-bottom: 1px solid var(--color-border);
}

.topnav__center {
    display: flex;
    gap: 4px;
    flex-wrap: wrap;
    justify-content: center;
    flex: 1;
}

.topnav__tab {
    padding: 8px 12px;
    border-radius: var(--radius);
    color: var(--color-muted);
    font-size: 14px;
    white-space: nowrap;
}
.topnav__tab:hover { background: var(--color-bg); text-decoration: none; }
/* Активная вкладка — тот же глянцевый "пластиковый" стиль, что у пилюль на плашках главной
   (решение пользователя 2026-08-19 "в том же стиле сделай"): радиальный градиент, двойной
   bevel, приподнимающая тень — а не плоская заливка var(--color-accent-soft), как было. */
.topnav__tab--active {
    color: #fff;
    background: radial-gradient(120% 170% at 30% -30%, #9dc2fb 0%, var(--color-accent) 55%, #1d4faf 100%);
    font-weight: 700;
    border-radius: 999px;
    text-shadow: 0 1px 1.5px rgba(0, 0, 0, 0.35);
    box-shadow:
        inset 0 1.5px 0 rgba(255, 255, 255, 0.7),
        inset 0 -4px 6px rgba(0, 0, 0, 0.3),
        0 1px 1px rgba(0, 0, 0, 0.2),
        0 4px 8px -2px rgba(0, 0, 0, 0.3);
}

.topnav__right {
    display: flex;
    align-items: center;
    gap: 12px;
    position: relative;
}

.topnav__gear { font-size: 14px; color: var(--color-muted); white-space: nowrap; }

.topnav__user {
    position: relative;
    cursor: pointer;
    padding: 6px 10px;
    border-radius: var(--radius);
    font-size: 14px;
}
.topnav__user:hover { background: var(--color-bg); }

.topnav__menu {
    position: absolute;
    right: 0;
    top: calc(100% + 4px);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 4px 12px rgba(0,0,0,0.08);
    min-width: 160px;
    padding: 4px;
    display: flex;
    flex-direction: column;
}
.topnav__menu a, .topnav__menu-logout {
    padding: 8px 10px;
    border-radius: 6px;
    color: var(--color-text);
    text-align: left;
    background: none;
    border: none;
    font-size: 14px;
    font-family: inherit;
    cursor: pointer;
}
.topnav__menu a:hover, .topnav__menu-logout:hover { background: var(--color-bg); text-decoration: none; }

/* ---- Контент ---- */
.page { max-width: 1200px; margin: 0 auto; padding: 24px; }

.stub { text-align: center; padding: 80px 20px; color: var(--color-muted); }
.stub h1 { color: var(--color-text); }

/* ---- Форма входа ---- */
.login-wrap {
    min-height: 100vh;
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 20px;
}
.login-form {
    background: var(--color-surface);
    border-radius: var(--radius);
    padding: 32px;
    width: 100%;
    max-width: 360px;
    box-shadow: 0 4px 20px rgba(0,0,0,0.06);
    display: flex;
    flex-direction: column;
    gap: 14px;
}
.login-form__title { margin: 0 0 8px; text-align: center; font-size: 20px; }

.field { display: flex; flex-direction: column; gap: 6px; font-size: 14px; color: var(--color-muted); }
.field input {
    padding: 10px 12px;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius);
    font-size: 14px;
    font-family: inherit;
    color: var(--color-text);
}
.field input:focus { outline: 2px solid var(--color-accent); outline-offset: 1px; }

.btn {
    padding: 10px 16px;
    border-radius: var(--radius);
    border: 1px solid transparent;
    font-size: 14px;
    font-family: inherit;
    cursor: pointer;
}
.btn--primary { background: var(--color-accent); color: var(--color-on-accent); }
.btn--primary:hover { opacity: 0.92; }
.btn--block { width: 100%; }

.alert { padding: 10px 12px; border-radius: var(--radius); font-size: 14px; }
.alert--error { background: var(--color-error-soft); color: var(--color-error); }
.alert--ok { background: var(--color-ok-soft); color: var(--color-ok); }
.alert--warn { background: var(--color-warn-soft); color: var(--color-warn); }

/* ---- Тосты ---- */
.toast-container {
    position: fixed;
    bottom: 20px;
    right: 20px;
    display: flex;
    flex-direction: column;
    gap: 8px;
    z-index: 100;
}
.toast {
    background: var(--color-text);
    color: var(--color-on-accent);
    padding: 12px 16px;
    border-radius: var(--radius);
    max-width: 320px;
    font-size: 14px;
    box-shadow: 0 4px 12px rgba(0,0,0,0.15);
}
.toast--error { background: var(--color-error); }

/* ---- Настройки ---- */
.settings { display: flex; flex-direction: column; gap: 20px; max-width: 560px; margin: 0 auto; }
.card {
    background: var(--color-surface);
    border-radius: var(--radius);
    padding: 20px 24px;
    box-shadow: 0 1px 4px rgba(0,0,0,0.05);
}
.card h2 { margin-top: 0; font-size: 16px; }
.settings-form { display: flex; flex-direction: column; gap: 12px; margin-top: 12px; }
.muted { color: var(--color-muted); font-size: 13px; }
.btn:not(.btn--primary) { background: var(--color-bg); color: var(--color-text); border: 1px solid var(--color-border-strong); }
.btn:not(.btn--primary):hover { background: var(--color-border); }

/* ---- Себестоимость: плитки ---- */
.tiles {
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    gap: 12px;
    margin-bottom: 16px;
}
.tile {
    background: var(--color-surface);
    border-radius: var(--radius);
    padding: 16px;
    box-shadow: 0 1px 4px rgba(0,0,0,0.05);
    text-align: center;
    color: var(--color-text);
}
.tile__value { font-size: 24px; font-weight: 700; }
.tile__label { font-size: 13px; color: var(--color-muted); margin-top: 4px; }
.tile--warn { background: var(--color-warn-soft); }
.tile--warn .tile__value { color: var(--color-warn); }
.tile--link { text-decoration: none; cursor: pointer; }
.tile--link:hover { opacity: 0.9; text-decoration: none; }

/* ---- Главная: карточки-статистики (решение пользователя 2026-08-19 — полная замена
   прежнего объёмного "пластикового" стиля плашек .tile-group/.tile-pill на плоский
   современный, по присланному референсу: белая карточка, цветная иконка, бейдж тренда,
   мини-график снизу). Старые классы удалены целиком — .tile-group/.tile-pill в разметке
   больше нет нигде в проекте (использовались только в этом блоке home.html). */
.home-tiles {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(260px, 1fr));
    gap: 14px;
    margin-bottom: 16px;
}
.stat-card {
    background: var(--color-surface);
    border-radius: 16px;
    border: 1px solid var(--color-border);
    /* Отступы чуть шире (решение пользователя 2026-08-19, "в точности как на референсе") —
       было 18/14, на референсе карточка выглядит просторнее. */
    padding: 20px 20px 16px;
    box-shadow: 0 1px 2px rgba(15, 23, 42, 0.04), 0 8px 20px -14px rgba(15, 23, 42, 0.18);
    display: flex;
    flex-direction: column;
    min-width: 0;
    container-type: inline-size;
}
.stat-card__top { display: flex; align-items: flex-start; justify-content: space-between; gap: 8px; margin-bottom: 14px; }
.stat-card__icon {
    width: 40px; height: 40px; border-radius: 10px; flex: none;
    display: flex; align-items: center; justify-content: center;
    color: #fff;
}
.stat-card__icon svg { width: 20px; height: 20px; }
.stat-card__icon--accent { background: var(--color-accent); }
.stat-card__icon--warn { background: var(--color-warn); }
.stat-card__icon--return { background: var(--color-return); }
.stat-card__icon--ok { background: var(--color-ok); }
/* Бейдж тренда — стрелка направления (▲/▼ по знаку числа) + цвет "хорошо/плохо" по смыслу
   метрики (та же логика, что раньше решала цвет всей второй ячейки в старом дизайне).
   Компактнее, чем было (решение 2026-08-19: "в точности как на референсе" — там бейдж
   заметно плотнее). */
.stat-card__trend {
    /* Шрифт вдвое крупнее (решение пользователя 2026-08-19: "проценты на плашках увеличить
       вдвое") — было 12px, теперь 24px; паддинг/скругление пропорционально увеличены. */
    display: inline-flex; align-items: center; gap: 4px;
    padding: 4px 14px; border-radius: 999px;
    font-size: 24px; font-weight: 700; white-space: nowrap;
}
.stat-card__trend--ok { background: var(--color-ok-soft); color: var(--color-ok); }
.stat-card__trend--warn { background: var(--color-warn-soft); color: var(--color-warn); }
@container (max-width: 220px) { .stat-card__trend { font-size: 18px; padding: 3px 11px; } }
@container (max-width: 170px) { .stat-card__trend { font-size: 14px; padding: 2px 9px; } }

/* Колонка из двух бейджей — % выручки (крупный) сверху, % штук (мельче, приглушённее) под
   ним (решение пользователя 2026-08-26: "под плашкой сравнения в % ... штуки тоже показывал",
   карточка «Выручка» на главной). */
.stat-card__trends { display: flex; flex-direction: column; align-items: flex-end; gap: 4px; }
.stat-card__trend--sub {
    /* Нейтральная плашка (не ok/warn — это не сигнал "хорошо/плохо", а справочное число). */
    font-size: 13px; font-weight: 600; padding: 2px 10px;
    background: var(--color-bg); color: var(--color-muted);
}
@container (max-width: 220px) { .stat-card__trend--sub { font-size: 11px; padding: 2px 8px; } }
/* Часы вместо бейджа — там, где нет периода для сравнения (Остаток, Сегодня/Прогноз). */
.stat-card__clock { color: var(--color-muted); flex: none; padding-top: 2px; }
.stat-card__clock svg { width: 18px; height: 18px; }
.stat-card__title { font-size: 14.5px; font-weight: 500; color: var(--color-muted); margin-bottom: 6px; }
.stat-card__value {
    /* Крупнее и чуть легче по насыщенности (решение 2026-08-19) — было 24px/800, на
       референсе цифра заметно крупнее самого заголовка карточки, но не "жирный кирпич". */
    font-size: 27px; font-weight: 700; color: var(--color-text);
    white-space: nowrap; letter-spacing: -0.005em;
}
@container (max-width: 150px) { .stat-card__value { font-size: 21px; } }
@container (max-width: 120px) { .stat-card__value { font-size: 17px; } }
.stat-card__caption { font-size: 13px; color: var(--color-muted); margin-top: 4px; margin-bottom: auto; }
.stat-card__spark { display: block; width: 100%; height: 34px; margin-top: 10px; }
.stat-card__spark-bar { opacity: 0.85; }
/* Минимальная сетка у мини-графика (решение пользователя 2026-08-19: "числа надо, сетка но
   минимал") — 2 горизонтальные линии (макс/мин ряда) с короткими подписями слева, не полная
   ось как у большого графика ниже. */
.stat-card__spark-grid { stroke: var(--color-border); stroke-width: 1; }
.stat-card__spark-label { font-size: 7.5px; fill: var(--color-muted); }
/* Хит-зона и тултип мини-графика в карточке статистики (решение пользователя 2026-09-02) —
   тот же визуальный язык, что у .home-chart__tooltip ниже (тёмный фон, текст фона), но проще:
   без списка товаров внутри, просто дата + сумма. */
.stat-card__spark-hit { fill: transparent; cursor: pointer; }
.stat-card__spark-tooltip {
    position: fixed;
    background: var(--color-text);
    color: var(--color-bg);
    padding: 6px 10px;
    border-radius: 6px;
    font-size: 12px;
    line-height: 1.4;
    white-space: nowrap;
    pointer-events: none;
    z-index: 20;
}

/* ---- Плашка устаревшего каталога ---- */
.stale-banner {
    display: flex;
    align-items: center;
    gap: 8px;
    background: var(--color-warn-soft);
    color: var(--color-warn);
    padding: 10px 14px;
    border-radius: var(--radius);
    font-size: 14px;
    margin-bottom: 16px;
}

/* ---- Панель управления ---- */
.costs-toolbar { display: flex; justify-content: flex-end; margin-bottom: 12px; }
.costs-toolbar__sync { display: flex; align-items: center; gap: 10px; font-size: 13px; }

.costs-controls {
    display: flex;
    flex-wrap: wrap;
    gap: 10px;
    margin-bottom: 16px;
}
.costs-controls select, .costs-controls__search {
    padding: 8px 10px;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius);
    font-size: 14px;
    font-family: inherit;
    background: var(--color-surface);
    color: var(--color-text);
}
.costs-controls__search { flex: 1; min-width: 200px; }

/* ---- Таблица товаров ---- */
.costs-table-wrap { overflow-x: auto; }
.costs-table { width: 100%; border-collapse: collapse; background: var(--color-surface); border-radius: var(--radius); overflow: hidden; }
.costs-table th {
    text-align: left;
    font-size: 12px;
    text-transform: uppercase;
    color: var(--color-muted);
    padding: 10px 12px;
    border-bottom: 1px solid var(--color-border);
}
.costs-table td { padding: 10px 12px; border-bottom: 1px solid var(--color-border); vertical-align: middle; font-size: 14px; }
.costs-empty { text-align: center; color: var(--color-muted); padding: 30px; }

.costs-row--missing { border-left: 3px solid var(--color-error); }
.costs-row--archived { opacity: 0.55; }

.costs-row__thumb { width: 56px; height: 56px; object-fit: cover; border-radius: 6px; display: block; background: var(--color-border); }
.costs-row__thumb--placeholder { background: var(--color-border); }

.costs-row__chevron { background: none; border: none; cursor: pointer; color: var(--color-muted); margin-right: 4px; font-size: 12px; }

.costs-row__cost { cursor: pointer; border-bottom: 1px dashed var(--color-muted); }
.costs-row__cost:hover { color: var(--color-accent); }

.costs-row__edit-form { display: flex; gap: 6px; align-items: center; flex-wrap: wrap; }
.costs-row__input { padding: 6px 8px; border: 1px solid var(--color-border-strong); border-radius: 6px; font-size: 13px; width: 90px; font-family: inherit; }
.costs-row__input--date { width: 130px; }

.btn--small { padding: 5px 9px; font-size: 13px; }

.costs-row__history-wrap td { background: var(--color-bg); padding: 12px; }

/* ---- История цен ---- */
.history__table { width: 100%; border-collapse: collapse; font-size: 13px; }
.history__table th, .history__table td { padding: 6px 8px; text-align: left; }
.badge { padding: 2px 8px; border-radius: 999px; font-size: 11px; background: var(--color-border); color: var(--color-muted); }
.badge--ok { background: var(--color-ok-soft); color: var(--color-ok); }
.admin-actions { display: flex; gap: 6px; }

/* ---- Модалка импорта ---- */
.modal-backdrop {
    position: fixed;
    inset: 0;
    background: rgba(0,0,0,0.4);
    display: flex;
    align-items: flex-start;
    justify-content: center;
    padding: 40px 16px;
    z-index: 200;
    overflow-y: auto;
}
.modal {
    background: var(--color-surface);
    border-radius: var(--radius);
    padding: 24px;
    width: 100%;
    max-width: 640px;
}
.modal h2 { margin-top: 0; }
.import-preview__errors { max-height: 200px; overflow-y: auto; margin: 8px 0 0; padding-left: 20px; }

/* ---- Магазины в настройках ---- */
.settings__section-title { max-width: 560px; margin: 4px auto 0; font-size: 15px; color: var(--color-muted); }
.store-card { max-width: 560px; margin: 0 auto; }
.store-card--inactive { opacity: 0.6; }
.store-card__header { display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.store-card__header h3 { margin: 0; font-size: 15px; }
.store-card__actions { display: flex; gap: 8px; margin-top: 10px; }
.alert--warn-text { color: var(--color-warn); }

/* ---- Переключатель магазина в шапке ---- */
.store-switcher { position: relative; }
/* Тот же пластиковый стиль, что у плашек на главной (решение пользователя 2026-08-19 "в том
   же стиле сделай") — раньше это была голая браузерная кнопка без явного фона/тени (border
   в скриншоте — просто дефолтный вид <button>, не задумывался). Теперь настоящая объёмная
   капсула: градиентная база, двойной молдинг-край, многослойная тень. */
.store-switcher__button {
    display: flex;
    align-items: center;
    gap: 8px;
    cursor: pointer;
    font-weight: 700;
    font-size: 15px;
    font-family: inherit;
    color: var(--color-text);
    /* Раньше 6px 16px 6px 6px c логотипом 48px — вместе с отдельной строкой topnav__brand
       над этой пилюлей шапка выходила высокой в два ряда. Плашку убрали, а саму пилюлю заодно
       сжали (решение пользователя 2026-08-26: "сузь в высоту чтобы вмещалось больше полезной
       инфы") — логотип теперь 32px, паддинг ниже. */
    padding: 4px 14px 4px 4px;
    border-radius: 999px;
    background: linear-gradient(180deg, #ffffff 0%, #e2e5ea 100%);
    border: 1.5px solid rgba(255, 255, 255, 0.95);
    outline: 1.5px solid rgba(15, 23, 42, 0.16);
    outline-offset: -2px;
    box-shadow:
        0 2px 0 rgba(255, 255, 255, 0.9),
        0 10px 18px -8px rgba(15, 23, 42, 0.32),
        0 3px 7px rgba(15, 23, 42, 0.14),
        inset 0 1px 0 rgba(255, 255, 255, 0.95),
        inset 0 -6px 9px rgba(15, 23, 42, 0.08);
    transition: box-shadow 0.15s, transform 0.15s;
}
.store-switcher__button:hover {
    background: linear-gradient(180deg, #ffffff 0%, #d7dbe1 100%);
    transform: translateY(-1px);
}
.store-switcher__button:active { transform: translateY(0); }
.store-switcher__chevron { font-size: 11px; color: var(--color-muted); }
.store-switcher__logo {
    width: 32px;
    height: 32px;
    border-radius: 999px;
    object-fit: cover;
    vertical-align: middle;
    /* Логотип-медальон утоплен в капсулу — та же логика bevel, что у ячеек плашек. */
    box-shadow: inset 0 2px 4px rgba(15, 23, 42, 0.25), 0 0 0 2px rgba(255, 255, 255, 0.8);
}
.store-switcher__menu {
    position: absolute;
    left: 0;
    top: calc(100% + 4px);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 4px 12px rgba(0,0,0,0.08);
    min-width: 220px;
    padding: 4px;
    z-index: 60;
}
.store-switcher__item {
    display: block;
    width: 100%;
    text-align: left;
    padding: 8px 10px;
    border-radius: 6px;
    background: none;
    border: none;
    font-size: 14px;
    font-family: inherit;
    color: var(--color-text);
    cursor: pointer;
}
.store-switcher__item:hover { background: var(--color-bg); }
.store-switcher__item--active { color: var(--color-accent); font-weight: 600; }

/* ---- Финансы: реестр транзакций ---- */
.finance-subtabs { display: flex; gap: 4px; margin-bottom: 16px; border-bottom: 1px solid var(--color-border); }
.finance-subtabs__item {
    padding: 8px 14px;
    font-size: 14px;
    color: var(--color-muted);
    text-decoration: none;
    border-bottom: 2px solid transparent;
}
.finance-subtabs__item--active { color: var(--color-text); font-weight: 600; border-bottom-color: var(--color-accent); }
.finance-form { display: flex; flex-direction: column; gap: 10px; }
.finance-form label { display: flex; flex-direction: column; gap: 4px; font-size: 13px; color: var(--color-muted); }
.finance-form input, .finance-form select { font-family: inherit; font-size: 14px; padding: 8px 10px; border: 1px solid var(--color-border-strong); border-radius: var(--radius); }
.modal__actions { display: flex; gap: 8px; margin-top: 6px; }
.finance-row--income td:nth-child(4) { color: var(--color-ok); }
.finance-row--expense td:nth-child(4) { color: var(--color-error); }
.finance-negative { color: var(--color-error); font-weight: 600; }

/* ---- Главная: график заказов ---- */
.home-chart-legend { display: flex; gap: 18px; margin-bottom: 8px; font-size: 13px; color: var(--color-muted); }
.home-chart-legend__item { display: inline-flex; align-items: center; gap: 6px; }
.home-chart-legend__dot { width: 10px; height: 10px; border-radius: 50%; display: inline-block; }
.home-chart-legend__dot--orders { background: var(--color-accent); }
.home-chart-legend__dot--cancel { background: var(--color-error); }
.home-chart-legend__dot--return { background: var(--color-return); }
.home-chart-legend__dot--cpc { background: var(--color-ads-cpc); }
.home-chart-legend__dot--cpo { background: var(--color-ads-cpo); }

.home-chart-wrap {
    position: relative;
    background: var(--color-surface);
    border-radius: var(--radius);
    padding: 16px 24px;
    /* Растягиваем на всю ширину окна, вылезая за max-width:1200px у .page — иначе 30 дневных
       подписей (дата + день недели) друг на друге. */
    width: 100vw;
    margin-left: calc(50% - 50vw);
    box-sizing: border-box;
}
/* aspect-ratio вместо фиксированной height — так масштаб по X (px на день) у обоих графиков
   строго совпадает (оба = containerWidth / 1400, тот же viewBox width), а высота у каждого
   считается из его СОБСТВЕННОГО соотношения viewBox. Фиксированная height:300px для разных
   viewBox этого не гарантирует: при "meet" может добавиться масштаб по высоте, и даты на
   графиках визуально разъезжаются по X. Оба графика теперь одного размера (решение
   пользователя 2026-08-17: CHART_HEIGHT = ADS_CHART_HEIGHT в app/routers/home.py) — держать
   в синхроне: значение здесь должно совпадать с CHART_HEIGHT там. */
.home-chart { width: 100%; display: block; }
.home-chart--orders, .home-chart--ads { aspect-ratio: 1400 / 160; }
.home-chart__grid { stroke: var(--color-border); stroke-width: 1; }
.home-chart__axis-label { fill: var(--color-muted); font-size: 11px; }
.home-chart__axis-label--y { text-anchor: end; }
.home-chart__axis-label--x { text-anchor: middle; }
.home-chart__axis-label--weekend { fill: var(--color-warn); font-weight: 600; }
.home-chart__line { fill: none; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.home-chart__line--orders { stroke: var(--color-accent); }
.home-chart__dot { stroke: var(--color-surface); stroke-width: 1.5; cursor: pointer; transition: r 0.1s; }
.home-chart__dot--orders { fill: var(--color-accent); }
.home-chart__bar { cursor: pointer; transition: opacity 0.1s; }
.home-chart__bar--cancel { fill: var(--color-error); }
.home-chart__bar--return { fill: var(--color-return); }
.home-chart__bar--cpc { fill: var(--color-ads-cpc); }
.home-chart__bar--cpo { fill: var(--color-ads-cpo); }
.home-chart__bar--hover { opacity: 0.75; }
.home-chart__tooltip {
    position: absolute;
    background: var(--color-text);
    color: var(--color-bg);
    padding: 6px 10px;
    border-radius: 6px;
    font-size: 12px;
    line-height: 1.4;
    /* auto, не none: список возвратов/отмен внутри (.home-chart__tooltip-items) должен
       принимать курсор и колёсико мыши, иначе прокрутить его нельзя (решение пользователя
       2026-08-26 — "окошко скроллить не могу, оно исчезает"). Скрытие тултипа теперь на
       задержке через JS (см. templates/home.html), а не мгновенно по mouseleave. */
    pointer-events: auto;
    white-space: nowrap;
    z-index: 10;
}
.home-chart__tooltip-items {
    white-space: normal;
    margin-top: 6px;
    padding-top: 6px;
    border-top: 1px solid rgba(255, 255, 255, 0.25);
    max-width: 220px;
    max-height: 200px;
    overflow-y: auto;
}
.home-chart__tooltip-item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 3px 0;
}
.home-chart__tooltip-thumb {
    width: 24px;
    height: 24px;
    border-radius: 4px;
    object-fit: cover;
    flex: none;
    background: rgba(255, 255, 255, 0.15);
}
.home-chart__tooltip-thumb--placeholder { display: inline-block; }
.home-chart__tooltip-info {
    flex: 1 1 auto;
    min-width: 0;
    display: flex;
    flex-direction: column;
    gap: 1px;
}
.home-chart__tooltip-name {
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}
.home-chart__tooltip-reason {
    font-size: 11px;
    opacity: 0.7;
    overflow: hidden;
    text-overflow: ellipsis;
    display: -webkit-box;
    -webkit-line-clamp: 2;
    -webkit-box-orient: vertical;
}
.home-chart__tooltip-qty {
    flex: none;
    opacity: 0.85;
    white-space: nowrap;
}

.home-chart__updated-at {
    position: absolute;
    right: 24px;
    bottom: 8px;
    font-size: 11px;
    color: var(--color-muted);
    pointer-events: none;
}

/* ---- Мобильная адаптация ---- */
@media (max-width: 720px) {
    .topnav { flex-wrap: wrap; padding: 10px 12px; }
    .topnav__center { order: 3; width: 100%; justify-content: flex-start; overflow-x: auto; }
    .page { padding: 16px; }

    .tiles { grid-template-columns: repeat(2, 1fr); }
    .home-tiles { grid-template-columns: 1fr; }

    /* Таблица себестоимости -> карточки */
    .costs-table thead { display: none; }
    .costs-table, .costs-table tbody, .costs-table tr, .costs-table td { display: block; width: 100%; }
    .costs-table tr.costs-row {
        border: 1px solid var(--color-border);
        border-radius: var(--radius);
        margin-bottom: 10px;
        padding: 10px;
    }
    .costs-table tr.costs-row--missing { border-left: 3px solid var(--color-error); }
    .costs-table td { border-bottom: none; padding: 4px 0; }
    .costs-table td[data-label]::before {
        content: attr(data-label);
        display: block;
        font-size: 11px;
        text-transform: uppercase;
        color: var(--color-muted);
    }
    .costs-row__history-wrap { margin-bottom: 10px; }
    .costs-row__history-wrap td { background: var(--color-bg); border-radius: var(--radius); }
}

/* Лента продаж на главной (под графиком) — переиспользует .costs-table/.costs-row__thumb */
.home-feed__title { margin: 28px 0 12px; font-size: 16px; }
.home-feed__status {
    display: inline-block; padding: 2px 8px; border-radius: 999px; font-size: 12px; white-space: nowrap;
    background: var(--color-accent-soft); color: var(--color-accent);
}
.home-feed__status--delivered { background: var(--color-ok-soft); color: var(--color-ok); }
.home-feed__status--cancelled,
.home-feed__status--not_accepted { background: var(--color-error-soft); color: var(--color-error); }
.home-feed__status--awaiting_packaging,
.home-feed__status--awaiting_deliver,
.home-feed__status--arbitration,
.home-feed__status--client_arbitration { background: var(--color-warn-soft); color: var(--color-warn); }

.costs-row--day-sep td { padding: 0; border: none; }
.costs-row__day-sep {
    padding: 10px 12px 6px !important;
    font-size: 12px; font-weight: 600; color: var(--color-muted);
    background: var(--color-bg);
    border-bottom: 1px solid var(--color-border);
}

/* Сентинел-строка бесконечного скролла ленты продаж (решение пользователя 2026-08-26) —
   htmx подгружает следующую порцию, когда эта строка становится видна (hx-trigger="revealed"). */
.costs-row--sentinel td { border: none; }
.home-feed__loading, .home-feed__end {
    display: block; padding: 14px 0; text-align: center; font-size: 13px; color: var(--color-muted);
}


/* ---- Аналитика: тулбар, вкладки, сетка плиток ---- */
.an { display: flex; flex-direction: column; gap: 16px; }

.an-toolbar {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 16px;
    flex-wrap: wrap;
}
.an-toolbar__filters { display: flex; gap: 12px; flex-wrap: wrap; }

.an-tabs, .an-switch { display: flex; gap: 4px; }
.an-tabs__item, .an-switch__item {
    padding: 8px 14px;
    border-radius: 999px;
    font-size: 14px;
    color: var(--color-muted);
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    white-space: nowrap;
}
.an-tabs__item:hover, .an-switch__item:hover { text-decoration: none; background: var(--color-bg); }
.an-tabs__item--active, .an-switch__item--active {
    color: var(--color-on-accent);
    background: var(--color-accent);
    border-color: var(--color-accent);
    font-weight: 600;
}

/* Отдельная форма «свой период числом дней» убрана из тулбара (решение пользователя
   2026-08-27: "вот эти вкладки удали") — дублировала мини-календарь ниже. CSS-класс
   .an-period-form* больше нигде в шаблонах не используется, поэтому правила удалены отсюда же. */

/* Мини-календарь на 2 месяца (решение пользователя 2026-08-27: "период там должен выскакивать
   мини календарь 2 прошедших месяца где можно задать период"). Попап позиционируется от кнопки
   вправо, чтобы не вылезать за левый край тулбара; z-index выше сетки таблицы (та тоже имеет
   свой локальный stacking context из-за position:sticky на заголовке). */
.an-cal { position: relative; }
.an-cal__toggle {
    padding: 8px 14px;
    border-radius: 999px;
    border: 1px solid var(--color-border-strong);
    background: var(--color-surface);
    color: var(--color-muted);
    font-size: 14px;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
}
.an-cal__toggle:hover { background: var(--color-bg); }
.an-cal__toggle--active { border-color: var(--color-accent); color: var(--color-accent); font-weight: 600; }
.an-cal__pop {
    position: absolute;
    top: calc(100% + 8px);
    right: 0;
    z-index: 40;
    background: var(--color-surface);
    border: 1px solid var(--color-border-strong);
    border-radius: 12px;
    box-shadow: 0 12px 32px rgba(0, 0, 0, 0.18);
    padding: 14px;
    width: max-content;
}
.an-cal__months { display: flex; gap: 20px; }
.an-cal__month-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-size: 14px;
    font-weight: 600;
    margin-bottom: 8px;
    text-transform: capitalize;
}
.an-cal__nav {
    width: 24px;
    height: 24px;
    border: none;
    background: transparent;
    color: var(--color-muted);
    font-size: 16px;
    line-height: 1;
    cursor: pointer;
    border-radius: 6px;
}
.an-cal__nav:hover { background: var(--color-bg); }
.an-cal__nav--spacer { visibility: hidden; cursor: default; }
.an-cal__grid { display: grid; grid-template-columns: repeat(7, 32px); gap: 2px; }
.an-cal__dow { font-size: 11px; color: var(--color-muted); text-align: center; padding-bottom: 4px; }
.an-cal__day {
    width: 32px;
    height: 32px;
    border: none;
    border-radius: 8px;
    background: transparent;
    color: var(--color-text);
    font-size: 13px;
    font-family: inherit;
    cursor: pointer;
}
.an-cal__day:disabled { visibility: hidden; cursor: default; }
.an-cal__day:hover:not(:disabled) { background: var(--color-bg); }
.an-cal__day--in { background: color-mix(in srgb, var(--color-accent) 14%, transparent); border-radius: 0; }
.an-cal__day--from, .an-cal__day--to {
    background: var(--color-accent);
    color: #fff;
    font-weight: 600;
}
.an-cal__foot {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: 12px;
    margin-top: 12px;
    padding-top: 12px;
    border-top: 1px solid var(--color-border);
}
.an-cal__hint { font-size: 13px; color: var(--color-muted); }
.an-cal__actions { display: flex; gap: 8px; }
.an-cal__clear, .an-cal__apply {
    padding: 7px 14px;
    border-radius: 999px;
    border: 1px solid var(--color-border-strong);
    font-size: 13px;
    font-family: inherit;
    cursor: pointer;
    background: var(--color-surface);
    color: var(--color-muted);
}
.an-cal__clear:hover { background: var(--color-bg); }
.an-cal__apply { background: var(--color-accent); border-color: var(--color-accent); color: #fff; }
.an-cal__apply:hover { opacity: 0.9; }
.an-cal__apply:disabled { opacity: 0.4; cursor: default; }

.an-header { display: flex; gap: 12px; flex-wrap: wrap; }
.an-header__cell {
    flex: 1 1 200px;
    padding: 14px 16px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
}
.an-header__value { font-size: 24px; font-weight: 700; }
.an-header__label { font-size: 13px; color: var(--color-muted); margin-top: 4px; }
.an-header__hint { font-size: 12px; color: var(--color-muted); font-style: italic; }

.an-metrics { display: flex; gap: 4px; flex-wrap: wrap; }
.an-metrics__item {
    padding: 6px 12px;
    border-radius: 999px;
    border: 1px solid var(--color-border);
    background: var(--color-surface);
    color: var(--color-muted);
    font-size: 13px;
    cursor: pointer;
    font-family: inherit;
}
.an-metrics__item--active {
    background: var(--color-accent);
    border-color: var(--color-accent);
    color: var(--color-on-accent);
    font-weight: 600;
}

/* Тулбар «поиск + фильтры» над списком товаров (решение пользователя 2026-08-26: вид как у
   списка товаров в самом Ozon) — только для вкладки «Выкупы» (analytics_buyouts.html), где
   переключатель метрики теперь выпадающее меню, а не ряд пилюль на весь экран. */
.an-list-toolbar { display: flex; gap: 10px; margin-bottom: 4px; }
.an-list-toolbar__search { flex: 1; min-width: 200px; max-width: 360px; }

.an-filter { position: relative; flex: none; }
.an-filter__btn {
    height: 100%;
    padding: 8px 14px;
    border: 1px solid var(--color-border-strong);
    border-radius: var(--radius);
    background: var(--color-surface);
    color: var(--color-text);
    font-size: 14px;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
}
.an-filter__btn:hover { background: var(--color-bg); }
.an-filter__menu {
    position: absolute;
    top: calc(100% + 4px);
    left: 0;
    z-index: 20;
    min-width: 220px;
    max-height: 320px;
    overflow-y: auto;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.08);
    padding: 4px;
    display: flex;
    flex-direction: column;
}
.an-filter__item {
    padding: 8px 10px;
    border-radius: 6px;
    color: var(--color-text);
    text-align: left;
    background: none;
    border: none;
    font-size: 14px;
    font-family: inherit;
    cursor: pointer;
    white-space: nowrap;
}
.an-filter__item:hover { background: var(--color-bg); }
.an-filter__item--active { background: var(--color-accent-soft); color: var(--color-accent); font-weight: 600; }

/* Шестерёнка «Настройки таблицы» — какие метрики-колонки показывать (решение пользователя
   2026-08-26, вид по образцу настроек таблицы в самом Ozon: заголовок, тумблеры, кнопка сброса
   снизу). */
/* ⚠️ 2026-08-28, повторно: .an-settings/.an-settings__btn/.an-settings__gear (крайний правый
   край тулбара + объёмная 3D-шестерёнка вместо плоского символа ⚙) уже собирались (ffefa5a) и
   были случайно унесены назад той же коллизией параллельной сессии, что откатывала пилюлю CPO
   (a42d335, старая докоммитная копия style.css). Восстановлено заново — задевает обе страницы,
   где используется .an-settings (Выкупы и Цены), т.к. класс общий. */
.an-settings { position: relative; flex: 0 0 auto; margin-left: auto; align-self: stretch; }
.an-settings__btn {
    /* Подсвечена синим постоянно (решение пользователя 2026-08-27: "шестерёнку подсвети
       синеньким") — не только на hover, акцентным цветом, чтобы сразу было видно, что кнопка
       кликабельна и что-то настраивает. Сама кнопка увеличена вровень с высотой плашек рядом
       (решение пользователя 2026-08-28: "саму плашечку побольше, чтобы она была видна"). */
    display: flex;
    align-items: center;
    justify-content: center;
    height: 100%;
    min-height: 60px;
    padding: 8px 20px;
    border: 1px solid var(--color-accent);
    border-radius: var(--radius);
    background: var(--color-accent-soft);
    color: var(--color-accent);
    cursor: pointer;
    transition: background 0.15s, color 0.15s;
}
.an-settings__btn:hover { background: var(--color-accent); color: var(--color-on-accent); }
.an-settings__gear {
    width: 30px;
    height: 30px;
    filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.15));
}
/* Шестерёнка на "Ценах" — металлическая версия, крупнее (решение пользователя 2026-08-28:
   "должна быть крупненькая... как бы металлической, что ли"): своя градиентная заливка
   (светлый блик → тёмная сталь) вместо currentColor-обводки, сама иконка больше, чем на
   "Выкупах" — там кнопка синяя-акцентная и символ маленький, тут акцент на самой шестерёнке. */
.prices-page .an-settings__gear {
    width: 40px;
    height: 40px;
    filter: none;
}
.an-settings__menu {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    z-index: 20;
    width: 260px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 8px 24px rgba(0, 0, 0, 0.12);
    display: flex;
    flex-direction: column;
    max-height: 420px;
}
.an-settings__title { padding: 14px 16px 8px; font-weight: 700; font-size: 15px; }
.an-settings__list { overflow-y: auto; padding: 4px 8px; }
.an-settings__item {
    /* Теперь это div, не label целиком (решение пользователя 2026-08-27: перетаскивание
       столбцов мышью) — сама метка с тумблером и ручка ⋮⋮ лежат РЯДОМ, не одна внутри другой,
       иначе клик по ручке форвардился бы на чекбокс через нативное поведение <label>. */
    display: flex;
    align-items: center;
    gap: 4px;
    padding: 4px 4px 4px 8px;
    border-radius: 6px;
    font-size: 14px;
}
.an-settings__item:hover { background: var(--color-bg); }
.an-settings__item.is-dragging-item { background: var(--color-accent-soft); opacity: 0.85; }
.an-settings__item-label {
    display: flex;
    align-items: center;
    gap: 10px;
    flex: 1;
    min-width: 0;
    padding: 4px 0;
    cursor: pointer;
}
.an-settings__drag {
    flex: none;
    padding: 4px 8px;
    color: var(--color-muted);
    font-size: 16px;
    line-height: 1;
    cursor: grab;
    touch-action: none;
    user-select: none;
}
.an-settings__drag:active { cursor: grabbing; }
.an-settings__reset {
    margin: 4px 8px 10px;
    padding: 8px 10px;
    border: none;
    border-radius: var(--radius);
    background: var(--color-bg);
    color: var(--color-text);
    font-size: 13px;
    font-family: inherit;
    cursor: pointer;
}
.an-settings__reset:hover { background: var(--color-border); }

/* Тумблер — checkbox спрятан, вместо него нарисованная дорожка+бегунок (тот же приём, что у
   переключателя "Общий доступ" и подобных в проекте: input визуально display:none, но остаётся
   в DOM и в табе для доступности, состояние читается через :checked у соседнего элемента). */
.an-toggle { position: relative; flex: none; width: 34px; height: 20px; }
.an-toggle input {
    position: absolute;
    inset: 0;
    margin: 0;
    opacity: 0;
    cursor: pointer;
}
.an-toggle__track {
    /* pointer-events:none обязателен — иначе эта чисто декоративная дорожка (идёт в DOM
       ПОСЛЕ input) перехватывает клик на себя, а настоящий чекбокс под ней вообще не
       кликается (нашли через тест: Playwright указывал "intercepts pointer events"). */
    position: absolute;
    inset: 0;
    border-radius: 999px;
    background: var(--color-border-strong);
    transition: background 0.15s;
    pointer-events: none;
}
.an-toggle__thumb {
    position: absolute;
    top: 2px;
    left: 2px;
    width: 16px;
    height: 16px;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 1px 2px rgba(0, 0, 0, 0.25);
    transition: transform 0.15s;
}
.an-toggle input:checked ~ .an-toggle__track { background: var(--color-accent); }
.an-toggle input:checked ~ .an-toggle__track .an-toggle__thumb { transform: translateX(14px); }

.an-note {
    padding: 10px 14px;
    border-radius: var(--radius);
    background: var(--color-accent-soft);
    color: var(--color-text);
    font-size: 13px;
    line-height: 1.5;
}
.an-note--warn { background: var(--color-warn-soft); color: var(--color-warn); }

/* Переключение метрики меняет только CSS order у уже отрисованных строк — ни одного запроса.
   Плитки заменены на низкие строки: имя слева, дальше в одну линию артикул/значение/флаг —
   чтобы в экран влезало больше товаров без скролла.

   Базовые .an-tile__* — общие для двух вкладок с РАЗНОЙ структурой строки: «Выкупы»
   (analytics_buyouts.html, ниже #an-grid переопределяет их под колоночную сетку с
   перетаскиваемой шириной) и «Капитал» (analytics_capital.html, там нет отдельной колонки
   .an-tile__flag — он лежит ВНУТРИ .an-tile__body — и есть .an-tile__label, которого у
   «Выкупов» нет). Поэтому здесь — безопасный общий вид "по содержимому" (flex), а вся жёсткая
   раскладка колонок — ниже, в блоке #an-grid, и на «Капитал» не действует. */
.an-grid {
    display: flex;
    flex-direction: column;
    gap: 1px;
    background: var(--color-border);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
}
.an-tile {
    flex: none;
    max-width: none;
    padding: 4px 12px;
    background: var(--color-surface);
    border: none;
    border-radius: 0;
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 10px;
    min-height: 30px;
}
.an-tile--link { cursor: pointer; }
.an-tile--link:hover { background: var(--color-accent-soft); }
.an-tile--all { background: var(--color-accent-soft); font-weight: 600; }
.an-tile--trap { box-shadow: inset 3px 0 0 var(--color-error); }
.an-tile--no_data { opacity: 0.75; }

.an-tile__name {
    flex: 1 1 260px;
    min-width: 0;
    font-weight: 600;
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.an-tile__sub {
    flex: 0 0 auto;
    font-size: 11px;
    color: var(--color-muted);
    margin-bottom: 0;
    white-space: nowrap;
}
.an-tile__body {
    flex: 2 1 320px;
    min-width: 0;
    display: flex;
    flex-direction: row;
    align-items: center;
    gap: 8px;
}
.an-tile__value { font-size: 14px; font-weight: 700; white-space: nowrap; }
.an-tile__unit { font-size: 11px; font-weight: 400; color: var(--color-muted); }
.an-tile__label {
    font-size: 11px;
    color: var(--color-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.an-tile__flag {
    font-size: 10px;
    color: var(--color-muted);
    margin-top: 0;
    font-style: italic;
    white-space: nowrap;
    flex: 0 0 auto;
}
.an-tile__nodata { font-size: 12px; color: var(--color-muted); padding: 0; white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.an-tile__value--ok { color: var(--color-ok); }
.an-tile__value--warn { color: var(--color-warn); }
.an-tile__value--bad { color: var(--color-error); }

/* ---- Только вкладка «Выкупы»: колоночная сетка с ручками ширины, "как в Excel" (решение
   пользователя 2026-08-26). Все ЧЕТЫРЕ колонки, включая имя — независимые фиксированные
   ширины через CSS-переменные на #an-grid (--an-col-name/sub/body/flag), НЕ minmax(...,1fr).

   Раньше имя было "резиновым" (1fr, забирало остаток) — из-за этого при растягивании ЛЮБОЙ
   другой колонки имя молча сжималось, чтобы освободить место (общая ширина строки не менялась,
   держалась шириной страницы). Пользователь именно это и словил как баг: "жмёшь на одну
   границу, ползёт вторая" (2026-08-26) — тащишь границу sub/body, а граница name/sub уезжает
   влево сама по себе, потому что имя ужалось. Теперь колонки полностью независимы: ширина
   строки = сумма всех четырёх ширин, не подгоняется под контейнер. Если сумма больше ширины
   экрана — .an-grid-wrap скроллится по горизонтали (см. ниже), как в настоящей таблице/Excel,
   а не сжимает соседние колонки, чтобы влезть.

   Id #an-grid — только на этой странице, на «Капитал» (та же .an-grid/.an-tile классами, но
   другая структура) эти правила не попадают ни при каких условиях. */
/* "Full bleed" — вырывается из .page (max-width:1200px, центрирует контент), занимает всю
   ширину окна браузера (решение пользователя 2026-08-26: "пустые места слева и справа
   забей"). Приём с отрицательными margin: 50%-50vw подтягивает край к границе viewport
   независимо от того, где на самом деле стоит .page. Свой padding вместо родительского —
   иначе таблица упёрлась бы в самый край окна без отступа. */
.an-grid-wrap {
    overflow-x: auto;
    width: 100vw;
    margin-left: calc(50% - 50vw);
    margin-right: calc(50% - 50vw);
    padding: 0 24px;
}
#an-grid {
    /* Базовый .an-grid (см. выше) даёт overflow:hidden — нужен для скруглённых углов, но он же
       обрезал бы строки шире контейнера, и .an-grid-wrap ниже никогда не увидел бы переполнение
       (обрезка происходит РАНЬШЕ, чем контент доходит до .an-grid-wrap, скроллить нечего).
       width:max-content — сам #an-grid растягивается под самую широкую строку, тогда обрезать
       уже нечего, а переполнение относительно .an-grid-wrap видно по-настоящему и скроллится. */
    position: relative;
    width: max-content;
    min-width: 100%;
}
/* grid-template-columns НЕ здесь — колонок теперь переменное число (имя+артикул+13 метрик+флаг,
   решение пользователя 2026-08-26: "выведи все показатели в единую таблицу"), список и ширины
   по умолчанию собираются из app/analytics_service.py:METRICS через Jinja и заданы инлайновым
   <style> прямо в analytics_buyouts.html (там же, где x-init). ВАЖНО: раньше здесь была
   статичная 4-колоночная grid-template-columns со ссылкой на var(--an-col-body) — когда эту
   переменную переименовали под метрики, ссылка стала битой (несуществующая custom property без
   фолбэка), а невалидный var() обнуляет ВСЁ значение свойства целиком до "none" — таблица
   визуально держалась только на инлайновом правиле шаблона, а это правило её тихо перебивало.
   Отсюда и не работал ресайз/скролл, пока не нашли через getComputedStyle. */
#an-grid .an-tile, #an-grid .an-thead {
    /* gap:0 (не просто «не объявлять») — обязательно ЯВНО обнулить: базовый .an-tile (общий
       со вкладкой «Капитал», см. ниже по файлу) сам даёт gap:10px, а более узкая специфичность
       "не объявлять свойство" не отменяет чужое объявление с тем же свойством — оно просто
       остаётся действовать. .an-thead этот класс не носит, там .an-tile базовый gap не
       подмешивался никогда — из-за этого шапка и строки разъехались на 10px×N (решение
       пользователя 2026-08-27: "заглавная строка съехала"). Сам отступ между колонками теперь
       даёт padding-right на ячейках (см. ниже) — его, в отличие от общего grid-gap, можно
       обнулить для ОДНОЙ конкретной скрытой колонки (решение "убирай эти пробелы"). */
    display: grid;
    gap: 0;
    width: max-content;
    min-width: 100%;
}
#an-grid .an-tile { align-items: center; }
#an-grid .an-thead {
    /* НЕ center — ячейки шапки пустые (<div></div>, текста нет), при center они схлопывались
       бы в высоту 0 и вместе с ними ручка (position:absolute;top:0;bottom:0 внутри
       0-высотного родителя = тоже 0 высотой, тащить нечего). stretch растягивает пустые ячейки
       на всю высоту строки — ручке есть где быть. */
    align-items: stretch;
}
#an-grid .an-tile__name {
    flex: none;
    min-width: 0;
}
#an-grid .an-tile__body {
    flex: none;
    min-width: 0;
    /* center, не flex-end (решение пользователя 2026-08-27: "автоматически центровались все
       цифры... в тот размер, который ей задал, она самоцентрируется") — значение+спарклайн
       как группа теперь по центру ВСЕЙ ширины колонки, а не жмутся к правому краю. При ресайзе
       колонки мышью (см. #an-grid resize) группа сама остаётся по центру нового размера, JS
       трогать не нужно — это просто justify-content, а не фиксированный отступ. */
    justify-content: center;
    /* overflow:hidden обязателен — когда колонку прячут через шестерёнку (см. .an-settings),
       её ширина обнуляется (--an-col-m-<key>: 0px !important), а без обрезки число+спарклайн
       просто наехали бы на соседнюю колонку вместо того, чтобы исчезнуть. */
    overflow: hidden;
}
#an-grid .an-tile__value {
    /* Раньше flex:0 0 74px — фиксированный слот, из-за которого число не могло встать по
       центру широкой колонки (просто прижималось к спарклайну сбоку). auto — ширина по
       содержимому, центрирование делает родитель. */
    flex: 0 0 auto;
    text-align: right;
    font-variant-numeric: tabular-nums;
}
#an-grid .an-tile__nodata {
    /* width:100% — не для растягивания, а чтобы text-overflow:ellipsis (из базового
       .an-tile__nodata) было от чего обрезать текст: без ширины блок просто растёт под
       содержимое и обрезать нечего. text-align:center — по центру, как и число/спарклайн в
       остальных строках той же колонки (решение пользователя 2026-08-27: "чтобы смотрелось
       красиво и полноценно") — раньше было слева вплотную к границе, на фоне центрированных
       чисел смотрелось как отдельный сбой. */
    width: 100%;
    text-align: center;
}
/* Границы колонок на всю высоту таблицы, не только в шапке (решение пользователя 2026-08-26:
   "принеси эти границы полностью по всей таблице, чтобы видел не только наверху") — та же
   позиция, что и полоска-ручка в .an-thead (правый край ячейки = граница колонки), тот же цвет,
   просто в каждой строке своя, без JS — обычная CSS-граница. padding-right вместо gap (см.
   #an-grid .an-tile выше) — тот же визуальный отступ 10px, что раньше давал grid-gap, но
   ЖИВЁТ НА КОНКРЕТНОЙ ЯЧЕЙКЕ, поэтому его (вместе с границей) можно обнулить у ОДНОЙ скрытой
   метрики ниже, не трогая отступы у остальных, видимых колонок. */
#an-grid .an-tile__name,
#an-grid .an-tile__body {
    padding-right: 10px;
    border-right: 1px solid var(--color-border-strong);
}

/* Шапка с ручками изменения ширины колонок — у метрик теперь есть подпись (решение
   пользователя 2026-08-26: все 13 метрик стали отдельными видимыми колонками одновременно,
   без подписи 13 голых чисел нечитаемы). Границы всё равно видны линией на всю высоту таблицы
   (см. border-right на .an-tile__* ниже) — курсор ↔ добавляется при наведении на ручку. */
.an-thead__cell {
    /* НЕ overflow:hidden на самой ячейке — ручка ресайза торчит за её край (right:-7px,
       см. .an-col-resizer), overflow:hidden обрезал бы половину её кликабельной области вместе
       с текстом (нашли через тест: ресайз метрик-колонок молча переставал работать). Обрезка
       длинных подписей — только на вложенном .an-thead__cell-label. */
    padding: 4px 0;
}
/* Поиск в шапке таблицы «Выкупы» (решение пользователя 2026-08-27: перенести сюда из
   отдельного тулбара — раньше первая ячейка .an-thead была пустой). По центру колонки «Название»
   при ресайзе мышью — тот же приём, что у чисел в .an-tile__body (flex + justify-content:center,
   решение пользователя 2026-08-27: "центрируй как и цифры при изменении ширины столбца"):
   инпут не растянут на всю ширину (иначе центрировать нечего, он и так занял бы весь трек),
   а на flex-центрирующем родителе, поэтому сам съезжает к центру при изменении --an-col-name. */
.an-thead__cell--search {
    /* Не flex — раз через justify-content видимо не центрировалось (решение пользователя
       2026-08-27: "текст в поле таблицы не самоцентрируется"), центрируем самым прямым
       способом: инпут — блочный с ограниченной шириной, margin:auto тянет его к центру
       родителя сам, без промежуточного flex-контекста, который мог с чем-то конфликтовать
       (ячейка — ещё и грид-трек колонки «Название», см. #an-grid .an-thead). */
    overflow: hidden;
}
.an-thead__search {
    display: block;
    width: 100%;
    max-width: 220px;
    min-width: 0;
    height: 24px;
    margin: 2px auto 0;
    padding: 2px 6px;
    font-size: 12px;
    border: 1px solid var(--color-border);
    border-radius: 4px;
    background: var(--color-bg);
    color: var(--color-text);
    text-align: center;
}
.an-thead__cell-label {
    display: block;
    font-size: 11px;
    font-weight: 600;
    color: var(--color-muted);
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.an-thead {
    background: var(--color-bg);
    padding: 6px 12px;
    /* Первые две ячейки (имя/артикул) пустые (без текста) — грид сам по себе сжал бы
       единственный ряд треков в 0px, если бы min-height не давал ряду на что растягиваться.
       border-box: паддинг (12px по вертикали) вычитается ИЗ min-height — 36px даёт ~24px
       реальной высоты под ручку, за такую удобно цепляться мышью. */
    min-height: 36px;
}
.an-thead > div { position: relative; }
.an-col-resizer {
    /* Сидит на ПРАВОЙ границе своей колонки (не левой!) — тащишь именно эту границу, растёт
       именно эта колонка, ровно как в Excel: правый край столбца = его собственная ручка.
       Хитбокс шире полоски (14px против видимой линии в 2px) — легче попасть мышью. */
    position: absolute;
    top: 0;
    bottom: 0;
    right: -7px;
    width: 14px;
    cursor: col-resize;
    z-index: 5;
    touch-action: none;
}
.an-col-resizer::after {
    /* Видна всегда (решение пользователя 2026-08-26: "сделал сверху эти полосочки, чтобы я их
       видел, а то тыкаю вслепую") — раньше сверяли с Excel и там в покое не видно ничего, но
       пользователю удобнее видеть заранее, где вообще можно тащить. */
    content: '';
    position: absolute;
    top: 6px;
    bottom: 6px;
    left: 6px;
    width: 2px;
    border-radius: 1px;
    background: var(--color-border-strong);
}
.an-col-resizer:hover::after, .an-col-resizer.is-dragging::after {
    background: var(--color-accent);
    top: 2px;
    bottom: 2px;
    width: 3px;
}

/* Пока идёт драг — курсор col-resize держится ВЕЗДЕ на странице (не только над 14px-ручкой:
   мышь при быстром движении легко её обгоняет), а выделение текста строк отключено — раньше
   без этого при перетаскивании мигал обычный курсор и выделялся текст соседних ячеек, ощущалось
   сломанным, а не "как в Excel". */
body.an-col-resizing, body.an-col-resizing * { cursor: col-resize !important; user-select: none !important; }

.an-spark { width: 56px; height: 16px; margin-top: 0; flex: 0 0 auto; color: var(--color-accent); }
.an-spark--ok { color: var(--color-ok); }
.an-spark--warn { color: var(--color-warn); }
.an-spark--bad { color: var(--color-error); }

/* ---- Модалка деталей ---- */
.an-modal {
    position: fixed;
    inset: 0;
    z-index: 100;
    background: rgba(0, 0, 0, 0.45);
    display: flex;
    align-items: center;
    justify-content: center;
    padding: 24px;
}
.an-modal__box {
    background: var(--color-surface);
    border-radius: var(--radius);
    padding: 20px 24px;
    width: min(560px, 100%);
    max-height: 85vh;
    overflow-y: auto;
}
.an-modal__title { font-size: 18px; font-weight: 700; }
.an-modal__sub { font-size: 12px; color: var(--color-muted); margin-bottom: 12px; }
.an-modal__metrics { display: flex; flex-direction: column; gap: 14px; }
.an-modal__metric-label { font-size: 12px; color: var(--color-muted); }
.an-modal__metric-value { font-size: 20px; font-weight: 700; }
.an-modal__expenses { margin-top: 18px; }
.an-modal__loading, .an-modal__empty { color: var(--color-muted); font-size: 14px; }

.an-table { width: 100%; border-collapse: collapse; font-size: 13px; margin-top: 6px; }
.an-table td { padding: 4px 0; border-bottom: 1px solid var(--color-border); }
.an-table__num { text-align: right; font-variant-numeric: tabular-nums; }

/* ---- Карта: кластеры отгрузки ---- */
.an-clusters { display: flex; flex-direction: column; gap: 6px; }
.an-cluster {
    position: relative;
    display: grid;
    grid-template-columns: 1fr auto auto;
    gap: 12px;
    align-items: center;
    padding: 10px 14px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    overflow: hidden;
}
.an-cluster__bar {
    position: absolute;
    inset: 0 auto 0 0;
    background: var(--color-accent-soft);
    z-index: 0;
}
.an-cluster__name, .an-cluster__value, .an-cluster__stock { position: relative; z-index: 1; }
.an-cluster__name { font-size: 14px; font-weight: 600; }
.an-cluster__value { font-size: 14px; font-variant-numeric: tabular-nums; }
.an-cluster__stock { font-size: 12px; color: var(--color-muted); }
.an-cluster__weak { font-size: 11px; color: var(--color-muted); margin-left: 6px; font-style: italic; }

@media (max-width: 720px) {
    .an-tile { max-width: none; }
}

/* ---- Цены: та же сетка an-grid/an-tile, что в «Аналитике», И та же регулировка ширины
   колонок мышью (решение пользователя 2026-08-27: сначала "только внешний вид", затем уточнили
   "регулировка столбцов точно такая как в аналитике" — добавили и её). Механика 1:1 с
   #an-grid на вкладке «Выкупы» (см. analytics_buyouts.html и блок #an-grid ниже в этом файле):
   независимые CSS-переменные --pg-col-* на #prices-grid, JS-перетаскивание в x-init самого
   prices.html, свой ключ localStorage (an-prices-col-widths-v1, чтобы не смешивался с
   an-buyouts-col-widths-v3 — разный набор и разные дефолтные ширины колонок). */
#prices-grid {
    --pg-col-photo: 46px;
    --pg-col-name: 260px;
    --pg-col-stock: 110px;
    --pg-col-returns: 110px;
    --pg-col-price: 110px;
    --pg-col-margin: 90px;
    --pg-col-target: 320px;
    --pg-col-reached: 130px;
    --pg-col-status: 220px;
    --pg-col-action: 90px;
}
#prices-grid .an-tile, #prices-grid .an-thead {
    display: grid;
    gap: 0;
    grid-template-columns: var(--pg-col-photo) var(--pg-col-name) var(--pg-col-stock) var(--pg-col-returns) var(--pg-col-price) var(--pg-col-margin) var(--pg-col-target) var(--pg-col-reached) var(--pg-col-status) var(--pg-col-action);
    width: max-content;
    min-width: 100%;
}
#prices-grid { position: relative; width: max-content; min-width: 100%; }
/* Ячейки строки растягиваются на всю высоту ряда, не центрируются "по контенту" (решение
   пользователя 2026-08-28: "полоски получаются прерывистые, как штрихпунктирные... надо
   сделать полностью длинными полосками, по всей таблице проходящими"). Раньше align-items:
   center на самом .an-tile НЕ растягивал ячейки — каждая ячейка была высотой ровно со свой
   контент (одна строка текста), а рамка border-right рисовалась только вдоль этой короткой
   высоты. Между соседними строками ещё был зазор от .an-tile{padding:4px...} сверху/снизу —
   итого на стыке каждой позиции линия обрывалась, выглядело как пунктир. Теперь ячейка
   растягивается на всю высоту строки (stretch), а её СОБСТВЕННЫЙ контент центрируется внутри
   display:flex ниже — граница уже спускается до самого низа строки, следующая строка начинает
   свою границу вплотную (между .an-tile нет gap/margin) — визуально одна сплошная линия через
   всю таблицу. */
#prices-grid .an-tile { align-items: stretch; }
#prices-grid .an-tile > .prices-col--returns,
#prices-grid .an-tile > .prices-col--price,
#prices-grid .an-tile > .prices-col--margin,
#prices-grid .an-tile > .prices-col--status,
#prices-grid .an-tile > .prices-col--action,
#prices-grid .an-tile > .prices-col--target {
    display: flex;
    align-items: center;
    justify-content: center;
}
#prices-grid .an-tile > .an-tile__name {
    display: flex;
    flex-direction: column;
    justify-content: center;
    /* align-items НЕ center — растягиваем title/sub на всю ширину ячейки (stretch, дефолт),
       иначе overflow/text-overflow:ellipsis на длинных названиях перестаёт работать (span сам
       ужмётся под контент вместо ширины колонки, обрезать станет нечего). Сам текст внутри
       по-прежнему центрируется через text-align:center (см. общий блок автоцентрирования). */
}
#prices-grid .an-thead { align-items: stretch; }
/* НЕ overflow:hidden в шапке (.an-thead) — ручка ресайза (.an-col-resizer) торчит за правый
   край ячейки (right:-7px, см. style.css общий блок), overflow:hidden обрезал бы половину её
   кликабельной области (та же ловушка, что уже решена на «Выкупах» — см. коммент у
   .an-thead__cell в analytics_buyouts.html). Обрезка длинного текста остаётся только в
   строках-товарах (.an-tile), где overflow:hidden ничего не задевает — там ручек нет. */
#prices-grid .an-tile .prices-col--photo,
#prices-grid .an-tile .prices-col--stock,
#prices-grid .an-tile .prices-col--returns,
#prices-grid .an-tile .an-tile__name,
#prices-grid .an-tile .prices-col--price,
#prices-grid .an-tile .prices-col--margin,
#prices-grid .an-tile .prices-col--target,
#prices-grid .an-tile .prices-col--reached,
#prices-grid .an-tile .prices-col--status,
#prices-grid .an-thead .an-thead__cell {
    min-width: 0;
    padding-right: 10px;
    /* Толщина/цвет — #9ca3af 1px, пользователь подтвердил, что устраивает (решение
       2026-08-28). Проблема была не в этом, а в том, что линия рвалась на каждой строке —
       см. #prices-grid .an-tile { align-items: stretch } ниже и большой комментарий там же:
       "сплошными" пользователь имел в виду ОДНУ длинную линию через всю таблицу, а не жирную. */
    border-right: 1px solid #9ca3af;
}
/* Автоцентрирование всего содержимого таблицы, включая шапку (решение пользователя 2026-08-28:
   "чтобы всё центрировалось по центру... в том числе и заголовки", при любом изменении ширины
   или высоты колонки) — общее правило поверх точечных text-align: right/left, которые были у
   отдельных колонок раньше (Название, Цена, Остаток, Достигаемая цена, Действие). Поле поиска
   в шапке "Название" не трогаем — оно уже центрируется своим более прямым приёмом (margin:auto,
   см. комментарий у .an-thead__cell--search). */
#prices-grid .an-thead__cell,
#prices-grid .an-tile__name,
#prices-grid .prices-col--stock,
#prices-grid .prices-col--returns,
#prices-grid .prices-col--price,
#prices-grid .prices-col--reached,
#prices-grid .prices-col--status,
#prices-grid .prices-col--action {
    text-align: center;
}
#prices-grid .prices-col--stock,
#prices-grid .prices-col--returns,
#prices-grid .prices-col--reached {
    align-items: center;
    justify-content: center;
}
#prices-grid .prices-col--target .price-target-form {
    justify-content: center;
}
#prices-grid .an-tile .prices-col--photo,
#prices-grid .an-tile .prices-col--stock,
#prices-grid .an-tile .prices-col--returns,
#prices-grid .an-tile .an-tile__name,
#prices-grid .an-tile .prices-col--price,
#prices-grid .an-tile .prices-col--margin,
#prices-grid .an-tile .prices-col--target,
#prices-grid .an-tile .prices-col--reached,
#prices-grid .an-tile .prices-col--status {
    overflow: hidden;
}
/* Остаток FBO — вторая колонка, сразу после названия (решение пользователя 2026-08-28:
   "перенеси её... после названия... второй столб"), не через шестерёнку настроек — та же
   логика, что у "Товар"/"Действие" (см. PRICE_METRICS в app/routers/prices.py). Число сверху,
   под ним — мини-график-столбики динамики остатка за месяц (та же ширина 90px, что у
   viewBox графика в шаблоне). */
/* Число СПРАВА от графика, в один ряд с остальными ячейками (решение пользователя
   2026-08-28: "цифра должна быть справа от графика... не надо раздувать высоту строки") —
   flex-row вместо column, высота графика (22px) укладывается в обычную высоту .an-tile,
   строка не растёт. */
/* Фото карточки — компактная версия .costs-row__thumb с Главной (решение пользователя
   2026-08-28: "вид карточки точно такой же, как на Главной... маленькая такая иконочка") —
   тот же object-fit:cover + скруглённые углы, но 28px вместо 56px, чтобы не раздувать высоту
   строки (та же забота, что и у остатка FBO выше). */
.prices-col--photo { display: flex; align-items: center; justify-content: center; padding-left: 6px; }
.prices-col--photo__img {
    width: 28px;
    height: 28px;
    object-fit: cover;
    border-radius: 4px;
    display: block;
    background: var(--color-border);
    flex: none;
}
.prices-col--stock { text-align: right; font-variant-numeric: tabular-nums; display: flex; flex-direction: row; align-items: center; justify-content: flex-end; gap: 6px; }
.prices-col--returns { font-variant-numeric: tabular-nums; }
.prices-stock-value { font-weight: 600; font-size: 13px; }
.prices-stock-bars { width: 56px; height: 22px; color: var(--color-accent); flex: none; }
.prices-stock-bars rect { fill: currentColor; }
.prices-col--name-title {
    font-weight: 600;
    font-size: 13px;
    overflow: hidden;
    text-overflow: ellipsis;
    white-space: nowrap;
}
.prices-col--price { text-align: right; font-variant-numeric: tabular-nums; }
.prices-col--margin { text-align: center; }

/* Фильтр/сортировка "как в Excel" по шапке Маржи (решение пользователя 2026-08-28) — стрелочка
   рядом с подписью колонки, по клику выпадает панель с двумя пунктами сортировки; выбор сразу
   применяется и закрывает панель (никакого отдельного ОК — так и в самом Excel для сортировки,
   в отличие от чек-листа значений, тот не делали, по марже он не нужен, значение непрерывное). */
.prices-sort-btn {
    /* Побольше, в квадратике, объёмная (решение пользователя 2026-08-28: "сделай её побольше
       и в квадратике, более 3D") — тот же приём градиент+inset-блик/тень, что у активного
       сегмента пилюли CPO (.prices-cpo__seg--active), только в серых, не красных тонах —
       нейтральная кнопка-утилита, а не акцентное действие. Прибита в правый нижний угол ячейки
       (решение пользователя 2026-08-28: "стрелка в квадрате должна находиться в правом нижнем
       углу этой ячейки и так у всех") — position:absolute внутри заголовка (у .an-thead > div
       уже есть position:relative, см. общий блок style.css), а не в потоке рядом с подписью
       колонки. */
    position: absolute;
    right: 2px;
    bottom: 2px;
    display: inline-flex;
    align-items: center;
    justify-content: center;
    width: 22px;
    height: 22px;
    padding: 0;
    border: 1px solid var(--color-border-strong);
    border-radius: 5px;
    background: linear-gradient(180deg, var(--color-surface) 0%, var(--color-bg) 100%);
    color: var(--color-muted);
    font-size: 13px;
    line-height: 1;
    cursor: pointer;
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.6),
        inset 0 -1px 2px rgba(0, 0, 0, 0.08),
        0 1px 2px rgba(0, 0, 0, 0.12);
    transition: background 0.15s, color 0.15s, box-shadow 0.15s, transform 0.1s;
}
.prices-sort-btn:hover {
    color: var(--color-accent);
    border-color: var(--color-accent);
    background: linear-gradient(180deg, var(--color-surface) 0%, var(--color-accent-soft) 100%);
}
.prices-sort-btn:active { transform: translateY(1px); box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.18); }
/* Последний тронутый фильтр — приоритетно подсвечен (решение пользователя 2026-08-28:
   "приоритетно показывать тот фильтр, который мы трогали последним"), синим акцентом, как и
   остальные активные элементы управления на странице (шестерёнка, пилюля CPO). */
.prices-sort-btn--active {
    border-color: var(--color-accent);
    color: var(--color-accent);
    background: linear-gradient(180deg, var(--color-surface) 0%, var(--color-accent-soft) 100%);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.6),
        inset 0 -1px 2px rgba(0, 0, 0, 0.08),
        0 0 0 2px var(--color-accent-soft);
}
.prices-sort-menu {
    position: absolute;
    top: calc(100% + 4px);
    right: 0;
    z-index: 30;
    min-width: 220px;
    background: var(--color-surface);
    border: 1px solid var(--color-border);
    border-radius: var(--radius);
    box-shadow: 0 4px 12px rgba(0, 0, 0, 0.12);
    padding: 4px;
    display: flex;
    flex-direction: column;
    font-weight: 400;
    text-align: left;
}
.prices-sort-menu__item {
    display: flex;
    align-items: center;
    gap: 8px;
    padding: 8px 10px;
    border: none;
    border-radius: 6px;
    background: none;
    color: var(--color-text);
    font-size: 13px;
    font-family: inherit;
    white-space: nowrap;
    cursor: pointer;
}
.prices-sort-menu__item svg { width: 14px; height: 14px; flex: none; color: var(--color-muted); }
.prices-sort-menu__item:hover { background: var(--color-bg); }
.prices-col--target .price-target-form { display: flex; align-items: center; gap: 8px; width: 100%; }
.prices-col--target input[type="range"] { flex: 1 1 auto; min-width: 60px; }
.prices-col--target output { font-size: 13px; font-variant-numeric: tabular-nums; min-width: 34px; text-align: right; }
/* Достигаемая цена — своя колонка, живой пересчёт от положения слайдера (JS updatePriceTarget
   в prices.html), тот же табличный формат чисел, что у "Цена сейчас". */
.prices-col--reached { text-align: right; font-variant-numeric: tabular-nums; display: flex; flex-direction: column; gap: 1px; }
.prices-reached-price { font-weight: 600; }
.prices-reached-margin { font-size: 12px; }
.prices-col--status { font-size: 13px; }
.prices-col--action { text-align: right; }
/* Существовал в разметке и раньше, но правила для него не было нигде — зелёный цвет для
   положительной маржи молча не применялся (текст был обычным чёрным). */
.prices-margin--pos { color: var(--color-ok); font-weight: 600; }

/* Подсветка клетки статуса "цель достигнута" зелёным (решение пользователя 2026-08-30) —
   именно клетки, не всей строки: row_active намеренно не включает 'reached' (см. комментарий
   в prices_row.html), менять в этой строке больше нечего, подсвечивать нечего.
   font-size уменьшен и line-height сжат (решение пользователя 2026-08-30: "две строки, а не
   надо увеличивать высоту таблицы только из-за этого... поуже, чтобы не надо было строку
   увеличивать") — раньше "было X"/"маржа была Y%" были на отдельных строках (3 строки), теперь
   объединены в одну (см. prices_row.html), а меньший шрифт даёт запас по ширине, чтобы эта
   более длинная строка не переносилась и не задирала высоту всей строки таблицы обратно. */
.prices-status--reached {
    display: block;
    padding: 3px 6px;
    border-radius: 6px;
    background: var(--color-ok-soft);
    border-left: 3px solid var(--color-ok);
    font-size: 11px;
    line-height: 1.3;
}

/* Цвет слайдера цели (решение пользователя 2026-08-27): 0%/нет цели — нейтральный (браузерный
   дефолт), повышаем и цель ещё "в пути" — зелёный, понижаем и "в пути" — красный, цель
   достигнута — синий ("успокоился"), упёрлись в лимит Ozon раньше цели — жёлтый/warn (это не
   "в пути", нужна ручная правка). Живая перекраска при самом перетаскивании — JS
   updatePriceTarget в prices.html; начальный цвет при отрисовке страницы — slider_state в
   app/routers/prices.py. accent-color красит и трек, и бегунок нативного <input type=range>
   одной строкой, без хаков с vendor-псевдоэлементами — поддержка во всех актуальных браузерах. */
.prices-slider--up { accent-color: var(--color-ok); }
.prices-slider--down { accent-color: var(--color-error); }
.prices-slider--reached { accent-color: var(--color-accent); }
.prices-slider--blocked { accent-color: var(--color-warn); }

/* Лёгкая подсветка всей строки, пока по товару идёт активное изменение цены (в пути/упёрлись
   в лимит) — "всю строчку немножко надо цветом выделять" (решение пользователя 2026-08-27).
   Класс prices-tile--active ставится в prices.html только для этих двух статусов, НЕ для
   'reached' — цель уже достигнута, подсвечивать больше нечего. */
#prices-grid .an-tile.prices-tile--active { background: var(--color-accent-soft); }

/* Название товара кликабельно — открывает график истории цены за год (решение пользователя
   2026-08-27), см. openHistory в prices.html + endpoint /prices/history. */
.prices-name-link { cursor: pointer; text-decoration: underline dotted; text-underline-offset: 2px; }

/* Плашка Ozon-акции «Оплата за заказ» — «сочная», выпуклая версия (решение пользователя
   2026-08-28: "3D-шной, выпуклой... чтобы это было смачно... подсвечивалась скидка, если она
   включена, сама пилюля тоже светилась... если не активна — просто пусть будет плашка серой").
   Формы внутри — display:contents, чтобы <form> не ломал flex-раскладку сегментов (тот приём
   уже был в предыдущей версии этого блока, сохранил).

   ⚠️ 2026-08-28, повторно: весь этот блок (включая .prices-cpo-wrap/__status ниже) уже
   собирался дважды (e344e02, bdd7fa8) и дважды случайно откатывался назад параллельными
   сессиями, работавшими со старой докоммитной копией style.css (последний раз — a42d335).
   Восстановлено заново. */
.prices-cpo-wrap { display: flex; flex-direction: column; gap: 4px; }
.prices-cpo-status {
    display: inline-flex;
    align-items: center;
    gap: 5px;
    padding-left: 12px;
    font-size: 12px;
    white-space: nowrap;
}
.prices-cpo-status svg { width: 13px; height: 13px; flex: none; }
.prices-cpo-status--ok { color: var(--color-error); font-weight: 600; }
.prices-cpo-status--unverified { color: var(--color-muted); }
/* Реальная проверка через Ozon Performance API (решение пользователя 2026-08-28: "ключи же у
   тебя есть, посмотри повнимательнее") — зелёная, когда Ozon подтверждает то же самое, что и
   наша локальная настройка; красная, когда расходится (например, кампанию выключили в личном
   кабинете Ozon, а у нас в настройках всё ещё стоит ставка) — это сигнал разобраться, а не
   просто нейтральная информация, поэтому цвет ошибки, не мьютед. */
.prices-cpo-status--verified-ok { color: #16a34a; font-weight: 600; }
.prices-cpo-status--verified-bad { color: var(--color-error); font-weight: 600; }

.prices-cpo {
    display: inline-flex;
    align-items: center;
    gap: 2px;
    padding: 4px;
    border-radius: 999px;
    border: 1px solid var(--color-border-strong);
    background: var(--color-surface);
    /* Лёгкая тень пилюли даже в покое (решение пользователя 2026-08-28: "панелька сама должна
       выглядеть эффектно") — не только когда акция включена (та подсветка сильнее, см.
       .prices-cpo--active ниже). */
    box-shadow: 0 1px 3px rgba(0, 0, 0, 0.08);
    transition: border-color 0.2s, box-shadow 0.2s;
}
.prices-cpo--active {
    border-color: rgba(220, 38, 38, 0.4);
    box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.12), 0 3px 12px rgba(220, 38, 38, 0.22);
}
.prices-cpo__icon {
    display: inline-flex;
    align-items: center;
    gap: 6px;
    padding: 0 8px;
    font-size: 13px;
    color: var(--color-muted);
    white-space: nowrap;
    transition: color 0.2s;
}
.prices-cpo__icon svg { width: 15px; height: 15px; flex: none; }
.prices-cpo--active .prices-cpo__icon { color: var(--color-error); font-weight: 600; }
.prices-cpo form { display: contents; }
.prices-cpo__seg {
    padding: 7px 13px;
    border-radius: 999px;
    border: 1px solid transparent;
    font-size: 13px;
    font-family: inherit;
    color: var(--color-muted);
    background: transparent;
    cursor: pointer;
    white-space: nowrap;
    transition: background 0.15s, color 0.15s;
}
.prices-cpo__seg:hover { background: var(--color-bg); }
.prices-cpo__seg--active {
    color: #fff;
    font-weight: 700;
    background: linear-gradient(180deg, #f16464 0%, #dc2626 55%, #b91c1c 100%);
    text-shadow: 0 1px 1px rgba(0, 0, 0, 0.25);
    box-shadow:
        inset 0 1px 0 rgba(255, 255, 255, 0.55),
        inset 0 -2px 3px rgba(0, 0, 0, 0.25),
        0 2px 6px rgba(220, 38, 38, 0.55);
}
.prices-cpo__seg--active:hover { background: linear-gradient(180deg, #f47a7a 0%, #e13030 55%, #c22222 100%); }

/* Поиск на "Ценах" подсвечен синим (решение пользователя 2026-08-27) — своя, а не общая
   .an-thead__search-правка, чтобы не задеть поиск на "Выкупах" (тот же класс, другая страница). */
.prices-page .an-thead__search {
    border-color: var(--color-accent);
    box-shadow: 0 0 0 1px var(--color-accent);
}
.prices-page .an-thead__search:focus {
    outline: none;
    box-shadow: 0 0 0 2px var(--color-accent);
}
.prices-name-link:hover { color: var(--color-accent); }

/* Модалка с графиком шире обычной (560px) — 720×220 виджет плюс подписи осей ужимаются
   слишком мелко в узкой карточке. :has() — только для .an-modal__box, что реально содержит
   .prices-chart, обычные модалки (детали "Выкупов") остаются на 560px. */
.an-modal__box:has(.prices-chart) { width: min(820px, 100%); }

.prices-chart-note { margin-bottom: 10px; line-height: 1.6; }
.prices-chart { width: 100%; height: auto; overflow: visible; margin-top: 4px; }
.prices-chart__grid { stroke: var(--color-border); stroke-width: 1; }
.prices-chart__tick { stroke: var(--color-border-strong); stroke-width: 1; }
.prices-chart__axis { stroke: var(--color-border-strong); stroke-width: 1; }
.prices-chart__line { stroke: var(--color-accent); stroke-width: 2; }
.prices-chart__ylabel, .prices-chart__xlabel {
    font-size: 10px;
    fill: var(--color-muted);
    font-variant-numeric: tabular-nums;
}

/* Столбиковый график остатка под графиком цены в модалке (решение пользователя 2026-08-28:
   "график по остаткам... за тот же период... чтобы можно было сопоставлять") — та же ширина
   viewBox и padding.left/right, что у .prices-chart цены, поэтому одна дата стоит строго под
   собой на обоих графиках, хотя это два отдельных <svg>. Ниже и без подписей месяцев снизу —
   вспомогательный график, ось X уже подписана у графика цены сверху. */
.prices-chart--stock { margin-top: 2px; }
.prices-chart__bar { fill: var(--color-accent); opacity: 0.75; }
.prices-chart__bar:hover { opacity: 1; }

/* Три источника истории цены (решение пользователя 2026-08-27: "смотри порой в библиотеке" —
   нашлось три источника разной природы, красим точки по источнику и не смешиваем их молча) —
   те же три цвета, что и легенда под графиком (prices-chart__legend--*). */
.prices-chart__dot--listing { fill: var(--color-accent); }
.prices-chart__dot--snapshot { fill: var(--color-warn); }
.prices-chart__dot--sale { fill: var(--color-ok); }

.prices-chart__legend { display: inline-flex; align-items: center; gap: 3px; font-size: 11px; margin-right: 10px; }
.prices-chart__legend--listing { color: var(--color-accent); }
.prices-chart__legend--snapshot { color: var(--color-warn); }
.prices-chart__legend--sale { color: var(--color-ok); }

/* Скелетоны плашек Главной на время догрузки через htmx (решение пользователя 2026-09-08:
   плашки подгружаются независимо друг от друга, см. app/routers/home.py) — тот же размер и
   форма карточки, чтобы сетка .home-tiles не прыгала, когда плашка появляется. */
.stat-card--skeleton {
    min-height: 148px;
    background: linear-gradient(90deg, var(--color-surface) 25%, var(--color-border) 50%, var(--color-surface) 75%);
    background-size: 200% 100%;
    animation: stat-card-skeleton-pulse 1.4s ease-in-out infinite;
}
@keyframes stat-card-skeleton-pulse {
    0% { background-position: 200% 0; }
    100% { background-position: -200% 0; }
}
@media (prefers-reduced-motion: reduce) {
    .stat-card--skeleton { animation: none; background: var(--color-border); }
}

/* Скелетон основного графика на время догрузки /home/tile-orders (см. templates/home.html) —
   тот же приём, что .stat-card--skeleton выше, только под высоту графика. */
.home-chart-wrap--skeleton {
    min-height: 160px;
    border-radius: 12px;
    background: linear-gradient(90deg, var(--color-surface) 25%, var(--color-border) 50%, var(--color-surface) 75%);
    background-size: 200% 100%;
    animation: stat-card-skeleton-pulse 1.4s ease-in-out infinite;
}
@media (prefers-reduced-motion: reduce) {
    .home-chart-wrap--skeleton { animation: none; background: var(--color-border); }
}

/* Обёртка htmx-якоря вокруг скелетонов/плашек Главной должна быть невидима для .home-tiles
   grid — иначе она сама становится одной ячейкой со сложенными в неё карточками (баг
   2026-09-09, см. templates/home.html). display:contents убирает бокс самого div, оставляя
   в раскладке только его детей. */
.home-tile-slot { display: contents; }
