/* Стили, часть 1 из 12: основа: раскладка, шапка, кнопки, таблицы. Подключаются в base.html строго по порядку —
   от него зависит, какое правило главнее. Один base.css разбит 30.09.2026: Cloudflare
   отдавал файлы крупнее ~20 КБ обрезанными. Файл держать меньше 15 КБ. */

/* Базовая раскладка — docs/design-system.md. Значения только через
   переменные из tokens.css (правило 5 в CLAUDE.md). */

* { box-sizing: border-box; }

/* Атрибут hidden обязан побеждать любой другой display — иначе любое
   правило вида «.класс { display: ... }» ниже по файлу молча отменяет
   hidden (авторские стили всегда сильнее стилей браузера по умолчанию,
   даже при равной специфичности). Нашли на этом баг 24.08.2026: меню
   сортировки и кнопка «Сбросить» были hidden в разметке, но показаны
   на экране — из-за button{display:inline-block} и .sort-menu{display:flex}. */
[hidden] { display: none !important; }

html, body {
    margin: 0;
    min-height: 100%;
    font-family: var(--font);
    font-size: var(--font-size-base);
    font-weight: 500;
    color: var(--text-primary);
    background: var(--bg-app);
    font-variant-numeric: tabular-nums;
}

/* Приложение — плавающее «окно» на цветном фоне --bg-app. */
.app-window {
    margin: var(--gap);
    background: var(--bg-canvas);
    border-radius: var(--r-window);
    box-shadow: var(--shadow-window);
    overflow: hidden;
    min-height: calc(100vh - 2 * var(--gap));
}

/* Шапка в две строки, как в кабинете Ozon Seller — правка 24.08.2026
   (владелец: боковая панель съедала текст, вернулись к горизонтальной
   навигации). Первая строка — логотип, переключатель кабинета,
   шестерёнка со служебными разделами, пользователь. Вторая —
   горизонтальное меню рабочих разделов. Шапка прижата к краю экрана,
   во всю ширину, без скруглений — плавающее окно начинается ниже,
   у самого содержимого (владелец: «как в Ozon», стиль карточек
   ниже сохраняется). */
.topbar {
    background: var(--bg-surface);
    border-bottom: var(--border-width) solid var(--line);
}

.topbar-main {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--gap);
    padding: var(--space-md) var(--pad-card);
    flex-wrap: wrap;
}
.topbar-main-right { display: flex; align-items: center; gap: var(--space-md); }

.topbar-logo {
    font-size: 20px;
    font-weight: 600;
    color: var(--text-primary);
    text-decoration: none;
}

.topbar-nav {
    display: flex;
    gap: var(--space-md);
    padding: 0 var(--pad-card) var(--space-md);
    flex-wrap: wrap;
}
.topbar-nav a {
    color: var(--text-secondary);
    text-decoration: none;
    font-weight: 500;
    padding-bottom: var(--space-xs);
    border-bottom: 3px solid transparent;
}
.topbar-nav a:hover { color: var(--text-primary); }
.topbar-nav a.active {
    color: var(--text-primary);
    font-weight: 600;
    border-bottom-color: var(--accent-violet);
}

.gear-menu { position: relative; }
.gear-menu summary {
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: center;
    width: 36px;
    height: 36px;
    border: var(--border-width) solid var(--border-strong);
    border-radius: var(--r-pill);
    color: var(--text-secondary);
}
.gear-menu summary::-webkit-details-marker { display: none; }
.gear-menu summary::marker { content: ""; }
.gear-menu summary:hover { color: var(--text-primary); }
.gear-menu-panel {
    position: absolute;
    right: 0;
    top: calc(100% + var(--space-xs));
    z-index: 10;
    width: 220px;
    display: flex;
    flex-direction: column;
    padding: var(--space-sm);
    background: var(--bg-surface);
    border-radius: var(--r-card);
    box-shadow: var(--shadow-pop);
}
.gear-menu-panel a {
    color: var(--text-primary);
    text-decoration: none;
    font-weight: 500;
    padding: var(--space-sm);
    border-radius: var(--r-sm);
}
.gear-menu-panel a:hover { background: var(--bg-canvas); }

.gear-menu-user {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: var(--space-xs);
    margin-top: var(--space-xs);
    padding: var(--space-sm);
    border-top: var(--border-width) solid var(--line);
}
.gear-menu-user a { padding: 0; color: var(--accent-violet); }
.gear-menu-user a:hover { background: none; text-decoration: underline; }
.gear-menu-user form { margin: 0; }

/* Вкладки второго уровня внутри раздела — плоский список через
   разделитель, как «Связанные разделы» в Ozon Seller, не пилюли. */
.subnav {
    display: flex;
    align-items: center;
    gap: var(--space-sm);
    padding: var(--space-sm) var(--pad-card);
    font-size: var(--font-size-small);
    border-bottom: var(--border-width) solid var(--line);
}
.subnav-label { color: var(--text-muted); }
.subnav a {
    color: var(--text-secondary);
    text-decoration: none;
    font-weight: 500;
}
.subnav a:hover { color: var(--text-primary); }
.subnav a.active { color: var(--text-primary); font-weight: 600; }
.subnav .sep { color: var(--border-strong); }

main { padding: var(--pad-card); }

.card {
    max-width: 720px;
    padding: var(--pad-card);
    background: var(--bg-surface);
    border-radius: var(--r-card);
    box-shadow: var(--shadow-card);
}
.unified-card { max-width: 100%; }

.card h1, main > h1 { margin-top: 0; font-size: var(--font-size-title); font-weight: 600; }
h2 { font-size: var(--font-size-card-title); font-weight: 600; }
.metric { font-size: var(--font-size-metric); font-weight: 600; }
.muted { color: var(--text-muted); }

form p { margin-bottom: var(--space-md); }
label { display: block; margin-bottom: var(--space-xs); font-size: var(--font-size-small); color: var(--text-secondary); font-weight: 500; }

/* Форма периода отчёта: поля дат и кнопки — раздельные группы
   с гарантированным промежутком между ними, не одна общая строка
   на голом inline-стиле (правило 5 — раскладка тоже в стиле, не
   по месту). */
.period-form {
    display: flex;
    align-items: flex-end;
    gap: var(--space-lg);
    flex-wrap: wrap;
    margin-bottom: var(--space-md);
}
.period-form-dates, .period-form-actions {
    display: flex;
    align-items: flex-end;
    gap: var(--space-md);
    flex-wrap: wrap;
}
.period-form label { margin-bottom: 0; }

input[type="text"], input[type="password"], input[type="date"],
input[type="number"], input[type="file"] {
    padding: var(--space-sm) var(--space-md);
    font-family: var(--font);
    font-size: var(--font-size-base);
    font-weight: 500;
    color: var(--text-primary);
    background: var(--bg-surface);
    border: var(--border-width) solid var(--border-strong);
    border-radius: var(--r-pill);
}
input[type="file"] { border-radius: var(--r-sm); }

button, .button {
    display: inline-block;
    padding: var(--space-sm) var(--space-md);
    font-family: var(--font);
    font-size: var(--font-size-base);
    font-weight: 600;
    color: var(--accent-lime);
    background: var(--bg-inverse);
    border: none;
    border-radius: var(--r-pill);
    cursor: pointer;
    text-decoration: none;
}
button:hover, .button:hover { opacity: .88; }

.button-secondary, button.button-secondary {
    color: var(--text-primary);
    background: var(--bg-surface);
    border: var(--border-width) solid var(--border-strong);
}

.errorlist { color: var(--state-bad-text); padding-left: 0; list-style: none; }

table { width: 100%; border-collapse: collapse; margin-bottom: var(--space-md); }
th, td { padding: var(--space-sm); text-align: left; border: none; }
th { font-weight: 500; color: var(--text-muted); font-size: var(--font-size-table-head); background: none; }
tbody tr { border-top: var(--border-width) solid var(--line); }
thead tr, tbody tr:first-child { border-top: none; }

.mono { font-family: var(--font-mono); font-size: var(--font-size-small); font-variant-numeric: tabular-nums; }

/* Позитив/негатив — заливка-пилюля для коротких меток
   (docs/design-system.md); для предложений и целых строк/ячеек —
   тем же цветом, но текстом, без пилюли (иначе целое предложение
   в форме таблетки выглядит нелепо). */
span.state-good, span.state-bad {
    display: inline-block;
    padding: 1px var(--space-sm);
    border-radius: var(--r-pill);
    font-weight: 600;
    font-size: var(--font-size-small);
}
span.state-good { color: var(--state-good-text); background: var(--state-good-bg); }
span.state-bad { color: var(--state-bad-text); background: var(--state-bad-bg); }
p.state-good, p.state-bad, td.state-bad, td.state-good,
tr.state-bad td, tr.state-good td {
    background: none;
    font-weight: 600;
}
p.state-good, td.state-good { color: var(--state-good-text); }
p.state-bad, td.state-bad, tr.state-bad td { color: var(--state-bad-text); }

/* Критичное значение — акцент цветом, без заливки. */
.state-critical { color: var(--accent-magenta); font-weight: 600; }

/* Единый отчёт: закреплённые шапка и первая колонка при прокрутке,
   моноширинные/табличные числа по правому краю, тысячи через пробел
   (spacenum). */
.unified-table-wrap, .hidden-table-wrap {
    overflow: auto;
    max-height: 75vh;
    border: var(--border-width) solid var(--border);
    border-radius: var(--r-sm);
    margin-bottom: var(--space-md);
}
/* table-layout: fixed — ширина колонки не зависит от содержимого
   (владелец, 24.08.2026): у двух независимых таблиц (основная и блок
   «Скрыто») иначе браузер считает ширины по-своему, и колонки не стоят
   одна под другой. Ширины — из unified_views.py (UNIFIED_COLUMN_WIDTHS),
   один список на обе таблицы.

   Заданы через <colgroup>, а не через width на th: при fixed браузер
   берёт ширины с ПЕРВОЙ строки шапки, а первой стала группирующая
   («Поиск», «Рекомендации») с colspan — отдельных ширин в ней нет,
   и все 45 колонок схлопывались в полоски по букве (владелец,
   01.09.2026). colgroup задаёт их независимо от рядов шапки.

   Ширина самой таблицы задана в разметке суммой колонок: иначе
   таблица ужимается под ширину экрана и fixed делит место заново. */
.unified-table { border-collapse: separate; border-spacing: 0; margin-bottom: 0; table-layout: fixed; }
.unified-table th, .unified-table td { white-space: nowrap; border: none; overflow: hidden; text-overflow: ellipsis; }
.unified-table tbody tr.group-row { border-top: var(--border-width) solid var(--line); }
.unified-table thead th {
    position: sticky; top: 0; z-index: 2;
    background: var(--bg-canvas);
}
.unified-table td.num, .unified-table th:not(:first-child) {
    text-align: right;
}
.unified-table td.num {
    font-family: var(--font-mono);
    font-variant-numeric: tabular-nums;
}
.unified-table td:first-child, .unified-table th:first-child {
    position: sticky; left: 0; z-index: 1;
    background: var(--bg-canvas);
    box-shadow: 2px 0 0 var(--line);
    text-align: left;
}
.unified-table thead th:first-child { z-index: 3; }
.unified-table tr.size-row td:first-child { padding-left: var(--space-lg); }
/* Строки без заказов и без остатка живут только в отдельном нижнем
   блоке (владелец, 24.08.2026), не в основной таблице — приглушены
   серым, чтобы отличаться от рабочих строк на глаз. */
.unified-table tr.size-row-zero td { color: var(--text-muted); }
