/* По-хычыну — фирменные цвета и лёгкая мобильная вёрстка.
   Палитра — из брендбука. Заголовки — фирменный Bloc Heavy (лицензия куплена),
   самохостный; если файл вдруг не подгрузится — системный sans-serif. */

/* Montserrat — свой хостинг вместо fonts.googleapis.com (разбор скорости
   2026-09-04: внешний блокирующий CSS от Google в России на мобильных
   грузится нестабильно). Вариативный woff2 с Google Fonts v31, вес 400–700,
   два сабсета по unicode-range — браузер скачает только нужный. */
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/static/fonts/montserrat-cyrillic.woff2') format('woff2');
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: 'Montserrat';
  font-style: normal;
  font-weight: 400 700;
  font-display: swap;
  src: url('/static/fonts/montserrat-latin.woff2') format('woff2');
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+0304, U+0308, U+0329, U+2000-206F, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
}
/* Bloc Heavy: woff2-сабсет (кириллица + латиница + ₽/№/кавычки, 46 КБ) вместо
   полного OTF на 273 КБ, который качался на каждый первый заход (2026-09-04).
   OTF/TTF оставлены как запасной вариант для очень старых браузеров. */
@font-face {
  font-family: 'Bloc Heavy';
  font-display: swap;
  src: url('/static/fonts/bloc_heavy.woff2') format('woff2'),
       url('/static/fonts/bloc_heavy.otf') format('opentype'),
       url('/static/fonts/bloc_heavy.ttf') format('truetype');
  font-weight: 800;
  font-style: normal;
  font-display: swap;
}

:root {
  --maroon: #892A1F;
  --red: #AD2B21;
  --cream: #E9DBC2;
  --ink: #1F1B20;
  --white: #FEFEFE;
  --green: #2f6e4f;
  --border: #e7ded0;
  /* Оттенки текста между --ink и фоном — раньше разбросаны по файлу сырыми
     hex, свели в один ряд без изменения самих значений (только имя). */
  --text-secondary: #4a4038;
  --text-muted: #5a5450;
  --text-faint: #6b6255;
  --text-faintest: #7a7268;

  --font-head: 'Bloc Heavy', sans-serif;
  --font-body: 'Montserrat', sans-serif;
}

* { box-sizing: border-box; }

html {
  scroll-behavior: smooth;
}

html, body {
  margin: 0;
  padding: 0;
  background: var(--white);
  color: var(--ink);
  font-family: var(--font-body);
  font-size: 16px;
  line-height: 1.45;
  -webkit-text-size-adjust: 100%;
}

body.has-mini-cart {
  padding-bottom: 68px;
}

img { max-width: 100%; display: block; }

/* ---------- Иконки (см. icons.py) — заменяют эмодзи-как-иконки ---------- */
.icon {
  width: 1em;
  height: 1em;
  display: inline-block;
  vertical-align: -0.125em;
  flex-shrink: 0;
}

a { color: inherit; }

h1, h2, h3 {
  font-family: var(--font-head);
  line-height: 1.15;
  margin: 0 0 0.5em;
}

.container {
  max-width: 720px;
  margin: 0 auto;
  padding: 0 16px;
}

/* ---------- Хедер ---------- */

.site-header {
  background: var(--cream);
  color: var(--maroon);
  position: sticky;
  top: 0;
  z-index: 10;
}

.header-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding-top: 12px;
  padding-bottom: 12px;
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  text-decoration: none;
  color: var(--maroon);
}

.brand img {
  width: 44px;
  height: 44px;
  border-radius: 50%;
}

.brand span {
  font-family: var(--font-head);
  font-size: 1.15rem;
  white-space: nowrap;
}

.header-links {
  display: flex;
  align-items: center;
  gap: 14px;
  font-size: 0.85rem;
}

.header-links a {
  text-decoration: none;
  color: var(--maroon);
  opacity: 0.85;
  white-space: nowrap;
  /* Ссылки в шапке — самые нажимаемые 20px на сайте: расширяем зону нажатия
     до ~44px без сдвига вёрстки. */
  padding: 12px 6px;
  margin: -12px -6px;
}

.cart-link {
  position: relative;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 40px;
  height: 40px;
  margin: -8px -6px;
  text-decoration: none;
  color: var(--maroon);
}

.cart-icon {
  font-size: 1.4rem;
  line-height: 1;
}

.cart-badge {
  position: absolute;
  top: 2px;
  right: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  min-width: 17px;
  height: 17px;
  background: var(--red);
  color: var(--white);
  border-radius: 999px;
  font-size: 0.68rem;
  font-weight: 700;
  padding: 0 4px;
  line-height: 1;
}

/* ---------- Герой ---------- */

.hero {
  background: var(--cream);
  color: var(--maroon);
  padding: 6px 0 16px;
  text-align: center;
}

.sold-counter {
  background: var(--maroon);
  color: var(--white);
  text-align: center;
  padding: 18px 16px;
}

.sold-counter-number {
  font-family: var(--font-head);
  font-size: clamp(2.4rem, 11vw, 3.6rem);
  line-height: 1;
  color: var(--cream);
  font-variant-numeric: tabular-nums;
}

.sold-counter-label {
  margin-top: 4px;
  font-size: 0.9rem;
  font-weight: 600;
  text-transform: uppercase;
  letter-spacing: 0.04em;
  opacity: 0.92;
}

.hero-trust {
  margin: 8px 0 0;
  font-size: 0.82rem;
  color: var(--maroon);
  opacity: 0.85;
}

.hero p.hero-explainer {
  margin: 4px auto 0;
  font-size: 0.85rem;
  color: var(--ink);
  opacity: 1;
  max-width: 34em;
}

.hours-badge {
  display: inline-block;
  font-size: 0.72rem;
  font-weight: 700;
  white-space: nowrap;
  margin-top: 8px;
  padding: 3px 10px;
  border-radius: 999px;
  background: var(--white);
}

.hours-badge.hours-open { color: var(--green); }
.hours-badge.hours-closed { color: var(--text-faint); }

.hero h1 {
  font-size: 1.3rem;
  color: var(--maroon);
  margin: 0 0 2px;
}

.hero p {
  margin: 0;
  font-size: 0.82rem;
  color: var(--ink);
  opacity: 0.8;
}

/* ---------- Как это работает (компактная строка) ---------- */

.mini-steps {
  background: var(--cream);
  color: var(--ink);
  font-size: 0.8rem;
  font-weight: 600;
  text-align: center;
  padding: 7px 16px;
  margin: 0 auto;
}

.delivery-info {
  display: flex;
  align-items: center;
  gap: 14px;
  width: fit-content;
  /* Не шире колонки за вычетом полей по 16px, как у остальных блоков страницы:
     длинный текст («Самовывоз: По-хычыну на Зиповской») иначе растягивал плашку
     на узком экране от края до края, без полей. */
  max-width: calc(100% - 32px);
  padding: 10px 16px;
  margin: 0 auto;
  background: var(--cream);
  color: var(--maroon);
  text-decoration: none;
  border-radius: 999px;
  font-size: 0.85rem;
  font-weight: 600;
}

.delivery-info-text {
  display: flex;
  align-items: center;
  gap: 6px;
}

.delivery-info-action {
  color: var(--red);
  font-weight: 700;
  white-space: nowrap;
}

/* Гость уже ответил гейту (см. address-gate-backdrop) — тот же ряд, но
   персональный результат вместо общего тарифа, зелёным как hours-open. */
.delivery-info.delivery-info-answered {
  background: #e6f0ea;
  color: var(--green);
}

.delivery-info.delivery-info-answered .delivery-info-action {
  color: var(--green);
}

/* ---------- Гейт проверки адреса на главной ---------- */

.address-gate-backdrop {
  position: fixed;
  inset: 0;
  z-index: 500;
  background: rgba(31, 27, 32, 0.55);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 16px;
}

.address-gate-backdrop[hidden] {
  display: none;
}

.address-gate-modal {
  position: relative;
  background: var(--white);
  border-radius: 16px;
  padding: 20px;
  max-width: 420px;
  width: 100%;
  max-height: calc(100dvh - 32px);
  overflow-y: auto;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.28);
}

.address-gate-close {
  position: absolute;
  top: 10px;
  right: 10px;
  width: 32px;
  height: 32px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--cream);
  color: var(--ink);
  font-size: 1rem;
  line-height: 1;
  cursor: pointer;
}

.address-gate-close:active { background: #ddd0b5; }

.address-gate-modal h2 {
  font-family: var(--font-head);
  color: var(--maroon);
  margin: 0 0 6px;
  font-size: 1.3rem;
}

.address-gate-modal > p {
  margin: 0 0 12px;
  font-size: 0.9rem;
  color: var(--text-muted);
}

.gate-success {
  display: flex;
  align-items: center;
  gap: 10px;
  background: #eaf3ee;
  border: 1px solid #bcdec9;
  border-radius: 12px;
  padding: 12px 14px;
  margin: 8px 0 4px;
}

.gate-success[hidden] {
  display: none;
}

#gate-continue-btn[hidden] {
  display: none;
}

.gate-success-icon {
  font-size: 1.6rem;
  line-height: 1;
}

.gate-success-title {
  margin: 0;
  font-family: var(--font-head);
  font-size: 1rem;
  color: var(--green);
}

.gate-success-detail {
  margin: 2px 0 0;
  font-size: 0.85rem;
  color: #3d6350;
}

.btn-link {
  display: block;
  width: 100%;
  text-align: center;
  background: none;
  border: none;
  padding: 8px 0;
  margin-top: 8px;
  color: var(--red);
  text-decoration: underline;
  cursor: pointer;
  font: inherit;
  font-size: 0.85rem;
}

.btn-link[hidden] {
  display: none;
}

/* Выбор точки самовывоза внутри гейта на главной (запуск Зиповской, 2026-10) —
   показывается после «Хочу самовывоз», когда точек самовывоза две и больше.
   Пока он открыт (.is-choosing-pickup), остальное содержимое модалки (адрес,
   проверка доставки) скрыто — остаётся только крестик и сам выбор. */
.address-gate-modal.is-choosing-pickup > :not(.gate-pickup-choice):not(.address-gate-close) {
  display: none;
}

.gate-pickup-choice[hidden] {
  display: none;
}

.gate-pickup-choice > p {
  margin: 0 0 12px;
  font-size: 0.9rem;
  color: var(--text-muted);
}

.gate-pickup-choice > p.submit-error {
  margin: 8px 0 0;
  font-size: 0.85rem;
}

.gate-pickup-list {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.gate-pickup-option {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 2px;
  width: 100%;
  text-align: left;
  background: var(--cream);
  border: 2px solid transparent;
  border-radius: 12px;
  padding: 12px 14px;
  font: inherit;
  color: var(--ink);
  cursor: pointer;
}

.gate-pickup-option strong {
  font-size: 0.95rem;
  color: var(--maroon);
}

.gate-pickup-option span {
  font-size: 0.82rem;
  color: var(--text-muted);
}

.gate-pickup-option:hover,
.gate-pickup-option:focus-visible {
  border-color: var(--red);
}

/* Фокус с клавиатуры — настоящее кольцо, а не только цвет рамки: у «текущей» точки
   (.is-current ниже) рамка зелёная и перебивает красную, а фокус диалог переводит
   именно на первую точку — без кольца он был бы не виден. */
.gate-pickup-option:focus-visible {
  outline: 3px solid var(--ink);
  outline-offset: 2px;
}

.gate-pickup-option.is-current {
  border-color: var(--green);
}

/* ---------- Табы категорий (липкие, под шапкой) ---------- */

.category-tabs {
  position: sticky;
  top: var(--header-height, 57px);
  z-index: 9;
  background: var(--white);
  border-bottom: 1px solid var(--border);
}

.cat-tabs-inner {
  display: flex;
  gap: 20px;
  overflow-x: auto;
  padding: 8px 16px 0;
  scrollbar-width: none;
}

.cat-tabs-inner::-webkit-scrollbar { display: none; }

.cat-tab {
  flex: 0 0 auto;
  white-space: nowrap;
  text-decoration: none;
  font-family: var(--font-body);
  font-weight: 600;
  font-size: 0.88rem;
  color: var(--text-faint);
  padding: 8px 2px;
  border-bottom: 2px solid transparent;
  transition: color 0.15s, border-color 0.15s;
}

.cat-tab.active {
  color: var(--red);
  border-bottom-color: var(--red);
}

/* ---------- Мини-корзина (липкая снизу) ---------- */

.mini-cart-bar {
  position: fixed;
  right: 16px;
  bottom: calc(16px + env(safe-area-inset-bottom));
  z-index: 20;
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--red);
  color: var(--white);
  padding: 13px 20px;
  border-radius: 999px;
  box-shadow: 0 6px 18px rgba(31,27,32,0.28);
  text-decoration: none;
}

.mini-cart-bar[hidden] {
  display: none;
}

.mini-cart-bar:active {
  background: var(--maroon);
}

.mini-cart-bar .mini-cart-total {
  font-family: var(--font-head);
  font-size: 1.1rem;
}

.mini-cart-bar .mini-cart-icon {
  font-size: 1.15rem;
  line-height: 1;
}

@media (min-width: 720px) {
  .mini-cart-bar {
    right: 24px;
    bottom: 24px;
  }
}

/* ---------- Плашка "добавить топинг?" ---------- */

.topping-toast {
  position: fixed;
  left: 12px;
  right: 12px;
  bottom: 12px;
  z-index: 25;
  background: var(--white);
  color: var(--ink);
  border-radius: 14px;
  padding: 10px;
  box-shadow: 0 6px 20px rgba(0,0,0,0.22);
  max-width: 480px;
  margin: 0 auto;
  animation: topping-toast-in 0.2s ease-out;
}

.topping-toast[hidden] {
  display: none;
}

body.has-mini-cart .topping-toast {
  bottom: 80px;
}

.topping-toast-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  margin-bottom: 8px;
}

.topping-toast-label {
  font-family: var(--font-head);
  font-size: 0.82rem;
  color: var(--maroon);
}

.topping-toast-close {
  background: none;
  border: none;
  color: var(--ink);
  opacity: 0.45;
  font-size: 1rem;
  padding: 4px 6px;
  cursor: pointer;
  line-height: 1;
  position: relative;
}

/* Видимая зона была ~28×24px — легче случайно принять апселл рядом,
   чем закрыть тост. Расширяем зону нажатия до 44px тем же приёмом,
   что и у qty-control, не трогая вёрстку тоста. */
.topping-toast-close::after {
  content: "";
  position: absolute;
  inset: -10px -12px;
}

.topping-toast-list {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 2px;
}

.topping-option-row {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 6px 8px;
  white-space: nowrap;
}

.topping-option-photo {
  width: 36px;
  height: 36px;
  border-radius: 8px;
  object-fit: cover;
  flex-shrink: 0;
}

.topping-option-name {
  font-weight: 600;
  font-size: 0.8rem;
}

.topping-option-price {
  font-size: 0.78rem;
  opacity: 0.75;
}

.topping-option-add {
  background: var(--red);
  color: var(--white);
  border: none;
  font-family: var(--font-head);
  font-size: 0.76rem;
  padding: 7px 12px;
  border-radius: 999px;
  white-space: nowrap;
  cursor: pointer;
}

.topping-option-add:disabled {
  opacity: 0.5;
  cursor: default;
}

@keyframes topping-toast-in {
  from { transform: translateY(16px); opacity: 0; }
  to { transform: translateY(0); opacity: 1; }
}

/* ---------- Баннер контроля качества ---------- */

.quality-banner {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--cream);
  border-radius: 14px;
  padding: 10px 12px;
  margin: 26px 0 10px;
  text-decoration: none;
  color: var(--ink);
}

.quality-banner img {
  width: 40px;
  height: 40px;
  border-radius: 50%;
  flex-shrink: 0;
}

.quality-banner-text {
  flex: 1;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--maroon);
  line-height: 1.3;
}

/* ---------- Промо приложения (App Store) ---------- */
/* Осознанно НЕ секция меню (см. .category-section h2) — самостоятельная
   карточка после всех товаров, чтобы не спорить с основным CTA заказа.
   Плоская, без тени — обычная карточка в потоке (см. The Floating-Only
   Rule в DESIGN.md). */

.app-promo {
  background: var(--cream);
  border-radius: 14px;
  padding: 18px 18px 20px;
  margin: 14px 0 10px;
}

.app-promo-title {
  margin: 0 0 12px;
  font-family: var(--font-head);
  font-size: 1.15rem;
  font-weight: 800;
  color: var(--ink);
}

.app-promo-list {
  list-style: none;
  margin: 0;
  padding: 0;
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.app-promo-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--ink);
}

.app-promo-icon {
  font-size: 1.15rem;
  color: var(--maroon);
}

.app-promo-badge-link {
  display: inline-block;
  line-height: 0;
  margin-top: 18px;
}

/* Правила Apple: не менять сам значок, только высоту (мин. 40px онлайн) —
   ширину не фиксируем, чтобы реальный файл встал с верной пропорцией.
   Отступы карточки (18px) вокруг бейджа перекрывают минимальное clear
   space Apple (высота строчной буквы "з" в "Загрузите"). */
.app-promo-badge {
  height: 44px;
  width: auto;
  display: block;
}

/* ---------- Промо приложения: нижний шит при входе ---------- */
/* Одноразовое ненавязчивое предложение поставить приложение при первом
   заходе — НЕ модалка (страница под ним живая: скроллится, заказ работает).
   Показывается только после того, как гейт адреса ("Доставим к вам?") уже
   закрыт/отвечен — см. scheduleAppEntrySheet() в home.html — поэтому с ним
   не пересекается. С cookie-баннером (templates/base.html) не пересекается
   по расположению: тот — обычная строка в потоке у ВЕРХА страницы, этот —
   плавающий у НИЗА, общей области экрана у них нет. */

.app-entry-sheet {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 400; /* ниже гейта адреса (500, .address-gate-backdrop) — так и не должны показываться разом */
  background: var(--white);
  border-top: 1px solid var(--border);
  border-radius: 16px 16px 0 0;
  box-shadow: 0 -8px 24px rgba(31, 27, 32, 0.18);
  padding: 16px 16px calc(16px + env(safe-area-inset-bottom));
  max-width: 520px;
  margin: 0 auto;
  transform: translateY(100%);
  opacity: 0;
  transition: transform 0.32s ease, opacity 0.32s ease;
}

.app-entry-sheet[hidden] {
  display: none;
}

.app-entry-sheet.is-visible {
  transform: translateY(0);
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .app-entry-sheet {
    transition: none;
  }
}

.app-entry-sheet-close {
  position: absolute;
  top: 8px;
  right: 8px;
  width: 30px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: none;
  border-radius: 50%;
  background: var(--cream);
  color: var(--ink);
  font-size: 0.95rem;
  line-height: 1;
  cursor: pointer;
}

.app-entry-sheet-close:active { background: #ddd0b5; }

.app-entry-sheet-body {
  display: flex;
  align-items: center;
  gap: 12px;
  padding-right: 26px; /* крестик в углу не наезжает на текст */
}

.app-entry-sheet-icon {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  flex-shrink: 0;
}

.app-entry-sheet-title {
  margin: 0 0 2px;
  font-family: var(--font-head);
  font-size: 1rem;
  font-weight: 800;
  color: var(--maroon);
}

.app-entry-sheet-desc {
  margin: 0;
  font-size: 0.82rem;
  color: var(--text-muted);
  line-height: 1.35;
}

.app-entry-sheet-actions {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 12px;
}

.app-entry-sheet-cta {
  display: inline-block;
  line-height: 0;
}

.app-entry-sheet-badge {
  height: 42px;
  width: auto;
  display: block;
}

.app-entry-sheet-later {
  flex-shrink: 0;
  background: none;
  border: none;
  padding: 8px 2px;
  margin: 0;
  color: var(--text-muted);
  font: inherit;
  font-size: 0.85rem;
  text-decoration: underline;
  cursor: pointer;
  white-space: nowrap;
}

.app-entry-sheet-close:focus-visible,
.app-entry-sheet-later:focus-visible,
.app-entry-sheet-cta:focus-visible {
  outline: 2px solid var(--red);
  outline-offset: 2px;
}

/* Пока шит открыт, приподнимаем плавающую кнопку корзины на его высоту
   (--app-sheet-h выставляет JS через offsetHeight), иначе шит на всю ширину
   экрана перекрывает её собой и блокирует переход в корзину. Через класс на
   body (а не переопределением .mini-cart-bar напрямую), чтобы не спорить по
   порядку источника с медиа-запросом для широких экранов ниже по файлу —
   .mini-cart-bar { bottom: 24px } там же. */
body.app-entry-sheet-open .mini-cart-bar {
  transition: bottom 0.28s ease;
  bottom: calc(16px + env(safe-area-inset-bottom) + var(--app-sheet-h, 0px));
}

@media (min-width: 720px) {
  body.app-entry-sheet-open .mini-cart-bar {
    bottom: calc(24px + var(--app-sheet-h, 0px));
  }
}

/* ---------- Промо приложения: страница статуса заказа ---------- */
/* "Спасибо, заказ принят" / статус заказа — спокойный блок ниже основного
   действия (кнопка "Вернуться в меню"), без спора с ней. Рендерится в
   разметке для всех (см. SHOW_APP_STORE_PROMO в шаблоне), но остаётся
   hidden, пока JS не подтвердит iPhone/iPad (см. phRevealIOSOnlyPromo
   в cart.js). */

.order-app-promo {
  background: var(--cream);
  border-radius: 14px;
  padding: 16px 18px;
  margin: 4px 0 18px;
  text-align: center;
}

.order-app-promo[hidden] {
  display: none;
}

.order-app-promo-title {
  margin: 0 0 4px;
  font-family: var(--font-head);
  font-size: 1rem;
  font-weight: 800;
  color: var(--maroon);
}

.order-app-promo-desc {
  margin: 0 0 12px;
  font-size: 0.85rem;
  color: var(--text-muted);
}

.order-app-promo-badge-link {
  display: inline-block;
  line-height: 0;
}

.order-app-promo-badge {
  height: 42px;
  width: auto;
  display: block;
  margin: 0 auto;
}

/* ---------- Промо приложения: тихая строка в чек-ауте ---------- */
/* Единственное место, где промо появляется прямо в процессе заказа — по
   просьбе владельца, но подчёркнуто тихо: под кнопкой оплаты, мелким
   текстом, без бейджа и без цвета CTA, чтобы не спорить с ней и не звать
   пересобирать текущую корзину в приложении. */

.checkout-app-hint {
  margin: 18px 0 4px;
  text-align: center;
  font-size: 0.8rem;
  color: var(--text-faint);
}

.checkout-app-hint[hidden] {
  display: none;
}

.checkout-app-hint a {
  color: var(--maroon);
  text-decoration: underline;
}

/* ---------- Категории / меню ---------- */

.category-section {
  padding: 22px 0 6px;
  scroll-margin-top: 112px;
}

.category-section h2 {
  font-size: 1.3rem;
  color: var(--maroon);
  border-bottom: 3px solid var(--red);
  display: inline-block;
  padding-bottom: 2px;
}

.category-intro {
  /* Для аудитории, впервые видящей хычыны, это главный обучающий текст
     на странице — он не должен быть самым мелким. max-width в ch (не em) —
     это реально ограничивает длину строки под ширину символа, а не почти
     не работает вблизи ширины самой колонки. */
  margin: 6px 0 0;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--text-secondary);
  /* В кириллице символы у Montserrat в среднем уже, чем эталонный "0", на
     котором строится единица ch — 65ch на практике давал ~86 реальных
     символов в строке вместо расчётных 65. Понижено эмпирически. */
  max-width: 50ch;
}

.product-grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
  margin-top: 12px;
}

@media (min-width: 560px) {
  .product-grid { gap: 14px; }
}

@media (min-width: 720px) {
  .product-grid { grid-template-columns: repeat(3, 1fr); }
}

/* ---------- Десктоп ----------
   Раньше .container-wide была шире обычной .container (1120px против
   720px) ради 4 колонок в сетке товаров — но это давало две разные по
   ширине центрированные колонки на странице: контент сетки товаров,
   прижатый к левому краю СВОЕЙ более широкой колонки, визуально уезжал
   влево относительно героя/чипов, центрированных в узкой колонке. На
   реально широких мониторах разница огромна. Убрали — теперь на сайте
   везде одна колонка (720px), сетка остаётся 3-колоночной (см. выше). */
@media (min-width: 1024px) {
  /* Табы короткие и на десктопе не нуждаются в горизонтальном скролле —
     центрируем их, как и герой, и чипы доставки. */
  .cat-tabs-inner {
    justify-content: center;
  }
}

.product-card {
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  background: var(--white);
  position: relative;
}

.product-card .photo {
  aspect-ratio: 4 / 3.2;
  overflow: hidden;
  background: var(--cream);
  position: relative;
}

.badge-hit {
  position: absolute;
  top: 6px;
  left: 6px;
  background: var(--red);
  color: var(--white);
  font-family: var(--font-head);
  font-size: 0.7rem;
  padding: 3px 7px;
  border-radius: 999px;
  z-index: 1;
  box-shadow: 0 2px 6px rgba(0,0,0,0.25);
  white-space: nowrap;
}

.badge-halal {
  position: absolute;
  top: 6px;
  right: 6px;
  background: var(--green);
  color: var(--white);
  font-family: var(--font-head);
  font-size: 0.7rem;
  padding: 3px 7px;
  border-radius: 999px;
  z-index: 1;
  box-shadow: 0 2px 6px rgba(0,0,0,0.25);
  white-space: nowrap;
}

/* ---------- Товар "нет в наличии" (карточка остаётся на месте и видна,
   меняется только кнопка покупки и фото) ---------- */

.unavailable-label {
  display: inline-flex;
  align-items: center;
  font-family: var(--font-head);
  font-size: 0.72rem;
  color: var(--text-faint);
  background: var(--cream);
  border: 1px solid var(--border);
  padding: 6px 10px;
  border-radius: 999px;
  white-space: nowrap;
}

.product-card.is-unavailable .photo img,
.product-strip-card.is-unavailable .photo img,
.topping-swatch.is-unavailable .topping-swatch-photo img {
  filter: grayscale(0.9);
  opacity: 0.5;
}

.product-card .photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.product-card .body {
  padding: 8px 9px 10px;
  display: flex;
  flex-direction: column;
  gap: 3px;
  flex: 1;
}

.product-card h3 {
  font-size: 0.85rem;
  font-family: var(--font-body);
  font-weight: 700;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  line-height: 1.25;
  height: 3.75em;
  min-height: 0;
}

.product-card .desc {
  font-size: 0.82rem;
  color: var(--text-muted);
  margin: 0;
  flex: 1;
  /* Описания-простыни (до 10 строк) раздували карточку на весь экран —
     сворачиваем до 3 строк, полный текст раскрывается тапом (cart.js). */
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  cursor: pointer;
}

.product-card .desc.expanded {
  display: block;
  -webkit-line-clamp: unset;
  overflow: visible;
}

.product-card .meta {
  font-size: 0.8rem;
  color: var(--text-faint);
  margin: 0;
}

.product-card .product-rating {
  font-size: 0.8rem;
  font-weight: 700;
  color: #7a5b00;
  margin: 0;
}

.product-rating-count {
  font-weight: 400;
  color: var(--text-faint);
}

.product-card .row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  margin-top: auto;
  padding-top: 2px;
}

@media (min-width: 560px) {
  .product-card h3 { font-size: 1rem; }
  .product-card .body { padding: 10px 12px 12px; gap: 4px; }
}

.price {
  font-weight: 700;
  color: var(--red);
  font-size: 0.88rem;
  font-variant-numeric: tabular-nums;
}

/* ---------- Компактная лента (категории с большим числом позиций, напр. напитки) ---------- */

.product-strip {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  padding: 12px 0 4px;
  scrollbar-width: none;
}

.product-strip::-webkit-scrollbar { display: none; }

/* На широких экранах горизонтальный скролл без стрелок прятал 2/3 напитков
   за обрезанной последней карточкой — на десктопе просто переносим в сетку,
   как остальные категории. */
@media (min-width: 1024px) {
  .product-strip {
    display: grid;
    grid-template-columns: repeat(5, 1fr);
    gap: 18px;
    overflow-x: visible;
  }
  .product-strip-card { flex: initial; }
}

.product-strip-card {
  flex: 0 0 122px;
  border: 1px solid var(--border);
  border-radius: 14px;
  overflow: hidden;
  background: var(--white);
  display: flex;
  flex-direction: column;
}

.product-strip-card .photo {
  aspect-ratio: 1 / 1;
  overflow: hidden;
  background: var(--cream);
  position: relative;
}

.product-strip-card .photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.product-strip-card .body {
  padding: 7px 8px 9px;
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex: 1;
}

.product-strip-card h3 {
  font-size: 0.8rem;
  font-family: var(--font-body);
  font-weight: 700;
  margin: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  line-height: 1.25;
  height: 2.5em;
  min-height: 0;
}

.product-strip-card .strip-desc {
  font-size: 0.875rem;
  color: var(--text-muted);
  margin: 0;
  line-height: 1.3;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  /* Длинные слова (например, "негазированная") иначе вылезают за пределы
     узкой карточки вместо переноса — line-clamp сам по себе режет строки,
     но не разбивает слово, которое шире всей колонки. */
  overflow-wrap: break-word;
}

.product-strip-card .row {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 4px;
  margin-top: auto;
}

.product-strip-card .price {
  font-size: 0.8rem;
}

/* ---------- Топинги (палитра соусов) ---------- */

.topping-palette {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 18px 8px;
  padding: 10px 0 4px;
}

.topping-swatch {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.topping-swatch-photo {
  width: 72px;
  height: 72px;
  border-radius: 50%;
  overflow: hidden;
  box-shadow: 0 3px 10px rgba(0, 0, 0, 0.16);
  margin-bottom: 6px;
}

.topping-swatch-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.topping-swatch h3 {
  font-size: 0.8rem;
  font-family: var(--font-body);
  font-weight: 700;
  margin: 0 0 2px;
  line-height: 1.2;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  height: 2.4em;
  min-height: 0;
}

.topping-swatch .price {
  font-size: 0.76rem;
  display: block;
  margin-bottom: 4px;
}

.topping-swatch .qty-widget {
  display: flex;
  justify-content: center;
}

@media (min-width: 560px) {
  .topping-palette { grid-template-columns: repeat(5, 1fr); }
  .topping-swatch-photo { width: 84px; height: 84px; }
}

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

.btn {
  display: inline-block;
  border: none;
  border-radius: 10px;
  padding: 9px 16px;
  font-family: var(--font-body);
  font-weight: 700;
  font-size: 0.9rem;
  cursor: pointer;
  text-decoration: none;
  text-align: center;
}

.btn-primary {
  background: var(--red);
  color: var(--white);
}

.btn-primary:active { background: var(--maroon); }

.btn-outline {
  background: transparent;
  border: 2px solid var(--red);
  color: var(--red);
}

.btn-block { display: block; width: 100%; }

.btn-sm { padding: 6px 10px; font-size: 0.8rem; }

.btn:disabled { opacity: 0.55; cursor: not-allowed; }

/* ---------- Корзина ---------- */

.cart-line {
  display: flex;
  gap: 10px;
  align-items: center;
  padding: 12px 0;
  border-bottom: 1px solid #eee2d0;
}

.cart-line img {
  width: 56px;
  height: 56px;
  object-fit: cover;
  border-radius: 8px;
  flex-shrink: 0;
}

.cart-line .info { flex: 1; min-width: 0; }
.cart-line .name { font-weight: 700; font-size: 0.9rem; }

.qty-control {
  display: flex;
  align-items: center;
  gap: 10px;
}

.qty-control button {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: 1px solid var(--red);
  background: var(--white);
  color: var(--red);
  font-size: 1.05rem;
  line-height: 1;
  cursor: pointer;
  position: relative;
}

/* Зона нажатия шире видимого кружка (34px → 44px): норма для большого пальца,
   не ломая компактную вёрстку карточек. Расширение ±5px при зазоре 10px —
   соседние +/- не перекрываются. */
.qty-control button::after,
.add-btn::after {
  content: "";
  position: absolute;
  inset: -5px;
  border-radius: 50%;
}

.add-btn {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  border: none;
  background: var(--red);
  color: var(--white);
  font-size: 1.2rem;
  line-height: 1;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  position: relative;
}

.add-btn:active { background: var(--maroon); }

/* Кнопка "+" на границе MAX_ORDER_ITEM_QTY (config.py) — та же форма, что и
   обычная qty-control button, но приглушена и без указателя-руки: видно,
   что дальше не пойдёт, без отдельного текста-пояснения на самой кнопке. */
.qty-control button:disabled {
  opacity: 0.35;
  cursor: default;
}

.cart-total {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-head);
  font-size: 1.1rem;
  padding: 16px 0;
  font-variant-numeric: tabular-nums;
}

.empty-state {
  text-align: center;
  padding: 40px 16px;
  color: var(--text-muted);
}

.delivery-nudge {
  background: var(--cream);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 0.82rem;
  font-weight: 600;
  color: var(--maroon);
  margin: 10px 0;
}

.delivery-nudge a {
  text-decoration: underline;
}

.cookie-banner {
  background: var(--cream);
  border-bottom: 1px solid var(--border);
  font-size: 0.85rem;
  padding: 10px 16px;
}

.cookie-banner[hidden] {
  display: none;
}

.cookie-banner-inner {
  display: flex;
  align-items: center;
  justify-content: center;
  flex-wrap: wrap;
  gap: 10px;
}

.cookie-banner a {
  color: var(--maroon);
}

.payment-pause-banner {
  background: var(--red);
  color: var(--white);
  font-size: 0.85rem;
  font-weight: 600;
  text-align: center;
  padding: 10px 16px;
  line-height: 1.5;
}

.payment-pause-banner a {
  color: var(--white);
  text-decoration: underline;
}

.closed-banner {
  background: #f3ece0;
  border: 1px solid #ddcda9;
  border-radius: 10px;
  padding: 12px 14px;
  font-size: 0.85rem;
  font-weight: 600;
  color: var(--maroon);
  margin-bottom: 16px;
}

.upsell {
  margin: 14px 0;
}

.upsell-title {
  font-family: var(--font-head);
  font-size: 0.85rem;
  color: var(--maroon);
  margin-bottom: 8px;
}

.upsell-row {
  display: flex;
  gap: 10px;
  overflow-x: auto;
  padding-bottom: 4px;
}

.upsell-card {
  flex: 0 0 120px;
  border: 1px solid var(--border);
  border-radius: 14px;
  padding: 8px;
  text-align: center;
  display: flex;
  flex-direction: column;
}

.upsell-card img {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 8px;
  margin-bottom: 6px;
}

.upsell-name {
  font-size: 0.78rem;
  font-weight: 600;
  line-height: 1.2;
  height: 2.4em;
  min-height: 0;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

.upsell-bottom-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 6px;
  margin-top: auto;
  padding-top: 6px;
}

.upsell-price {
  font-size: 0.78rem;
  color: var(--red);
  font-weight: 700;
}

/* ---------- Формы ---------- */

.form-group { margin-bottom: 14px; }

.form-row-split {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 8px;
  margin-bottom: 14px;
}

.form-row-split .form-group {
  margin-bottom: 0;
}

.form-row-split input {
  padding-left: 8px;
  padding-right: 8px;
}

label {
  display: block;
  font-size: 0.82rem;
  font-weight: 600;
  margin-bottom: 4px;
}

.label-optional {
  font-size: 0.8rem;
  font-weight: 500;
  color: var(--text-muted);
}

input[type=text], input[type=tel], input[type=date], input[type=time], textarea, select {
  width: 100%;
  padding: 10px 12px;
  border: 1px solid #d8cdb8;
  border-radius: 10px;
  font-family: var(--font-body);
  font-size: 0.95rem;
  background: var(--white);
  color: var(--ink);
}

/* input[type=date]/[time] не наследуют цвет через `color` для своей
   встроенной иконки календаря/часов (Chrome/Safari/Edge) — красим отдельно,
   иначе иконка остаётся серой и торчит инородным пятном рядом с текстом. */
input[type=date]::-webkit-calendar-picker-indicator,
input[type=time]::-webkit-calendar-picker-indicator {
  filter: invert(28%) sepia(23%) saturate(2018%) hue-rotate(324deg) brightness(92%) contrast(90%);
  cursor: pointer;
}

.radio-row {
  display: flex;
  gap: 16px;
  font-size: 0.9rem;
}

/* ---------- Сегментированный переключатель (Получение / Когда нужен заказ) ---------- */

.segmented-toggle {
  display: flex;
  gap: 3px;
  background: var(--cream);
  border-radius: 999px;
  padding: 3px;
}

.segmented-toggle label {
  flex: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  text-align: center;
  gap: 0;
  padding: 6px 8px;
  border-radius: 999px;
  font-weight: 600;
  font-size: 0.82rem;
  line-height: 1.25;
  color: var(--ink);
  cursor: pointer;
  transition: background 0.15s, color 0.15s;
}

.segmented-toggle input[type="radio"] {
  position: absolute;
  width: 1px; height: 1px;
  opacity: 0;
  pointer-events: none;
}

.segmented-toggle label:has(input:checked) {
  background: var(--maroon);
  color: var(--white);
}

.segmented-toggle label:has(input:checked) .fulfillment-time {
  color: var(--white);
  opacity: 0.8;
}

.segmented-toggle label:has(input:disabled) {
  opacity: 0.45;
  cursor: not-allowed;
}

.segmented-toggle label:has(input:focus-visible) {
  outline: 2px solid var(--maroon);
  outline-offset: 2px;
}

.segmented-toggle .fulfillment-time {
  font-weight: 500;
  font-size: 0.72rem;
  line-height: 1.2;
  color: var(--text-muted);
}

/* Нативные контролы в цветах бренда вместо дефолтного синего. */
input[type="radio"],
input[type="checkbox"] {
  accent-color: var(--red);
}

.submit-error {
  color: var(--red);
  font-weight: 600;
  margin: 0 0 8px;
}

.payment-note {
  font-size: 0.8rem;
  color: var(--text-muted);
  text-align: center;
  margin: 10px 0 0;
  line-height: 1.5;
}

.pickup-single-card {
  display: flex;
  flex-direction: column;
  gap: 2px;
  background: var(--cream);
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 0.9rem;
}

.pickup-single-card span {
  font-size: 0.82rem;
  color: var(--text-muted);
}

.fulfillment-time {
  color: var(--text-muted);
  font-size: 0.82rem;
}

.delivery-hint {
  font-size: 0.82rem;
  color: var(--text-muted);
  margin: 6px 0 0;
}

.address-autocomplete { position: relative; }

.address-suggestions {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 5;
  background: var(--white);
  border: 1px solid var(--border);
  border-top: none;
  border-radius: 0 0 10px 10px;
  box-shadow: 0 6px 14px rgba(0,0,0,0.08);
  max-height: 220px;
  overflow-y: auto;
}

.address-suggestion-item {
  padding: 9px 12px;
  font-size: 0.85rem;
  cursor: pointer;
  border-bottom: 1px solid #f2ece1;
}

.address-suggestion-item:last-child { border-bottom: none; }
.address-suggestion-item:hover,
.address-suggestion-item--active { background: var(--cream); }

.consent-row { margin-top: 4px; }
.consent-label {
  display: flex;
  align-items: flex-start;
  gap: 8px;
  font-size: 0.82rem;
  color: var(--text-secondary);
  line-height: 1.4;
}
.consent-label input { margin-top: 3px; flex-shrink: 0; }
.consent-label a { color: var(--red); }

/* ---------- Локации ---------- */

.location-card {
  background: var(--cream);
  border-radius: 14px;
  padding: 14px 16px;
  margin-bottom: 14px;
}

.location-card h3 {
  font-family: var(--font-body);
  font-size: 1.05rem;
  margin-bottom: 4px;
}

.location-card .meta { font-size: 0.85rem; color: var(--text-secondary); margin: 2px 0; }

.location-map {
  margin: 10px 0;
  border-radius: 10px;
  overflow: hidden;
  border: 1px solid var(--border);
}
.location-map iframe { display: block; }

.policy-page { padding-bottom: 20px; }
.policy-page h3 {
  font-family: var(--font-body);
  font-size: 1rem;
  color: var(--maroon);
  margin: 20px 0 6px;
}
.policy-page p {
  font-size: 0.88rem;
  line-height: 1.5;
  color: #3a342e;
  margin: 0 0 4px;
}
.policy-page .meta {
  font-size: 0.8rem;
  color: var(--text-faintest);
  margin-bottom: 16px;
}

/* ---------- Страница 404 ---------- */

.not-found {
  text-align: center;
  padding: 60px 16px;
}

.not-found-emoji {
  font-size: 3rem;
  margin-bottom: 12px;
}

.not-found h2 {
  color: var(--maroon);
  margin-bottom: 8px;
}

.not-found p {
  color: var(--text-muted);
  font-size: 0.9rem;
  margin: 0 0 20px;
}

/* ---------- Футер ---------- */

.site-footer {
  background: var(--cream);
  color: var(--ink);
  text-align: center;
  padding: 24px 16px 28px;
  margin-top: 30px;
  font-size: 0.82rem;
  border-top: 1px solid #ddcda9;
}

.site-footer .tagline {
  font-family: var(--font-head);
  font-size: 0.95rem;
  color: var(--maroon);
  margin-bottom: 6px;
}

.footer-hours {
  margin-top: 10px;
}

.footer-contacts {
  display: flex;
  justify-content: center;
  gap: 16px;
  flex-wrap: wrap;
  margin-top: 8px;
  font-size: 0.8rem;
}

.footer-contacts a {
  color: var(--maroon);
  text-decoration: none;
}

/* ---------- Полоски (мотив тента/фартука) ---------- */

.stripe-bar {
  height: 5px;
  background: repeating-linear-gradient(
    45deg,
    var(--red) 0 14px,
    var(--cream) 14px 28px
  );
}

/* ---------- Плашки статуса / подтверждение заказа ---------- */

.status-card {
  background: var(--cream);
  border-radius: 14px;
  padding: 24px 20px;
  text-align: center;
  margin: 20px 0;
}

.status-card h2 { color: var(--maroon); }

.order-status-block {
  margin-bottom: 18px;
}

.current-status {
  text-align: center;
  font-family: var(--font-head);
  font-size: 1rem;
  color: var(--red);
  margin-bottom: 14px;
}

.status-steps {
  display: flex;
  justify-content: space-between;
  position: relative;
}

.status-steps::before {
  content: "";
  position: absolute;
  top: 8px;
  left: 8%;
  right: 8%;
  height: 2px;
  background: var(--border);
  z-index: 0;
}

.status-step {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 6px;
  flex: 1;
}

.status-step .dot {
  width: 16px;
  height: 16px;
  border-radius: 50%;
  background: var(--white);
  border: 2px solid var(--border);
}

.status-step.done .dot { background: var(--red); border-color: var(--red); }
.status-step.active .dot { background: var(--maroon); border-color: var(--maroon); box-shadow: 0 0 0 4px rgba(137,42,31,0.15); }

.status-step .step-name {
  font-size: 0.68rem;
  text-align: center;
  color: var(--text-faintest);
}

.status-step.done .step-name,
.status-step.active .step-name { color: var(--ink); font-weight: 600; }

.track-hint {
  text-align: center;
  font-size: 0.78rem;
  color: var(--text-faintest);
  margin-top: 10px;
}

/* ---------- Оценка заказа ---------- */

.rating-form {
  background: var(--cream);
  border-radius: 14px;
  padding: 16px;
  margin: 18px 0;
}

.rating-form h3 {
  font-size: 1rem;
  color: var(--maroon);
  margin-bottom: 10px;
}

.rating-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  padding: 8px 0;
  border-bottom: 1px solid rgba(0,0,0,0.06);
}

.rating-row:last-of-type {
  border-bottom: none;
}

.rating-row-name {
  font-size: 0.85rem;
  flex: 1;
  min-width: 0;
}

.star-rating {
  display: inline-flex;
  flex-direction: row-reverse;
  gap: 2px;
  flex-shrink: 0;
}

.star-rating input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}

.star-rating label {
  font-size: 1.5rem;
  line-height: 1;
  color: #d8cdb8;
  cursor: pointer;
  /* Глиф ~24px — расширяем зону нажатия до 44px, не раздвигая сами звёзды. */
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  margin: -10px -12px;
}

.star-rating input:checked ~ label,
.star-rating label:hover,
.star-rating label:hover ~ label {
  color: var(--red);
}

.rating-thanks {
  background: var(--cream);
  border-radius: 14px;
  padding: 14px 16px;
  margin: 18px 0;
  text-align: center;
  font-weight: 600;
  color: var(--maroon);
}

.badge-test {
  display: inline-block;
  background: var(--ink);
  color: var(--white);
  font-size: 0.72rem;
  padding: 3px 10px;
  border-radius: 999px;
  margin-bottom: 10px;
}

/* ---------- Админка ---------- */

.admin-header {
  background: var(--maroon);
  color: var(--white);
  padding: 12px 0;
  /* position: relative + z-index — ревью 2026-09-28 (panel-ui-c2, фикс
     подложки под .period-dates-form, см. .period-dates-backdrop ниже):
     подложка — position: fixed; inset: 0 (весь вьюпорт, не только область
     под чипами), поэтому без явного z-index здесь она перекрывала бы и
     САМУ шапку (ссылка на /admin, кнопка «Выйти») — не только контент под
     попапом. Клик по «Выйти»/логотипу при открытой панели дат закрывал бы
     панель ВМЕСТО перехода/выхода, второй клик уже требовался бы для
     самого действия. 10 — заведомо больше z-index подложки (5) и самой
     формы дат (6), с запасом; ни с чем ещё в админке не конфликтует (сверено
     grep по z-index в этом файле — .site-header с тем же z-index:10 это
     ПУБЛИЧНЫЙ хедер, в разметке админки не участвует). */
  position: relative;
  z-index: 10;
}

.admin-header-inner {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 12px;
}

.admin-brand {
  color: var(--white);
  text-decoration: none;
  font-family: var(--font-head);
  font-size: 0.95rem;
}

/* Кнопка «Выйти» в шапке админки — жалоба владельца 2026-09-28: общий
   .btn-outline (border/color: var(--red)) на тёмно-красном .admin-header
   (background: var(--maroon)) даёт красный текст/обводку на красном фоне —
   контраст ~1.1:1, кнопка почти не видна. Не трогаем сам .btn-outline (он
   общий для всей остальной админки И публичного сайта — WhatsApp/Telegram
   на checkout.html, «Вернуться в меню» на confirmation и т.д., там фон
   светлый и текущий контраст в порядке) — переопределяем ТОЛЬКО внутри
   .admin-header. var(--white) на var(--maroon) — контраст 8.62:1 (расчёт
   WCAG), с большим запасом выше AA (4.5:1). Остальной вид шапки (фон,
   .admin-brand) не меняется. */
.admin-header .btn-outline {
  border-color: var(--white);
  color: var(--white);
}
.admin-header .btn-outline:focus-visible {
  outline: 2px solid var(--white);
  outline-offset: 2px;
}

.admin-main {
  padding: 24px 16px 60px;
}

.admin-nav-cards {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 16px;
  max-width: 360px;
}

.admin-nav-card {
  display: block;
  background: var(--cream);
  border-radius: 14px;
  padding: 16px;
  text-decoration: none;
  color: var(--maroon);
  font-weight: 700;
  font-family: var(--font-head);
  font-size: 0.95rem;
}

/* Замочная карточка «Сайт и приложение — для владельца» (задача 2026-09-27, обычный
   admin без «режима владельца», см. templates/admin_dashboard.html) — та же
   форма/размер, что и у обычной .admin-nav-card (общий список, не должна
   прыгать по высоте/ширине), но приглушённая: полупрозрачный фон и пунктирная
   рамка вместо сплошной заливки, сигнализируют "не обычный пункт меню, туда
   нужен отдельный вход" ещё до чтения текста. Остаётся вне .stats-page (эта
   карточка — на /admin, не на /admin/stats) — поэтому токены --sp-* здесь не
   определены и не используются, только уже существующие --maroon/--border. */
.admin-nav-card--locked {
  background: transparent;
  border: 1.5px dashed var(--border);
  color: var(--maroon);
  opacity: 0.72;
}

.admin-product-row {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}

.admin-product-row img {
  width: 48px;
  height: 48px;
  object-fit: cover;
  border-radius: 8px;
  flex-shrink: 0;
}

.admin-product-info {
  flex: 1;
  min-width: 0;
}

.admin-product-name {
  font-weight: 700;
  font-size: 0.85rem;
}

.admin-product-meta {
  font-size: 0.78rem;
  color: var(--text-faintest);
  margin-top: 2px;
}

.admin-product-actions {
  display: flex;
  flex-direction: column;
  gap: 4px;
  flex-shrink: 0;
}

.admin-product-actions .btn { white-space: nowrap; }

/* /admin/products — «нет в наличии» по точкам (запуск Зиповской, 2026-10).
   Под обычной строкой товара — блок переключателей: «Все точки сразу» (общий
   products.is_available) и по одной строке на каждую открытую точку. Строка
   товара переносится (wrap), блок занимает всю ширину под ней. */
.admin-product-row { flex-wrap: wrap; }

.admin-product-avail {
  flex: 0 0 100%;
  display: flex;
  flex-direction: column;
  gap: 6px;
  margin-top: 4px;
}

.admin-avail-line {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 4px 10px;
  font-size: 0.8rem;
}

.admin-avail-line form { margin: 0; }

.admin-avail-name {
  font-weight: 700;
  flex: 1 1 11em;
  min-width: 0;
}

.admin-avail-state {
  flex: 1 1 8em;
  min-width: 0;
}

.admin-avail-state.is-on { color: var(--green); font-weight: 600; }
.admin-avail-state.is-off { color: var(--red); font-weight: 600; }
.admin-avail-state.is-na { color: var(--text-faintest); font-style: italic; }

.admin-avail-line .btn { white-space: nowrap; }

/* «Все точки сразу» — общий флаг products.is_available, не основной
   инструмент (основной — стоп на конкретной точке ниже): приглушён. */
.admin-avail-line--global {
  padding-bottom: 6px;
  border-bottom: 1px dashed var(--border);
}

.admin-avail-line--global .admin-avail-name {
  font-weight: 600;
  color: var(--text-faintest);
}

.admin-avail-line--global .btn-outline {
  border-color: var(--border);
  color: var(--text-muted);
}

/* «Скрыть с сайта и приложения» (products.is_hidden): первая строка блока, как «Все точки сразу», отделена
   пунктиром; у скрытого товара строка и фото приглушены, рядом с названием — метка «скрыт». */
.admin-avail-line--visibility {
  padding-bottom: 6px;
  border-bottom: 1px dashed var(--border);
}

.admin-avail-line--visibility .admin-avail-name {
  font-weight: 600;
}

.admin-product-row.is-product-hidden > img {
  opacity: 0.45;
}

.admin-hidden-badge {
  display: inline-block;
  margin-left: 6px;
  padding: 1px 8px;
  border-radius: 999px;
  background: var(--red);
  color: #fff;
  font-size: 0.72rem;
  font-weight: 600;
  vertical-align: middle;
}

.admin-avail-hint {
  font-size: 0.8rem;
  color: var(--text-faintest);
  margin: 10px 0 0;
}

/* Товар скрыт на всех точках (products.is_available=0, .is-hidden-everywhere на блоке):
   отметки по точкам сохраняются, но сейчас ни на что не влияют — название и состояние
   приглушены до нейтрального серого (без зелёного/красного — это не «живой» статус; цвет
   --text-faintest читается, контраст 4.7:1, в отличие от opacity), над ними пояснение.
   Кнопки не приглушаем: переключатели рабочие (стоп на точке можно выставить заранее, до
   возврата товара в продажу). */
.admin-avail-shadow-note {
  margin: 0;
  font-size: 0.8rem;
  font-weight: 600;
  color: var(--red);
}

.admin-product-avail.is-hidden-everywhere .admin-avail-line[data-location-id] .admin-avail-name,
.admin-product-avail.is-hidden-everywhere .admin-avail-line[data-location-id] .admin-avail-state {
  color: var(--text-faintest);
  font-weight: 400;
}

/* /admin/locations — строка состояния точки (db.describe_location_orders):
   принимает ли она заказы на самом деле, а не только что стоит в галочках. */
.admin-loc-status {
  flex: 0 0 100%;
  font-size: 0.82rem;
  font-weight: 600;
}

.admin-loc-status--ok { color: var(--green); }
.admin-loc-status--warn { color: var(--red); }
.admin-loc-status--off { color: var(--text-faintest); }

.admin-loc-note {
  flex: 0 0 100%;
  font-size: 0.78rem;
  color: var(--text-faintest);
}

.admin-row-form {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  align-items: center;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
}

.admin-row-form input[type=text],
.admin-row-form input[type=number] {
  width: auto;
  flex: 1;
  min-width: 90px;
}

.admin-order-row {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  gap: 10px;
  padding: 10px 0;
  border-bottom: 1px solid var(--border);
  text-decoration: none;
  color: var(--ink);
}

.admin-order-title {
  font-weight: 700;
  font-size: 0.88rem;
}

.admin-order-preorder {
  display: inline-block;
  background: var(--cream);
  color: var(--maroon);
  font-size: 0.68rem;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 999px;
  margin-left: 6px;
}

/* BACKEND-04 (2026-09-24) — заказ аккаунта RuStore-модератора (orders.is_test,
   см. db.py/routers/mobile_api.py). Отдельный, узнаваемо ДРУГОЙ цвет от
   admin-order-preorder (кремовый/бордовый) и admin-order-unnotified (красный)
   — это не тревога и не обычный статус, а "этот заказ вообще не настоящий". */
.admin-order-test {
  display: inline-block;
  background: #6b3fa0;
  color: var(--white);
  font-size: 0.68rem;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 999px;
  margin-left: 6px;
}

.admin-order-unnotified {
  display: inline-block;
  background: var(--red);
  color: var(--white);
  font-size: 0.68rem;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 999px;
  margin-left: 6px;
}

.admin-order-meta {
  font-size: 0.78rem;
  color: var(--text-faintest);
  margin-top: 2px;
}

.admin-order-side {
  text-align: right;
  flex-shrink: 0;
}

.admin-order-total {
  font-weight: 700;
  color: var(--red);
  font-size: 0.9rem;
}

.admin-order-status {
  font-size: 0.72rem;
  color: var(--text-faintest);
  margin-top: 2px;
  white-space: nowrap;
}

@media (min-width: 720px) {
  html, body { font-size: 17px; }
}

/* ============================================================
   /admin/stats — редизайн «в стиле Apple» (2026-09-27)
   Скоуп: ТОЛЬКО .stats-page (эта страница + карточка клиента на
   /admin/orders?user_id=) — остальная админка (товары/точки/история
   заказов) не трогается ни шрифтом, ни цветами.

   Токены — фирменная палитра сайта (вариант «Б чистый», решение владельца
   2026-09-28): белые карточки на светлом тёплом фоне из тех же переменных,
   что и у остального сайта (--ink/--red/--maroon/--green/--border/
   --text-secondary/--text-faint), не системные цвета iOS. Тёмной темы нет —
   владелец ей не пользуется, страница всегда светлая независимо от
   системной настройки устройства (см. ниже — блок
   @media (prefers-color-scheme: dark) убран целиком). ---------- */

.stats-page {
  /* Вариант «Б чистый» — фирменный красный --red ТОЛЬКО как акцент (активная
     вкладка/чип, полоски и столбцы графика, ссылки), НЕ для главных чисел:
     --sp-label ниже — тёмный нейтральный var(--ink), не красный. Для
     "падения/тревоги" — фирменный --maroon (темнее и другого тона, чем
     акцентный --red, — чтобы не путать активную вкладку с сигналом "тут
     что-то не так"). Все пары ниже проверены расчётом WCAG AA (≥4.5:1) и на
     --sp-bg, и на белой карточке. */
  --sp-bg: #F8F3EA;
  --sp-card: var(--white);
  --sp-separator: var(--border);
  --sp-label: var(--ink);
  --sp-label-2: var(--text-secondary);
  --sp-label-3: var(--text-faint);
  --sp-accent: var(--red);
  --sp-accent-soft: rgba(173, 43, 33, 0.10);
  --sp-green: var(--green);
  --sp-red: var(--maroon);
  /* --sp-orange — тревога себестоимости (см. .owner-source-error/
     .stats-list-icon--orange) — не фирменный тон (на сайте своего оранжевого
     нет), но тёплый и с контрастом ≥4.5:1 и на --sp-bg, и на белой карточке
     (системный iOS #FF9500 этот порог не проходит, ~2:1). */
  --sp-orange: #8A4B0F;
  --sp-fill: rgba(31, 27, 32, 0.07);
  --sp-fill-2: rgba(31, 27, 32, 0.13);
  /* --sp-fill-3 — задача 2026-09-27, «Выручка»: третий сегмент
     .stats-splitbar-* (каналы зал/доставка/самовывоз, 3 категории — та же
     accent+серая-прогрессия палитра, что и у --sp-fill-2, НЕ новый цвет:
     splitbar намеренно двухцветный по всему дизайну (см. --sp-fill-2), а
     не радуга категорий. */
  --sp-fill-3: rgba(31, 27, 32, 0.22);
  --sp-radius-lg: 16px;
  --sp-radius-md: 12px;
  --sp-shadow: 0 1px 2px rgba(31, 27, 32, 0.04), 0 3px 12px rgba(31, 27, 32, 0.06);
  display: block;
  font-family: -apple-system, BlinkMacSystemFont, "SF Pro Text", "SF Pro Display", "Segoe UI", Roboto, sans-serif;
  color: var(--sp-label);
  -webkit-font-smoothing: antialiased;
}

/* Вариант «Б чистый» — заголовки страницы/карточек фирменным Bloc Heavy
   (var(--font-head), тот же шрифт, что у заголовков остального сайта),
   тело/цифры остаются системным шрифтом (плотные таблицы цифр читаются
   лучше на нейтральном UI-шрифте, см. .stats-title/.stats-card-title/
   .stats-superlogin-title ниже — там раньше стоял font-family: inherit,
   намеренно ушедший от Bloc Heavy; решением владельца 2026-09-28 это
   перевёрнуто обратно). letter-spacing: normal — отрицательный трекинг
   подобран под системный шрифт, на Bloc Heavy выглядит зажато. Bloc Heavy
   проверен на полный набор кириллицы (92/96 символов диапазона U+0400–
   U+045F, включая все буквы, которые встречаются в текстах этой страницы) —
   глифы есть. */
.stats-title, .stats-card-title, .stats-superlogin-title {
  font-family: var(--font-head);
  letter-spacing: normal;
}

/* .stats-canvas — ТОЛЬКО обёртка целой страницы /admin/stats (#stats-app),
   НЕ карточка клиента на /admin/orders (та использует один .stats-page
   ради токенов/шрифта, без полноэкранного grouped-фона — остальная часть
   /admin/orders не редизайнится, см. докстринг класса выше). Вырывается из
   padding .admin-main (24px 16px 60px), чтобы серый/чёрный grouped-фон
   доходил до самых краёв колонки админки (720px, не вьюпорта — вне
   скоупа перекраивать общий .container ради одной страницы), а не
   оставлял белую рамку вокруг канваса. min-height — фон не обрывается
   раньше конца короткой страницы (например при активном поиске без
   результатов) на границе видимой области.*/
.stats-canvas {
  background: var(--sp-bg);
  margin: -24px -16px -60px;
  padding: 24px 16px 60px;
  min-height: calc(100vh - 53px);
}

/* Широкий экран: .stats-canvas остаётся только у степ-ап входа «Режим владельца» (/admin/super/login) —
   фон цвета страницы заходит за узкую колонку админки (.admin-main, 720px) до краёв экрана. Без
   100vw/calc(50% - 50vw): они давали горизонтальную прокрутку страницы при обычной полосе прокрутки
   (Windows, замеры 2026-10-13). Вместо этого фон выходит за рамки тенью (box-shadow не входит в
   прокручиваемую область) и обрезается clip-path по вертикали. Рабочее место владельца (/admin/owner,
   /admin/stats) живёт в своей оболочке — templates/workspace.html + static/css/workspace.css. */
@media (min-width: 860px) {
  .stats-canvas {
    box-shadow: 0 0 0 100vmax var(--sp-bg);
    clip-path: inset(0 -100vmax);
  }
}

/* Тёмная тема убрана (решение владельца 2026-09-28 — он ей не пользуется,
   ей больше не место ни на /admin/stats, ни на /admin/owner, ни на
   /admin/super/login). Раньше здесь был
   @media (prefers-color-scheme: dark) { .stats-canvas.stats-page { ... } },
   переопределявший --sp-* на чёрную палитру для полностью редизайненных
   страниц (карточка клиента на /admin/orders?user_id= использует токены
   .stats-page без .stats-canvas и его не касался и раньше, см. её докстринг
   выше — сам список заказов остаётся светлым всегда) — блок удалён целиком,
   эти страницы всегда светлые независимо от системной настройки
   устройства. */

.stats-page a { text-decoration: none; color: inherit; }

.stats-page *:focus-visible {
  outline: 2px solid var(--sp-accent);
  outline-offset: 2px;
  border-radius: 6px;
}

@media (prefers-reduced-motion: reduce) {
  .stats-page * { transition: none !important; animation: none !important; scroll-behavior: auto !important; }
}

.stats-title {
  /* font-family/letter-spacing — из общего правила
     .stats-title, .stats-card-title, .stats-superlogin-title выше (Bloc
     Heavy, вариант «Б чистый», решение владельца 2026-09-28). Не
     переопределяем здесь ни то, ни другое — иначе более позднее (это же)
     правило той же специфичности снова утащило бы заголовок на системный
     шрифт с отрицательным трекингом, подобранным под него. */
  font-size: 2rem;
  font-weight: 750;
  margin: 4px 0 14px;
  color: var(--sp-label);
}

/* ---------- Сегментированный контроль (период/канал/точка/метрика/способ входа) ---------- */

.stats-sticky {
  position: sticky;
  top: 0;
  z-index: 5;
  margin: 0 -16px 16px;
  padding: 10px 16px;
  background: var(--sp-bg);
  background: color-mix(in srgb, var(--sp-bg) 82%, transparent);
  -webkit-backdrop-filter: blur(20px);
  backdrop-filter: blur(20px);
}

.stats-segmented {
  display: flex;
  gap: 2px;
  background: var(--sp-fill);
  border-radius: 10px;
  padding: 2px;
}

.stats-segmented-item {
  flex: 1;
  text-align: center;
  padding: 8px 6px;
  /* ≥44px — брифовый минимум зоны нажатия (см. общий докстринг блока
     редизайна «Accessibility: tap targets ≥44 px») — это ЕДИНСТВЕННЫЙ способ
     переключить период/канал/точку/метрику/способ входа на всей странице,
     поэтому не компактнее, чем любая другая интерактивная зона здесь же
     (карточки клиентов, кнопка «Показать ещё» — у них тот же 44px, см. ниже
     .stats-list-row/.stats-more). Раньше было 32px — найдено фреш-ревью
     2026-09-27 (замерено getBoundingClientRect на живой странице: 35.95px
     фактической высоты пилюли, чем эта min-height и была ограничена). */
  min-height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  border-radius: 8px;
  font-size: 0.86rem;
  font-weight: 590;
  color: var(--sp-label-2);
  white-space: nowrap;
}

.stats-segmented-item.is-active {
  background: var(--sp-card);
  color: var(--sp-accent);
  box-shadow: var(--sp-shadow);
}

.stats-segmented--sm .stats-segmented-item {
  padding: 6px 8px;
  /* Тот же 44px-минимум, что и у основного .stats-segmented-item выше (тем
     же брифовым требованием) — компактный размер шрифта/паддинга у --sm
     (Канал/Точка/Метрика/Способ входа) не повод давать более мелкую зону
     нажатия, чем у периода. */
  min-height: 44px;
  font-size: 0.78rem;
}

.stats-filters {
  display: flex;
  flex-direction: column;
  gap: 12px;
  margin-bottom: 18px;
}

.stats-filter-group { min-width: 0; }

.stats-filter-caption {
  font-size: 0.72rem;
  font-weight: 600;
  color: var(--sp-label-3);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  margin: 0 2px 5px;
}

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

.stats-kpi-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 10px;
  margin-bottom: 18px;
}

.stats-kpi-card {
  position: relative;
  background: var(--sp-card);
  border-radius: var(--sp-radius-lg);
  padding: 14px 14px 16px;
  box-shadow: var(--sp-shadow);
  min-width: 0;
  overflow: hidden;
}

.stats-kpi-label {
  font-size: 0.78rem;
  font-weight: 590;
  color: var(--sp-label-2);
}

.stats-kpi-value {
  font-size: 1.7rem;
  font-weight: 700;
  letter-spacing: -0.02em;
  margin-top: 3px;
  font-variant-numeric: tabular-nums;
  color: var(--sp-label);
}

.stats-kpi-delta {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 4px;
  font-size: 0.76rem;
  font-weight: 650;
  margin-top: 6px;
  font-variant-numeric: tabular-nums;
}

.stats-kpi-delta--up { color: var(--sp-green); }
.stats-kpi-delta--down { color: var(--sp-red); }
.stats-kpi-delta--flat { color: var(--sp-label-3); }
.stats-kpi-delta-arrow { font-size: 0.7rem; }
.stats-kpi-delta-note { color: var(--sp-label-3); font-weight: 500; }

.stats-spark {
  display: block;
  width: 100%;
  height: 22px;
  margin-top: 8px;
  overflow: visible;
}

.stats-spark polyline {
  fill: none;
  stroke: var(--sp-accent);
  stroke-width: 1.6;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.55;
}

@media (min-width: 640px) {
  .stats-kpi-grid { grid-template-columns: repeat(4, 1fr); }
  .stats-filters { flex-direction: row; }
  .stats-filter-group { flex: 1; }
}

/* ---------- Карточки разделов ---------- */

.stats-card {
  background: var(--sp-card);
  border-radius: var(--sp-radius-lg);
  padding: 16px;
  box-shadow: var(--sp-shadow);
  margin-bottom: 14px;
}

.stats-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 10px;
  margin-bottom: 12px;
}

.stats-card-header .stats-segmented { flex: 0 0 auto; }
.stats-card-header .stats-card-title { margin-bottom: 0; }

.stats-card-title {
  /* font-family/letter-spacing — из общего правила выше (см. комментарий у
     .stats-title): заголовки карточек ("Заказы в работе", "Проблемы",
     "По точкам", "Динамика" и т.д.) — фирменный Bloc Heavy. */
  font-size: 1.05rem;
  font-weight: 700;
  margin: 0 0 12px;
  color: var(--sp-label);
}

.stats-note {
  font-size: 0.8rem;
  color: var(--sp-label-2);
  line-height: 1.5;
  margin: 8px 2px 0;
}

.stats-empty {
  color: var(--sp-label-3);
  font-size: 0.85rem;
  padding: 20px 4px;
  text-align: center;
}

.stats-empty--chart { min-height: 120px; display: flex; align-items: center; justify-content: center; }

/* ---------- График (инлайн SVG, без внешних библиотек) ---------- */

.stats-chart-wrap {
  position: relative;
  overflow-x: auto;
  -webkit-overflow-scrolling: touch;
}

.stats-chart-wrap svg { display: block; }

/* Широкий экран (см. комментарий у .stats-canvas выше про breakout до
   1040px) — геометрия графика (routers/admin.py: _CHART_TARGET_WIDTH и
   соседние константы) по-прежнему считается под мобильную ширину карточки
   и НЕ тянется на всю широкую карточку (превратить 2-3 бара "Всё время" в
   растянутые на 900px гигантские прямоугольники было бы хуже, чем оставить
   как есть — сама суть "iOS-карточки", не тянуть контент насильно). Вместо
   этого центрируем сам SVG внутри карточки, а не оставляем его прижатым к
   левому краю с пустым полем справа (найдено фреш-ревью 2026-09-27) —
   `safe center`, чтобы график с МНОГИМИ барами (30 дней/24 часа), который
   шире карточки и всё ещё скроллится, не обрезался слева уже центрированным
   flex-контейнером. */
@media (min-width: 860px) {
  .stats-chart-wrap {
    display: flex;
    justify-content: safe center;
  }
}

.stats-chart-axis { stroke: var(--sp-separator); stroke-width: 1; }

.stats-chart-bar {
  fill: var(--sp-accent);
  cursor: pointer;
}

.stats-chart-bar:hover,
.stats-chart-bar:focus-visible { fill: var(--sp-accent); fill: color-mix(in srgb, var(--sp-accent) 82%, black); }

.stats-chart-label { fill: var(--sp-label-3); font-family: inherit; }

/* Фиксированная "полоса подсказки" у самого верха графика (JS двигает
   только по X, вслед за наведённым/выбранным баром) — не над каждым баром
   индивидуально: у высоких баров сверху почти нет места в пределах
   .stats-chart-wrap (см. _CHART_PAD_TOP в routers/admin.py — специально
   достаточный, чтобы этой полосе хватало высоты), а "подсказка над баром"
   для самого высокого бара упиралась бы в заголовок карточки сверху. */
.stats-chart-tooltip {
  position: absolute;
  top: 2px;
  transform: translateX(-50%);
  background: var(--sp-label);
  color: var(--sp-bg);
  border-radius: 8px;
  padding: 6px 10px;
  font-size: 0.72rem;
  line-height: 1.35;
  white-space: nowrap;
  pointer-events: none;
  z-index: 2;
  box-shadow: 0 4px 14px rgba(0, 0, 0, 0.18);
}

.stats-chart-tooltip-value { font-weight: 700; font-variant-numeric: tabular-nums; }
.stats-chart-tooltip-date { opacity: 0.72; }

/* ---------- Доли (сайт/приложение, точки, оплата) ---------- */

.stats-compare-block { margin-bottom: 14px; }
.stats-compare-block:last-child { margin-bottom: 0; }

.stats-compare-label {
  font-size: 0.78rem;
  font-weight: 600;
  color: var(--sp-label-2);
  margin-bottom: 8px;
}

.stats-splitbar-track {
  display: flex;
  height: 10px;
  border-radius: 5px;
  overflow: hidden;
  background: var(--sp-fill);
}

.stats-splitbar-seg { background: var(--sp-accent); }
.stats-splitbar-seg--2 { background: var(--sp-fill-2); }
/* --3/--4 — задача 2026-09-27, «Выручка»: канал зал/доставка/самовывоз
   (иногда +«прочее») — до 4 сегментов, не только 2 (сайт/приложение,
   точка А/точка Б), см. --sp-fill-3 выше. */
.stats-splitbar-seg--3 { background: var(--sp-fill-3); }
.stats-splitbar-seg--4 { background: var(--sp-fill); }

.stats-splitbar-legend {
  display: flex;
  flex-wrap: wrap;
  gap: 6px 16px;
  margin-top: 8px;
}

.stats-splitbar-legend-item {
  display: flex;
  align-items: baseline;
  gap: 6px;
  font-size: 0.78rem;
  min-width: 0;
}

.stats-splitbar-dot {
  width: 8px; height: 8px; border-radius: 50%;
  background: var(--sp-accent);
  flex-shrink: 0;
  align-self: center;
}
.stats-splitbar-dot--2 { background: var(--sp-fill-2); }
.stats-splitbar-dot--3 { background: var(--sp-fill-3); }
.stats-splitbar-dot--4 { background: var(--sp-fill); }

.stats-splitbar-legend-label { color: var(--sp-label); font-weight: 600; }
.stats-splitbar-legend-value { color: var(--sp-label-2); font-variant-numeric: tabular-nums; white-space: nowrap; }
.stats-splitbar-legend-detail { color: var(--sp-label-3); }

/* ---------- Списки в стиле iOS (Оплата / Версии приложения) ---------- */

.stats-list { display: flex; flex-direction: column; }

.stats-list-row {
  display: flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 9px 2px;
  border-bottom: 1px solid var(--sp-separator);
  font-size: 0.86rem;
}

.stats-list--tight .stats-list-row:last-child { border-bottom: none; }

.stats-list-icon {
  width: 28px; height: 28px;
  border-radius: 50%;
  display: flex; align-items: center; justify-content: center;
  flex-shrink: 0;
  background: var(--sp-fill);
  color: var(--sp-label-2);
}
.stats-list-icon--red { background: var(--sp-fill); background: color-mix(in srgb, var(--sp-red) 16%, transparent); color: var(--sp-red); }
.stats-list-icon--muted { background: var(--sp-fill); color: var(--sp-label-2); }

.stats-list-row-title { flex: 1; min-width: 0; color: var(--sp-label); }
.stats-list-row-value { color: var(--sp-label-2); font-variant-numeric: tabular-nums; font-weight: 600; white-space: nowrap; }

.stats-list-row--build { align-items: stretch; flex-direction: column; gap: 4px; }
.stats-list-row--build .stats-list-row-main { display: flex; flex-direction: column; gap: 6px; }
.stats-list-row--build { display: flex; flex-direction: row; align-items: center; }
.stats-list-row-main { flex: 1; min-width: 0; }
.stats-list-row-main .stats-list-row-title { font-size: 0.82rem; font-weight: 600; }

.stats-minibar-track {
  height: 5px;
  border-radius: 3px;
  background: var(--sp-fill);
  overflow: hidden;
}
.stats-minibar-fill { height: 100%; background: var(--sp-accent); border-radius: 3px; }

/* ---------- Постоянные гости: кольцо ---------- */

.stats-ring-row {
  display: flex;
  align-items: center;
  gap: 18px;
  flex-wrap: wrap;
}

.stats-ring-wrap { position: relative; width: 112px; height: 112px; flex-shrink: 0; }
.stats-ring-track { stroke: var(--sp-fill); }
.stats-ring-fill { stroke: var(--sp-accent); transition: stroke-dasharray 0.4s ease; }

.stats-ring-center {
  position: absolute; inset: 0;
  display: flex; align-items: center; justify-content: center;
}
.stats-ring-value { font-size: 1.3rem; font-weight: 750; font-variant-numeric: tabular-nums; }
.stats-ring-note { flex: 1; min-width: 180px; margin: 0; }

/* ---------- Клиенты ---------- */

.stats-search-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: 10px;
}

.stats-search {
  flex: 1 1 180px;
  display: flex;
  align-items: center;
  gap: 6px;
  background: var(--sp-fill);
  border-radius: 10px;
  padding: 8px 10px;
  color: var(--sp-label-3);
}

.stats-search input {
  border: none;
  background: transparent;
  outline: none;
  flex: 1;
  min-width: 0;
  font-size: 0.9rem;
  font-family: inherit;
  color: var(--sp-label);
}
.stats-search input::placeholder { color: var(--sp-label-3); }

.stats-customer-row {
  display: flex;
  align-items: center;
  gap: 12px;
  min-height: 60px;
  padding: 10px 2px;
  border-bottom: 1px solid var(--sp-separator);
}
.stats-list--rows .stats-customer-row:last-child { border-bottom: none; }

.stats-avatar {
  width: 38px; height: 38px;
  border-radius: 50%;
  background: var(--sp-accent-soft);
  color: var(--sp-accent);
  display: flex; align-items: center; justify-content: center;
  font-size: 0.82rem;
  font-weight: 700;
  flex-shrink: 0;
}

.stats-customer-main { flex: 1; min-width: 0; display: flex; flex-direction: column; gap: 2px; }
.stats-customer-name { font-weight: 650; font-size: 0.92rem; color: var(--sp-label); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; }
.stats-customer-sub { font-size: 0.78rem; color: var(--sp-label-2); display: flex; align-items: center; gap: 6px; min-width: 0; }
.stats-customer-email { min-width: 0; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
.stats-customer-date { font-size: 0.72rem; color: var(--sp-label-3); }

.stats-badge {
  font-size: 0.66rem;
  font-weight: 700;
  padding: 1px 6px;
  border-radius: 5px;
  background: var(--sp-fill);
  color: var(--sp-label-2);
  flex-shrink: 0;
}
.stats-badge--apple { background: var(--sp-fill-2); color: var(--sp-label); }

.stats-customer-trailing {
  display: flex;
  align-items: center;
  gap: 6px;
  flex-shrink: 0;
  color: var(--sp-label-2);
}
.stats-customer-orders { font-size: 0.82rem; font-weight: 600; white-space: nowrap; }
.stats-customer-sum { font-size: 0.82rem; font-weight: 700; color: var(--sp-label); white-space: nowrap; }
.stats-chevron { color: var(--sp-label-3); flex-shrink: 0; }

.stats-more {
  display: block;
  text-align: center;
  margin-top: 12px;
  padding: 10px;
  min-height: 44px;
  display: flex; align-items: center; justify-content: center;
  border-radius: 10px;
  background: var(--sp-fill);
  color: var(--sp-accent);
  font-weight: 650;
  font-size: 0.86rem;
}

/* ---------- Подвал ---------- */

.stats-fineprint {
  color: var(--sp-label-3);
  font-size: 0.74rem;
  line-height: 1.55;
  margin: 10px 2px 18px;
}

.stats-back { margin: 4px 2px 8px; }
.stats-back a { color: var(--sp-accent); font-weight: 600; }

/* ---------- Карточка клиента на /admin/orders?user_id= ---------- */

.stats-customer-card {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-bottom: 16px;
}

.stats-customer-card .stats-avatar { width: 52px; height: 52px; font-size: 1.05rem; }

.stats-customer-card-main { flex: 1; min-width: 0; }
.stats-customer-card-eyebrow { font-size: 0.7rem; font-weight: 650; text-transform: uppercase; letter-spacing: 0.04em; color: var(--sp-label-3); margin-bottom: 2px; }
.stats-customer-card-name { font-size: 1.05rem; font-weight: 700; color: var(--sp-label); }
.stats-customer-card-sub { font-size: 0.82rem; color: var(--sp-label-2); margin-top: 2px; display: flex; align-items: center; gap: 6px; flex-wrap: wrap; }
.stats-customer-card-meta { font-size: 0.74rem; color: var(--sp-label-3); margin-top: 4px; }

.stats-customer-card-totals {
  text-align: right;
  flex-shrink: 0;
}
.stats-customer-card-sum { font-size: 1.2rem; font-weight: 750; color: var(--sp-label); font-variant-numeric: tabular-nums; }
.stats-customer-card-orders { font-size: 0.76rem; color: var(--sp-label-2); margin-top: 2px; }

.stats-reset-link {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 0 10px;
  border-radius: 8px;
  background: var(--sp-fill);
  color: var(--sp-accent);
  font-weight: 600;
  font-size: 0.78rem;
  white-space: nowrap;
  margin-bottom: 16px;
}

/* ---------- «Режим владельца» — степ-ап логин (/admin/super/login, задача
   2026-09-27) + кнопка выхода из него на /admin/stats ----------
   Скоуп: тот же .stats-page (класс есть и на обёртке admin_super_login.html,
   см. её докстринг) — токены --sp-* уже определены там же, что и для
   остального /admin/stats, так что степ-ап логин автоматически получает ту
   же (всегда светлую) палитру без дублирования. */

.stats-superlogin-wrap {
  display: flex;
  justify-content: center;
  padding-top: 8vh;
}

.stats-superlogin-card {
  width: 100%;
  max-width: 380px;
  text-align: center;
  padding: 28px 22px;
}

.stats-superlogin-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  height: 52px;
  border-radius: 50%;
  background: var(--sp-accent-soft);
  font-size: 1.4rem;
  margin-bottom: 14px;
}

.stats-superlogin-title {
  /* font-family/letter-spacing — из общего правила выше (см. комментарий у
     .stats-title): заголовок входа в режим владельца — фирменный Bloc
     Heavy. */
  font-size: 1.5rem;
  font-weight: 750;
  margin: 0 0 10px;
  color: var(--sp-label);
}

.stats-superlogin-sub {
  font-size: 0.9rem;
  line-height: 1.5;
  color: var(--sp-label-2);
  margin: 0 0 18px;
}

.stats-superlogin-error {
  font-size: 0.86rem;
  font-weight: 600;
  color: var(--sp-red);
  /* Тот же двойной background (фоллбэк без color-mix, затем сам color-mix),
     что и .stats-list-icon--red выше. */
  background: var(--sp-fill);
  background: color-mix(in srgb, var(--sp-red) 12%, transparent);
  border-radius: 10px;
  padding: 10px 12px;
  margin: 0 0 16px;
}

.stats-superlogin-form {
  display: flex;
  flex-direction: column;
  gap: 10px;
}

.stats-superlogin-input {
  min-height: 44px;
  padding: 0 14px;
  border-radius: 10px;
  border: 1px solid var(--sp-separator);
  background: var(--sp-fill);
  font-size: 0.95rem;
  font-family: inherit;
  color: var(--sp-label);
  text-align: center;
}
.stats-superlogin-input::placeholder { color: var(--sp-label-3); }
.stats-superlogin-input:focus {
  outline: none;
  border-color: var(--sp-accent);
  background: var(--sp-card);
}

.stats-superlogin-submit {
  min-height: 44px;
  border: none;
  border-radius: 10px;
  background: var(--sp-accent);
  /* var(--sp-bg), не белый напрямую — то же противопоставление фон/акцент,
     на котором построена вся остальная страница: --sp-bg (почти белый
     кремовый) на --sp-accent (тёмно-бордовый --red) — контраст ~6:1,
     выше WCAG AA (4.5:1) для текста кнопки. */
  color: var(--sp-bg);
  font-weight: 650;
  font-size: 0.95rem;
  font-family: inherit;
  cursor: pointer;
}
.stats-superlogin-submit:active { opacity: 0.85; }

.stats-superlogin-back {
  display: inline-block;
  margin-top: 18px;
  font-size: 0.84rem;
  font-weight: 600;
  color: var(--sp-accent);
}

/* «Выйти из режима владельца» на /admin/stats (задача 2026-09-27) — тот же
   визуальный приём, что и .stats-reset-link выше (пилюля на var(--sp-fill)),
   но <button> внутри <form method="post">, а не <a> — выход обязан быть
   POST (мутирующее действие, чистит сессию), не GET-ссылкой. */
.stats-super-logout {
  display: inline-flex;
  align-items: center;
  min-height: 32px;
  padding: 0 12px;
  border: none;
  border-radius: 8px;
  background: var(--sp-fill);
  color: var(--sp-accent);
  font-weight: 600;
  font-size: 0.78rem;
  font-family: inherit;
  white-space: nowrap;
  margin-bottom: 16px;
  cursor: pointer;
}
.stats-super-logout:active { opacity: 0.85; }
