/* Компоненты панели (блок Э-0.6a). Всё, что рисуется в панели, одевается
   классами отсюда — модуль своего CSS не пишет. Это и есть проверка блока:
   если при работе над экраном цен (Ф1) понадобится дописать стиль в модуле —
   значит примитив выбран не тот, и чинить надо здесь, а не там.

   Как CSS доставляется (решение блока): ДВА файла ядра, tokens.css + base.css,
   подключены из panel/index.html <link>-ами. Не по файлу на компонент —
   сборщика нет и не будет, а десять модулей превратились бы в десять
   запросов, каждый со своим шансом опечатки в пути. Не один общий файл —
   токены отделены сознательно: их читают и правят люди, компоненты растут
   блоками 0.6b/0.7. Модульного CSS у модулей нет: понадобилось модулю особое
   — это либо новый примитив здесь, либо признак, что экран спроектирован мимо
   системы.

   Соглашение по именам: блок `.card`, элемент `.card__title`, модификатор
   `.card--flush`, состояние `.is-active`. Состояния — единственное, что
   переключается из JS.

   Голые теги (h1, p, label, input, table) стилизованы намеренно: экран,
   написанный обычной разметкой без единого класса, обязан выглядеть прилично
   сам по себе — иначе классы начнут забывать. */

/* ── База ──────────────────────────────────────────────────────────────────── */

* { box-sizing: border-box; }

/* Атрибут hidden обязан побеждать компоненты. Правило браузера [hidden] по
   специфичности слабее любого класса, поэтому .btn { display: inline-flex }
   молча показывал кнопку «Выйти» на экране входа. Оболочка прячет hidden'ом
   и кнопку выхода, и шаги формы входа, и строки таблицы под фильтром —
   ошибка тихая и в каждом случае выглядит по-разному. */
[hidden] { display: none !important; }

body {
  margin: 0;
  min-height: 100vh;
  display: flex;
  flex-direction: column;
  font-family: var(--font-sans);
  font-size: var(--fs-base);
  line-height: var(--lh);
  background: var(--c-bg);
  color: var(--c-text);
}

h1, h2, h3 { line-height: var(--lh-tight); font-weight: 600; }
h1 { margin: 0 0 var(--sp-2); font-size: var(--fs-lg); }
h2 { margin: 0 0 var(--sp-3); font-size: var(--fs-md); }
h3 { margin: 0 0 var(--sp-2); font-size: var(--fs-base); }
p  { margin: 0 0 var(--sp-3); }
p:last-child { margin-bottom: 0; }

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

:focus-visible { outline: var(--focus-ring); outline-offset: 1px; }

.muted { color: var(--c-text-muted); }
.small { font-size: var(--fs-sm); }
.nowrap { white-space: nowrap; }
.spacer { flex: 1; }
.row { display: flex; gap: var(--sp-3); flex-wrap: wrap; align-items: center; }
.stack > * + * { margin-top: var(--sp-4); }

/* ── Раскладка оболочки ────────────────────────────────────────────────────── */
/* Ширины в rem и minmax: фиксированной пиксельной сетки нет — с ней «мой
   график» с телефона (0.6b) пришлось бы выкорчёвывать. */

.app-header {
  position: sticky;
  top: 0;
  z-index: var(--z-header);
  display: flex;
  align-items: center;
  gap: var(--sp-4);
  padding: var(--sp-3) var(--sp-5);
  background: var(--c-header-bg);
  color: var(--c-header-text);
  border-bottom: 1px solid var(--c-header-border);
}
.app-header__title { font-size: var(--fs-md); font-weight: 600; }
.app-header__who { font-size: var(--fs-sm); color: var(--c-header-muted); }

.app-body { display: flex; flex: 1; min-height: 0; }

.app-sidebar {
  width: var(--sidebar-w);
  flex: none;
  padding: var(--sp-3) 0;
  background: var(--c-surface);
  border-right: 1px solid var(--c-border);
}
/* На экране входа меню пустое: полоса пустого сайдбара выглядит как
   недогрузившаяся страница. Пустой сайдбар выпадает из раскладки целиком. */
.app-sidebar:empty { display: none; }

.app-main {
  flex: 1;
  min-width: 0;              /* иначе широкая таблица растянет всю раскладку */
  padding: var(--sp-5);
  max-width: var(--content-max);
}

/* ── Меню (core/menu.js) ───────────────────────────────────────────────────── */

.menu { display: flex; flex-direction: column; }
.menu__label {
  margin: var(--sp-4) var(--sp-4) var(--sp-1);
  font-size: var(--fs-xs);
  text-transform: uppercase;
  letter-spacing: 0.06em;
  color: var(--c-text-faint);
}
.menu__link {
  display: block;
  padding: var(--sp-2) var(--sp-4);
  color: var(--c-text);
  font-size: var(--fs-base);
  border-left: 2px solid transparent;
}
.menu__link:hover { background: var(--c-surface-hover); text-decoration: none; }
.menu__link.is-active {
  background: var(--c-accent-soft);
  border-left-color: var(--c-accent);
  font-weight: 600;
}
/* Иконок в пунктах пока нет сознательно (решение блока 0.6a): поле icon в
   манифесте объявлено и ждёт 0.6b. Четырнадцать текстовых пунктов на десктопе
   читаются нормально, а набор иконок, подобранный до живых экранов,
   подбирается вслепую и переделывается вместе с ними. */

/* ── Карточка ──────────────────────────────────────────────────────────────── */

.card {
  background: var(--c-surface);
  border: 1px solid var(--c-border);
  border-radius: var(--r-md);
  box-shadow: var(--shadow-card);
  padding: var(--sp-5);
}
.card + .card { margin-top: var(--sp-4); }
/* Карточка вокруг таблицы и тулбара: свои отступы у них уже есть. */
.card--flush { padding: 0; overflow: hidden; }
.card__title { margin: 0 0 var(--sp-1); font-size: var(--fs-md); font-weight: 600; }
.card__hint { margin: 0 0 var(--sp-4); font-size: var(--fs-sm); color: var(--c-text-muted); }

/* ── Кнопки ────────────────────────────────────────────────────────────────── */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: var(--sp-2);
  padding: var(--sp-2) var(--sp-4);
  font: inherit;
  font-size: var(--fs-sm);
  line-height: var(--lh-tight);
  border-radius: var(--r-sm);
  border: 1px solid var(--c-border-strong);
  background: var(--c-surface);
  color: var(--c-text);
  cursor: pointer;
  white-space: nowrap;
}
.btn:hover:not(:disabled) { background: var(--c-surface-hover); }
.btn:disabled { opacity: 0.55; cursor: default; }

.btn--primary {
  background: var(--c-accent);
  border-color: var(--c-accent);
  color: var(--c-on-accent);
  font-weight: 600;
}
.btn--primary:hover:not(:disabled) { background: var(--c-accent-hover); border-color: var(--c-accent-hover); }

.btn--danger { color: var(--c-danger); border-color: var(--c-danger); background: var(--c-surface); }
.btn--danger:hover:not(:disabled) { background: var(--c-danger-soft); }

.btn--link {
  border-color: transparent;
  background: none;
  color: var(--c-text-muted);
  text-decoration: underline;
}
.btn--link:hover:not(:disabled) { background: none; color: var(--c-text); }

/* Кнопка на тёмной шапке: обычная белая читалась бы как главное действие
   страницы, а это «Выйти». */
.btn--on-header {
  background: transparent;
  border-color: var(--c-header-border);
  color: var(--c-header-text);
}
.btn--on-header:hover:not(:disabled) { background: var(--c-header-border); }

.btn--block { width: 100%; }
.btn--sm { padding: var(--sp-1) var(--sp-3); font-size: var(--fs-xs); }

/* ── Поля ввода (минимум под поиск; формы целиком — 0.6b) ──────────────────── */

label { display: block; margin-bottom: var(--sp-1); font-size: var(--fs-sm); color: var(--c-text-muted); }

.input, input[type="text"], input[type="search"], input[type="email"],
input[type="password"], input[type="number"], select, textarea {
  width: 100%;
  max-width: 100%;
  padding: var(--sp-2) var(--sp-3);
  font: inherit;
  font-size: var(--fs-md);
  color: var(--c-text);
  background: var(--c-surface);
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-sm);
}
.input:focus, input:focus, select:focus, textarea:focus {
  outline: var(--focus-ring);
  outline-offset: -1px;
  border-color: var(--c-accent);
}
.input--search { max-width: var(--field-w); }

/* ── Тулбар ────────────────────────────────────────────────────────────────── */
/* Слева поиск, дальше слот под срезы (Опт / Акция / Безнал / сайт-Авито из
   Ф1), справа счётчик «показано N из M». Слот пуст в разметке — но место под
   него предусмотрено здесь, а не в модуле. */

.toolbar {
  display: flex;
  align-items: center;
  gap: var(--sp-3);
  flex-wrap: wrap;
  padding: var(--sp-3) var(--sp-4);
  background: var(--c-surface-sunken);
  border-bottom: 1px solid var(--c-border);
}
.toolbar__search { flex: 0 1 var(--field-w); min-width: 12rem; }
.toolbar__slot { display: flex; align-items: center; gap: var(--sp-2); flex-wrap: wrap; }
.toolbar__count { margin-left: auto; font-size: var(--fs-sm); color: var(--c-text-muted); white-space: nowrap; }

/* Переключатель срезов. Одна группа взаимоисключающих кнопок. */
.segmented {
  display: inline-flex;
  border: 1px solid var(--c-border-strong);
  border-radius: var(--r-sm);
  overflow: hidden;
  background: var(--c-surface);
}
.segmented__btn {
  padding: var(--sp-2) var(--sp-3);
  font: inherit;
  font-size: var(--fs-sm);
  line-height: var(--lh-tight);
  color: var(--c-text-muted);
  background: none;
  border: none;
  border-left: 1px solid var(--c-border);
  cursor: pointer;
}
.segmented__btn:first-child { border-left: none; }
.segmented__btn:hover { background: var(--c-surface-hover); }
.segmented__btn.is-active { background: var(--c-accent-soft); color: var(--c-accent); font-weight: 600; }

/* ── Таблица ───────────────────────────────────────────────────────────────── */
/* Плотность под десктоп: 13px, строка ~30px — на рабочем мониторе это ~25
   видимых строк из 170. Липкая шапка обязательна: без неё на сотне строк
   теряешь, какая колонка «Опт», а какая «Безнал».
   border-collapse: separate — с collapse липкий th теряет свои границы при
   прокрутке; границы рисуем box-shadow'ом. */

.table-wrap {
  max-height: var(--table-max-h);
  overflow: auto;
  overscroll-behavior: contain;
}

.table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  font-size: var(--fs-sm);
}
.table th {
  position: sticky;
  top: 0;
  z-index: var(--z-sticky);
  padding: var(--sp-2) var(--sp-3);
  text-align: left;
  font-size: var(--fs-xs);
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--c-text-faint);
  background: var(--c-surface-sunken);
  white-space: nowrap;
  box-shadow: inset 0 -1px 0 var(--c-border);
}
.table td {
  padding: var(--sp-2) var(--sp-3);
  border-bottom: 1px solid var(--c-border);
  vertical-align: top;
}
.table tbody tr:hover td { background: var(--c-surface-hover); }
.table tbody tr:last-child td { border-bottom: none; }

/* Числовые колонки — вправо и моноширинными цифрами: цены в столбик
   сравниваются глазом только выровненными по разряду. */
.cell-num {
  text-align: right;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
  font-family: var(--font-num);
}

/* ── Пустой результат поиска ───────────────────────────────────────────────── */
/* Только этот случай (общие пустые состояния — 0.7). Важно, чтобы пустой
   поиск не выглядел как сломанный экран: карточка и тулбар остаются на
   месте, объяснение — внутри области таблицы. */

.empty {
  padding: var(--sp-6) var(--sp-4);
  text-align: center;
  color: var(--c-text-muted);
}
.empty__title { margin: 0 0 var(--sp-1); font-size: var(--fs-base); font-weight: 600; color: var(--c-text); }
.empty__hint { margin: 0; font-size: var(--fs-sm); }

/* ── Pill ──────────────────────────────────────────────────────────────────── */

.pill {
  display: inline-block;
  padding: 1px var(--sp-2);
  border-radius: var(--r-pill);
  font-size: var(--fs-xs);
  font-weight: 600;
  line-height: 1.6;
  white-space: nowrap;
  background: var(--c-surface-hover);
  color: var(--c-text-muted);
}
.pill--ok     { background: var(--c-ok-soft);     color: var(--c-ok); }
.pill--warn   { background: var(--c-warn-soft);   color: var(--c-warn); }
.pill--danger { background: var(--c-danger-soft); color: var(--c-danger); }

/* ── Экран входа (core/auth.js) ────────────────────────────────────────────── */

.login { display: flex; justify-content: center; padding: var(--sp-6) var(--sp-4); }
.login-card { width: 100%; max-width: 24rem; }
.login-brand {
  font-size: var(--fs-xs);
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--c-text-faint);
  margin-bottom: var(--sp-1);
}
.login-card h1 { margin-bottom: var(--sp-5); }
.login-card label { margin-top: var(--sp-3); }
.login-card input { margin-bottom: var(--sp-3); }
.login-card .btn--block { margin-top: var(--sp-2); }
.login-note  { margin: var(--sp-4) 0 0; font-size: var(--fs-sm); color: var(--c-text-muted); }
.login-error { margin: var(--sp-4) 0 0; font-size: var(--fs-sm); color: var(--c-danger); }
.login-note:empty, .login-error:empty { display: none; }
