/* Этап 8: редизайн Mini App — фирменный стиль "Smokin Wolf" (тёмный неон +
   хром), собранный по референсам владельца. В отличие от Этапа 2, палитра
   больше НЕ подстраивается под тему Telegram (applyTelegramTheme в app.js
   теперь только просит Telegram выкрасить свой хедер/фон в наш тёмный цвет,
   а не наоборот) — это осознанное решение: бренд должен выглядеть одинаково
   у всех покупателей, а не терять вид в светлой теме Telegram. */

@import url("https://fonts.googleapis.com/css2?family=Tomorrow:wght@500;700;900&family=Chakra+Petch:wght@400;500;600;700&display=swap");

:root {
  --bg: #0b0c0f;
  --surface: #17181d;
  --surface-raised: #1e2026;
  --line: #2a2c33;
  --ember: #ff5a1f;
  --ember-deep: #c62b0a;
  --steel: #c3c9d1;
  --steel-dim: #8a8f98;
  --cyan: #3ee6e0;
  --text: #e8e9ec;
  --text-dim: #9a9ea6;
  --danger: #ff4d4d;
}

* {
  box-sizing: border-box;
}

[hidden] {
  display: none !important;
}

html, body {
  height: 100%;
}

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font-family: "Chakra Petch", -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif;
  -webkit-tap-highlight-color: transparent;
}

button, input {
  font-family: inherit;
}

.app {
  /* Именно height, не min-height: у флекс-контейнера с фиксированной
     высотой .tabs (flex:1) знает, сколько места ему реально осталось, и
     сжимается под свой overflow:auto вместо того, чтобы позволить .app
     разрастись под весь контент целиком (а именно так и было — .tabs
     растягивался на всю высоту содержимого, утаскивая .navbar за пределы
     экрана на вкладках с длинным контентом). 100vh — запасной вариант для
     браузеров без dvh, 100dvh переопределяет его там, где есть поддержка. */
  height: 100vh;
  height: 100dvh;
  display: flex;
  flex-direction: column;
}

/* ---------- Верхняя шапка (бренд) ---------- */

.topbar {
  position: sticky;
  top: 0;
  z-index: 5;
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 14px;
  background: var(--bg);
  border-bottom: 1px solid var(--line);
}

.brand {
  display: flex;
  align-items: center;
  gap: 10px;
  /* Раньше был просто <div> — теперь кнопка на главную, сбрасываем
     нативные стили button и возвращаем прежний вид. */
  border: none;
  background: none;
  padding: 0;
  font: inherit;
  cursor: pointer;
  transition: transform 0.15s ease;
}

/* Один эффект, не два: раньше сюда же добавлялось затемнение (opacity) —
   вместе с масштабом получалось избыточно для простого логотипа-кнопки. */
@media (hover: hover) and (pointer: fine) {
  .brand:hover {
    transform: scale(1.03);
  }
}

.brand:active {
  transform: scale(0.97);
}

/* Пульс по клику — JS-триггер (см. app.js), не просто :active: на некоторых
   мобильных WebView :active не срабатывает по тапу без дополнительных
   обработчиков touch-событий, а на вкладке "Главная" клик по лого больше
   ничего на экране не меняет (мы уже тут) — без явного пульса кнопка там
   выглядела статичной, будто не реагирует на нажатие. */
@keyframes brand-tap {
  0% { transform: scale(1); }
  45% { transform: scale(0.93); }
  100% { transform: scale(1); }
}

.brand.tapped {
  animation: brand-tap 0.22s ease;
}

.emblem {
  width: 30px;
  height: 30px;
  border-radius: 50%;
  position: relative;
  flex: none;
}

.emblem::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 220deg, var(--ember), var(--ember-deep), var(--ember));
  box-shadow:
    inset 1px 1px 2px rgba(255, 255, 255, 0.4),
    inset -1px -1px 2px rgba(0, 0, 0, 0.55),
    0 2px 6px rgba(255, 90, 31, 0.4);
}

.emblem::after {
  content: "";
  position: absolute;
  inset: 3px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 32% 26%, rgba(255, 255, 255, 0.12), transparent 42%),
    radial-gradient(circle at 38% 32%, #262933, #101116 72%);
  box-shadow: inset 0 1px 3px rgba(0, 0, 0, 0.65);
}

.emblem svg {
  position: absolute;
  inset: 5px;
  width: calc(100% - 10px);
  height: calc(100% - 10px);
  z-index: 1;
  filter: drop-shadow(0 1px 1px rgba(0, 0, 0, 0.6));
}

.brand-word {
  font-family: "Tomorrow", sans-serif;
  font-weight: 700;
  letter-spacing: 0.04em;
  font-size: 15px;
  color: var(--steel);
}

.brand-word b {
  color: var(--ember);
  font-weight: 900;
}

/* ---------- Вкладки ---------- */

.tabs {
  flex: 1;
  /* Без этого flex-элемент по умолчанию не сжимается меньше высоты своего
     содержимого (min-height: auto у флекс-детей по спецификации) — на
     вкладках с длинным контентом (Каталог) это раздувало ВСЮ страницу
     вместо внутреннего скролла, утаскивая нижнюю навигацию за пределы
     экрана. Классический флексбокс-баг. */
  min-height: 0;
  overflow-y: auto;
  /* «Воздух» под контентом теперь на самих .tab-panel, не здесь: липкий
     футер корзины (position: sticky; bottom: 0) прилипает к нижней границе
     ИМЕННО этого контейнера с учётом его padding-bottom — из-за 24px тут
     между футером и нижней навигацией оставался просвет, сквозь который
     виден список. */
  padding-bottom: 0;
  -webkit-overflow-scrolling: touch;
}

/* Пока открыт лайтбокс/детальный просмотр товара — фон под ними не должен
   прокручиваться колесом мыши/свайпом (см. openProductDetail/openLightbox
   в app.js). Сама модалка при этом скроллится своим блоком независимо. */
.tabs.scroll-locked {
  overflow: hidden;
}

.tab-panel {
  /* нижний отступ (был на .tabs) — чтобы контент не упирался в навигацию */
  padding: 16px 14px 24px;
}

.empty-state {
  text-align: center;
  color: var(--text-dim);
  margin-top: 40px;
  font-size: 14px;
}

/* ---------- Главная ---------- */

.hero {
  text-align: center;
  padding: 12px 4px 26px;
}

.hero-emblem {
  width: 88px;
  height: 88px;
  margin: 0 auto 14px;
  position: relative;
}

.hero-emblem::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 50%;
  background: conic-gradient(from 220deg, var(--ember), var(--ember-deep), var(--ember));
  box-shadow:
    inset 2px 2px 4px rgba(255, 255, 255, 0.4),
    inset -2px -2px 5px rgba(0, 0, 0, 0.55),
    0 6px 16px rgba(255, 90, 31, 0.4);
}

.hero-emblem::after {
  content: "";
  position: absolute;
  inset: 6px;
  border-radius: 50%;
  background:
    radial-gradient(circle at 32% 26%, rgba(255, 255, 255, 0.14), transparent 42%),
    radial-gradient(circle at 38% 32%, #262933, #101116 72%);
  box-shadow: inset 0 2px 6px rgba(0, 0, 0, 0.65);
}

.hero-emblem svg {
  position: absolute;
  inset: 14px;
  width: calc(100% - 28px);
  height: calc(100% - 28px);
  z-index: 1;
  filter: drop-shadow(0 2px 2px rgba(0, 0, 0, 0.6));
}

.hero h1 {
  font-family: "Tomorrow", sans-serif;
  font-weight: 900;
  font-size: 28px;
  letter-spacing: 0.03em;
  margin: 0;
  color: var(--steel);
  text-shadow: 0 0 34px rgba(255, 90, 31, 0.28);
}

.hero h1 span {
  color: var(--ember);
}

.hero-tagline {
  color: var(--text-dim);
  font-size: 14px;
  margin: 10px 0 16px;
}

.hero-rating {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 100px;
  padding: 7px 14px;
  font-size: 13px;
  color: var(--text);
  text-decoration: none;
  margin-bottom: 18px;
  transition: border-color 0.15s ease;
}

@media (hover: hover) and (pointer: fine) {
  .hero-rating:hover {
    border-color: rgba(255, 90, 31, 0.4);
  }
}

.hero-rating .stars {
  color: var(--ember);
}

.hero-cta {
  display: block;
  width: 100%;
  max-width: 280px;
  margin: 0 auto;
}

.home-section-title {
  font-family: "Tomorrow", sans-serif;
  font-weight: 700;
  font-size: 13px;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--cyan);
  margin: 4px 2px 10px;
}

.home-categories {
  display: flex;
  flex-direction: column;
  gap: 8px;
}

/* "Ранее заказывали" (Этап 18) — те же карточки товара, что и в каталоге
   (переиспользуем renderCard целиком: сердечко/степпер/клик для детального
   просмотра). Раскладка — обычная grid-сетка (класс .grid), как в каталоге:
   карточки идут друг под другом сверху вниз, новые заказы выше старых
   (порядок задаёт GET /api/orders/history — новые первыми). Горизонтальная
   лента была неудобна на десктопе (не прокрутить мышью). */
#home-reorder {
  margin-bottom: 4px;
}

.home-category-card {
  display: flex;
  align-items: center;
  justify-content: space-between;
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 14px 16px;
  color: var(--text);
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  text-align: left;
  transition: border-color 0.15s ease;
}

@media (hover: hover) and (pointer: fine) {
  .home-category-card:hover {
    border-color: rgba(255, 90, 31, 0.4);
  }

  /* Стрелка чуть сдвигается вправо вслед за наведением на всю карточку —
     не отдельный ховер сама по себе, а деталь того же эффекта. */
  .home-category-card:hover .arrow {
    transform: translateX(3px);
  }
}

.home-category-card .arrow {
  color: var(--ember);
  font-size: 18px;
  transition: transform 0.15s ease;
}

/* ---------- Поиск и категории (Каталог) ---------- */

.search-wrap {
  position: relative;
  display: flex;
  align-items: center;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 12px;
  padding: 0 12px;
  margin-bottom: 12px;
}

.search-icon {
  opacity: 0.6;
  margin-right: 8px;
  font-size: 14px;
}

.search-wrap input {
  flex: 1;
  border: none;
  background: transparent;
  /* type="search" на macOS/Safari рисуется нативным полем (своя форма,
     внутренние отступы под системную лупу/крестик очистки) поверх нашей
     иконки и стилей .search-wrap — сбрасываем нативный вид, как и у select. */
  appearance: none;
  -webkit-appearance: none;
  padding: 11px 0;
  font-size: 15px;
  color: var(--text);
  outline: none;
}

.search-wrap input::placeholder {
  color: var(--text-dim);
}

.search-wrap input::-webkit-search-cancel-button,
.search-wrap input::-webkit-search-decoration {
  -webkit-appearance: none;
  display: none;
}

/* ---------- Тулбар каталога: сортировка + избранное ---------- */

.catalog-count {
  font-size: 12px;
  color: var(--text-dim);
  margin: -4px 0 10px;
}

/* ---------- Постраничная навигация каталога ---------- */

.pager {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  align-items: center;
  gap: 6px;
  margin: 18px 0 4px;
}

.pager-btn {
  min-width: 34px;
  height: 34px;
  padding: 0 8px;
  border: 1px solid var(--line);
  border-radius: 8px;
  background: var(--surface);
  color: var(--text);
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  cursor: pointer;
}

.pager-btn.active {
  background: linear-gradient(180deg, var(--ember), var(--ember-deep));
  border-color: transparent;
  color: #1a0900;
}

.pager-btn:disabled {
  opacity: 0.4;
  cursor: default;
}

.pager-gap {
  color: var(--text-dim);
  padding: 0 2px;
}

@media (hover: hover) and (pointer: fine) {
  .pager-btn:not(:disabled):not(.active):hover {
    border-color: var(--steel-dim);
  }
}

.catalog-toolbar {
  display: flex;
  gap: 8px;
  margin-bottom: 12px;
}

.sort-select {
  flex: 1;
  min-width: 0;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 9px 28px 9px 10px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  transition: border-color 0.15s ease;
  /* Сбрасываем нативный вид select (на macOS/Safari он рисуется как крупный
     системный контрол с синим focus-ring, поверх background/border/radius —
     без этого каталог на Mac выглядел иначе, чем на Windows/телефоне). */
  appearance: none;
  -webkit-appearance: none;
  -moz-appearance: none;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%239a9ea6' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpolyline points='6 9 12 15 18 9'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: right 8px center;
  background-size: 16px;
}

.sort-select:focus {
  outline: none;
  border-color: var(--steel-dim);
}

@media (hover: hover) and (pointer: fine) {
  .sort-select:hover {
    border-color: var(--steel-dim);
  }
}

.favorites-toggle {
  flex: none;
  display: flex;
  align-items: center;
  gap: 5px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 0 12px;
  color: var(--text-dim);
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}

@media (hover: hover) and (pointer: fine) {
  .favorites-toggle:not(.active):hover {
    border-color: var(--steel-dim);
    color: var(--text);
  }
}

.favorites-toggle svg {
  width: 18px;
  height: 18px;
}

.favorites-toggle #favorites-toggle-count {
  font-size: 12px;
  font-weight: 700;
  font-variant-numeric: tabular-nums;
}

.favorites-toggle.active {
  background: linear-gradient(180deg, var(--ember), var(--ember-deep));
  border-color: transparent;
  color: #1a0900;
}

.categories {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  padding-bottom: 12px;
  scrollbar-width: none;
  -ms-overflow-style: none;
  /* На телефоне листается свайпом. На десктопе свайпа нет и полоса скрыта —
     ряд подкатегорий (до 18 брендов) невозможно было прокрутить мышью.
     Ниже: колесо мыши двигает ряд по горизонтали (js/app.js), а на
     устройствах с курсором показываем тонкую полосу прокрутки. */
  overscroll-behavior-x: contain;
}

.categories::-webkit-scrollbar {
  display: none;
}

@media (hover: hover) and (pointer: fine) {
  .categories {
    scrollbar-width: thin;
    scrollbar-color: var(--steel-dim) transparent;
    padding-bottom: 6px;
  }
  .categories::-webkit-scrollbar {
    display: block;
    height: 6px;
  }
  .categories::-webkit-scrollbar-thumb {
    background: var(--line);
    border-radius: 3px;
  }
  .categories::-webkit-scrollbar-thumb:hover {
    background: var(--steel-dim);
  }
  .categories::-webkit-scrollbar-track {
    background: transparent;
  }
}

.category-chip {
  flex: none;
  border: 1px solid var(--line);
  border-radius: 100px;
  padding: 7px 15px;
  font-size: 13px;
  font-weight: 600;
  white-space: nowrap;
  background: var(--surface);
  color: var(--text-dim);
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}

@media (hover: hover) and (pointer: fine) {
  .category-chip:not(.active):hover {
    border-color: var(--steel-dim);
    color: var(--text);
  }
}

.category-chip.sub {
  padding: 6px 13px;
  font-size: 12px;
}

/* ---------- Подкатегории (бренды) — выпадающий список ---------- */

.subcat-wrap {
  position: relative;
  margin-bottom: 12px;
}

.subcat-trigger {
  width: 100%;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 9px 12px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
  transition: border-color 0.15s ease;
}

.subcat-trigger.open {
  border-color: var(--ember);
}

.subcat-current {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.subcat-chev {
  width: 16px;
  height: 16px;
  flex: none;
  color: var(--text-dim);
  transition: transform 0.15s ease;
}

.subcat-trigger.open .subcat-chev {
  transform: rotate(180deg);
}

.subcat-menu {
  position: absolute;
  top: calc(100% + 4px);
  left: 0;
  right: 0;
  z-index: 30;
  max-height: 300px;
  overflow-y: auto;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 4px;
  box-shadow: 0 10px 28px rgba(0, 0, 0, 0.45);
  -webkit-overflow-scrolling: touch;
}

.subcat-option {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: none;
  border-radius: 7px;
  padding: 9px 10px;
  font-family: inherit;
  font-size: 13px;
  font-weight: 600;
  color: var(--text);
  cursor: pointer;
}

.subcat-option.active {
  color: var(--ember);
}

@media (hover: hover) and (pointer: fine) {
  .subcat-trigger:hover {
    border-color: var(--steel-dim);
  }
  .subcat-option:hover {
    background: var(--surface);
  }
}

.category-chip.active {
  background: linear-gradient(180deg, var(--ember), var(--ember-deep));
  color: #1a0900;
  border-color: transparent;
}

/* ---------- Сетка товаров ---------- */

.grid {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 10px;
}

.card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 16px;
  overflow: hidden;
  display: flex;
  flex-direction: column;
  position: relative;
  transition: border-color 0.15s ease, transform 0.15s ease, box-shadow 0.15s ease;
}

/* Карточка кликабельна целиком (открывает детальный просмотр) — лёгкий
   подъём + тёплая рамка вместо чего-то более заметного, чтобы не спорить
   с ховером кнопок/сердечка внутри самой карточки. */
@media (hover: hover) and (pointer: fine) {
  .card:hover {
    border-color: rgba(255, 90, 31, 0.4);
    transform: translateY(-2px);
    box-shadow: 0 8px 20px rgba(0, 0, 0, 0.35);
  }
}

.card::before {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: 16px;
  padding: 1px;
  background: linear-gradient(160deg, rgba(255, 90, 31, 0.45), transparent 40%);
  -webkit-mask: linear-gradient(#000 0 0) content-box, linear-gradient(#000 0 0);
  -webkit-mask-composite: xor;
  mask-composite: exclude;
  pointer-events: none;
}

.card .photo {
  position: relative;
  aspect-ratio: 1 / 1;
  background: radial-gradient(circle at 30% 25%, #2a2c33, #101116 70%);
  isolation: isolate; /* локальный контекст: заглушка ::after (z-index:-1) уходит под фото и бейджи */
}

/* Заглушка 📦 живёт под фото и видна ВСЕГДА, пока картинка не прогрузилась
   (ленивая загрузка + плавное проявление img поверх). Нет фото / битый src —
   img вообще нет или он удаляется в onerror, заглушка просто остаётся. */
.card .photo::after {
  content: "📦";
  position: absolute;
  inset: 0;
  z-index: -1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 30px;
  opacity: 0.35;
  pointer-events: none;
}

.card .photo.out-of-stock::after {
  display: none; /* оверлей "Нет в наличии" сам объясняет пустой квадрат */
}

.card .photo img {
  opacity: 0;
  transition: opacity 0.25s ease;
}

.card .photo img.loaded {
  opacity: 1;
}

@media (prefers-reduced-motion: reduce) {
  .card .photo img,
  .detail-photo img {
    transition: none;
  }
}

.card .photo img {
  /* position:absolute+inset:0, а не width/height:100% в обычном потоке —
     процентная height у ребёнка внутри родителя, чья собственная высота
     задана только через aspect-ratio (без явного height), по правилам
     CSS2.1 не резолвится (парадоксально даже при том, что у самого элемента
     computed aspect-ratio верный) — на практике это раздувало карточку под
     реальную высоту не-квадратного фото вместо обрезки его в квадрат
     (нашлось при загрузке настоящих фото товаров, Этап 18). Абсолютное
     позиционирование считает проценты от уже готового блока родителя и
     этой неоднозначности не подвержено. */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Единый оверлей "Нет в наличии" — и на карточке в сетке, и в детальном
   просмотре товара (там раньше был отдельный некрасивый бейдж-полоска
   внизу фото, к тому же не покрывавший .detail-photo вообще — селектор был
   ".card .stock-badge", а в детальном просмотре у бейджа другой родитель,
   из-за чего надпись съезжала без стилей и наезжала на сердечко
   избранного). Затемнение полупрозрачное, а не сплошное — фото должно
   оставаться узнаваемым (владелец хочет, чтобы ассортимент был виден, даже
   когда его нет в наличии), текст держит контраст за счёт text-shadow, а
   не плотного фона. */
.stock-badge {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 5px;
  background: rgba(11, 12, 15, 0.42);
  color: var(--steel);
  font-family: "Tomorrow", sans-serif;
  font-weight: 700;
  text-transform: uppercase;
  letter-spacing: 0.06em;
  font-size: 13px;
  text-align: center;
  padding: 0 10px;
  text-shadow: 0 1px 10px rgba(0, 0, 0, 0.95), 0 0 3px rgba(0, 0, 0, 0.9);
  transition: opacity 0.2s ease;
}

.detail-photo .stock-badge {
  font-size: 20px;
}

/* Кликабелен, только если есть что "подглядеть" — товар без фото вообще
   ничего не выигрывает от переключения (см. hasPhoto в productDetailHtml). */
.detail-photo .stock-badge.peekable {
  cursor: pointer;
}

.stock-badge-hint {
  font-family: "Chakra Petch", sans-serif;
  text-transform: none;
  letter-spacing: normal;
  font-weight: 500;
  font-size: 11px;
  color: var(--text-dim);
}

/* Пока пользователь "подглядывает" фото товара без наличия (клик по
   оверлею) — прячем сам оверлей, но оставляем маленькую подсказку в углу,
   чтобы статус "нет в наличии" не терялся из виду и можно было вернуть
   затемнение обратно тем же жестом. */
.detail-photo.peeking .stock-badge {
  opacity: 0;
  pointer-events: none;
}

.stock-peek-chip {
  display: none;
  position: absolute;
  /* Не top/right: там в детальном просмотре сидит кнопка закрытия панели
     (.lightbox-close, привязана к .product-detail-sheet, а не к самому
     фото) — та же ловушка, что уже была с сердечком избранного в Этапе 17.
     Низ фото свободен от других элементов. */
  bottom: 10px;
  right: 10px;
  align-items: center;
  gap: 4px;
  background: rgba(11, 12, 15, 0.75);
  border: 1px solid var(--line);
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 600;
  border-radius: 100px;
  padding: 5px 11px;
  cursor: pointer;
  transition: border-color 0.15s ease, color 0.15s ease;
}

.detail-photo.peeking .stock-peek-chip {
  display: flex;
}

@media (hover: hover) and (pointer: fine) {
  .stock-peek-chip:hover {
    border-color: var(--steel-dim);
    color: var(--text);
  }
}

.hit-badge {
  position: absolute;
  top: 8px;
  left: 8px;
  background: linear-gradient(180deg, var(--ember), var(--ember-deep));
  color: #1a0900;
  font-size: 10px;
  font-weight: 700;
  border-radius: 100px;
  padding: 3px 8px;
}

.favorite-btn {
  position: absolute;
  top: 6px;
  right: 6px;
  width: 28px;
  height: 28px;
  border-radius: 50%;
  border: none;
  background: rgba(11, 12, 15, 0.6);
  color: #fff;
  display: flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: transform 0.15s ease, background-color 0.15s ease, color 0.15s ease;
}

/* Один эффект — лёгкое увеличение, без смены цвета: цвет сердечка уже несёт
   смысл (закрашено/нет = в избранном или нет), трогать его при простом
   наведении не стоит, чтобы не путать с фактическим переключением. */
@media (hover: hover) and (pointer: fine) {
  .favorite-btn:hover {
    background: rgba(11, 12, 15, 0.85);
    transform: scale(1.1);
  }
}

.favorite-btn svg {
  width: 16px;
  height: 16px;
}

.favorite-btn.active {
  color: var(--ember);
}

.detail-photo .favorite-btn {
  width: 34px;
  height: 34px;
  top: 10px;
  /* Не right, а left: у правого верхнего угла в детальном просмотре уже
     сидит кнопка закрытия панели (.lightbox-close, тоже верхний правый
     угол, но относительно всей панели, а не фото) — на маленьких карточках
     они визуально накладывались друг на друга, и сердечко оказывалось под
     крестиком: клик по нему на самом деле закрывал карточку. */
  left: 10px;
}

.detail-photo .favorite-btn svg {
  width: 19px;
  height: 19px;
}

.card .body {
  padding: 10px 11px 11px;
  display: flex;
  flex-direction: column;
  gap: 5px;
  flex: 1;
}

.card .name {
  font-size: 13.5px;
  font-weight: 600;
  line-height: 1.25;
  min-height: 2.5em;
  color: var(--text);
}

/* Название в две строки: марка сверху, "МРЦ …" — отдельной строкой ниже,
   мельче и приглушённее (см. splitProductName / productNameHtml в app.js). */
.pn-main {
  display: block;
}

.pn-sub {
  display: block;
  margin-top: 2px;
  font-weight: 500;
  font-size: 0.82em;
  color: var(--text-dim);
  font-variant-numeric: tabular-nums;
}

.card .price {
  font-family: "Tomorrow", sans-serif;
  font-weight: 700;
  font-size: 14px;
  color: var(--ember);
  font-variant-numeric: tabular-nums;
}

.card .actions {
  margin-top: auto;
}

/* ---------- Кнопки ---------- */

.btn {
  border: none;
  border-radius: 10px;
  padding: 10px 12px;
  font-size: 14px;
  font-weight: 600;
  cursor: pointer;
  font-family: inherit;
}

.btn-primary {
  width: 100%;
  background: linear-gradient(180deg, var(--ember), var(--ember-deep));
  color: #1a0900;
  transition: filter 0.15s ease;
}

@media (hover: hover) and (pointer: fine) {
  .btn-primary:not(:disabled):hover {
    filter: brightness(1.1);
  }
}

.btn-disabled {
  width: 100%;
  background: var(--surface-raised);
  color: var(--text-dim);
  cursor: default;
  text-align: center;
}

.btn-disabled.restock-sent {
  color: var(--cyan);
  margin-top: 6px;
}

.qty-stepper {
  display: flex;
  align-items: center;
  justify-content: space-between;
  background: var(--surface-raised);
  border: 1px solid var(--line);
  border-radius: 10px;
  padding: 4px;
}

.qty-stepper button {
  width: 26px;
  height: 26px;
  border: none;
  border-radius: 8px;
  background: linear-gradient(180deg, var(--ember), var(--ember-deep));
  color: #1a0900;
  font-size: 15px;
  font-weight: 700;
  cursor: pointer;
  transition: filter 0.15s ease;
}

@media (hover: hover) and (pointer: fine) {
  .qty-stepper button:not(:disabled):hover {
    filter: brightness(1.1);
  }
}

.qty-stepper .qty-value {
  font-weight: 700;
  min-width: 20px;
  text-align: center;
  color: var(--text);
  font-variant-numeric: tabular-nums;
}

.qty-stepper .qty-input {
  width: 38px;
  min-width: 0;
  border: none;
  background: transparent;
  color: var(--text);
  font-family: inherit;
  font-weight: 700;
  font-size: 14px;
  text-align: center;
  font-variant-numeric: tabular-nums;
  -moz-appearance: textfield;
}

.qty-stepper .qty-input::-webkit-outer-spin-button,
.qty-stepper .qty-input::-webkit-inner-spin-button {
  -webkit-appearance: none;
  margin: 0;
}

.qty-stepper .qty-input:focus {
  outline: none;
}

/* ---------- Карточка товара (детальный просмотр) ---------- */

.card {
  cursor: pointer;
}

.product-detail-overlay {
  position: fixed;
  inset: 0;
  z-index: 45;
  background: rgba(5, 5, 7, 0.85);
  display: flex;
  align-items: flex-end;
  justify-content: center;
}

/* Раньше вся панель скроллилась целиком, и на товарах с длинным описанием
   кнопку "Добавить в корзину" приходилось долистывать (жалоба владельца,
   Этап 18). Теперь сама .sheet не скроллится — скроллится только
   .detail-scroll внутри неё (см. #product-detail-content/.detail-scroll
   ниже), а .detail-actions остаётся снаружи этого скролла и всегда на
   виду, тем же приёмом, что и .navbar относительно .tabs в основном
   каркасе приложения (см. .tabs выше по файлу). */
.product-detail-sheet {
  position: relative;
  width: 100%;
  max-width: 480px;
  max-height: 88vh;
  display: flex;
  flex-direction: column;
  background: var(--bg);
  border: 1px solid var(--line);
  border-bottom: none;
  border-radius: 20px 20px 0 0;
  overflow: hidden;
}

#product-detail-content {
  display: flex;
  flex-direction: column;
  flex: 1;
  min-height: 0; /* см. .tabs — иначе flex-ребёнок не сожмётся меньше высоты своего контента */
}

.detail-scroll {
  flex: 1;
  min-height: 0;
  overflow-y: auto;
  padding: 18px 16px 12px;
}

.detail-actions {
  flex: none;
  padding: 12px 16px calc(12px + env(safe-area-inset-bottom));
  background: var(--bg);
  border-top: 1px solid var(--line);
}

.detail-photo {
  position: relative;
  aspect-ratio: 1 / 1;
  border-radius: 14px;
  background: radial-gradient(circle at 30% 25%, #2a2c33, #101116 70%);
  overflow: hidden;
  isolation: isolate;
  margin-bottom: 14px;
}

.detail-photo img {
  /* Тот же приём и по той же причине, что .card .photo img — см. комментарий там. */
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  cursor: pointer; /* открывает лайтбокс на весь экран, см. openCurrentProductGallery в app.js */
  opacity: 0;
  transition: opacity 0.25s ease;
}

.detail-photo img.loaded {
  opacity: 1;
}

/* Точки — только индикатор ("тут не одно фото"), не интерактивны: реальное
   листание живёт в лайтбоксе, где для стрелок больше места (Этап 18). */
.detail-photo-dots {
  position: absolute;
  left: 50%;
  bottom: 10px;
  transform: translateX(-50%);
  display: flex;
  gap: 5px;
  z-index: 1;
}

.detail-photo-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.4);
}

.detail-photo-dot.active {
  background: var(--ember);
}

/* Заглушка 📦 под фото — видна всегда, пока картинка не проявилась
   (см. .card .photo::after). */
.detail-photo::after {
  content: "📦";
  position: absolute;
  inset: 0;
  z-index: -1;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 48px;
  opacity: 0.35;
  pointer-events: none;
}

.detail-photo.out-of-stock::after {
  display: none;
}

.detail-name {
  font-family: "Tomorrow", sans-serif;
  font-weight: 700;
  font-size: 18px;
  color: var(--text);
  margin-bottom: 6px;
}

.detail-price {
  font-family: "Tomorrow", sans-serif;
  font-weight: 700;
  font-size: 18px;
  color: var(--ember);
  font-variant-numeric: tabular-nums;
  margin-bottom: 10px;
}

.detail-description {
  font-size: 14px;
  line-height: 1.5;
  color: var(--text-dim);
  margin: 0 0 18px;
  white-space: pre-line;
}

.detail-description-empty {
  font-style: italic;
  opacity: 0.7;
}

/* ---------- Отзывы ---------- */

.reviews-summary {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 14px;
  font-family: "Tomorrow", sans-serif;
}

.reviews-summary .avg {
  font-size: 22px;
  font-weight: 900;
  color: var(--ember);
}

.reviews-summary .count {
  font-size: 13px;
  color: var(--text-dim);
}

.reviews-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
}

.review-card {
  background: var(--surface);
  border: 1px solid var(--line);
  border-radius: 14px;
  padding: 13px 14px;
}

.review-card-header {
  display: flex;
  align-items: center;
  justify-content: space-between;
  margin-bottom: 6px;
}

.review-card-author {
  font-weight: 600;
  font-size: 14px;
  color: var(--text);
}

.review-card-stars {
  color: var(--ember);
  font-size: 13px;
}

.review-card-text {
  font-size: 14px;
  line-height: 1.45;
  color: var(--text);
  margin-bottom: 8px;
}

.review-card-media {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(96px, 1fr));
  gap: 6px;
}

.media-thumb {
  position: relative;
  padding: 0;
  border: none;
  cursor: pointer;
  background: none;
  display: block;
}

.media-thumb img,
.media-thumb video {
  width: 100%;
  aspect-ratio: 1 / 1;
  object-fit: cover;
  border-radius: 8px;
  background: var(--surface-raised);
  display: block;
  pointer-events: none;
  transition: transform 0.15s ease;
}

@media (hover: hover) and (pointer: fine) {
  .media-thumb:hover img,
  .media-thumb:hover video {
    transform: scale(1.05);
  }
}

.media-thumb .play-badge {
  position: absolute;
  inset: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 18px;
  color: #fff;
  background: rgba(11, 12, 15, 0.35);
  border-radius: 8px;
}

.btn-secondary {
  width: 100%;
  background: var(--surface);
  border: 1px solid var(--line);
  color: var(--ember);
  margin-top: 6px;
  transition: border-color 0.15s ease;
}

@media (hover: hover) and (pointer: fine) {
  .btn-secondary:not(:disabled):hover {
    border-color: var(--ember);
  }
}

.btn-secondary:disabled {
  color: var(--text-dim);
}

/* ---------- Лайтбокс (просмотр фото/видео) ---------- */

.lightbox {
  position: fixed;
  inset: 0;
  z-index: 50;
  background: rgba(5, 5, 7, 0.94);
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 28px 18px;
}

.lightbox-content {
  max-width: 100%;
  max-height: 100%;
}

.lightbox-content img,
.lightbox-content video {
  max-width: 100%;
  max-height: 80vh;
  border-radius: 12px;
  display: block;
}

/* Стрелки/точки галереи фото товара (Этап 18) — рисуются вложенными в
   .lightbox-content, но т.к. у неё самой нет position, абсолютно
   спозиционированные дети берут ближайшего позиционированного предка —
   .lightbox (position:fixed) — то есть фактически привязаны к экрану, не к
   размеру самой картинки. */
.lightbox-nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 40px;
  height: 40px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.18);
  background: rgba(20, 21, 26, 0.75);
  color: var(--text);
  font-size: 24px;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

.lightbox-prev {
  left: 4px;
}

.lightbox-next {
  right: 4px;
}

@media (hover: hover) and (pointer: fine) {
  .lightbox-nav:hover {
    background: rgba(42, 44, 51, 0.9);
  }
}

.lightbox-dots {
  position: absolute;
  left: 50%;
  bottom: max(12px, env(safe-area-inset-bottom));
  transform: translateX(-50%);
  display: flex;
  gap: 6px;
}

.lightbox-dot {
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: rgba(255, 255, 255, 0.35);
}

.lightbox-dot.active {
  background: var(--ember);
}

.lightbox-close {
  position: absolute;
  top: max(16px, env(safe-area-inset-top));
  right: 16px;
  z-index: 2;
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: rgba(20, 21, 26, 0.92);
  border: 1px solid rgba(255, 255, 255, 0.18);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.7);
  color: var(--text);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
  transition: background-color 0.15s ease;
}

@media (hover: hover) and (pointer: fine) {
  .lightbox-close:hover {
    background: rgba(42, 44, 51, 0.95);
  }
}

/* ---------- Корзина (вкладка) ---------- */

.cart-items {
  display: flex;
  flex-direction: column;
  gap: 2px;
}

.cart-item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 12px 0;
  border-bottom: 1px solid var(--line);
}

.cart-item .name {
  flex: 1;
  font-size: 14px;
  color: var(--text);
}

.cart-item .line-total {
  font-family: "Tomorrow", sans-serif;
  font-weight: 700;
  font-size: 14px;
  min-width: 68px;
  text-align: right;
  color: var(--ember);
  font-variant-numeric: tabular-nums;
}

/* Корзина: липкий футер сам закрывает низ, поэтому нижний отступ панели тут
   не нужен (из-за него под кнопкой оставался просвет). */
#tab-cart {
  padding-bottom: 0;
}

.cart-footer {
  position: sticky;
  bottom: 0;
  z-index: 5; /* поверх карточек/степперов — иначе оранжевые +/- просвечивали сквозь футер при прокрутке */
  /* на всю ширину (гасим боковые отступы .tab-panel 14px), чтобы полоса и
     её верхняя граница шли от края до края */
  margin: 16px -14px 0;
  padding: 14px 14px 16px;
  background: var(--bg);
  border-top: 1px solid var(--line);
}

.cart-total {
  font-family: "Tomorrow", sans-serif;
  font-weight: 700;
  font-size: 16px;
  margin-bottom: 10px;
  color: var(--text);
}

.cart-total span {
  color: var(--ember);
  font-variant-numeric: tabular-nums;
}

/* Цены скрыты (show_price=false): пояснение вместо "Итого" */
.cart-notice {
  display: flex;
  gap: 10px;
  align-items: flex-start;
  margin-bottom: 12px;
  padding: 12px;
  border: 1px solid var(--line);
  border-radius: 10px;
  background: var(--surface);
  font-size: 13px;
  line-height: 1.45;
  color: var(--text-dim);
}

.cart-notice svg {
  width: 18px;
  height: 18px;
  flex: none;
  margin-top: 1px;
  color: var(--ember);
}

/* ---------- Нижняя навигация ---------- */

.navbar {
  display: flex;
  justify-content: space-around;
  align-items: center;
  background: var(--surface-raised);
  border-top: 1px solid var(--line);
  padding: 8px 0 max(8px, env(safe-area-inset-bottom));
  flex: none;
}

.navitem {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 4px;
  background: none;
  border: none;
  color: var(--text-dim);
  font-size: 11px;
  font-weight: 600;
  font-family: inherit;
  cursor: pointer;
  position: relative;
  padding: 4px 14px;
}

.navitem svg {
  width: 21px;
  height: 21px;
}

.navitem.active {
  color: var(--ember);
}

.navitem.active .ring {
  position: absolute;
  top: -4px;
  left: 50%;
  transform: translateX(-50%);
  width: 36px;
  height: 36px;
  border-radius: 50%;
  background: radial-gradient(circle, rgba(255, 90, 31, 0.22), transparent 70%);
}

.cart-badge {
  position: absolute;
  top: -2px;
  right: 6px;
  background: var(--ember);
  color: #1a0900;
  font-size: 10px;
  font-weight: 700;
  border-radius: 100px;
  padding: 1px 5px;
  min-width: 15px;
  text-align: center;
}
