/* ==========================================================================
   Page-level section styles — composed from tokens.css + components.css
   ========================================================================== */

/* Заголовки секций в макете всегда прижаты влево. По центру бывает только
   колонка текста в SEO-блоке, и только на десктопе — см. .text-stack--centered.
   (figma-data/spec/README.md → «Системные расхождения») */
.section {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-10);
  padding: var(--space-15);
  background: var(--color-bg);
}
.section__title { width: 100%; }
.section__lead {
  max-width: 650px;
  color: var(--color-text-muted-80);
}
/* Кнопка под сеткой товаров в макете отцентрована, хотя заголовок слева */
.section__action { align-self: center; }

/* SEO-блоки набраны с вертикальным паддингом 80, а не 60 */
.section--lg { padding-block: 80px; }
@media (max-width: 1023px) { .section--lg { padding-block: var(--space-15); } }
@media (max-width: 767px) { .section--lg { padding-block: var(--space-10); } }

/* Секция «Линейки серии Avatar» на Главной начинается с отступа 80 */
.section--pt-lg { padding-top: 80px; }
@media (max-width: 1023px) { .section--pt-lg { padding-top: var(--space-15); } }
@media (max-width: 767px) { .section--pt-lg { padding-top: var(--space-10); } }

.btn--lg { padding: 21px var(--space-8); }

/* ------------------------------------------------------------------- Hero */
/* Герой ровно 700 на всех трёх брейкпоинтах — мобильные 560 были
   пересчётом десктопа, а не макетом (spec/10-page-home.md) */
.hero {
  position: relative;
  min-height: 700px;
  display: flex;
  flex-direction: column;
  background: var(--color-bg);
  overflow: hidden;
}
.hero__bg {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}
.hero .site-header { position: relative; z-index: 2; }
.hero__content {
  position: relative;
  z-index: 1;
  margin-top: auto;
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  max-width: 558px;
  padding: 0 var(--gutter-desktop) var(--space-15);
}
.hero__subtitle { color: var(--color-text-muted-80); max-width: 358px; opacity: .9; }

@media (max-width: 1023px) {
  .hero__content { padding: 0 var(--gutter-tablet) var(--space-10); max-width: 440px; }
}
@media (max-width: 767px) {
  .hero__content { padding: 0 var(--gutter-mobile) var(--space-10); gap: var(--space-4); max-width: 100%; }
  .hero__subtitle { max-width: 100%; }
}

/* --------------------------------------------------------------- Promo banner */
/* Между картинкой и точками в макете 20 — раньше они прилипали друг к другу,
   из-за чего блок был 368 вместо 388. Стрелки теперь центрируются по самой
   картинке, а не по всему блоку: паддинги сверху и снизу разные, и от
   центра блока стрелки уезжали. */
.promo-banner {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  padding: var(--space-10) var(--gutter-desktop) var(--space-5);
  background: var(--color-bg);
}
.promo-banner__frame { position: relative; overflow: hidden; }
.promo-banner__track { display: flex; transition: transform .4s ease; }
.promo-banner__slide {
  flex: 0 0 100%;
  display: block;
  width: 100%;
  height: 300px;
  overflow: hidden;
}
.promo-banner__slide img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  user-select: none;
  -webkit-user-drag: none;
}
@media (prefers-reduced-motion: reduce) {
  .promo-banner__track { transition: none; }
}

/* Кнопки стоят вровень с краями картинки: в макете строка со стрелками
   имеет padding 60 и justify-between, то есть они совпадают с гуттером. */
.promo-banner__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: rgba(255, 255, 255, 0.3);
  backdrop-filter: var(--blur-header);
  -webkit-backdrop-filter: var(--blur-header);
  transition: background-color .15s ease;
}
.promo-banner__nav:hover { background: rgba(255, 255, 255, 0.45); }
.promo-banner__nav img { width: 24px; height: 24px; }
.promo-banner__nav--prev { left: 0; }
.promo-banner__nav--next { right: 0; }
.promo-banner__nav[hidden] { display: none; }
/* Точки баннера — не прямоугольники: трапеции 28×8, у которых направление
   сужения чередуется. Геометрия из макета: M0 0 H28 L24 8 H4 Z. */
.promo-banner__dots { display: flex; justify-content: center; align-items: center; gap: var(--space-1); }
.promo-banner__dots button {
  width: 28px;
  height: 8px;
  padding: 0;
  background: var(--color-surface-hover);
  clip-path: polygon(0 0, 100% 0, 85.72% 100%, 14.28% 100%);
  transition: background-color .15s ease;
}
.promo-banner__dots button:nth-child(even) {
  clip-path: polygon(14.28% 0, 85.72% 0, 100% 100%, 0 100%);
}
.promo-banner__dots button:hover { background: var(--color-gray); }
.promo-banner__dots button.is-active { background: var(--color-accent); }

/* Стрелки показываем на всех ширинах: в макете они есть и на планшете, и на
   мобилке. Прятали их по замечанию клиента (docs/автр.docx п.124) только
   потому, что карусели не было и они висели мёртвым грузом поверх статичной
   картинки, — причина отпала. */
@media (max-width: 1023px) { .promo-banner { padding: var(--space-5) var(--gutter-tablet); } .promo-banner__slide { height: 300px; } }
@media (max-width: 767px) { .promo-banner { padding: var(--space-5) var(--gutter-mobile); } .promo-banner__slide { height: 200px; } }

/* ---------------------------------------------------------------- Tags row */
.tags-row {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-start;
  gap: var(--space-1);
}
.tag {
  padding: 15px var(--space-4);
  background: var(--color-surface);
  color: var(--color-text);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--fs-label-m);
  letter-spacing: -0.02em;
}
.tag--active { background: var(--color-accent); color: var(--color-text-on-accent); }

/* ------------------------------------------------------------- Product grid */
.product-grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-5);
  width: 100%;
}
@media (max-width: 1023px) { .product-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
/* На мобилке в макете тоже две колонки, зазор по горизонтали 4, по вертикали 8 */
@media (max-width: 767px) { .product-grid { gap: var(--space-2) var(--space-1); } }

/* ---------------------------------------------------------- Sound picker */
.sound-picker {
  scroll-margin-top: var(--space-5);
}
.sound-picker__panel {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-10);
  width: 100%;
}
.sound-picker__panel[hidden] { display: none; }
.sound-picker__empty {
  width: 100%;
  margin: 0;
  padding: var(--space-8);
  color: var(--color-text-muted-80);
  background: var(--color-surface);
  text-align: center;
}
@media (max-width: 767px) {
  .sound-picker__panel { gap: var(--space-6); }
  .sound-picker__empty { padding: var(--space-6) var(--space-4); }
}

/* ---------------------------------------------------------------- About + features */
/* Блок о бренде: в макете это одна колонка 650 с абзацами друг под другом и
   кнопкой снизу. Колонка отцентрована только на десктопе. */
.about-block {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-10);
  width: 650px;
  max-width: 100%;
  align-self: center;
}
.about-block__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  width: 100%;
}
.about-block__text p { margin: 0; }

.features { display: flex; flex-direction: column; gap: var(--space-10); width: 100%; }
.features__grid {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-6);
}
/* В макете номер → заголовок 20, заголовок → текст 12. Общий gap даёт 12,
   недостающие 8 добираем отступом под номером — чтобы не заводить обёртку. */
.feature { display: flex; flex-direction: column; gap: var(--space-3); padding-right: var(--space-5); }
.feature__num { color: var(--color-accent); margin-bottom: var(--space-2); }
.feature h5 { margin: 0; }
.feature p { margin: 0; color: var(--color-text-muted-80); }

@media (max-width: 1023px) {
  .features__grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .about-block { width: 100%; align-self: stretch; }
}
@media (max-width: 767px) {
  .features__grid { grid-template-columns: 1fr; }
  .about-block { gap: var(--space-8); }
}

/* --------------------------------------------------------------------- CTA */
.cta {
  position: relative;
  display: flex;
  justify-content: center;
  padding: var(--space-15) var(--gutter-desktop);
  background: var(--color-bg);
  overflow: hidden;
}
.cta__glow {
  position: absolute;
  width: 600px;
  height: 560px;
  border-radius: 50%;
  background: var(--color-surface);
  filter: blur(120px);
  opacity: .6;
}
.cta__glow--1 { top: -30%; left: 10%; }
.cta__glow--2 { top: -50%; right: -10%; }
.cta__glow--3 { bottom: -50%; left: -15%; }
.cta__content {
  position: relative;
  z-index: 1;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-6);
  max-width: 598px;
  text-align: center;
}
.cta__content p { max-width: 374px; color: var(--color-text-muted-80); margin: 0; }
/* В макете заголовок → описание 24, а описание → кнопка 40. Общий gap даёт
   24, недостающие 16 добираем отступом у кнопки. */
.cta__content .btn { margin-top: var(--space-4); }
@media (max-width: 1023px) {
  .cta__content { gap: var(--space-5); }
  .cta__content .btn { margin-top: var(--space-5); }
}
@media (max-width: 767px) {
  .cta__content { gap: var(--space-4); }
  .cta__content .btn { margin-top: var(--space-6); }
}

@media (max-width: 1023px) { .section { padding: var(--space-15) var(--gutter-tablet); gap: var(--space-8); } .cta { padding: var(--space-15) var(--gutter-tablet); } }
@media (max-width: 767px) { .section { padding: var(--space-10) var(--gutter-mobile); gap: var(--space-6); } .cta { padding: var(--space-10) var(--gutter-mobile); } }

/* ------------------------------------------------------------ Breadcrumbs
   В макете крошки набраны Label M (14) на десктопе и планшете и
   Mobile/Label S (11) на мобилке — размер задаём здесь, чтобы он не зависел
   от того, какой утилитарный класс повесили на элемент. */
.breadcrumbs {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-label-m);
  line-height: var(--lh-label-m);
  letter-spacing: -0.02em;
}
.breadcrumbs a { color: var(--color-text); }
.breadcrumbs a:hover { color: var(--color-accent-hover); }
.breadcrumbs__current { color: var(--color-text-muted-50); }
@media (max-width: 767px) {
  .breadcrumbs { font-size: var(--fs-label-s-mobile); letter-spacing: 0; }
}

/* -------------------------------------------------------- Category header */
.tag--dropdown { display: inline-flex; align-items: center; gap: var(--space-1); }
.tag--dropdown img { width: 14px; height: 14px; opacity: .7; transform: rotate(90deg); }

.category-filters {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: var(--space-2);
  width: 100%;
}
.category-filters__group { display: flex; flex-wrap: wrap; gap: var(--space-4); align-items: flex-end; }

/* Выпадающий фильтр. Раскрытого состояния в макете нет ни разу, поэтому
   панель со значениями сделана по мотивам гео-дропдауна хедера. */
.filter-drop { position: relative; }
.filter-drop > summary { list-style: none; cursor: pointer; }
.filter-drop > summary::-webkit-details-marker { display: none; }
.filter-drop[open] > summary .chip__icon { transform: rotate(-90deg) !important; }
/* Закрытый details в Chromium не прячет абсолютно спозиционированного
   потомка — гасим панель явно, иначе она считается в ширину страницы */
.filter-drop:not([open]) .filter-drop__panel { display: none; }
/* Последний фильтр раскрывается влево, чтобы не выходить за правый край */
.filter-drop:last-child .filter-drop__panel { left: auto; right: 0; }
.filter-drop__panel {
  position: absolute;
  top: calc(100% + var(--space-1));
  left: 0;
  z-index: 20;
  display: flex;
  flex-direction: column;
  min-width: 200px;
  padding: var(--space-2) 0;
  background: var(--color-surface);
  box-shadow: 0 12px 32px rgba(0, 0, 0, .45);
}
.filter-drop__option {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  padding: var(--space-3) var(--space-4);
  font-size: var(--fs-label-m);
  letter-spacing: -0.02em;
  cursor: pointer;
  white-space: nowrap;
}
.filter-drop__option:hover { background: var(--color-surface-hover); }

/* Селект сортировки выглядит чипом */
select.category-filters__sort { appearance: none; -webkit-appearance: none; }

/* Сортировка: чип на десктопе и планшете, кнопка-иконка 44×44 на мобилке */
.category-filters__sort-icon {
  display: none;
  width: 44px;
  height: 44px;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
}
.category-filters__sort-icon img { width: 24px; height: 25px; }

/* Селект сортировки на мобилке превращается в иконку. Глиф — отдельный
   <img> в разметке, а НЕ background-image: относительный url() в этом файле
   разрешается по-разному в статике (styles/ и assets/ — соседи) и в Django
   (оба лежат в /static/). Иконки в общем CSS ставить нельзя. */
.category-filters__sort-wrap { position: relative; display: inline-flex; }
.category-filters__sort-glyph { display: none; }

@media (max-width: 767px) {
  .category-filters__sort-icon { display: flex; }
  button.category-filters__sort { display: none; }

  .category-filters__sort-wrap { width: 44px; height: 44px; }
  .category-filters__sort-glyph {
    display: block;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 24px;
    height: 25px;
    pointer-events: none;
  }
  select.category-filters__sort {
    position: absolute;
    inset: 0;
    width: 100%;
    height: 100%;
    padding: 0;
    color: transparent;
    background: transparent;
    clip-path: none;
  }
  select.category-filters__sort option { color: var(--color-text); }
}

.filter-group { display: flex; flex-direction: column; gap: var(--space-2); }
.filter-group__options { display: flex; flex-wrap: wrap; gap: var(--space-2); }
.tag { cursor: pointer; }
.tag input[type="checkbox"] { position: absolute; opacity: 0; width: 0; height: 0; pointer-events: none; }
select.tag { appearance: none; -webkit-appearance: none; border: none; }

/* ----------------------------------------------------- Category / catalog */
.catalog-body {
  display: flex;
  flex-direction: column;
  gap: var(--space-15);
  padding: var(--space-15);
  background: var(--color-bg);
}
.category-intro { display: flex; flex-direction: column; gap: var(--space-10); align-items: flex-start; width: 100%; }

/* Каталог линейки: под заголовком описание, между ними 24 */
.line-intro { display: flex; flex-direction: column; gap: var(--space-6); width: 100%; }
.line-intro h1 { margin: 0; }
.line-intro p { margin: 0; max-width: 650px; color: var(--color-text-muted-80); }

/* Заголовок линейки → сетка: 40 на десктопе и планшете, 20 на мобилке */
.product-lineup { display: flex; flex-direction: column; gap: var(--space-10); width: 100%; }
@media (max-width: 767px) { .product-lineup { gap: var(--space-5); } }
.product-row { display: flex; flex-wrap: wrap; gap: var(--space-5); width: 100%; }
.product-row .product-card { flex: 1 1 315px; max-width: 315px; }

/* Верхний паддинг в макете заметно меньше нижнего: 60/60 на десктопе,
   32/60 на планшете, 24/40 на мобилке (spec/08-page-catalog.md) */
@media (max-width: 1023px) {
  .catalog-body { padding: var(--space-8) var(--gutter-tablet) var(--space-15); }
}
@media (max-width: 767px) {
  .catalog-body { padding: var(--space-6) var(--gutter-mobile) var(--space-10); gap: var(--space-10); }
  .category-intro { gap: var(--space-8); }
  .product-row .product-card { flex: 1 1 100%; max-width: none; }
}

/* -------------------------------------------------------------- Text stack */
.text-stack { display: flex; flex-direction: column; gap: var(--space-5); max-width: 650px; text-align: left; }
.text-stack p { margin: 0; color: var(--color-text-muted-80); }

/* SEO-блок: колонка 650 отцентрована внутри контента — но только на десктопе.
   На планшете и мобилке она занимает всю ширину. */
.text-stack--centered { align-self: center; width: 650px; }
@media (max-width: 1023px) {
  .text-stack--centered { align-self: stretch; width: auto; max-width: none; }
}

/* ---------------------------------------------------------------- Content block (title + alternating media/text rows) */
.content-block {
  display: flex;
  flex-direction: column;
  gap: var(--space-15);
  padding: 80px var(--gutter-desktop);
  background: var(--color-bg);
}
.split-row { display: flex; align-items: center; gap: var(--space-10); }
.split-row--reverse { flex-direction: row-reverse; }
.split-row__media { flex: 1 1 0; min-width: 0; }
.split-row__media img { width: 100%; height: 600px; object-fit: cover; }
.split-row__text { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: var(--space-5); color: var(--color-text); }
.split-row__text p { margin: 0; color: var(--color-text-muted-80); }

/* На планшете ряд встаёт в колонку, но картинка остаётся 600 — уменьшается
   она только на мобилке (350). Правило height:320 доставало до 768 после
   слияния брейкпоинтов и было чистой отсебятиной. */
@media (max-width: 1023px) {
  .content-block { padding: var(--space-15) var(--gutter-tablet); }
  .split-row, .split-row--reverse { flex-direction: column; }
}
@media (max-width: 767px) {
  .content-block { padding: var(--space-10) var(--gutter-mobile); gap: var(--space-10); }
  .split-row__media img { height: 350px; }
}

/* ------------------------------------------------------------- Line cards */
.line-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-5);
  width: 100%;
}
.line-card { display: flex; flex-direction: column; border: 1px solid var(--color-border); background: var(--color-bg); }
.line-card__media img { width: 100%; height: 320px; object-fit: cover; }
.line-card__body { display: flex; flex-direction: column; gap: var(--space-2); padding: var(--space-6); color: var(--color-text); }
.line-card__body p { margin: 0; color: var(--color-text-muted-80); }

@media (max-width: 1023px) { .line-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 767px) {
  .line-grid { grid-template-columns: 1fr; gap: var(--space-2); }
  /* На мобилке название карточки 20 (Mobile/H3), описание 13 (Mobile/Body M).
     Утилитарный .h4 дал бы 15 — это размер Mobile/H4, не тот стиль. */
  .line-card__body h2,
  .line-card__body h3 { font-size: var(--fs-h3-mobile); }
}

/* ---------------------------------------------------------- Product hero */
.product-hero {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-10);
  padding: var(--space-15);
  background: var(--color-bg);
}
/* Между галереей и инфо-колонкой в макете 60, а не 40 */
.product-hero__layout { display: flex; gap: var(--space-15); width: 100%; }

.product-gallery { display: flex; gap: var(--space-1); flex: 1 1 0; min-width: 0; }
.product-gallery__thumbs { display: flex; flex-direction: column; align-items: center; gap: var(--space-1); width: 60px; flex-shrink: 0; }
.product-gallery__thumbs-list { display: flex; flex-direction: column; gap: var(--space-1); overflow-y: auto; max-height: 428px; }
.product-gallery__thumb { width: 60px; height: 60px; flex-shrink: 0; border: 1px solid transparent; overflow: hidden; padding: 0; }
.product-gallery__thumb.is-active { border-color: var(--color-accent); }
.product-gallery__thumb img { width: 100%; height: 100%; object-fit: contain; }
.product-gallery__nav { width: 60px; height: 40px; display: flex; align-items: center; justify-content: center; background: var(--color-surface); flex-shrink: 0; }
.product-gallery__nav img { width: 20px; height: 20px; }
.product-gallery__main { flex: 1 1 0; min-width: 0; position: relative; }
.product-gallery__zoom { position: relative; display: block; width: 100%; cursor: zoom-in; }
.product-gallery__zoom > img { width: 100%; height: 500px; object-fit: contain; }
.product-gallery__zoom-icon {
  position: absolute;
  right: var(--space-3);
  bottom: var(--space-3);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: rgba(7, 16, 19, .7);
  backdrop-filter: var(--blur-header);
}
.product-gallery__zoom-icon img { width: 20px; height: 20px; }

.product-lightbox {
  width: min(1100px, calc(100vw - 48px));
  height: min(820px, calc(100vh - 48px));
  padding: 0;
  border: 0;
  overflow: hidden;
  background: var(--color-bg);
  color: var(--color-text);
}
.product-lightbox::backdrop { background: rgba(0, 0, 0, .86); backdrop-filter: blur(6px); }
.product-lightbox__image { width: 100%; height: 100%; object-fit: contain; }
.product-lightbox__close {
  position: absolute;
  z-index: 1;
  top: var(--space-3);
  right: var(--space-3);
  display: flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  background: var(--color-surface);
}
.product-lightbox__close img { width: 20px; height: 20px; }

.product-info { flex: 1 1 0; min-width: 0; display: flex; flex-direction: column; gap: var(--space-10); }
.product-info__head { display: flex; flex-direction: column; gap: var(--space-6); }
.product-info__head p { margin: 0; color: var(--color-text-muted-80); }

/* Прайс-блок. Цена — шрифтом заголовков, 26px, АКЦЕНТНЫМ цветом; блок,
   который в прошлой сессии верстался по скриншотам, расходился с макетом по
   трём параметрам из четырёх (см. spec/09-page-product.md). */
.price-block {
  display: flex;
  align-items: center;
  gap: var(--space-1);
  width: 100%;
  padding: var(--space-5);
  border: 1px solid var(--color-border);
}
.price-block__prices { display: flex; flex: 1 0 0; min-width: 0; align-items: baseline; gap: var(--space-2); }
.price-block__price {
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: var(--fs-h4);
  line-height: var(--lh-h4);
  letter-spacing: -0.01em;
  text-transform: uppercase;
  color: var(--color-accent);
}
.price-block__price-old { color: var(--color-text-muted-50); text-decoration: line-through; text-decoration-color: var(--color-gray); }
.price-block__badge { color: var(--color-accent); font-size: var(--fs-label-m); }
.price-block__buy { min-width: 210px; }

/* Ключевые характеристики в герое: зазор между строками 24, на мобилке 16.
   Значение приглушено до .8 (в карточке товара оно, наоборот, полное). */
.spec-list { display: flex; flex-direction: column; gap: var(--space-6); margin: 0; width: 100%; }
.spec-list .spec-row dd { opacity: .8; }

.spec-columns { display: flex; gap: var(--space-10); width: 100%; }
.spec-columns .spec-list { flex: 1; }

/* Блок инструкции: иконка PDF 32×38, название акцентным цветом */
.instruction-download { display: flex; align-items: center; gap: var(--space-3); }
.instruction-download__icon { width: 32px; height: 38px; flex-shrink: 0; }
.instruction-download__meta { display: flex; flex-direction: column; justify-content: center; gap: var(--space-1); }
.instruction-download__title { color: var(--color-accent); }
.instruction-download__meta .body-s { color: var(--color-text-muted-50); }

@media (max-width: 1023px) {
  .product-hero { padding: var(--space-8) var(--gutter-tablet) var(--space-15); }
  .product-hero__layout { flex-direction: column; }
}
@media (max-width: 767px) {
  .product-hero { padding: var(--space-6) var(--gutter-mobile) var(--space-10); gap: var(--space-6); }
  .product-hero__layout { gap: var(--space-10); }
  .product-info { gap: var(--space-6); }
  .product-info__head { gap: var(--space-6); }
  .product-gallery { flex-direction: column-reverse; }
  .product-gallery__thumbs { flex-direction: row; width: 100%; }
  .product-gallery__thumbs-list { flex-direction: row; max-height: none; overflow-x: auto; }
  .product-gallery__nav { display: none; }
  .product-gallery__zoom > img { height: 280px; }
  .product-lightbox { width: calc(100vw - 24px); height: calc(100vh - 24px); }
  /* На мобилке прайс-блок — колонка с зазором 20, цена 20px (Mobile/H3) */
  .price-block { flex-direction: column; align-items: flex-start; gap: var(--space-5); }
  .price-block__price { font-size: var(--fs-h3-mobile); letter-spacing: -0.01em; }
  .price-block__buy { width: 100%; }
  /* Ключевые характеристики на мобилке 11px, а не 13 */
  .spec-list { gap: var(--space-4); font-size: var(--fs-label-s-mobile); letter-spacing: 0; }
  .spec-list .label-m { font-size: inherit; letter-spacing: inherit; }
  .spec-columns { flex-direction: column; gap: var(--space-6); }
}

/* ------------------------------------------- Характеристики: группы + «Развернуть все»
   Вариант Б из макета (figma-data/spec/09-page-product.md). Табов нет:
   все группы раскрываются одной кнопкой, свёрнутое состояние показывает
   только первую. */
.spec-groups {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-10);
  width: 100%;
}
.spec-groups__title { width: 100%; }

.spec-group { display: flex; flex-direction: column; gap: var(--space-10); width: 100%; }
.spec-group__title { width: 100%; }

/* Сетка характеристик: две колонки на десктопе, зазор между ними 60 */
.spec-group__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: var(--space-6) var(--space-15);
  width: 100%;
}
.spec-group__col { display: flex; flex-direction: column; gap: var(--space-6); }

/* Свёрнутое состояние: видна только первая группа */
.spec-groups:not(.is-expanded) .spec-group + .spec-group { display: none; }

.spec-groups__toggle { align-self: center; }

@media (max-width: 1023px) {
  .spec-group { gap: var(--space-6); }
  .spec-group__grid { gap: var(--space-6) var(--space-10); }
}
@media (max-width: 767px) {
  .spec-groups { gap: var(--space-6); }
  .spec-group { gap: var(--space-6); }
  .spec-group__grid { grid-template-columns: minmax(0, 1fr); gap: var(--space-4); }
  .spec-group__col { gap: var(--space-4); }
  /* На мобилке макет берёт Mobile/H3 (20) для заголовка секции и Mobile/H4 (15)
     для заголовка группы. Утилитарные .h4/.h5 дают ровно наоборот. */
  .spec-groups__title { font-size: var(--fs-h3-mobile); }
  .spec-group__title { font-size: var(--fs-h4-mobile); }
}

/* ------------------------------------------------------------- Carousel */
.carousel-head { display: flex; align-items: center; justify-content: space-between; width: 100%; gap: var(--space-4); }
.carousel-nav { display: flex; gap: var(--space-2); }
.carousel-nav__btn { width: 44px; height: 44px; display: flex; align-items: center; justify-content: center; background: var(--color-surface); flex-shrink: 0; }
.carousel-nav__btn img { width: 16px; height: 16px; }
.carousel-nav__btn--next img { transform: rotate(180deg); }
.carousel-track { display: flex; gap: var(--space-5); width: 100%; overflow-x: auto; scroll-snap-type: x mandatory; scrollbar-width: none; }
.carousel-track::-webkit-scrollbar { display: none; }
.carousel-track > * { scroll-snap-align: start; flex: 0 0 315px; }
@media (max-width: 767px) { .carousel-track > * { flex-basis: 260px; } }

/* --------------------------------------------------------------- Review card
   spec/04-page-reviews.md. Типографика карточки одинакова на всех
   брейкпоинтах — меняется только ширина. Картинка всегда 240. */
.review-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-5);
  width: 100%;
}

.review-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--color-border);
  background: var(--color-bg);
}
.review-card__link { display: flex; flex-direction: column; color: inherit; text-decoration: none; }
.review-card__link:hover .review-card__head h3 { color: var(--color-accent); }

/* У медиа-блока нет нижнего паддинга: отступ до заголовка даёт body */
.review-card__media { position: relative; padding: var(--space-6) var(--space-6) 0; }
.review-card__media img { width: 100%; height: 240px; object-fit: cover; }

/* Бейджа источника в макете нет — он добавлен по ревью клиента, когда
   обзоры научились вести на внешние площадки. Кладём внутрь картинки. */
.review-card__source {
  position: absolute;
  top: calc(var(--space-6) + var(--space-3));
  left: calc(var(--space-6) + var(--space-3));
  padding: 4px 10px;
  background: var(--color-accent);
  color: var(--color-bg);
}

.review-card__body { display: flex; flex-direction: column; gap: var(--space-5); padding: var(--space-6); }
.review-card__head { display: flex; flex-direction: column; gap: var(--space-3); }
.review-card__head h3 { margin: 0; }
.review-card__meta { margin: 0; opacity: .8; }

.review-card__footer { display: flex; align-items: baseline; gap: var(--space-2); }
.review-card__date { flex: 1 0 0; min-width: 0; margin: 0; opacity: .8; }
.review-card__author { display: flex; align-items: baseline; gap: var(--space-2); white-space: nowrap; }
.review-card__author-label { opacity: .5; }
.review-card__author-name { opacity: .8; }

@media (max-width: 1023px) { .review-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 767px) { .review-grid { grid-template-columns: minmax(0, 1fr); gap: var(--space-2); } }

/* ------------------------------------------------------------------ 404
   spec/03-pages-tech.md. Ноль в графике — фотография динамика между двумя
   векторными четвёрками, поэтому блок собран из трёх слоёв, а не одной
   картинкой: так он масштабируется без потери резкости у цифр. */
.error-404 {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-10);
  width: 100%;
}

.error-404__art {
  position: relative;
  width: 470px;
  max-width: 100%;
  aspect-ratio: 470 / 199;
}
.error-404__speaker {
  position: absolute;
  top: 0;
  left: 29.79%;
  width: 42.12%;
  height: auto;
}
.error-404__digit {
  position: absolute;
  top: 17.59%;
  height: 70.35%;
  width: auto;
}
.error-404__digit--left { left: 0; }
.error-404__digit--right { right: 0; }

.error-404__text {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  text-align: center;
}
.error-404__text h1 { margin: 0; }
.error-404__text p { margin: 0; opacity: .9; }

.error-404__cats {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: var(--space-6) 28px;
  width: 874px;
  max-width: 100%;
}
.error-404__cat {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  font-size: var(--fs-label-m);
  line-height: var(--lh-label-m);
  letter-spacing: -0.02em;
  color: var(--color-text);
}
.error-404__cat:hover { color: var(--color-accent-hover); }
.error-404__cat img { width: 32px; height: 18px; flex-shrink: 0; }

/* ------------------------------------------------------- Гео-попапы
   ОТЛОЖЕНО: выбор города убран по ревью клиента. Свёрстано как справка,
   на сайте не подключено. spec/12-page-where-to-buy.md */
.geo-demo { display: flex; flex-wrap: wrap; gap: var(--space-10); align-items: flex-start; }
.geo-demo__stage { display: flex; flex-direction: column; gap: var(--space-4); }

/* A. Подтверждение города — плашка 305 под хедером */
.geo-confirm {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  width: 305px;
  max-width: 100%;
  padding: var(--space-5) var(--space-4);
  background: var(--color-bg);
}
.geo-confirm__question {
  display: flex;
  align-items: center;
  gap: var(--space-2);
  margin: 0;
  font-weight: 600;
  font-size: var(--fs-button);
  line-height: var(--lh-button);
  letter-spacing: -0.02em;
}
.geo-confirm__question img { width: 20px; height: 20px; flex-shrink: 0; }
.geo-confirm__actions { display: flex; gap: var(--space-2); }

/* B. Выбор города — модалка 328 поверх затемнения */
.geo-picker {
  display: flex;
  flex-direction: column;
  gap: 2px;
  width: 328px;
  max-width: 100%;
  padding: var(--space-3) var(--space-1);
  background: var(--color-bg);
}
.geo-picker__close { align-self: flex-end; padding: 0 var(--space-2); opacity: .5; }
.geo-picker__close img { width: 24px; height: 24px; }
.geo-picker__title { padding: 0 var(--space-4) 18px; }
.geo-picker .input-search { margin: 0 var(--space-1); width: auto; }
.geo-picker__list { list-style: none; margin: 0; padding: 0; display: flex; flex-direction: column; gap: 2px; }
.geo-picker__city {
  display: block;
  width: 100%;
  padding: 14px var(--space-4);
  text-align: left;
  font-size: var(--fs-label-m);
  line-height: var(--lh-label-m);
  letter-spacing: -0.02em;
  color: var(--color-text);
}
.geo-picker__city:hover { background: var(--color-input-bg); }
.geo-picker__city.is-selected { background: var(--color-accent); color: var(--color-text-on-accent); }

/* ------------------------------------------------- Текстовая страница
   Заголовок и колонка текста — 874 по центру контента, но только на
   десктопе. Сам текст внутри колонки прижат влево. */
.text-page {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: var(--space-10);
  width: 100%;
}
.text-page__title { width: 874px; max-width: 100%; margin: 0; }
.text-page__body {
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  width: 874px;
  max-width: 100%;
}
.text-page__body p { margin: 0; color: var(--color-text-muted-80); }
.text-page__body h2 { margin: var(--space-4) 0 0; }
.text-page__body a:not(.btn) { color: var(--color-accent); }
.text-page__body ul { margin: 0; padding-left: var(--space-5); color: var(--color-text-muted-80); }

/* Реквизиты оператора: подпись — значение. На узких экранах строка
   разворачивается в две, иначе адрес и ОГРН не помещаются. */
.legal-details { display: flex; flex-direction: column; gap: var(--space-3); margin: 0; }
.legal-details__row { display: flex; gap: var(--space-4); }
.legal-details dt { flex-shrink: 0; width: 200px; color: var(--color-text-muted-80); }
.legal-details dd { margin: 0; }
@media (max-width: 767px) {
  .legal-details__row { flex-direction: column; gap: var(--space-1); }
  .legal-details dt { width: auto; }
}

/* --------------------------------------------------------------- Cookies */
.cookie-notice {
  position: fixed;
  z-index: 100;
  right: var(--space-5);
  bottom: var(--space-5);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
  width: min(620px, calc(100vw - 40px));
  padding: var(--space-5);
  background: var(--color-surface);
  box-shadow: 0 18px 60px rgba(0, 0, 0, .45);
}
.cookie-notice[hidden] { display: none; }
.cookie-notice p { margin: 0; color: var(--color-text-muted-80); }
.cookie-notice a { color: var(--color-accent); }
.cookie-notice__actions { display: flex; justify-content: flex-end; gap: var(--space-3); }
.cookie-notice__actions .btn { flex-shrink: 0; }
/* Фон плашки — тот же --color-surface, что и у .btn--secondary, поэтому на
   ней «Решить позже» читалось бы как простой текст. Рамка тут не годится:
   .btn скошена через clip-path и обрезала бы её по диагональным краям,
   поэтому кнопку отделяем фоном на ступень светлее. */
.cookie-notice__actions .btn--secondary { background: var(--color-surface-hover); }
.cookie-notice__actions .btn--secondary:hover { background: var(--color-text-muted-30); }
@media (max-width: 767px) {
  .cookie-notice { right: var(--space-3); bottom: var(--space-3); width: calc(100vw - 24px); }
  .cookie-notice__actions { flex-direction: column-reverse; }
}

@media (max-width: 1023px) {
  .text-page__title,
  .text-page__body { width: 100%; }
}

/* ---------------------------------------------------------------- Store map (static placeholder — see AGENTS.md) */
/* Карта в макете 550 высотой на всех трёх брейкпоинтах. Её внутренностей
   дизайна не существует вообще — пустой прямоугольник, ни пинов, ни попапа
   (spec/12-page-where-to-buy.md). Всё ниже — наша выдумка. */
.store-map {
  position: relative;
  width: 100%;
  height: 550px;
  overflow: hidden;
  background-image:
    linear-gradient(rgba(255, 255, 255, 0.05) 1px, transparent 1px),
    linear-gradient(90deg, rgba(255, 255, 255, 0.05) 1px, transparent 1px);
  background-size: 40px 40px;
  background-color: var(--color-surface);
}
.store-pin {
  position: absolute;
  width: 44px;
  height: 44px;
  display: flex;
  align-items: center;
  justify-content: center;
  transform: translate(-50%, -50%);
  border-radius: 50%;
  background: var(--color-accent);
  color: var(--color-text-on-accent);
  font-family: var(--font-heading);
  font-weight: 800;
  font-size: 12px;
  border: none;
}
.store-pin.is-active { background: var(--color-bg); color: var(--color-accent); box-shadow: inset 0 0 0 2px var(--color-accent); }

.store-popup {
  position: absolute;
  width: 320px;
  max-width: calc(100% - var(--space-6));
  background: var(--color-bg);
  border: 1px solid var(--color-border);
  padding: var(--space-5) var(--space-4);
  display: flex;
  flex-direction: column;
  gap: var(--space-5);
}
.store-popup__close { position: absolute; top: var(--space-2); right: var(--space-2); width: 24px; height: 24px; display: flex; align-items: center; justify-content: center; }
.store-popup__close img { width: 14px; height: 14px; opacity: .7; }
.store-popup__head p { margin: 0; }
.store-popup__meta { display: flex; flex-direction: column; gap: var(--space-2); }
.store-popup__meta p { margin: 0; color: var(--color-text-muted-80); }

/* Строка магазина: паддинг и зазор 20, название и адрес слева, режим и
   телефон тянутся, действие прижато вправо. Кнопки-иконки маршрута из
   макета не ставим — они часть отложенной карты; вместо них по ревью
   клиента ссылка на офсайт. */
.store-list { display: flex; flex-direction: column; gap: var(--space-5); width: 100%; }
.store-list__item {
  display: flex;
  align-items: center;
  gap: var(--space-5);
  padding: var(--space-5);
  border: 1px solid var(--color-border);
  flex-wrap: wrap;
}
.store-list__item p { margin: 0; }
.store-list__item > :first-child { width: 500px; max-width: 100%; flex-shrink: 0; }
.store-list__meta { display: flex; flex-direction: column; gap: var(--space-2); flex: 1 0 0; min-width: 0; color: var(--color-text-muted-80); }
@media (max-width: 1023px) {
  .store-list__item { align-items: flex-start; }
  .store-list__item > :first-child { width: 100%; }
}

@media (max-width: 1023px) {
  .store-popup { width: 280px; }
}
@media (max-width: 767px) {
  .store-popup {
    left: var(--space-3) !important;
    top: auto !important;
    right: var(--space-3);
    bottom: var(--space-3);
    width: auto;
  }
  .store-list__item { flex-direction: column; align-items: flex-start; }
}
