/* ==========================================================================
   Аксель·НН — главная страница
   ========================================================================== */

/* --- Токены ------------------------------------------------------------- */
:root {
  /* Цвет */
  --ink: #1E2A2C;
  /* 5.55:1 на белом, 4.93:1 на --grey, 4.64:1 на --canvas. Считать надо по самой
     тёмной подложке, а не по белому: на светло-серой плашке страницы прежний
     #6B7476 давал 4.01 — лид под заголовком, крошки и шапки таблиц не
     дотягивали до нормы. На телефоне на улице это и читалось хуже всего. */
  --muted: #616A6C;
  --teal: #1690A0;         /* акцент: линии, иконки, hover */
  --teal-deep: #0E7A88;    /* 5.05:1 с белым текстом — заливка кнопок */
  --teal-ink: #0C6B77;     /* тот же акцент для ссылок на заливках: на --tint
                              обычный --teal-deep даёт 4.12 при норме 4.5 */
  --tint: #DCEBED;
  --grey: #F0F2F2;         /* фон плейсхолдеров и фотографий товара */
  --line: #E4E6E6;
  --pill: #D8DDDD;
  --canvas: #EAEBEB;

  /* Каркас: контейнер с safe-зонами по краям */
  --maxw: 1440px;
  --gutter: clamp(16px, 3vw, 32px);

  /* Поля контейнера с запасом под вырез и скруглённые углы экрана. Мета стоит
     с viewport-fit=cover, поэтому в ландшафте на телефоне env() отличен от нуля
     и без max() первая колонка текста уезжала бы под «чёлку». */
  --pad-l: max(var(--gutter), env(safe-area-inset-left));
  --pad-r: max(var(--gutter), env(safe-area-inset-right));

  /* Высота липкой шапки. Точное значение проставляет скрипт в конце страницы:
     шапка растёт вместе с логотипом (clamp по ширине окна), и все отступы,
     которые обязаны с ней совпадать — якоря подразделов, верх липких колонок,
     начало выехавшего меню, — считаются отсюда, а не подбираются на глаз. */
  --header-h: 56px;

  /* Вертикальный ритм. Один токен на все секции — иначе интервалы разъезжаются */
  --space-section: clamp(56px, 7vw, 112px);
  --space-head: clamp(28px, 3.4vw, 48px);
}

/* --- Сброс -------------------------------------------------------------- */
* { box-sizing: border-box; }

html, body { margin: 0; }

/* Safari на телефоне при повороте в ландшафт сам увеличивает шрифт в узких
   блоках — «чтобы читалось». В макете с clamp() это лишнее: размеры и так
   считаются от ширины окна, а автоподгонка ломает их только в одной колонке. */
html {
  -webkit-text-size-adjust: 100%;
  text-size-adjust: 100%;
  /* Закрытое мобильное меню стоит за правым краем окна (translateX(100%)),
     и документ считал его шириной: на 320px появлялась горизонтальная
     прокрутка в пустоту на 320 лишних пикселей. Именно clip, а не hidden:
     hidden делает корень контейнером прокрутки и ломает липкую шапку. */
  overflow-x: clip;
}

body {
  background: #fff;
  color: var(--ink);
  font-family: 'Montserrat', system-ui, sans-serif;
  -webkit-font-smoothing: antialiased;
}

a {
  color: inherit;
  text-decoration: none;
  transition: color .2s ease, border-color .2s ease, opacity .2s ease, background-color .2s ease;
}

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

button { font: inherit; }

:focus-visible {
  outline: 2px solid var(--teal-deep);
  outline-offset: 3px;
}

::selection { background: var(--teal); color: #fff; }

/* --- Каркас -------------------------------------------------------------
   Контейнер фиксированной ширины по центру + поля по краям. Раньше страница
   тянулась во всю ширину монитора и на 1920 расползалась.
   -------------------------------------------------------------------- */
.container {
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-left: var(--pad-l);
  padding-right: var(--pad-r);
}

/* 12 колонок — общая сетка для блоков, которым нужна раскладка */
.grid-12 {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  gap: var(--gutter);
}

/* --- Типографика -------------------------------------------------------- */
.logo {
  font-family: 'Playfair Display', serif;
  letter-spacing: .02em;
}

.logo__dot { color: var(--teal); }

.section-title {
  font-family: 'Playfair Display', serif;
  font-weight: 400;
  font-size: clamp(28px, 3.8vw, 50px);
  line-height: 1.1;
  margin: 0;
  text-transform: uppercase;
  letter-spacing: .01em;
}

/* --- Утилиты ------------------------------------------------------------ */
/* Горизонтальная лента без видимого скроллбара */
.cx-scroll {
  scrollbar-width: none;
  -ms-overflow-style: none;
}

.cx-scroll::-webkit-scrollbar { height: 0; width: 0; display: none; }

/* Плейсхолдер под фото: серый блок в тон макета */
.ph {
  width: 100%;
  height: 100%;
  background: var(--grey);
  object-fit: cover;
}

.visually-hidden {
  position: absolute;
  width: 1px; height: 1px;
  overflow: hidden;
  clip-path: inset(50%);
  white-space: nowrap;
}

/* ==========================================================================
   Шапка
   ========================================================================== */
.header {
  position: sticky;
  top: 0;
  z-index: 30;
  background: #fff;
  border-bottom: 1px solid var(--line);
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(16px, 2vw, 32px);
  /* Единственный блок страницы во всю ширину окна: у остальных секций контейнер
     с max-width, а шапку он на широком мониторе поджимал бы к центру, оставляя
     по краям пустоту. Логотип и корзину ищут в углах экрана — там их и держим. */
  padding-block: clamp(9px, 1vw, 13px);
  padding-left: var(--pad-l);
  padding-right: var(--pad-r);
}

.header__logo {
  flex: 0 0 auto;
  display: block;
}

/* Высотой логотипа задаётся высота всей шапки: у него пропорция 4.46:1,
   и ограничивать его по ширине значило бы ловить высоту вслепую. */
.header__logo img {
  height: clamp(26px, 2.5vw, 34px);
  width: auto;
}

.header__nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: clamp(10px, 1.1vw, 22px);
}

.navlink {
  position: relative;
  font-size: 12px;
  letter-spacing: .11em;
  text-transform: uppercase;
  color: var(--ink);
  font-weight: 400;
  padding-block: 4px;
  white-space: nowrap;
}

.navlink::after {
  content: "";
  position: absolute;
  left: 0;
  bottom: 0;
  width: 100%;
  height: 1px;
  background: var(--teal);
  transform: scaleX(0);
  transform-origin: left;
  transition: transform .3s ease;
}

.navlink:hover { color: var(--teal-deep); }
.navlink:hover::after { transform: scaleX(1); }

/* --- Выпадающий каталог -------------------------------------------------
   Панель лежит внутри пункта «Каталог», а не рядом с ним: только так наведение
   на саму панель считается наведением на пункт и меню не захлопывается, пока
   ведёшь мышь вниз. Раскладку задаёт tools/build-catalog.mjs.
   ---------------------------------------------------------------------- */
.navitem--drop {
  /* static, чтобы .megamenu отсчитывался от шапки и растянулся во всю ширину,
     а не от узкого пункта меню */
  position: static;
  display: flex;
  align-items: center;
}

.navlink--drop {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}

.navlink__chev {
  transition: transform .25s ease;
}

.navitem--drop:focus-within .navlink__chev { transform: rotate(180deg); }

@media (hover: hover) {
  .navitem--drop:hover .navlink__chev { transform: rotate(180deg); }
}

/* Кнопка-шеврон рядом с «Каталогом». Нужна только в выехавшем меню: там
   разделы прячутся в аккордеон, иначе пятнадцать строк каталога отжимают
   «Контакты» на второй экран. На десктопе панель раскрывается наведением,
   и отдельная кнопка была бы второй, спорящей с ним, мишенью. */
.navlink__toggle {
  display: none;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--muted);
  /* Широкий паддинг, а не 20px по иконке: шеврон стоит вплотную к ссылке
     «Каталог», и промах по нему уводил бы на витрину вместо раскрытия */
  padding: 16px 14px;
  margin-right: -10px;
}

.navlink__toggle svg { transition: transform .25s ease; }

.navitem--drop[data-open="true"] .navlink__toggle svg { transform: rotate(180deg); }

.megamenu {
  position: absolute;
  left: 0;
  right: 0;
  top: 100%;
  z-index: 40;
  background: #fff;
  border-top: 1px solid var(--line);
  border-bottom: 1px solid var(--line);
  box-shadow: 0 24px 44px -30px rgba(30, 42, 44, .4);
  padding: clamp(24px, 3vw, 40px) var(--gutter);
  /* Полтора десятка разделов с подразделами на ноутбуке с экраном 768px по
     высоте не помещались: нижние колонки уходили за край, и добраться до них
     было нельзя — панель не прокручивалась вместе со страницей. */
  max-height: calc(100vh - var(--header-h));
  overflow-y: auto;
  overscroll-behavior: contain;
  opacity: 0;
  visibility: hidden;
  transform: translateY(-8px);
  transition: opacity .22s ease, transform .22s ease, visibility .22s;
}

/* Раскрытие по наведению — только там, где наведение существует. На планшете
   первый тап по «Каталогу» эмулирует hover и открывает панель, а переход
   по ссылке при этом всё равно происходит: панель успевает мигнуть и уехать
   вместе со страницей. С клавиатуры меню открывает :focus-within — оно ниже
   и под медиазапрос не заведено. */
@media (hover: hover) {
  .navitem--drop:hover .megamenu {
    opacity: 1;
    visibility: visible;
    transform: none;
  }
}

.navitem--drop:focus-within .megamenu {
  opacity: 1;
  visibility: visible;
  transform: none;
}

/* Колонки, а не грид: у разделов от нуля до семи подразделов, и грид оставлял
   бы под короткими зияющие дыры. Поток колонок укладывает их плотно,
   break-inside держит раздел целиком в одной колонке. */
.megamenu__inner {
  max-width: var(--maxw);
  margin-inline: auto;
  columns: 5 230px;
  column-gap: clamp(20px, 2.4vw, 38px);
}

.megamenu__group {
  break-inside: avoid;
  display: flex;
  flex-direction: column;
  margin-bottom: clamp(20px, 2vw, 30px);
}

.megamenu__title {
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  color: var(--ink);
  font-weight: 500;
  padding-bottom: 10px;
  margin-bottom: 8px;
  border-bottom: 1px solid var(--line);
}

.megamenu__title:hover { color: var(--teal-deep); }

.megamenu__link {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 10px;
  font-size: 13px;
  line-height: 1.4;
  color: var(--muted);
  padding-block: 5px;
}

.megamenu__link:hover { color: var(--teal-deep); }

/* min-width: 0 обязателен: без него flex-элемент не даёт себя сжать уже
   содержимого, и длинное название выдавливало счётчик в соседнюю колонку. */
.megamenu__name {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* Тот же случай, что у .filter__count: --pill не проходит по контрасту */
.megamenu__count {
  flex: 0 0 auto;
  font-size: 11px;
  color: var(--muted);
}

.megamenu__link--more {
  color: var(--teal-deep);
  font-size: 12px;
  letter-spacing: .04em;
}

.header__tools {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: clamp(4px, 1vw, 12px);
}

/* Телефон в шапке: для чека в 25-30 тысяч звонят, а не пишут */
.header__phone {
  font-size: 14px;
  letter-spacing: .02em;
  white-space: nowrap;
  margin-right: 4px;
}

.header__phone:hover { color: var(--teal-deep); }

.header__tool {
  display: inline-flex;
  align-items: center;
  gap: 5px;
  padding: 12px;           /* до 44×44 — норма зоны нажатия */
  margin: -12px;
  margin-left: 0;
}

.header__tool + .header__tool { margin-left: 0; }

.header__tool:hover { color: var(--teal); }

.header__count {
  font-size: 11px;
  letter-spacing: .06em;
  color: var(--muted);
}

/* Бургер — только на узких экранах */
.burger {
  display: none;
  background: none;
  border: 0;
  padding: 12px;
  margin: -12px;
  color: var(--ink);
  cursor: pointer;
}

/* Открытое меню закрывается той же кнопкой, которой открывалось, — она
   остаётся на виду и меняет три полоски на крестик. Отдельной кнопки закрытия
   внутри панели нет намеренно: искать её пришлось бы в другом углу экрана. */
.burger__close { display: none; }
.burger[aria-expanded="true"] .burger__open { display: none; }
.burger[aria-expanded="true"] .burger__close { display: block; }

/* ==========================================================================
   Герой
   ========================================================================== */
.hero {
  position: relative;
  /* 55.8vw — это ровно пропорция кадра 2752×1536 (1536/2752 = 0.558): до 1600px
     ширины фигуристка помещается целиком, по грудь. На 50vw блок был площе
     самого кадра, и cover срезал нижние 10% — плечи и верх куртки уходили
     под плашку преимуществ. Потолок 1000px — компромисс для 1920: кадру там
     нужно 1072px, и на 900 срезало 16% (те же плечи), а на 1000 остаётся 7%
     низа куртки, где всё равно ничего нет. */
  height: clamp(340px, 55.8vw, 1000px);
  background: #F7F8F8;
  overflow: hidden;
}

.hero__media {
  width: 100%;
  height: 100%;
  object-fit: cover;
  /* Верх кадра приколочен к верху блока: что бы ни случилось с высотой,
     обрезается низ (куртка), а голова не трогается никогда.
     По горизонтали 68% — на узких экранах в кадре остаётся сама фигуристка. */
  object-position: 68% 0;
}

.hero__inner {
  position: absolute;
  inset: 0;
  display: grid;
  align-content: center;
  justify-items: start;
  /* Тот же контейнер, что у секций: иначе заголовок героя не совпадает
     по левому краю ни с «Витриной», ни с чем-либо ещё на странице. */
  width: 100%;
  max-width: var(--maxw);
  margin-inline: auto;
  padding-inline: var(--gutter);
  pointer-events: none;
}

.hero__stack {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: clamp(16px, 2vw, 28px);
  /* Текст живёт в левой части — там, где в кадре пустое поле */
  max-width: min(52%, 620px);
}

.hero__title {
  font-family: 'Playfair Display', serif;
  font-weight: 400;
  font-size: clamp(30px, 5vw, 84px);
  line-height: 1.06;
  letter-spacing: -.005em;
  margin: 0;
  text-transform: uppercase;
  color: var(--ink);
  text-wrap: balance;
}

.hero__cta {
  pointer-events: auto;
  display: inline-flex;
  align-items: center;
  gap: 16px;
  background: var(--teal-deep);
  color: #fff;
  padding: clamp(13px, 1.4vw, 18px) clamp(20px, 2.2vw, 34px);
  font-size: 11px;
  letter-spacing: .18em;
  text-transform: uppercase;
}

.hero__cta:hover { background: var(--teal); }

/* ==========================================================================
   Полоса доверия — бирюзовая бегущая строка под героем
   ========================================================================== */
.marquee {
  background: var(--teal-deep);
  color: #fff;
  overflow: hidden;
  padding-block: clamp(9px, 1vw, 13px);
}

/* Внутри две одинаковые ленты подряд. Прокрутка ровно на половину дорожки —
   к концу анимации вторая лента стоит там же, где стартовала первая, поэтому
   склейка не видна и строка бежит бесконечно. */
.marquee__track {
  display: flex;
  width: max-content;
  animation: marquee-run 38s linear infinite;
}

.marquee:hover .marquee__track { animation-play-state: paused; }

.marquee__row {
  flex: 0 0 auto;
  display: flex;
  align-items: center;
  gap: clamp(24px, 3.2vw, 52px);
  /* Такой же отступ после последнего пункта, иначе на стыке лент пропадает пробел */
  padding-right: clamp(24px, 3.2vw, 52px);
}

.marquee__item {
  display: inline-flex;
  align-items: center;
  gap: 9px;
  white-space: nowrap;
  font-size: clamp(9px, .78vw, 11px);
  letter-spacing: .16em;
  text-transform: uppercase;
}

.marquee__item svg {
  flex: 0 0 auto;
  opacity: .65;
}

@keyframes marquee-run {
  from { transform: translateX(0); }
  to   { transform: translateX(-50%); }
}

@media (prefers-reduced-motion: reduce) {
  .marquee__track { animation: none; }
}

/* ==========================================================================
   Секции
   ========================================================================== */
.section { padding-block: calc(var(--space-section) / 2); }

.section__head {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  align-items: baseline;   /* было flex-end — подпись садилась ниже базовой линии */
  gap: 16px;
  margin-bottom: var(--space-head);
}

.section__link {
  display: inline-flex;
  align-items: center;
  gap: 12px;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: var(--teal-deep);
  white-space: nowrap;
}

.section__link:hover { color: var(--teal); }

/* --- Карусель ----------------------------------------------------------- */
.carousel { position: relative; }

.carousel__track {
  display: flex;
  gap: clamp(14px, 1.6vw, 26px);
  overflow-x: auto;
  scroll-snap-type: x proximity;
  padding-bottom: 4px;
}

.carousel__nav {
  position: absolute;
  top: clamp(104px, 13.5vw, 190px);
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: #fff;
  color: var(--ink);
  border: 1px solid var(--line);
  box-shadow: 0 6px 20px -8px rgba(30, 42, 44, .35);
  cursor: pointer;
  padding: 0;
  transition: opacity .2s ease, background-color .2s ease, color .2s ease;
}

.carousel__nav:hover:not(:disabled) { background: var(--teal-deep); color: #fff; border-color: var(--teal-deep); }

.carousel__nav:disabled { opacity: 0; pointer-events: none; }

.carousel__prev { left: -14px; }
.carousel__next { right: -14px; }

/* Полоса прогресса: реально отражает положение в ленте */
.progress {
  height: 2px;
  background: var(--line);
  margin-top: 20px;
  position: relative;
  overflow: hidden;
}

.progress__bar {
  position: absolute;
  left: 0;
  top: 0;
  height: 100%;
  width: 30%;
  background: var(--teal);
  transition: transform .15s linear, width .15s linear;
}

/* --- Карточка товара ---------------------------------------------------- */
.card {
  flex: 0 0 auto;
  width: clamp(240px, 26vw, 340px);
  scroll-snap-align: start;
}

.card:hover .card__media { opacity: .88; }

/* Фон белый и object-fit: contain, а не cover. Товары сняты с разным запасом
   по краям: cover обрезал бы лезвие и раздувал ботинок. contain с одинаковым
   полем показывает предмет целиком и выравнивает видимый масштаб по ряду. */
.card__media {
  position: relative;
  aspect-ratio: 4 / 5;
  background: #fff;
  border: 1px solid var(--line);
  overflow: hidden;
  transition: opacity .25s ease, border-color .25s ease;
  padding: clamp(14px, 1.6vw, 26px);
}

.card__media .ph {
  object-fit: contain;
  background: transparent;   /* иначе серый фон плейсхолдера торчит полосами */
}

/* Карточки каталога/корзины/избранного: студийные фото на белом фоне,
   объект не обрезаем по краю кадра — обрезка допустима, поэтому кроем
   рамку без полей. Кадры без фона (вырезанные объекты на главной)
   этот модификатор не получают — там поля остаются намеренно. */
.card__media--fill {
  padding: 0;
}

.card__media--fill .ph {
  object-fit: cover;
}

.card:hover .card__media { border-color: var(--pill); }

/* Кадры, где предплечье срезано рамкой съёмки (перчатка, защита запястья).
   По центру такой срез висит в воздухе и читается как брак — уводим его
   за левый край. Паддинг и object-fit остаются как у всех карточек, поэтому
   масштаб предмета в ряду не меняется: двигается только положение.
   Сдвиг = паддинг контейнера + белое поле слева от среза внутри самого кадра. */
.card__media--bleed .ph {
  transform: translateX(calc(-1 * clamp(14px, 1.6vw, 26px) - 5%));
}

.card__badge {
  position: absolute;
  top: 12px;
  left: 12px;
  background: var(--teal-deep);
  color: #fff;
  font-size: 11px;
  letter-spacing: .06em;
  padding: 5px 10px;
}

/* Единая структура для обеих каруселей: медиа -> название -> цена.
   Раньше «Новинки» и «Товары недели» верстались по-разному, и низ лент был рваный. */
.card__name {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-top: 16px;
  height: 2.8em;           /* ровно две строки: цены стоят на одной линии по всему ряду */
  font-size: 14px;
  line-height: 1.4;
  color: var(--ink);
}

.card__prices {
  display: flex;
  gap: 10px;
  align-items: baseline;
  flex-wrap: wrap;
}

.card__price,
.card__price-new {
  font-size: 15px;
  font-weight: 500;
  color: var(--ink);
  white-space: nowrap;
}

.card__price-old {
  font-size: 13px;
  color: var(--muted);
  text-decoration: line-through;
  white-space: nowrap;
}

/* ==========================================================================
   Промо-баннер
   ========================================================================== */
/* Две колонки, а не текст поверх фото. Кадры в фонде вертикальные: любая попытка
   растянуть их в полосу 21:9 срезает модели голову. Рядом — не срезает ничего,
   и текст читается без градиента-подложки. */
/* Карусель промо. Листается нативным горизонтальным скроллом со snap, а не
   transform'ом трека: так работает свайп на телефоне и трекпаде без единой
   строчки JS, а скрипту остаются только автоплей, стрелки и точки. */
.promo-slider {
  position: relative;
}

/* scroll-behavior здесь намеренно не задан: он подменил бы и мгновенные
   перестановки после ресайза, и слайд бы уезжал с анимацией на каждый пиксель
   изменения ширины окна. Плавность включает JS, точечно — behavior: 'smooth'. */
.promo-slider__track {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
}

/* Слайд ровно во всю ширину трека — половинки соседнего кадра здесь были бы
   шумом: у промо крупный заголовок, и рядом с ним обрезанная картинка читается
   как сбитая вёрстка, а не как подсказка «дальше есть ещё». */
.promo-slider__track > .promo {
  flex: 0 0 100%;
  scroll-snap-align: start;
}

/* Стрелки поверх кадра. Полупрозрачная заливка нужна из-за того, что фон под
   ними меняется от слайда к слайду: на белом поле ботинка и на тёмном рюкзаке
   один и тот же сплошной цвет выглядел бы то грязью, то дырой. */
.promo-slider__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  /* До 760px слайд разворачивается в колонку — фото сверху, текст снизу, —
     и вертикальная середина приходится ровно на заголовок. Стрелки там не
     сдвинуть, не задев текст, поэтому их просто нет: листается свайпом,
     а положение показывают точки. */
  display: none;
  place-items: center;
  width: 44px;
  height: 44px;
  border: 1px solid var(--line);
  border-radius: 50%;
  background: rgba(255, 255, 255, .82);
  backdrop-filter: blur(6px);
  color: var(--ink);
  cursor: pointer;
  transition: background-color .2s ease, border-color .2s ease, opacity .2s ease;
}

.promo-slider__nav:hover {
  background: #fff;
  border-color: var(--pill);
}

.promo-slider__prev { left: clamp(8px, 1.4vw, 20px); }
.promo-slider__next { right: clamp(8px, 1.4vw, 20px); }

/* Точки — единственный указатель, сколько всего слайдов и где мы сейчас.
   Полосы прогресса, как у товарных каруселей, тут нет: слайд один на экран,
   и доля видимого всегда одинаковая, показывать нечего. */
.promo-slider__dots {
  display: flex;
  justify-content: center;
  gap: 10px;
  margin-top: clamp(18px, 2vw, 28px);
}

.promo-slider__dot {
  width: 32px;
  height: 2px;
  padding: 10px 0;          /* до 44px по высоте — зона нажатия, сама черта тонкая */
  background: none;
  border: 0;
  cursor: pointer;
  box-sizing: content-box;
}

.promo-slider__dot::before {
  content: "";
  display: block;
  height: 2px;
  background: var(--pill);
  transition: background-color .25s ease;
}

.promo-slider__dot[aria-current="true"]::before { background: var(--teal-deep); }
.promo-slider__dot:hover::before { background: var(--muted); }

/* Рамка та же, что у .card__media в товарных каруселях. Без неё слайд — белое
   поле на белом фоне страницы: не видно ни где он начинается, ни что кадр
   и текст рядом с ним это один блок, а не два соседних. */
.promo {
  display: grid;
  grid-template-columns: 1fr;
  background: #fff;
  border: 1px solid var(--line);
  overflow: hidden;
}

/* Кадр вырезан по предмету и лежит на прозрачном квадрате. cover обрезал бы
   этот квадрат по краям 4/3 и раздул ботинок; contain с полем показывает его
   целиком и держит тот же масштаб, что в карточках. */
.promo__media {
  background: #fff;
  border-bottom: 1px solid var(--line);
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 3;
  object-fit: contain;
  padding: clamp(20px, 3vw, 52px);
  transition: opacity .3s ease;
}

.promo:hover { border-color: var(--pill); }
.promo:hover .promo__media { opacity: .94; }

.promo__inner {
  display: flex;
  flex-direction: column;
  justify-content: center;
  align-items: flex-start;
  gap: clamp(16px, 1.8vw, 24px);
  padding: clamp(28px, 4vw, 68px);
}

.promo__eyebrow {
  font-size: clamp(10px, 1vw, 12px);
  letter-spacing: .26em;
  text-transform: uppercase;
  color: var(--teal-deep);
}

.promo__title {
  font-family: 'Playfair Display', serif;
  font-weight: 400;
  font-size: clamp(26px, 3.4vw, 52px);
  line-height: 1.06;
  margin: 0;
  text-transform: uppercase;
  letter-spacing: .01em;
  color: var(--ink);
  max-width: 16ch;
}

.promo__text {
  font-size: 14px;
  line-height: 1.65;
  color: var(--muted);
  max-width: 40ch;
  margin: 0;
}

.promo__cta {
  display: inline-flex;
  align-items: center;
  gap: 14px;
  font-size: 11px;
  letter-spacing: .16em;
  text-transform: uppercase;
  color: #fff;
  background: var(--teal-deep);
  padding: 16px 30px;
}

.promo__cta:hover { background: var(--teal); }

@media (min-width: 760px) {
  .promo-slider__nav { display: grid; }
  .promo { grid-template-columns: 1fr 1fr; }
  .promo__media {
    aspect-ratio: auto;
    min-height: 400px;
    max-height: 520px;
    object-fit: contain;
    object-position: 50% 50%;
    padding: clamp(20px, 3vw, 48px);
    border-bottom: 0;
    border-right: 1px solid var(--line);
  }
}

/* ==========================================================================
   Категории
   ========================================================================== */
.categories__grid {
  display: grid;
  /* Фиксированное число колонок вместо auto-fill: последний ряд всегда полный */
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(34px, 3.6vw, 56px) clamp(14px, 1.4vw, 22px);
}

.category { display: block; }

.category:hover .category__media { opacity: .9; }

.category__media {
  aspect-ratio: 1 / 1;
  background: #F5F6F6;
  border-radius: 50%;
  overflow: hidden;
  padding: 14%;
  transition: opacity .25s ease, background-color .25s ease;
}

.category__media .ph {
  object-fit: contain;
  background: transparent;
}

.category:hover .category__media { background: var(--tint); }

/* То же, что .card__media--bleed, но паддинг здесь 14% ширины круга,
   а не пиксельный: 14% / 72% содержимого = 19.4% ширины самой картинки. */
.category__media--bleed .ph {
  transform: translateX(calc(-19.4% - 5%));
}

/* Тот же приём для среза сверху, а не сбоку. Одежду в доноре снимали только
   на моделях: единственный предметный кадр раздела — ноги в колготках и коньках,
   обрезанные по бедру. По центру круга такой срез читается как брак, поэтому
   кадр увеличен и поднят, чтобы линия среза ушла под верхний край. Масштаб
   компенсирует подъём: иначе коньки уехали бы вверх и низ круга опустел. */
.category__media--bleed-top .ph {
  transform: scale(1.62) translateY(-11%);
}

.category__name {
  margin-top: 12px;
  text-align: center;
  font-size: 11px;
  letter-spacing: .1em;
  text-transform: uppercase;
  line-height: 1.45;
}

/* ==========================================================================
   Соцсети — баннеры на главной
   ========================================================================== */
.socials {
  display: grid;
  grid-template-columns: 1fr;
  gap: 14px;
}

@media (min-width: 620px) {
  .socials { grid-template-columns: 1fr 1fr; }
}

.social-banner {
  display: flex;
  align-items: center;
  gap: 16px;
  padding: clamp(20px, 2.4vw, 30px);
  border-radius: 9px;
  background: var(--teal-deep);
  color: #fff;
  transition: background-color .2s ease;
}

.social-banner:hover { background: var(--teal); }

.social-banner__icon { flex: 0 0 auto; }

.social-banner__text { display: flex; flex-direction: column; gap: 4px; }

.social-banner__title {
  font-family: 'Playfair Display', serif;
  font-size: clamp(19px, 1.8vw, 22px);
}

.social-banner__sub {
  font-size: 13px;
  color: rgba(255, 255, 255, .8);
  line-height: 1.4;
}

/* ==========================================================================
   Подвал
   ========================================================================== */
.footer-wrap {
  background: #F7F8F8;
  border-top: 1px solid var(--line);
  margin-top: clamp(40px, 5vw, 80px);
}

.footer { padding-block: clamp(48px, 5vw, 76px) clamp(24px, 3vw, 36px); }

.footer__top {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(28px, 4vw, 48px);
  align-items: start;
}

/* Крупнее, чем в шапке: подвал не липкий, экономить высоту здесь не на чем,
   а знак — единственная картинка в блоке сплошного текста. */
.footer__logo {
  display: inline-block;
  margin-bottom: 18px;
}

.footer__logo img {
  height: 44px;
  width: auto;
}

.footer__col-title {
  display: block;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 16px;
}

.footer__list {
  display: grid;
  gap: 11px;
  font-size: 13px;
}

.footer__list a:hover { color: var(--teal-deep); }

.footer__about {
  font-size: 13px;
  line-height: 1.65;
  color: var(--muted);
  max-width: 34ch;
  margin: 0 0 18px;
}

.footer__phone {
  display: inline-block;
  font-size: 20px;
  letter-spacing: .02em;
  margin-bottom: 6px;
}

.footer__phone:hover { color: var(--teal-deep); }

.footer__hours {
  display: block;
  font-size: 12px;
  color: var(--muted);
  margin-bottom: 18px;
}

.footer__social {
  display: flex;
  gap: 22px;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
}

.footer__social a {
  border-bottom: 1px solid var(--ink);
  padding-bottom: 2px;
}

.footer__social a:hover { color: var(--teal-deep); border-color: var(--teal-deep); }

.footer__bottom {
  margin-top: clamp(34px, 4vw, 52px);
  padding-top: 22px;
  border-top: 1px solid var(--line);
  display: flex;
  flex-wrap: wrap;
  gap: 10px 26px;
  align-items: center;
  font-size: 11px;
  letter-spacing: .04em;
  color: var(--muted);
}

.footer__bottom a:hover { color: var(--teal-deep); }

.footer__legal {
  margin: 10px 0 0;
  font-size: 10px;
  line-height: 1.5;
  color: var(--muted);
  max-width: 760px;
}

/* ==========================================================================
   Внутренняя страница
   Общий каркас для всех информационных разделов: шапка с крошками,
   боковое меню раздела и колонка текста.
   ========================================================================== */

/* Шапка страницы: светлая плашка во всю ширину, чтобы заголовок не висел
   встык под навигацией и раздел читался как отдельный экран. */
.page-head {
  background: var(--canvas);
  border-bottom: 1px solid var(--line);
  padding-block: clamp(28px, 4vw, 56px);
}

.crumbs {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: clamp(14px, 1.8vw, 22px);
}

.crumbs a:hover { color: var(--teal-deep); }

.crumbs__sep { opacity: .5; }

/* Текущая страница в крошках — не ссылка, поэтому и цвет обычный текстовый */
.crumbs__current { color: var(--ink); }

/* ==========================================================================
   Каталог: сетка разделов
   ========================================================================== */
.section__note {
  font-size: 12px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted);
  white-space: nowrap;
}

/* На телефоне жёстко две колонки. auto-fill с минимумом 200px на 390px
   укладывался в одну, и витрина из пятнадцати разделов вытягивалась
   на восемь с половиной тысяч пикселей — до нижних разделов не долистать. */
.section-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: clamp(16px, 1.8vw, 28px);
}

@media (min-width: 620px) {
  .section-grid { grid-template-columns: repeat(auto-fill, minmax(clamp(200px, 22vw, 280px), 1fr)); }
}

.section-card {
  display: flex;
  flex-direction: column;
  border: 1px solid var(--line);
  background: #fff;
  transition: border-color .25s ease;
}

.section-card:hover { border-color: var(--pill); }

/* Те же 4/5 и contain, что у карточки товара: кадры разделов приходят из
   одного пула, и любой другой кроп ломал бы единый масштаб предмета. */
.section-card__media {
  position: relative;
  aspect-ratio: 4 / 5;
  background: #fff;
  overflow: hidden;
  padding: clamp(14px, 1.6vw, 26px);
  border-bottom: 1px solid var(--line);
}

.section-card__media .ph {
  object-fit: contain;
  background: transparent;
}

.section-card:hover .ph { opacity: .9; }

.section-card__body {
  display: flex;
  flex-direction: column;
  gap: 6px;
  padding: clamp(12px, 1.4vw, 18px);
}

.section-card__name {
  font-size: 13px;
  line-height: 1.35;
  color: var(--ink);
}

.section-card__count {
  font-size: 11px;
  letter-spacing: .06em;
  color: var(--muted);
}

/* ==========================================================================
   Страница раздела: чипы подразделов и сетка товаров
   ========================================================================== */

/* Подразделы — якоря внутри страницы, а не отдельные страницы: в половине
   из них меньше десятка товаров. Чипы работают как оглавление. */
.chips {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  margin-bottom: clamp(24px, 3vw, 40px);
}

.chip {
  display: inline-flex;
  align-items: baseline;
  gap: 7px;
  border: 1px solid var(--line);
  padding: 8px 14px;
  font-size: 12px;
  color: var(--ink);
  transition: border-color .2s ease, background-color .2s ease;
}

.chip:hover {
  border-color: var(--teal-deep);
  background: var(--tint);
}

.chip__count {
  font-size: 11px;
  color: var(--muted);
}

.subsection {
  /* Шапка липкая, поэтому якорь без отступа прячет заголовок под неё */
  scroll-margin-top: calc(var(--header-h) + 20px);
  margin-bottom: clamp(32px, 4vw, 56px);
}

.subsection__title {
  display: flex;
  align-items: baseline;
  gap: 10px;
  font-family: 'Playfair Display', serif;
  font-weight: 400;
  font-size: clamp(20px, 2.2vw, 28px);
  line-height: 1.2;
  margin: 0 0 clamp(16px, 2vw, 24px);
  padding-bottom: 12px;
  border-bottom: 1px solid var(--line);
  text-transform: uppercase;
}

.subsection__count {
  font-family: 'Montserrat', sans-serif;
  font-size: 12px;
  color: var(--muted);
}

/* Фильтры слева, товары справа. Колонка фильтров фиксированной ширины:
   резиновая на широком экране растягивала бы названия подразделов в строку
   на пол-экрана, а сетке товаров ширина нужнее. */
.catalog-layout {
  display: grid;
  grid-template-columns: 1fr;
  gap: clamp(20px, 2.4vw, 40px);
  align-items: start;
}

@media (min-width: 900px) {
  .catalog-layout { grid-template-columns: 250px 1fr; }
}

.catalog-main { min-width: 0; }

/* Три в ряд — как просили. auto-fill здесь не годится: он подстраивает число
   колонок под ширину, и на 1920 их становилось шесть.
   minmax(0, …) вместо голого 1fr: трек по умолчанию не даёт себя сжать уже
   своего содержимого, и на 320px пара «Выбрать размер» + сердечко распирала
   сетку до 342px — вся страница ползла вбок. */
.cards-grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: clamp(14px, 1.6vw, 26px);
  margin-bottom: clamp(32px, 4vw, 56px);
}

@media (min-width: 700px) {
  .cards-grid { grid-template-columns: repeat(3, minmax(0, 1fr)); }
}

.catalog-empty {
  color: var(--muted);
  font-size: 14px;
  padding: clamp(28px, 4vw, 56px) 0;
}

/* --- Панель фильтров --- */
.filters {
  display: grid;
  gap: clamp(18px, 2vw, 26px);
}

/* У .card собственный display, поэтому атрибут hidden сам по себе его не прячет —
   без этого правила фильтр «скрывал» карточки, а они оставались на месте. */
[hidden] { display: none !important; }

@media (min-width: 900px) {
  .filters {
    position: sticky;
    /* Шапка липкая: без отступа верх панели уезжает под неё */
    top: calc(var(--header-h) + 22px);
    max-height: calc(100vh - var(--header-h) - 44px);
    overflow-y: auto;
    padding-right: 4px;
  }
}

.filters__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding-bottom: 10px;
  border-bottom: 1px solid var(--line);
}

.filters__title {
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.filters__reset {
  background: none;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: var(--teal-deep);
  font-size: 11px;
  letter-spacing: .04em;
}

.filters__reset:hover { color: var(--teal); }

/* Крестик и подложка нужны только листу на телефоне: на десктопе панель стоит
   в колонке рядом с сеткой и закрывать её не от чего. Включаются ниже,
   в медиазапросе «фильтры листом». */
.filters__close,
.filters__backdrop,
.filters .filters__done { display: none; }

.filters__close {
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  padding: 10px;
  margin: -10px -10px -10px 0;
  color: var(--muted);
  cursor: pointer;
}

.filters__close:hover { color: var(--ink); }

/* Итог отбора не отходя от фильтров: сколько товаров останется — на кнопке,
   она же закрывает лист. Липкая, потому что список условий длиннее экрана. */
.filters .filters__done {
  position: sticky;
  bottom: 0;
  width: 100%;
  margin-top: 4px;
  text-align: center;
  cursor: pointer;
}

/* Кнопка нужна только там, где панель схлопывается, — на узком экране */
.filters__toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  border: 1px solid var(--line);
  background: #fff;
  padding: 11px 16px;
  font-size: 12px;
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
  justify-self: start;
}

@media (min-width: 900px) {
  .filters__toggle { display: none; }
}

/* Сколько фильтров уже стоит — прямо на кнопке. Иначе, закрыв лист, человек
   видит короткую выдачу и не понимает, это весь раздел или остаток отбора. */
.filters__toggle-count {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 18px;
  height: 18px;
  padding: 0 5px;
  border-radius: 9px;
  background: var(--teal-deep);
  color: #fff;
  font-size: 10px;
  letter-spacing: 0;
}

.filter__title {
  font-size: 12px;
  letter-spacing: .06em;
  margin-bottom: 10px;
  color: var(--ink);
}

/* Длинные списки (у одежды под два десятка подразделов) прокручиваем внутри,
   иначе панель фильтров вытягивается вдвое длиннее сетки товаров. */
.filter__list {
  display: grid;
  gap: 2px;
  max-height: 260px;
  overflow-y: auto;
}

.filter__row {
  display: flex;
  align-items: center;
  gap: 9px;
  padding: 5px 0;
  cursor: pointer;
  font-size: 13px;
  color: var(--muted);
  line-height: 1.35;
}

.filter__row:hover { color: var(--ink); }

.filter__row input {
  flex: 0 0 auto;
  accent-color: var(--teal-deep);
  width: 15px;
  height: 15px;
  margin: 0;
}

.filter__label {
  min-width: 0;
  overflow-wrap: anywhere;
}

/* --pill (#D8DDDD) — цвет линий, а не текста: на белом он даёт 1.37:1 при
   норме 4.5. От названия счётчик отличается размером, а не блёклостью. */
.filter__count {
  margin-left: auto;
  flex: 0 0 auto;
  font-size: 11px;
  color: var(--muted);
}

.filter__price {
  display: flex;
  align-items: center;
  gap: 8px;
}

.filter__num {
  min-width: 0;
  flex: 1 1 0;
  border: 1px solid var(--line);
  background: #fff;
  padding: 9px 10px;
  font: inherit;
  font-size: 13px;
  color: var(--ink);
}

.filter__num:focus-visible { border-color: var(--teal-deep); }

.filter__dash { color: var(--muted); }

/* --- Фильтры листом (до 900px) ------------------------------------------
   Раскрытая в потоке панель отжимала сетку товаров на второй экран: у одежды
   два десятка подразделов плюс бренды и размеры, и после каждой галочки
   приходилось листать вниз, чтобы увидеть, что изменилось. Лист лежит поверх
   сетки — результат виден сразу под ним, и закрывается он одним движением.
   Блок стоит последним в разделе: он переопределяет базовые правила панели,
   а при равной специфичности выигрывает то, что ниже по файлу.
   -------------------------------------------------------------------- */
@media (max-width: 899.98px) {
  .filters {
    display: none;
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 55;
    max-height: 84dvh;
    background: #fff;
    box-shadow: 0 -20px 50px -18px rgba(30, 42, 44, .34);
    overflow-y: auto;
    overscroll-behavior: contain;
    padding: 0 var(--pad-r) calc(18px + env(safe-area-inset-bottom)) var(--pad-l);
    gap: clamp(18px, 4vw, 26px);
  }

  .filters[data-open="true"] { display: grid; }

  /* Шапка листа липнет к его верху: список условий длинный, и «Сбросить»
     с крестиком обязаны оставаться на виду, куда бы его ни прокрутили. */
  .filters__head {
    position: sticky;
    top: 0;
    z-index: 1;
    align-items: center;
    background: #fff;
    padding-top: 16px;
  }

  .filters__close { display: inline-flex; }

  .filters .filters__done { display: block; }

  /* Вложенный скролл на тач-экране — ловушка: палец, начавший движение внутри
     списка, прокручивает список, а не лист, и кажется, что лист залип. */
  .filter__list { max-height: none; overflow: visible; }

  /* Затемнение под листом. Оно же — область «нажать мимо, чтобы закрыть». */
  .filters__backdrop {
    display: block;
    position: fixed;
    inset: 0;
    z-index: 54;
    background: rgba(30, 42, 44, .38);
  }
}

.cards-grid .card { width: auto; }

.card__price--none {
  color: var(--muted);
  font-size: 12px;
}

.page-title {
  font-family: 'Playfair Display', serif;
  font-weight: 400;
  font-size: clamp(28px, 4.4vw, 56px);
  line-height: 1.08;
  margin: 0;
  text-transform: uppercase;
  letter-spacing: .01em;
}

/* Подзаголовок-лид под H1: одна фраза о чём раздел */
.page-lead {
  max-width: 62ch;
  margin: clamp(12px, 1.4vw, 18px) 0 0;
  font-size: clamp(14px, 1.2vw, 17px);
  line-height: 1.6;
  color: var(--muted);
}

/* Раскладка: меню раздела слева, текст справа. До 900px (см. брейкпоинты)
   схлопывается в одну колонку и меню уезжает наверх. */
.page-body {
  padding-block: clamp(36px, 5vw, 72px);
  display: grid;
  gap: clamp(28px, 4vw, 56px);
  align-items: start;
}

/* min-width: 0 обязателен: по умолчанию грид-элемент не даёт себя сжать уже
   своего содержимого, и таблица сроков доставки (min-width: 520px) распирала
   не свою обёртку со скроллом, а всю страницу — на 390px текст уезжал за край. */
.page-body > * { min-width: 0; }

/* Страница без соседей по разделу (услуги, производители): меню из одного
   пункта не навигация, а пустая колонка. Уводить в чужие разделы такое меню
   тоже нельзя — оно меняется под ногами. Просто убираем колонку.
   Двойной класс — чтобы правило пережило медиазапрос с двумя колонками:
   тот объявлен ниже по файлу и при равной специфичности выигрывал бы. */
.page-body.page-body--solo { grid-template-columns: 1fr; }

/* --- Меню раздела ------------------------------------------------------- */
/* Липкой колонка становится только там, где она и есть колонка. До 900px
   меню раздела едет наверх обычным списком, и sticky на нём приклеивал бы
   этот список к верху экрана поверх текста. */
.sidenav { position: static; }

@media (min-width: 900px) {
  .sidenav { position: sticky; top: calc(var(--header-h) + 28px); }
}

.sidenav__title {
  display: block;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--muted);
  padding-bottom: 14px;
  border-bottom: 1px solid var(--line);
}

.sidenav__list { display: flex; flex-direction: column; }

.sidenav__list a {
  padding: 13px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
  line-height: 1.35;
  color: var(--muted);
}

.sidenav__list a:hover { color: var(--teal-deep); }

/* Текущий пункт — засечка фирменным цветом слева: подчёркивание тут спорит
   с разделителями списка, а заливка утяжеляет колонку. */
.sidenav__list a[aria-current="page"] {
  color: var(--ink);
  font-weight: 500;
  padding-left: 14px;
  box-shadow: inset 3px 0 0 var(--teal);
}

/* --- Текст -------------------------------------------------------------- */
.prose {
  max-width: 74ch;
  font-size: clamp(14px, 1.15vw, 16px);
  line-height: 1.75;
  color: var(--ink);
}

.prose > *:first-child { margin-top: 0; }
.prose > *:last-child { margin-bottom: 0; }

.prose p { margin: 0 0 1.1em; }

.prose h2 {
  font-family: 'Playfair Display', serif;
  font-weight: 400;
  font-size: clamp(21px, 2.4vw, 30px);
  line-height: 1.2;
  margin: 2em 0 .7em;
  text-transform: uppercase;
  letter-spacing: .01em;
}

.prose h3 {
  font-size: clamp(15px, 1.4vw, 18px);
  font-weight: 600;
  line-height: 1.35;
  margin: 1.9em 0 .6em;
  letter-spacing: .01em;
}

.prose a {
  color: var(--teal-deep);
  border-bottom: 1px solid var(--tint);
}

.prose a:hover { border-color: var(--teal-deep); }

.prose ul, .prose ol { margin: 0 0 1.1em; padding-left: 0; }

.prose li {
  position: relative;
  list-style: none;
  padding-left: 26px;
  margin-bottom: .55em;
}

/* Маркер — короткая бирюзовая черта вместо точки: перекликается с засечкой
   активного пункта меню и с линиями в карточках на главной. */
.prose ul > li::before {
  content: "";
  position: absolute;
  left: 0;
  top: .78em;
  width: 12px;
  height: 1px;
  background: var(--teal);
}

/* Пункт-шаг: заголовок и абзацы внутри li. Родные отступы h3/p здесь рвут
   список, поэтому внутри пункта ритм задаём заново. */
.prose li > h3:first-child { margin-top: 0; margin-bottom: .35em; }
.prose li > p:last-child { margin-bottom: 0; }
.prose li > p { margin-bottom: .6em; }
.prose ol > li { margin-bottom: 1.5em; }

.prose ol { counter-reset: n; }

.prose ol > li::before {
  counter-increment: n;
  content: counter(n) ".";
  position: absolute;
  left: 0;
  top: 0;
  font-size: 13px;
  color: var(--teal-deep);
}

/* --- Таблица ------------------------------------------------------------
   Обёртка со скроллом обязательна: таблица сроков доставки в пять колонок
   на телефоне иначе распирает страницу по горизонтали. */
/* Тень у обрезанного края — единственный признак, что таблицу можно тянуть
   вбок. Без неё на телефоне пятая колонка просто не существует: край ровный,
   полосы прокрутки нет. Слои с `local` едут вместе с содержимым и гасят тень,
   когда до края уже докрутили; слои со `scroll` — сама тень, она стоит на месте. */
.prose__table {
  overflow-x: auto;
  overscroll-behavior-x: contain;
  margin: 0 0 1.4em;
  -webkit-overflow-scrolling: touch;
  background:
    linear-gradient(to right, #fff, rgba(255, 255, 255, 0)) left / 28px 100% no-repeat local,
    linear-gradient(to left, #fff, rgba(255, 255, 255, 0)) right / 28px 100% no-repeat local,
    radial-gradient(farthest-side at 0 50%, rgba(30, 42, 44, .16), transparent) left / 12px 100% no-repeat scroll,
    radial-gradient(farthest-side at 100% 50%, rgba(30, 42, 44, .16), transparent) right / 12px 100% no-repeat scroll;
}

.prose table {
  width: 100%;
  min-width: 520px;
  border-collapse: collapse;
  font-size: 13px;
}

.prose th, .prose td {
  padding: 13px 16px;
  text-align: left;
  border-bottom: 1px solid var(--line);
  vertical-align: top;
}

.prose th {
  background: var(--grey);
  font-weight: 500;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  color: var(--muted);
}

.prose tbody tr:hover td { background: #FAFBFB; }

/* Меньше 520px таблице просто негде развернуться: тянуть её вбок на полтора
   экрана хуже, чем на треть. Уплотняем — до 460px она доезжает почти целиком. */
@media (max-width: 620px) {
  .prose table { min-width: 460px; font-size: 12px; }
  .prose th, .prose td { padding: 10px 12px; }
}

/* --- Выноска ------------------------------------------------------------
   Для одиночного важного факта в потоке текста (бесплатная доставка,
   срок возврата) — то, ради чего страницу и открывают. */
.note {
  margin: 0 0 1.4em;
  padding: clamp(16px, 2vw, 22px) clamp(18px, 2.2vw, 26px);
  background: var(--tint);
  border-left: 3px solid var(--teal);
  font-size: clamp(14px, 1.15vw, 16px);
  line-height: 1.6;
}

.note p { margin: 0; }
.note p + p { margin-top: .7em; }

/* Ссылка внутри выноски и отзыва лежит не на белом, а на заливке —
   и обычного акцента там на контраст не хватает. */
.note a,
.review a { color: var(--teal-ink); }

/* --- Карточки фактов ----------------------------------------------------
   Контакты, реквизиты, способы доставки: пары «подпись — значение»,
   которые в сплошном абзаце не сканируются глазом. */
.facts {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(240px, 1fr));
  gap: clamp(14px, 1.6vw, 20px);
  margin: 0 0 1.6em;
}

.fact {
  padding: clamp(18px, 2vw, 24px);
  border: 1px solid var(--line);
  background: #fff;
}

/* Четыре факта на всю ширину страницы: auto-fill укладывает три в ряд
   и роняет четвёртый в пустую строку. Раскладываем парами — сетка
   закрывается без дыры справа. До 620px колонка и так одна. */
@media (min-width: 620px) {
  .facts--pair { grid-template-columns: repeat(2, 1fr); }
}

.fact__label {
  display: block;
  font-size: 11px;
  letter-spacing: .12em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 10px;
}

.fact__value {
  font-size: clamp(15px, 1.3vw, 17px);
  line-height: 1.5;
}

.fact__value a:hover { color: var(--teal-deep); }

/* Мелкая приписка под значением — режим работы, комментарий к адресу */
.fact__note {
  display: block;
  margin-top: 8px;
  font-size: 13px;
  line-height: 1.55;
  color: var(--muted);
}

/* --- Кнопка ------------------------------------------------------------- */
.btn {
  display: inline-block;
  padding: 15px 30px;
  background: var(--teal-deep);
  color: #fff;
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  border: 1px solid var(--teal-deep);
}

.btn:hover { background: var(--teal); border-color: var(--teal); }

.btn--ghost { background: transparent; color: var(--ink); border-color: var(--pill); }
.btn--ghost:hover { background: transparent; color: var(--teal-deep); border-color: var(--teal-deep); }

/* --- Услуги -------------------------------------------------------------
   Фото + описание. Кадры у поставщика разного формата (печка 3:4, веер
   чехлов 1:1), поэтому высоту задаём мы, а не картинка. */
.svc {
  display: grid;
  gap: clamp(18px, 2.4vw, 32px);
  align-items: center;
  padding: clamp(20px, 2.4vw, 30px);
  border: 1px solid var(--line);
  margin-bottom: clamp(18px, 2vw, 26px);
}

.svc__media {
  aspect-ratio: 4 / 3;
  background: var(--grey);
  overflow: hidden;
}

.svc__media img { width: 100%; height: 100%; object-fit: cover; }

/* Заголовки карточек — h2 ради структуры документа, но выглядеть должны
   как подписи внутри блока, а не как разделы страницы. Селектор с .prose,
   иначе .prose h2 перебивает их своим Playfair в капсе. */
.prose .svc__title,
.svc__title {
  font-family: 'Montserrat', system-ui, sans-serif;
  font-size: clamp(16px, 1.5vw, 20px);
  font-weight: 500;
  line-height: 1.3;
  letter-spacing: 0;
  text-transform: none;
  margin: 0 0 .6em;
}

.svc__text { margin: 0; font-size: 14px; line-height: 1.7; color: var(--muted); }

/* --- Отзывы -------------------------------------------------------------- */
.reviews {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(280px, 1fr));
  gap: clamp(16px, 2vw, 24px);
  margin-bottom: clamp(24px, 3vw, 36px);
}

.review {
  display: flex;
  flex-direction: column;
  gap: 14px;
  padding: clamp(20px, 2.2vw, 28px);
  background: var(--grey);
}

.review__text { margin: 0; font-size: 14px; line-height: 1.7; }

.review__meta {
  margin-top: auto;
  padding-top: 14px;
  border-top: 1px solid var(--pill);
}

.review__name { display: block; font-size: 14px; font-weight: 500; }

.review__date {
  display: block;
  margin-top: 4px;
  font-size: 11px;
  letter-spacing: .06em;
  text-transform: uppercase;
  color: var(--muted);
}

/* --- Бренды --------------------------------------------------------------
   Логотипов марок в фонде нет, поэтому плитка текстовая: имя набрано
   заголовочным шрифтом, чтобы ряд не выглядел списком тегов. */
/* Поток, а не грид: у «Аксессуаров» марка одна, и в гриде пустые треки
   светились фоном контейнера на всю ширину строки. Плитки по содержимому
   заполняют ряд слева направо, короткий ряд просто короче. */
.brands {
  display: flex;
  flex-wrap: wrap;
  gap: clamp(8px, 1vw, 12px);
  margin-bottom: clamp(24px, 3vw, 36px);
}

.brand {
  flex: 0 0 auto;
  display: grid;
  place-items: center;
  min-width: 148px;
  min-height: 76px;
  padding: 16px 26px;
  border: 1px solid var(--line);
  background: #fff;
  font-family: 'Playfair Display', serif;
  font-size: clamp(15px, 1.4vw, 19px);
  letter-spacing: .02em;
  text-align: center;
}

/* Марка со своим разделом в каталоге — ссылка, но в общем ряду она должна
   читаться как такая же плитка: цвет и подчёркивание от .prose a убираем. */
.prose a.brand { color: var(--ink); border-bottom: 1px solid var(--line); }
.prose a.brand:hover { color: var(--teal-deep); border-color: var(--teal-deep); }

/* Подсветка только у кликабельных плиток: марки без своего раздела в каталоге
   остаются обычными ячейками, и hover на них обманывал бы. */
a.brand:hover { background: var(--tint); }

/* --- Документ ------------------------------------------------------------ */
.doc {
  display: inline-block;
  max-width: 340px;
  border: 1px solid var(--line);
  margin-bottom: clamp(20px, 2.4vw, 30px);
}

.doc img { width: 100%; height: auto; }

.doc__caption {
  display: block;
  padding: 14px 18px;
  border-top: 1px solid var(--line);
  font-size: 12px;
  letter-spacing: .04em;
  color: var(--muted);
}

.doc:hover { border-color: var(--pill); }

/* --- Вакансия ------------------------------------------------------------ */
.vacancy {
  border: 1px solid var(--line);
  padding: clamp(20px, 2.6vw, 32px);
  margin-bottom: clamp(20px, 2.4vw, 30px);
}

.vacancy__head {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px 20px;
  padding-bottom: 18px;
  margin-bottom: 20px;
  border-bottom: 1px solid var(--line);
}

.vacancy__title { font-size: clamp(17px, 1.7vw, 22px); font-weight: 500; margin: 0; }

.vacancy__salary {
  font-size: clamp(15px, 1.4vw, 18px);
  color: var(--teal-deep);
  white-space: nowrap;
}

/* Кнопка внутри текста: .prose a специфичнее .btn и красит подпись в цвет
   ссылки — на бирюзовой заливке она пропадает. Возвращаем свои цвета. */
.prose a.btn { color: #fff; border-bottom-color: transparent; }
.prose a.btn:hover { color: #fff; }
.prose a.btn--ghost { color: var(--ink); }
.prose a.btn--ghost:hover { color: var(--teal-deep); }

/* ==========================================================================
   Брейкпоинты
   Основа макета — clamp() и сетка. Медиазапросы только там, где нужна
   смена раскладки: её текучей типографикой не сделать.
   ========================================================================== */

/* --- от 600px: категории в 4 колонки --- */
@media (min-width: 620px) {
  .categories__grid { grid-template-columns: repeat(4, 1fr); }
}

/* --- подвал: 1 → 2 → 4 колонки ---
   Промежуточной ступени не было, и на планшете четыре списка вытягивались
   в одну колонку длиной в полтора экрана при пустых полях по бокам. */
@media (min-width: 560px) {
  .footer__top { grid-template-columns: repeat(2, 1fr); }
}

@media (min-width: 1024px) {
  .footer__top { grid-template-columns: 1.4fr 1fr 1fr 1.2fr; }
}

/* --- от 900px: внутренняя страница в две колонки ---
   Уже 900px меню раздела в узкой колонке ломает строки пунктов, поэтому
   до этой ширины оно едет наверх обычным списком. */
@media (min-width: 900px) {
  .page-body { grid-template-columns: minmax(200px, 1fr) 3fr; }
}

/* --- от 700px: у карточки услуги фото уходит влево --- */
@media (min-width: 700px) {
  .svc { grid-template-columns: minmax(180px, 260px) 1fr; align-items: start; }
}

/* --- до 1100px: меню уходит в бургер ---
   Порог не 900, а 1100: шесть пунктов, телефон и три иконки в одну строку
   помещаются только с 1200px, и на всём промежутке меню переносилось на вторую
   строку — шапка распухала с 55 до 84px и наезжала на первый экран. */
@media (max-width: 1099.98px) {
  .burger { display: inline-flex; }

  .header { padding-block: 14px; }

  .header__phone { display: none; }

  /* Панель начинается ПОД шапкой, а не поверх неё. Раньше стояло inset: 0,
     и белое полотно накрывало и логотип, и сам бургер: открытое меню нечем
     было закрыть, оставалось только листать его до конца или уйти по ссылке. */
  .header__nav {
    position: fixed;
    top: var(--header-h);
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    display: grid;
    align-content: start;
    justify-content: stretch;
    gap: 0;
    background: #fff;
    padding: 6px var(--pad-l) calc(40px + env(safe-area-inset-bottom)) var(--pad-r);
    transform: translateX(100%);
    transition: transform .3s ease;
    overflow-y: auto;
    /* Докрутив список до низа, палец продолжал тянуть за собой страницу
       под панелью — и после закрытия меню человек оказывался не там, где был */
    overscroll-behavior: contain;
  }

  .header__nav[data-open="true"] { transform: none; }

  .navlink {
    font-size: 15px;
    padding-block: 16px;
    border-bottom: 1px solid var(--line);
  }

  .navlink::after { display: none; }

  /* Каталог — аккордеон: ссылка ведёт на витрину, шеврон рядом раскрывает
     список разделов. Развёрнутый по умолчанию, он занимал весь экран, и до
     «Услуг» с «Контактами» приходилось листать полтора экрана. */
  .navitem--drop {
    display: grid;
    grid-template-columns: 1fr auto;
    align-items: center;
  }

  .navlink--drop { border-bottom: 0; }

  .navlink__chev { display: none; }

  .navlink__toggle {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    align-self: stretch;
  }

  /* Линия под строкой — общая для ссылки и кнопки, поэтому она на ячейке-фоне,
     а не на самой ссылке: иначе подчёркивание обрывалось перед шевроном. */
  .navlink--drop,
  .navlink__toggle { box-shadow: inset 0 -1px 0 var(--line); }

  .megamenu {
    grid-column: 1 / -1;
    position: static;
    display: none;
    max-height: none;
    overflow: visible;
    opacity: 1;
    visibility: visible;
    transform: none;
    box-shadow: none;
    border: 0;
    padding: 0;
  }

  .navitem--drop[data-open="true"] .megamenu { display: block; }

  .megamenu__inner { columns: 1; }

  .megamenu__group { margin-bottom: 0; }

  /* Подразделы здесь скрыты: пятнадцать разделов с вложениями дают полсотни
     строк даже в раскрытом аккордеоне. Разделы ведут на свои страницы,
     а там подраздел выбирается фильтром. */
  .megamenu__link { display: none; }

  .megamenu__title {
    font-size: 14px;
    text-transform: none;
    letter-spacing: .02em;
    color: var(--muted);
    padding: 14px 0 14px 16px;
    margin-bottom: 0;
  }

  .nav__phone {
    margin-top: 26px;
    font-size: 20px;
    display: inline-block;
  }
}

@media (min-width: 1100px) {
  .nav__phone { display: none; }
}

/* На 1100–1249 меню уже развёрнуто, но телефон рядом с ним в строку не влезает.
   Он не пропадает совсем — остаётся в подвале и на странице контактов. */
@media (min-width: 1100px) and (max-width: 1249.98px) {
  .header__phone { display: none; }
}

/* --- до 700px: герой становится вертикальным ---
   Левое пустое поле кадра на узком экране бесполезно: если оставить текст
   поверх фото, он ляжет на лицо. Разносим — снимок сверху, слово снизу. */
@media (max-width: 700px) {
  /* height обязательно снять, а не «отключить» через max-height: сверху стоит
     height: clamp(340px, …) и overflow: hidden. Кадр 5/4 на телефоне сам по себе
     выше этих 340px, поэтому весь блок под ним — заголовок, «Лёгкость и
     точность», кнопка «В магазин» — просто обрезался. На 390px от героя
     оставалась одна фотография без единого слова. */
  .hero {
    height: auto;
    aspect-ratio: auto;
    max-height: none;
    overflow: visible;
    display: grid;
  }

  .hero__media {
    aspect-ratio: 5 / 4;
    object-position: 76% 0;
  }

  /* Отступы те же, что у любой секции сайта: половина --space-section, сверху
     и снизу поровну. Раньше стояло 26px сверху и 4px снизу — кнопка «В магазин»
     упиралась в бирюзовую полосу под героем, и весь блок смотрелся сползшим. */
  .hero__inner {
    position: static;
    width: 100%;
    padding: calc(var(--space-section) / 2) var(--pad-r) calc(var(--space-section) / 2) var(--pad-l);
  }

  /* Ограничение в 52% держало текст в пустом поле кадра, когда он лежал поверх
     фотографии. Здесь фотография уже сверху, а под ней те же 52% — это 150px
     на узком телефоне: надпись рассыпалась на три строки, а «В магазин»
     переносилось внутри кнопки. */
  .hero__stack { max-width: none; }

  .hero__title { font-size: clamp(30px, 9vw, 44px); }

  .carousel__nav { display: none; }
}

/* --- телефон в ландшафте ---
   Экран 360px высотой, а герой считается от ширины: 50vw от 740px давало 370px,
   и первый экран целиком занимала фотография — ни строки текста под ней.
   Здесь высоту задаёт не ширина окна, а его высота. */
@media (orientation: landscape) and (max-height: 520px) {
  .hero { height: clamp(240px, 66vh, 420px); }

  .hero__title { font-size: clamp(26px, 6vh, 40px); }

  .hero__stack { gap: 12px; }
}

/* ==========================================================================
   Страница товара
   ==========================================================================
   Две колонки: слева галерея, справа блок покупки. Единственный брейкпоинт —
   те же 900px, что у шапки и каталога: ниже колонки складываются в одну.
   -------------------------------------------------------------------- */
.product-page { padding-block: calc(var(--space-section) / 2); }

.product {
  display: grid;
  gap: clamp(24px, 3.4vw, 56px);
  align-items: start;
  margin-top: clamp(18px, 2.2vw, 32px);
}

@media (min-width: 900px) {
  .product { grid-template-columns: minmax(0, 1.15fr) minmax(340px, 1fr); }
}

/* --- Галерея ------------------------------------------------------------ */
/* Миниатюры стоят колонкой слева от кадра: под кадром они отжимали бы цену
   и кнопку ниже первого экрана, а именно их человек ищет первыми. */
.gallery {
  display: grid;
  gap: 12px;
}

@media (min-width: 700px) {
  .gallery {
    grid-template-columns: 74px minmax(0, 1fr);
    grid-template-areas: 'thumbs stage';
  }

  .gallery__stage { grid-area: stage; }
  .gallery__thumbs { grid-area: thumbs; }
}

/* Фон белый, object-fit: cover без паддинга — те же правила и та же
   пропорция 4:5, что у карточки в каталоге (card__media--fill): кадр
   заполняет рамку целиком, а не вписан в неё с полями. У «Кадрировать»
   в админке результат ровно под эту рамку — см. openCropper в app.js. */
.gallery__stage {
  position: relative;
  aspect-ratio: 4 / 5;
  /* min-height: 0 обязателен: стейдж — ячейка грида, а у неё min-height по
     умолчанию auto. Вертикальный кадр (662×1000) распирал ячейку до своей
     натуральной высоты, и вместо квадрата выходила полоса на полтора экрана —
     aspect-ratio в этом споре проигрывает. */
  min-height: 0;
  background: #fff;
  border: 1px solid var(--line);
  overflow: hidden;
}

.gallery__img {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Увеличение по наведению: transform-origin и scale ставит JS по курсору
   (см. инлайн-скрипт в конце index.html), CSS тут только про то, что курсор
   должен показать «можно приблизить», и что stage режет вылезающий край
   (overflow: hidden уже есть выше — увеличенный кадр сам не вылезет). */
@media (hover: hover) {
  .gallery__stage { cursor: zoom-in; }
}

.gallery__stage .ph { width: 100%; height: 100%; background: var(--grey); }

/* Значок play на стейдже — ролик там показан постером (см. gallery() в
   tools/build-products.mjs), сыграть видео целиком можно только в полно-
   экранном просмотре, отсюда и подсказка, что клик — не просто зум. */
.gallery__stage-play {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  width: 56px;
  height: 56px;
  display: grid;
  place-items: center;
  border-radius: 50%;
  background: rgba(11, 16, 17, .55);
  color: #fff;
  pointer-events: none;
}

.gallery__thumbs {
  display: flex;
  gap: 8px;
  overflow-x: auto;
  scrollbar-width: none;
}

.gallery__thumbs::-webkit-scrollbar { height: 0; display: none; }

@media (min-width: 700px) {
  .gallery__thumbs {
    flex-direction: column;
    overflow-x: visible;
    overflow-y: auto;
    max-height: 100%;
  }
}

.gallery__thumb {
  position: relative;
  flex: 0 0 auto;
  width: 66px;
  height: 66px;
  background: #fff;
  border: 1px solid var(--line);
  cursor: pointer;
  transition: border-color .2s ease;
}

.gallery__thumb img { width: 100%; height: 100%; object-fit: cover; }
.gallery__thumb:hover { border-color: var(--pill); }
.gallery__thumb.is-on { border-color: var(--teal-deep); }

.gallery__thumb-play {
  position: absolute;
  inset: 0;
  display: grid;
  place-items: center;
  background: rgba(11, 16, 17, .28);
  color: #fff;
  pointer-events: none;
}

.gallery__note {
  margin: 0;
  font-size: 13px;
  color: var(--muted);
}

/* ==========================================================================
   Полноэкранный просмотр фотографий товара — клик по крупному кадру
   ========================================================================== */
.lightbox {
  position: fixed;
  inset: 0;
  z-index: 80;
  display: flex;
  align-items: center;
  justify-content: center;
}

.lightbox__backdrop {
  position: absolute;
  inset: 0;
  /* Сплошной, не полупрозрачный: тонкая заливка поверх контрастного чёрного
     текста на белом фоне страницы (заголовок, цена) всё равно просвечивала
     призраком даже на 92% альфы. */
  background: #0b1011;
  opacity: 0;
  transition: opacity .2s ease;
}

.lightbox--on .lightbox__backdrop { opacity: 1; }

.lightbox__stage {
  position: relative;
  z-index: 1;
  width: min(94vw, 960px);
  height: min(88vh, 960px);
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0;
  transform: scale(.97);
  transition: opacity .2s ease, transform .2s ease;
  touch-action: pan-y;
}

.lightbox--on .lightbox__stage { opacity: 1; transform: none; }

.lightbox__img { max-width: 100%; max-height: 100%; object-fit: contain; }
.lightbox__video { max-width: 100%; max-height: 100%; }

.lightbox__close,
.lightbox__nav {
  position: absolute;
  z-index: 2;
  width: 44px;
  height: 44px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  border-radius: 50%;
  background: rgba(255, 255, 255, .12);
  color: #fff;
  cursor: pointer;
  transition: background .15s ease;
}

.lightbox__close:hover,
.lightbox__nav:hover { background: rgba(255, 255, 255, .22); }

.lightbox__close { top: clamp(10px, 3vw, 26px); right: clamp(10px, 3vw, 26px); }
.lightbox__nav { top: 50%; transform: translateY(-50%); }
.lightbox__nav--prev { left: clamp(6px, 2vw, 22px); }
.lightbox__nav--next { right: clamp(6px, 2vw, 22px); }

.lightbox__count {
  position: absolute;
  left: 50%;
  bottom: clamp(10px, 3vw, 22px);
  transform: translateX(-50%);
  margin: 0;
  color: rgba(255, 255, 255, .78);
  font-size: 13px;
  letter-spacing: .04em;
  font-variant-numeric: tabular-nums;
}

@media (prefers-reduced-motion: reduce) {
  .lightbox__backdrop, .lightbox__stage { transition: none; }
}

/* --- Блок покупки ------------------------------------------------------- */
/* Липкий на десктопе: описание и лента похожих длинные, и без этого цена
   с кнопкой уезжают из виду на первом же прокруте. */
@media (min-width: 900px) {
  .product__buy {
    position: sticky;
    top: calc(var(--header-h) + 40px);
  }
}

.product__brand {
  display: block;
  font-size: 11px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--teal-deep);
  margin-bottom: 10px;
}

.product__title {
  font-family: 'Playfair Display', serif;
  font-weight: 400;
  font-size: clamp(24px, 2.6vw, 34px);
  line-height: 1.18;
  margin: 0;
  letter-spacing: .01em;
}

.product__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px 16px;
  margin-top: 14px;
  font-size: 12px;
  color: var(--muted);
}

/* Точка-индикатор перед статусом: зелёная заливка тут была бы пятым цветом
   в палитре, а фирменный teal читается как «есть» не хуже. */
.product__stock {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  color: var(--ink);
}

.product__stock::before {
  content: '';
  width: 6px;
  height: 6px;
  border-radius: 50%;
  background: var(--teal);
}

.product__stock--no { color: var(--muted); }
.product__stock--no::before { background: var(--pill); }

.product__prices {
  display: flex;
  align-items: baseline;
  flex-wrap: wrap;
  gap: 12px;
  margin: clamp(18px, 2vw, 26px) 0;
  padding-bottom: clamp(18px, 2vw, 26px);
  border-bottom: 1px solid var(--line);
}

.product__price {
  font-size: clamp(26px, 3vw, 34px);
  font-weight: 500;
  line-height: 1;
}

.product__price--none {
  font-size: 18px;
  font-weight: 400;
  color: var(--muted);
}

.product__price-old {
  font-size: 16px;
  color: var(--muted);
  text-decoration: line-through;
}

/* --- Размеры ------------------------------------------------------------ */
.sizes { margin-bottom: clamp(20px, 2.4vw, 28px); }

.sizes__head {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 10px;
}

.sizes__title {
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
}

.sizes__help {
  font-size: 12px;
  color: var(--muted);
  border-bottom: 1px solid var(--line);
}

.sizes__help:hover { color: var(--teal-deep); border-color: var(--teal-deep); }

.sizes__list {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}

.size { cursor: pointer; }

/* Радиокнопку прячем, а не убираем: клавиатурная навигация и чтение
   скринридером держатся именно на ней. */
.size input {
  position: absolute;
  opacity: 0;
  pointer-events: none;
}

.size__val {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 48px;
  height: 42px;
  padding: 0 12px;
  border: 1px solid var(--line);
  font-size: 13px;
  transition: border-color .2s ease, color .2s ease;
}

.size:hover .size__val { border-color: var(--pill); }
.size input:checked + .size__val { border-color: var(--teal-deep); color: var(--teal-deep); }
.size input:focus-visible + .size__val { outline: 2px solid var(--teal-deep); outline-offset: 2px; }

/* Нажали «в корзину», не выбрав размер: подсвечиваем то, чего не хватает */
.sizes--ask .size__val { border-color: var(--teal-deep); }
.sizes--ask .sizes__title { color: var(--teal-deep); }

/* --- Кнопки покупки ----------------------------------------------------- */
.product__actions {
  display: flex;
  gap: 10px;
  margin-bottom: clamp(22px, 2.6vw, 30px);
}

.product__add {
  flex: 1 1 auto;
  border: 1px solid var(--teal-deep);
  cursor: pointer;
  text-align: center;
  transition: background-color .2s ease, border-color .2s ease;
}

/* Подтверждение прямо на кнопке: тост внизу экрана легко пропустить,
   если смотришь на кнопку, по которой только что кликнул. */
.product__add.is-added,
.card__buy.is-added {
  background: var(--ink);
  border-color: var(--ink);
  color: #fff;
}

.product__add.is-added::after,
.card__buy.is-added::after { content: ' \2713'; }

.iconbtn {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 52px;
  border: 1px solid var(--line);
  background: #fff;
  color: var(--ink);
  cursor: pointer;
  transition: border-color .2s ease, color .2s ease;
}

.iconbtn:hover { border-color: var(--teal-deep); color: var(--teal-deep); }

.iconbtn.is-on {
  color: var(--teal-deep);
  border-color: var(--teal-deep);
}

.iconbtn.is-on svg { fill: currentColor; }

/* --- Что входит в покупку ----------------------------------------------- */
.perks {
  list-style: none;
  margin: 0 0 clamp(18px, 2vw, 24px);
  padding: 0;
  display: grid;
  gap: 12px;
}

.perk {
  display: flex;
  gap: 11px;
  align-items: start;
  font-size: 13px;
  line-height: 1.5;
  color: var(--muted);
}

.perk svg { flex: 0 0 auto; margin-top: 2px; color: var(--teal); }
.perk a { color: var(--ink); border-bottom: 1px solid var(--line); }
.perk a:hover { color: var(--teal-deep); border-color: var(--teal-deep); }

.product__ask {
  margin: 0;
  padding-top: clamp(16px, 2vw, 22px);
  border-top: 1px solid var(--line);
  font-size: 13px;
  color: var(--muted);
}

.product__ask a { color: var(--ink); }
.product__ask a:hover { color: var(--teal-deep); }

/* --- Описание и характеристики ------------------------------------------ */
.product-section { padding-top: clamp(40px, 5vw, 72px); }

.product-section__title {
  font-family: 'Playfair Display', serif;
  font-weight: 400;
  font-size: clamp(20px, 2.2vw, 28px);
  text-transform: uppercase;
  letter-spacing: .01em;
  margin: 0 0 clamp(16px, 2vw, 24px);
}

/* В .section__head отступ снизу задаёт сам блок — иначе он складывается
   с отступом заголовка и «Похожие товары» отъезжают от своей ленты. */
.section__head .product-section__title { margin-bottom: 0; }

.product-descr { max-width: 74ch; }

.specs {
  margin: 0;
  max-width: 74ch;
  border-top: 1px solid var(--line);
}

.spec {
  display: grid;
  grid-template-columns: minmax(120px, 200px) 1fr;
  gap: 16px;
  padding: 13px 0;
  border-bottom: 1px solid var(--line);
  font-size: 14px;
}

.spec__key { margin: 0; color: var(--muted); }
.spec__val { margin: 0; }
.spec__val a { border-bottom: 1px solid var(--line); }
.spec__val a:hover { color: var(--teal-deep); border-color: var(--teal-deep); }

/* ==========================================================================
   Кнопки на карточке каталога
   ==========================================================================
   Карточка перестала быть одной сплошной ссылкой: внутрь нужны кнопки,
   а <button> внутри <a> — невалидная вложенность. Теперь .card — контейнер,
   ссылка живёт в .card__link. Старая разметка (.card как <a>) осталась
   в каруселях главной и продолжает работать: правила ниже её не касаются.
   -------------------------------------------------------------------- */
.card { position: relative; }

.card__link { display: block; }

.card__actions {
  display: flex;
  gap: 8px;
  margin-top: 12px;
}

.card__buy {
  flex: 1 1 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  padding: 11px 14px;
  text-align: center;
  background: #fff;
  border: 1px solid var(--line);
  color: var(--ink);
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  cursor: pointer;
  transition: background-color .2s ease, border-color .2s ease, color .2s ease;
}

.card__buy:hover {
  background: var(--teal-deep);
  border-color: var(--teal-deep);
  color: #fff;
}

.card__fav {
  flex: 0 0 auto;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 42px;
  background: #fff;
  border: 1px solid var(--line);
  color: var(--muted);
  cursor: pointer;
  transition: border-color .2s ease, color .2s ease;
}

.card__fav:hover { border-color: var(--pill); color: var(--ink); }

.card__fav.is-on {
  color: var(--teal-deep);
  border-color: var(--teal-deep);
}

.card__fav.is-on svg { fill: currentColor; }

/* ==========================================================================
   Счётчик у иконок шапки
   ========================================================================== */
.header__tool { position: relative; }

/* Кнопка корзины должна выглядеть как соседние ссылки-иконки, а не как
   кнопка браузера по умолчанию. Паддинг при этом не обнуляем: на нём держится
   зона нажатия 44×44, и без него по корзине на телефоне приходилось попадать
   в саму иконку 20×20 — соседние «избранное» и «кабинет» ловили промахи. */
button.header__tool {
  background: none;
  border: 0;
  cursor: pointer;
  color: inherit;
}

.header__badge {
  position: absolute;
  /* .header__tool раздут паддингом 12px под зону нажатия 44×44 (со скомпен-
     сированным отступом наружу), и бейдж считается от границ этой раздутой
     зоны, а не от самой иконки — отсюда и +12px к «настоящим» -5px/-7px
     от угла иконки, иначе счётчик улетает вверх-вправо от корзины. */
  top: 7px;
  right: 5px;
  min-width: 17px;
  height: 17px;
  padding: 0 4px;
  border-radius: 9px;
  background: var(--teal-deep);
  color: #fff;
  font-size: 10px;
  line-height: 17px;
  text-align: center;
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   Поиск по каталогу
   ========================================================================== */
.search-overlay {
  position: fixed;
  inset: 0;
  z-index: 65;
  display: flex;
  justify-content: center;
  padding: min(12vh, 90px) var(--gutter) 24px;
  overflow-y: auto;
}

.search-overlay__backdrop {
  position: fixed;
  inset: 0;
  background: rgba(11, 16, 17, .5);
  opacity: 0;
  transition: opacity .2s ease;
}

.search-overlay--on .search-overlay__backdrop { opacity: 1; }

.search-panel {
  position: relative;
  z-index: 1;
  width: min(600px, 100%);
  height: fit-content;
  max-height: 100%;
  background: #fff;
  box-shadow: 0 30px 70px -24px rgba(30, 42, 44, .45);
  display: flex;
  flex-direction: column;
  overflow: hidden;
  opacity: 0;
  transform: translateY(-14px);
  transition: opacity .2s ease, transform .2s ease;
}

.search-overlay--on .search-panel { opacity: 1; transform: none; }

@media (prefers-reduced-motion: reduce) {
  .search-overlay__backdrop, .search-panel { transition: none; }
}

.search-panel__head {
  display: flex;
  align-items: center;
  gap: 12px;
  flex: 0 0 auto;
  padding: 0 var(--gutter);
  border-bottom: 1px solid var(--line);
}

.search-panel__icon { flex: 0 0 auto; color: var(--muted); }

.search-panel__input {
  flex: 1 1 auto;
  min-width: 0;
  border: 0;
  padding: 18px 0;
  font: inherit;
  font-size: 16px;
  color: var(--ink);
  background: none;
  outline: none;
}

.search-panel__input::placeholder { color: var(--muted); }

/* У <input type="search"> в Chrome/Safari своя иконка очистки — рисовать
   рядом свою незачем, крестик закрытия панели и так под рукой. */
.search-panel__input::-webkit-search-cancel-button { -webkit-appearance: none; }

.search-panel__close {
  flex: 0 0 auto;
  width: 32px;
  height: 32px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 0;
  background: none;
  color: var(--muted);
  cursor: pointer;
}

.search-panel__close:hover { color: var(--ink); }

.search-panel__body {
  flex: 1 1 auto;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: 0 var(--gutter);
}

.search-hint {
  margin: 0;
  padding: 22px 0;
  font-size: 13px;
  color: var(--muted);
}

.search-hint a { color: var(--teal-deep); }

.search-result {
  display: grid;
  grid-template-columns: 52px minmax(0, 1fr) auto;
  gap: 14px;
  align-items: center;
  padding: 10px 8px;
  margin: 0 -8px;
  border-bottom: 1px solid var(--line);
  color: inherit;
  text-decoration: none;
}

.search-result:last-child { border-bottom: 0; }
.search-result:hover, .search-result.is-active { background: var(--grey); }

.search-result__media {
  aspect-ratio: 1 / 1;
  background: #fff;
  border: 1px solid var(--line);
  overflow: hidden;
  padding: 4px;
}

.search-result__media img { width: 100%; height: 100%; object-fit: contain; }

.search-result__body { min-width: 0; }

.search-result__name {
  display: block;
  font-size: 13.5px;
  line-height: 1.35;
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.search-result__cat {
  display: block;
  margin-top: 3px;
  font-size: 12px;
  color: var(--muted);
}

.search-result__price {
  font-size: 13.5px;
  white-space: nowrap;
}

/* На узком экране панель занимает весь экран — плавающая карточка
   посередине телефона только теряла бы место под клавиатурой. */
@media (max-width: 619.98px) {
  .search-overlay { padding: 0; }
  .search-panel { width: 100%; height: 100%; max-height: none; }
}

/* ==========================================================================
   Выдвижная корзина
   ========================================================================== */
.drawer {
  position: fixed;
  inset: 0;
  z-index: 60;
}

.drawer__backdrop {
  position: absolute;
  inset: 0;
  background: rgba(30, 42, 44, .38);
  opacity: 0;
  transition: opacity .25s ease;
}

.drawer--on .drawer__backdrop { opacity: 1; }

.drawer__panel {
  position: absolute;
  top: 0;
  right: 0;
  height: 100%;
  width: min(420px, 100%);
  background: #fff;
  display: flex;
  flex-direction: column;
  transform: translateX(100%);
  transition: transform .28s ease;
  box-shadow: -18px 0 46px rgba(30, 42, 44, .12);
}

.drawer--on .drawer__panel { transform: none; }

/* Выезд — это движение через треть экрана. Кому оно мешает, тот выставил
   флаг в системе: панель просто появляется на месте. */
@media (prefers-reduced-motion: reduce) {
  .drawer__panel, .drawer__backdrop { transition: none; }
}

.drawer__head {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 20px var(--gutter);
  border-bottom: 1px solid var(--line);
}

.drawer__title {
  font-size: 12px;
  letter-spacing: .12em;
  text-transform: uppercase;
}

.drawer__close {
  background: none;
  border: 0;
  padding: 4px;
  cursor: pointer;
  color: var(--muted);
  display: inline-flex;
}

.drawer__close:hover { color: var(--ink); }

.drawer__body {
  flex: 1 1 auto;
  overflow-y: auto;
  /* Докрутив список до низа, палец тянул за собой страницу под панелью */
  overscroll-behavior: contain;
  padding: 6px var(--gutter);
}

.drawer__empty {
  color: var(--muted);
  font-size: 14px;
  line-height: 1.6;
  padding: 28px 0;
}

.drawer__empty a { color: var(--teal-deep); border-bottom: 1px solid var(--line); }

/* Панель прижата к правому краю экрана, поэтому справа поле считается от выреза:
   в ландшафте на телефоне сумма заказа иначе упирается в скруглённый угол.
   Снизу — запас под жестовую полосу, ею закрывалась кнопка «Оформить заказ». */
.drawer__foot {
  border-top: 1px solid var(--line);
  padding: 18px max(var(--gutter), env(safe-area-inset-right)) calc(22px + env(safe-area-inset-bottom)) var(--gutter);
}

.drawer__sum {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-bottom: 14px;
  font-size: 13px;
  color: var(--muted);
}

.drawer__total {
  font-size: 21px;
  font-weight: 500;
  color: var(--ink);
}

.drawer__btn {
  display: block;
  text-align: center;
  cursor: pointer;
}

/* --- Строка товара в корзине -------------------------------------------- */
.crow {
  display: grid;
  grid-template-columns: 76px minmax(0, 1fr) auto;
  gap: 14px;
  align-items: start;
  padding: 16px 0;
  border-bottom: 1px solid var(--line);
}

.crow:last-child { border-bottom: 0; }

.crow__media {
  aspect-ratio: 1 / 1;
  background: #fff;
  border: 1px solid var(--line);
  overflow: hidden;
  padding: 5px;
}

.crow__media img { width: 100%; height: 100%; object-fit: contain; }

.crow__body { min-width: 0; }

.crow__name {
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  font-size: 13px;
  line-height: 1.4;
}

.crow__name:hover { color: var(--teal-deep); }

.crow__size {
  display: block;
  margin-top: 5px;
  font-size: 12px;
  color: var(--muted);
}

.crow__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 11px;
}

.crow__price {
  font-size: 14px;
  font-weight: 500;
  white-space: nowrap;
}

.crow__del {
  background: none;
  border: 0;
  padding: 2px;
  cursor: pointer;
  color: var(--pill);
  display: inline-flex;
}

.crow__del:hover { color: var(--ink); }

.qty {
  display: inline-flex;
  align-items: center;
  border: 1px solid var(--line);
}

.qty__btn {
  width: 30px;
  height: 30px;
  background: none;
  border: 0;
  cursor: pointer;
  color: var(--muted);
  font-size: 15px;
  line-height: 1;
}

.qty__btn:hover { color: var(--teal-deep); }

.qty__val {
  min-width: 26px;
  text-align: center;
  font-size: 13px;
  font-variant-numeric: tabular-nums;
}

/* ==========================================================================
   Всплывающее уведомление
   ========================================================================== */
.toast {
  position: fixed;
  left: 50%;
  bottom: calc(26px + env(safe-area-inset-bottom));
  z-index: 70;
  display: flex;
  align-items: center;
  gap: 16px;
  max-width: calc(100vw - 2 * var(--gutter));
  padding: 14px 20px;
  background: var(--ink);
  color: #fff;
  font-size: 13px;
  transform: translate(-50%, 14px);
  opacity: 0;
  transition: opacity .22s ease, transform .22s ease;
}

.toast--on { opacity: 1; transform: translate(-50%, 0); }

.toast span {
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}

.toast a {
  flex: 0 0 auto;
  color: #fff;
  font-size: 11px;
  letter-spacing: .08em;
  text-transform: uppercase;
  border-bottom: 1px solid rgba(255, 255, 255, .4);
}

.toast a:hover { border-color: #fff; }

/* ==========================================================================
   Страница корзины
   ========================================================================== */
.cart-layout {
  display: grid;
  gap: clamp(24px, 3vw, 48px);
  align-items: start;
  margin-top: clamp(18px, 2.2vw, 32px);
}

@media (min-width: 900px) {
  .cart-layout { grid-template-columns: minmax(0, 1fr) 320px; }
}

.cart-list { border-top: 1px solid var(--line); }

/* На странице строка просторнее, чем в узкой панели: места хватает */
.cart-list .crow {
  grid-template-columns: 96px minmax(0, 1fr) auto;
  padding: 20px 0;
}

.cart-list .crow__name { font-size: 14px; }

.order {
  border: 1px solid var(--line);
  padding: clamp(20px, 2.4vw, 28px);
}

@media (min-width: 900px) {
  .order { position: sticky; top: calc(var(--header-h) + 40px); }
}

.order__title {
  font-size: 12px;
  letter-spacing: .1em;
  text-transform: uppercase;
  margin: 0 0 18px;
}

.order__row {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  padding: 9px 0;
  font-size: 13px;
  color: var(--muted);
}

.order__row--total {
  margin-top: 6px;
  padding-top: 16px;
  border-top: 1px solid var(--line);
  color: var(--ink);
}

.order__total {
  font-size: 22px;
  font-weight: 500;
}

.order__btn {
  display: block;
  width: 100%;
  margin-top: 18px;
  text-align: center;
  cursor: pointer;
}

.order__note {
  margin: 14px 0 0;
  font-size: 12px;
  line-height: 1.55;
  color: var(--muted);
}

.order__note a { color: var(--ink); border-bottom: 1px solid var(--line); }
.order__note a:hover { color: var(--teal-deep); border-color: var(--teal-deep); }

.order__field {
  display: block;
  margin-top: 12px;
  font-size: 12px;
  color: var(--muted);
}

.order__field span { display: block; margin-bottom: 6px; }

.order__field input {
  width: 100%;
  border: 1px solid var(--line);
  background: #fff;
  padding: 9px 10px;
  font: inherit;
  font-size: 13px;
  color: var(--ink);
}

.order__field input:focus-visible { border-color: var(--teal-deep); }

/* Ловушка для ботов-заполнителей форм: человек её не видит и не сможет
   заполнить, а автозаполнение форм — заполнит. Не display:none и не
   hidden — это боты умеют распознавать и пропускать. */
.order__hp {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: -1px;
  padding: 0;
  border: 0;
  overflow: hidden;
  clip: rect(0 0 0 0);
}

/* ==========================================================================
   Пальцем, а не мышью
   ==========================================================================
   Всё, что решается не шириной окна, а типом указателя. Курсор наводится точно
   и показывает hover; палец закрывает собой цель и промахивается. Разносим
   строки списков ближе к 44px по высоте — норма зоны нажатия, — но только там,
   где указатель грубый: на десктопе те же 44px превратили бы плотные перечни
   подразделов и подвала в простыни.

   Блок стоит в самом конце файла намеренно: он переопределяет отступы
   компонентов, объявленных по всему файлу, а при равной специфичности
   выигрывает то правило, что ниже.
   -------------------------------------------------------------------- */
@media (pointer: coarse) {
  .filter__row { padding: 10px 0; }

  .filter__row input { width: 19px; height: 19px; }

  /* Меньше 16px — и Safari на iOS приближает страницу, когда встаёшь в поле.
     Обратно она сама не отъезжает: человек остаётся на увеличенной вёрстке. */
  .filter__num { font-size: 16px; padding: 11px 12px; }

  .megamenu__link { padding-block: 9px; }

  .footer__list { gap: 2px; }

  .footer__list a {
    display: inline-block;
    padding-block: 9px;
  }

  .footer__social a { padding-block: 8px; }

  .crumbs { gap: 6px 10px; }

  .crumbs a { padding-block: 9px; }

  .sidenav__list a { padding: 15px 0; }

  /* Логотип в шапке — самая частая цель «вернуться на главную», а по высоте
     это всего 26px картинки. Поле добираем паддингом, а отрицательное
     внешнее поле возвращает шапке прежнюю высоту. */
  .header__logo {
    padding-block: 9px;
    margin-block: -9px;
  }

  .section__link,
  .sizes__help,
  .footer__phone,
  .footer__bottom a,
  .nav__phone { padding-block: 9px; }

  /* Точка промо-карусели — черта в 2px: без поля по ней просто не попасть */
  .promo-slider__dot { padding: 16px 6px; }

  .card__buy { padding: 14px; }

  .chip { padding: 11px 16px; }

  .drawer__close { padding: 11px; margin: -11px; }

  .crow__del { padding: 10px; margin: -10px; }

  .qty__btn { width: 38px; height: 38px; }
}

/* --- самые узкие экраны (320px и уже) ------------------------------------
   Две карточки в ряд остаются, но кнопка «Выбрать размер» с сердечком в них
   уже не помещается в прежнем наборе: 96 + 8 + 42 на трек в 137px. Ужимаем
   надпись и сердечко — иначе пришлось бы разворачивать сетку в одну колонку
   и вытягивать раздел вдвое. */
@media (max-width: 359.98px) {
  .card__buy {
    padding: 12px 8px;
    font-size: 10px;
    letter-spacing: .04em;
  }

  .card__fav { width: 36px; }

  .card__actions { gap: 6px; }
}
