/* SUDBA — стили страницы.
   Токены и base подключаются отдельно из ds.css (генерируется build.sh).
   Здесь только то, чего нет в дизайн-системе: компонент кнопки и раскладка
   главного экрана. */

/* ШРИФТ. Дизайн-система ставит Instrument Sans, но у него НЕТ кириллицы:
   Google отдаёт только латиницу и Latin Extended, поэтому весь русский текст
   сайта рисовался системным Helvetica — отсюда и ощущение «шрифт не тот».
   Manrope закрывает кириллицу целиком и держит геометричную, спокойную
   интонацию макета. Латиницу (SUDBA, MERIDIAN ONE) рисует не хуже.
   Сам файл шрифта подключает ds.css: build.sh меняет там ссылку на Google Fonts
   на наш site/css/fonts.css, чтобы браузер не ходил на чужой домен и не качал
   два неиспользуемых семейства. */
/* <picture> вокруг кадров товара — это только контейнер для набора размеров,
   собственной раскладки у него быть не должно. display:contents убирает его
   бокс, и <img> встаёт в сетку ровно так же, как стоял без обёртки: иначе все
   правила вида «.tile__media img{height:100%}» считали бы проценты от строки
   инлайнового элемента. */
picture{display:contents}

:root{
  --font-core:"Manrope","Instrument Sans","Helvetica Neue",Helvetica,Arial,sans-serif;
  --font-display:var(--font-core);

  /* Цены, характеристики, счётчики и суммы заказа — около тридцати мест в
     shop.css ходят через этот токен. Моноширинного шрифта здесь больше нет:
     вместо него тот же основной, а колонки не разъезжаются за счёт табличных
     цифр (ниже). Цифры одной ширины дают ровные столбцы, но выглядят частью
     макета, а не распечаткой из терминала. */
  --font-mono:var(--font-core);

  /* ── Вторичный и третичный текст ──────────────────────────────────────────
     Токены дизайн-системы --steel-400 и --steel-500 для текста не годятся: на
     фоне страницы (#0B0B0D) они дают 4.46:1 и 2.53:1 при норме 4.5:1. Ими были
     набраны цены со скидкой, хлебные крошки, подписи полей, даты в истории
     заказа и половина подвала — то есть половина текста сайта не читалась на
     плохом экране и при ярком свете.

     Здесь два уровня, оба проверенные: 6.5:1 и 5.3:1. Иерархия сохранена —
     второй уровень светлее третьего. Проверяются скриптом tools/check-contrast.mjs.

     Сами --steel-* остаются: они правильны для линий, точек и заливок, где
     норма 3:1 или её нет вовсе. */
  --text-second:#8E959B;
  --text-third:#7E858B;

  /* Сапфировый акцент. В дизайн-системе сигнальный цвет серо-голубой
     (--signal-*), для засечки на чёрном он тусклый — берём чище и синее. */
  --sapphire-mark:#4D8AE8;
  --sapphire-mark-glow:rgba(77,138,232,.75);

  /* ── Синяя кнопка: один набор токенов на весь сайт ────────────────────────
     Кнопок этого цвета по сайту полтора десятка (корзина, оформление, отзывы,
     404). Чтобы поменять оттенок разом, цвет вынесен сюда: правится этот блок,
     а не пятнадцать мест. Варианты оттенков — на /lab/buttons/.
     Текущий: «Стальной» — холодный, ближе к графиту, матовый. */
  --gel-1:#41688F;   /* верх камня */
  --gel-2:#325275;   /* верхняя треть */
  --gel-3:#243D59;   /* середина */
  --gel-4:#182B40;   /* низ */
  --gel-5:#101E2E;   /* нижняя кромка */
  --gel-rim:rgba(180,202,224,.58);      /* кромка света сверху */
  --gel-rim-l:rgba(142,172,200,.30);    /* боковая, холодная */
  --gel-rim-r:rgba(112,140,168,.22);    /* боковая, тёплая сторона */
  --gel-glow:rgba(64,104,144,.14);      /* свечение вокруг */
  --gel-top:rgba(255,255,255,.14);      /* блик по верхней части */
  --gel-text:#EAF0F6;
}

/* Табличные цифры включаем документу целиком: на витрине почти каждая цифра —
   это данные (цены, суммы, характеристики, счётчики, даты), и одинаковая ширина
   знаков нужна им всем. Ставить свойство точечно на три десятка правил в
   shop.css значило бы каждый раз помнить про него в новых.

   body в списке обязателен, и это не перестраховка: в base.css дизайн-системы
   у body стоит сокращённое `font: var(--type-body)`, а сокращённая запись
   сбрасывает font-variant-numeric в normal. Правило только на :root не
   доезжало до цен вообще. */
:root,body{font-variant-numeric:tabular-nums}

/* Код — единственное место, где моноширинный нужен по существу: там значима
   не ровность цифр, а то, что символы не слипаются. Возвращаем его явно,
   иначе он уехал бы вместе с --font-mono на основной шрифт. */
code,kbd,samp{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace}

/* ══════════════════════════════════════════════════════════════════════════
   Кнопка
   Геометрия (высоты, отступы, радиус, шрифт) — из components/core/Button.jsx
   дизайн-системы. Поверхности свои: DS-фаски «хром» и «сигнал» заменены на
   слейт, у которого кнопка почти не отличается по цвету от фона и держится на
   одной светящейся кромке.
   ══════════════════════════════════════════════════════════════════════════ */
.btn{
  position:relative;
  isolation:isolate;
  overflow:hidden;
  display:inline-flex;
  align-items:center;
  justify-content:center;
  gap:var(--sp-2);
  height:var(--ctl-h);
  padding:0 var(--ctl-px);
  font-family:var(--font-core);
  font-size:var(--fs-body-sm);
  font-weight:var(--w-medium);
  letter-spacing:var(--tr-normal);
  border:0;
  border-radius:var(--r-control);
  cursor:pointer;
  white-space:nowrap;
  text-decoration:none;
  background:transparent;
  transition:background var(--t-surface),color var(--t-surface),
             box-shadow var(--t-surface),backdrop-filter var(--t-surface),
             -webkit-backdrop-filter var(--t-surface),
             transform var(--dur-1) var(--ease-standard);
}
.btn:active{transform:var(--travel-press)}

.btn--sm{height:var(--ctl-h-sm);padding:0 var(--ctl-px-sm);font-size:var(--fs-body-sm)}

/* Проход света по поверхности. Узкий и слабый: это блик по шлифовке, а не
   белая полоса поверх кнопки. Режим наложения — чтобы блик подсвечивал то,
   что под ним, а не закрашивал. */
.btn--sheen::after{
  content:"";
  position:absolute;
  inset:-60% -70%;
  pointer-events:none;
  background:linear-gradient(102deg,
    transparent 42%,
    rgba(255,255,255,.05) 47.5%,
    rgba(255,255,255,.30) 50%,
    rgba(255,255,255,.05) 52.5%,
    transparent 58%);
  transform:translateX(-100%);
  mix-blend-mode:screen;
  animation:sudba-sweep 7s cubic-bezier(.55,0,.25,1) infinite;
}
@keyframes sudba-sweep{
  0%{transform:translateX(-100%)}
  48%{transform:translateX(100%)}
  100%{transform:translateX(100%)}
}

/* ── Слейт: состояние покоя ──────────────────────────────────────────────
   Заливка почти отсутствует — кнопка «выточена» из сцены, а не наклеена на
   неё. backdrop-filter здесь нейтральный (blur(0)), но объявлен: без него
   переход в стекло по наведению был бы скачком, а не морфом. */
.btn--slate{
  color:var(--text-primary);
  background:linear-gradient(180deg,rgba(255,255,255,.06),rgba(255,255,255,.015));
  -webkit-backdrop-filter:blur(0px) saturate(1);
  backdrop-filter:blur(0px) saturate(1);
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.34),
    inset 0 0 0 1px rgba(255,255,255,.16),
    inset 0 -6px 14px -8px rgba(0,0,0,.7),
    0 8px 22px -12px rgba(0,0,0,.9);
}

/* Акцентная синяя — гелевая таблетка. Стоит так всегда: по наведению меняется
   только подача света, цвет камня остаётся прежним. Все оттенки берутся из
   токенов --gel-* в начале файла: поменять цвет всех синих кнопок сайта — это
   правка одного блока, а не пятнадцати мест.

   Поверхность матовая: верхний блик слабый и растянутый, вместо стеклянного
   пятна на четверть кнопки. Именно оно и делало кнопку «яркой». */
.btn--gel{
  color:var(--gel-text);
  background:
    linear-gradient(180deg,var(--gel-top) 0%,rgba(255,255,255,0) 52%),
    linear-gradient(180deg,var(--gel-1) 0%,var(--gel-2) 26%,var(--gel-3) 58%,var(--gel-4) 86%,var(--gel-5) 100%);
  box-shadow:
    inset 0 1px 0 var(--gel-rim),
    inset 1px 0 0 var(--gel-rim-l),
    inset -1px 0 0 var(--gel-rim-r),
    inset 0 -2px 4px rgba(0,8,26,.42),
    0 0 14px -6px var(--gel-glow),
    0 12px 30px -16px rgba(0,0,0,.9);
  transition:background var(--t-control),box-shadow var(--t-control),
             transform var(--dur-2) var(--ease-stage);
}

/* Под курсором кнопка оживает: приподнимается, кромка светлеет, свечение чуть
   усиливается. Сам камень не подменяется на более светлый — от этого кнопка
   выглядела глянцевой. Плюс однократный проход блика. */
.btn--gel:hover{
  transform:translateY(-1px);
  box-shadow:
    inset 0 1px 0 color-mix(in srgb,var(--gel-rim),#FFFFFF 30%),
    inset 1px 0 0 color-mix(in srgb,var(--gel-rim-l),#FFFFFF 22%),
    inset -1px 0 0 color-mix(in srgb,var(--gel-rim-r),#FFFFFF 18%),
    inset 0 -2px 5px rgba(0,8,26,.38),
    0 0 20px -6px color-mix(in srgb,var(--gel-glow),#FFFFFF 14%),
    0 16px 34px -16px rgba(0,0,0,.92);
}

/* Блик по камню. Полоса намеренно широкая и слабая: узкая и яркая читалась как
   резкая вспышка, а не как свет, прошедший по поверхности. Ход длинный и почти
   равномерный по скорости — резкое ускорение в начале давало тот же эффект
   «дёрнулось». */
.btn--gel::after{
  content:"";
  position:absolute;
  inset:-60% -80%;
  pointer-events:none;
  opacity:0;
  background:linear-gradient(102deg,
    transparent 26%,
    rgba(255,255,255,.02) 38%,
    rgba(255,255,255,.06) 44%,
    rgba(255,255,255,.10) 50%,
    rgba(255,255,255,.06) 56%,
    rgba(255,255,255,.02) 62%,
    transparent 74%);
  transform:translateX(-100%);
  mix-blend-mode:screen;
}
.btn--gel:hover::after{
  animation:sudba-sweep-once 1500ms cubic-bezier(.37,.06,.28,.98) forwards;
}
@keyframes sudba-sweep-once{
  0%{opacity:0;transform:translateX(-100%)}
  18%{opacity:1}
  82%{opacity:1}
  100%{opacity:0;transform:translateX(100%)}
}

/* Нажатие: кнопка уходит вниз, камень темнеет, свечение почти гаснет —
   ощущение физического хода, а не смены картинки. */
.btn--gel:active{
  transform:translateY(1px) scale(.985);
  background:
    linear-gradient(180deg,rgba(255,255,255,.06) 0%,rgba(255,255,255,0) 46%),
    linear-gradient(180deg,var(--gel-3) 0%,var(--gel-4) 40%,var(--gel-5) 100%);
  box-shadow:
    inset 0 2px 6px rgba(0,8,26,.6),
    inset 0 -1px 0 var(--gel-rim-l),
    0 0 8px -4px var(--gel-glow),
    0 6px 16px -12px rgba(0,0,0,.9);
  transition:background var(--dur-1) var(--ease-standard),
             box-shadow var(--dur-1) var(--ease-standard),
             transform var(--dur-1) var(--ease-standard);
}

/* ── Слейт → жидкое стекло по близости курсора ──────────────────────────
   --t задаёт js/proximity.js: 0 — курсор далеко, 1 — вплотную. Все значения
   ниже посчитаны от него, поэтому кнопка не «включается», а проявляется по
   мере приближения. Разгорается только ближайшая — это тоже решает скрипт.

   Почему не :hover: он знает лишь «внутри / снаружи» и срабатывает скачком
   ровно по краю кнопки. Плавного подхода на нём не сделать.

   Переход в 200 мс нужен не для самой анимации (число и так меняется каждый
   кадр), а чтобы сгладить рывок в момент, когда ближайшей становится соседняя
   кнопка, и чтобы кнопка мягко гасла, когда курсор ушёл с окна. */
.btn--morph{
  --t:0;

  color:#EDEEEF;
  color:color-mix(in srgb,#EDEEEF,#FBFCFE calc(var(--t) * 100%));

  background:linear-gradient(180deg,
    rgba(255,255,255,calc(.06 + .20 * var(--t))),
    rgba(255,255,255,calc(.015 + .045 * var(--t))) 46%,
    rgba(255,255,255,calc(.015 + .125 * var(--t))));

  -webkit-backdrop-filter:blur(calc(14px * var(--t))) saturate(calc(1 + .7 * var(--t))) brightness(calc(1 + .06 * var(--t)));
  backdrop-filter:blur(calc(14px * var(--t))) saturate(calc(1 + .7 * var(--t))) brightness(calc(1 + .06 * var(--t)));

  box-shadow:
    /* верхняя кромка: есть всегда, к стеклу разгорается */
    inset 0 1.5px 0 rgba(255,255,255,calc(.34 + .41 * var(--t))),
    /* боковая дисперсия — только у стекла */
    inset 1.5px 0 0 rgba(180,214,255,calc(.45 * var(--t))),
    inset -1.5px 0 0 rgba(255,220,190,calc(.38 * var(--t))),
    inset 0 -1.5px 0 rgba(255,255,255,calc(.30 * var(--t))),
    inset 0 0 18px rgba(255,255,255,calc(.18 * var(--t))),
    /* обводка и внутренняя тень слейта, наоборот, уходят */
    inset 0 0 0 1px rgba(255,255,255,calc(.16 * (1 - var(--t)))),
    inset 0 -6px 14px -8px rgba(0,0,0,calc(.7 - .7 * var(--t))),
    /* кнопка чуть приподнимается над сценой */
    0 calc(8px + 6px * var(--t)) calc(22px + 18px * var(--t)) -12px rgba(0,0,0,.92);

  transition:background 200ms linear,color 200ms linear,
             box-shadow 200ms linear,
             backdrop-filter 200ms linear,-webkit-backdrop-filter 200ms linear,
             transform var(--dur-1) var(--ease-standard);
}

/* С клавиатуры близости курсора нет — фокус включает стекло целиком. */
.btn--morph:focus-visible{--t:1}

/* Тач и «меньше движения»: скрипт молчит, --t остаётся нулём, поэтому стекло
   включаем правилом. Иначе на телефоне кнопки навсегда остались бы в слейте. */
@media (hover:none){ .btn--morph{--t:1} }
@media (prefers-reduced-motion:reduce){ .btn--morph{--t:1} }

/* ══════════════════════════════════════════════════════════════════════════
   Кнопки: остальные роли
   Геометрия та же, что у .btn выше; здесь только ширина, тихий вариант и
   круглые кнопки-иконки, которых в макете первого экрана ещё не было.
   ══════════════════════════════════════════════════════════════════════════ */
.btn--wide{width:100%}
.btn--lg{height:var(--ctl-h-lg);padding:0 var(--ctl-px-lg);font-size:var(--fs-body)}
.btn[disabled],.btn.is-off{opacity:.4;pointer-events:none}

/* Тихая кнопка: только хайрлайн. Для второстепенных действий рядом с гелевой —
   две «громкие» кнопки в одном блоке спорят друг с другом. */
.btn--quiet{
  color:var(--text-body);
  background:transparent;
  box-shadow:inset 0 0 0 1px var(--border-hairline);
}
.btn--quiet:hover{color:var(--paper-000);background:var(--fill-ghost);box-shadow:inset 0 0 0 1px var(--border-strong)}

.iconbtn{
  position:relative;
  display:inline-flex;align-items:center;justify-content:center;
  width:38px;height:38px;flex:none;
  border:0;border-radius:var(--r-full);
  background:transparent;color:var(--steel-200);
  cursor:pointer;text-decoration:none;
  transition:background var(--t-control),color var(--t-control);
}
.iconbtn:hover{background:var(--fill-ghost-hover);color:var(--paper-000)}
.iconbtn:active{transform:scale(.94)}
/* Счётчик на иконке. Сапфир, а не сигнальный цвет DS: на чёрном он читается. */
/* [hidden] сам по себе не работает: display:grid ниже его перебивает. */
/* Буква вошедшего вместо человечка. Гость и вошедший должны выглядеть
   по-разному: раньше по шапке нельзя было понять, действует ли сессия. */
.iconbtn__me{
  display:flex;align-items:center;justify-content:center;
  width:26px;height:26px;border-radius:var(--r-full);
  background:rgba(77,138,232,.18);
  box-shadow:inset 0 0 0 1px var(--sapphire-mark);
  color:var(--text-display);font-size:var(--fs-body-sm);font-weight:var(--w-medium);
  line-height:1;
}
.iconbtn__n[hidden]{display:none}
.iconbtn__n{
  position:absolute;top:1px;right:0;
  min-width:16px;height:16px;padding:0 4px;
  display:grid;place-items:center;
  font-family:var(--font-mono);font-size:9.5px;line-height:1;
  color:#fff;background:var(--sapphire-mark);
  border-radius:var(--r-full);
  box-shadow:0 0 0 2px var(--ink-000),0 0 10px var(--sapphire-mark-glow);
}

.linkbtn{
  border:0;background:none;padding:0;
  color:var(--text-second);cursor:pointer;
  display:inline-flex;align-items:center;gap:var(--sp-2);
  font-size:var(--fs-body-sm);
  transition:color var(--t-control);
}
.linkbtn:hover{color:var(--paper-000)}

/* Счётчик количества. Утоплен в поверхность — это поле ввода, а не кнопка. */
.stepper{
  display:inline-flex;align-items:center;
  height:32px;
  border-radius:var(--r-full);
  background:var(--surface-well);
  box-shadow:var(--well-inset);
}
.stepper button{
  width:32px;height:32px;flex:none;
  display:grid;place-items:center;
  border:0;background:none;color:var(--steel-300);cursor:pointer;
  border-radius:var(--r-full);
  transition:color var(--t-control),background var(--t-control);
}
.stepper button:hover{color:var(--paper-000);background:var(--fill-ghost-hover)}
.stepper span{
  min-width:26px;text-align:center;
  font-family:var(--font-mono);font-size:var(--fs-mono);color:var(--text-primary);
}

/* ══════════════════════════════════════════════════════════════════════════
   Каркас страницы
   ══════════════════════════════════════════════════════════════════════════ */
body{background:var(--bg-page);font-family:var(--font-core)}
body.is-locked{overflow:hidden}

/* У всех картинок в разметке проставлены width/height, чтобы браузер держал под
   них место до загрузки. Без height:auto атрибут height выигрывает у расчёта по
   aspect-ratio, и миниатюра вытягивается в столб — в base.css дизайн-системы
   задан только max-width. Правило без класса, поэтому любой явный height ниже
   его перебивает. */
img{height:auto}

.wrap{max-width:var(--max-w);margin:0 auto;padding:0 var(--gutter)}
.wrap--narrow{max-width:1080px}

.section{padding:var(--section-y) 0}
.section--tight{padding:var(--section-y-sm) 0}
.section--well{background:var(--bg-stage)}

/* Шапка блока: надзаголовок, заголовок, ссылка вправо. Ритм из дизайн-системы:
   eyebrow → 16 → заголовок. */
.shead{
  display:flex;align-items:flex-end;justify-content:space-between;
  gap:var(--sp-8);margin-bottom:var(--sp-12);
}
.shead__t{max-width:52ch}
.eyebrow{
  display:block;
  font-size:var(--fs-label);font-weight:var(--w-medium);
  letter-spacing:var(--tr-label);text-transform:uppercase;
  color:var(--text-second);
}
.shead h2{margin-top:var(--sp-4);font:var(--type-h1);letter-spacing:var(--tr-tight)}
.shead__note{margin-top:var(--sp-4);color:var(--text-muted);max-width:56ch}
.shead__more{
  flex:none;display:inline-flex;align-items:center;gap:var(--sp-2);
  font-size:var(--fs-body-sm);color:var(--text-primary);
  border-bottom:1px solid var(--alpha-line-strong);
}
.shead__more:hover{border-bottom-color:var(--accent-rule)}

/* Появление блоков при прокрутке. Только подъём и проявление — в языке бренда
   ничего не масштабируется и не пружинит. */
/* Появление блоков при прокрутке. Скрываем ТОЛЬКО при работающем скрипте:
   класс js ставит ui.js первым делом. Иначе при отключённых скриптах, при
   ошибке загрузки и на печати половина страницы оставалась бы невидимой —
   содержимое не должно зависеть от украшения. */
.js [data-reveal]{opacity:0;transform:translateY(18px);
  transition:opacity var(--dur-4) var(--ease-stage),transform var(--dur-4) var(--ease-stage)}
.js [data-reveal].is-seen{opacity:1;transform:none}
@media (prefers-reduced-motion:reduce){.js [data-reveal]{opacity:1;transform:none}}
@media print{.js [data-reveal]{opacity:1!important;transform:none!important}}

/* ══════════════════════════════════════════════════════════════════════════
   Шапка
   Липкая на всех страницах. На главной первый экран подтянут под неё
   отрицательным полем, поэтому шапка лежит поверх кадра и фон получает только
   после прокрутки — до этого она часть сцены, а не полоса над ней.
   ══════════════════════════════════════════════════════════════════════════ */
.masthead{
  position:sticky;top:0;z-index:60;
  height:var(--nav-h);
  display:flex;align-items:center;gap:var(--sp-10);
  padding:0 var(--gutter);
  background:transparent;
  transition:background var(--t-surface),box-shadow var(--t-surface),height var(--t-surface);
}
.masthead.is-stuck{
  background:rgba(8,8,10,.78);
  -webkit-backdrop-filter:var(--blur-glass);
  backdrop-filter:var(--blur-glass);
  box-shadow:inset 0 -1px 0 var(--border-hairline);
}
.masthead__home{border-bottom:0;display:block;flex:none}
/* Логотип заметно крупнее, чем в первом макете: на чёрном светлая марка сильно
   теряется в размере, и на 34px её просто не видно. */
.masthead__logo{height:46px;width:auto;transition:height var(--t-surface)}
.masthead.is-stuck .masthead__logo{height:38px}

.masthead__nav{display:flex;gap:var(--sp-8);flex:1}
.masthead__nav a{
  font-size:var(--fs-body-sm);font-weight:var(--w-medium);
  color:var(--steel-300);text-decoration:none;border-bottom:0;
  transition:color var(--t-control);
}
.masthead__nav a:hover{color:var(--paper-000)}
.masthead__nav a[aria-current]{color:var(--text-display)}
.masthead__tools{display:flex;align-items:center;gap:var(--sp-1);flex:none}
.iconbtn--burger{display:none}

/* ══════════════════════════════════════════════════════════════════════════
   Первый экран главной
   Презентация бренда: кадр, название, две кнопки и переключатель витрины
   внизу. Высота — 74vh вместо полного экрана: под сгибом должен начинаться
   каталог, иначе страница выглядит как одна картинка без магазина.
   ══════════════════════════════════════════════════════════════════════════ */
.stage{
  position:relative;
  margin-top:calc(var(--nav-h) * -1);   /* уводим кадр под липкую шапку */
  min-height:min(74vh,760px);
  padding-top:var(--nav-h);
  overflow:hidden;
  background:var(--ink-000);
  display:flex;flex-direction:column;
}
/* Кадр прижат к низу сцены и занимает не всю её высоту: сверху нужна чистая
   тёмная полоса под заголовок. Прибор при этом остаётся целым вместе с полом и
   отражением — обрезать их нельзя, на них держится вся студийная сцена. */
/* Блок кадра повторяет пропорции самого кадра (1200×760) и прижат к низу сцены:
   сверху остаётся чистая тёмная полоса под заголовок. При таком размере
   object-fit:contain ложится точь-в-точь в блок, поэтому проценты виньетки ниже
   попадают в те же места картинки на любой ширине экрана. */
.stage__media{
  position:absolute;left:50%;bottom:0;
  height:82%;aspect-ratio:4/3;width:auto;
  transform:translateX(-50%);
  z-index:0;
}
/* Виньетка поверх кадра. У рисованных сцен она уже вшита генератором, а у
   настоящего снимка пол подсвечен до самого края файла, и без затемнения его
   прямоугольник читается на чёрной сцене как приклеенная картинка. Затемнение,
   а не маска: на чёрном результат тот же, зато не зависит от поддержки
   mask-image и одинаково работает для всех кадров витрины. */
.stage__media::after{
  content:"";position:absolute;inset:0;pointer-events:none;
  background:radial-gradient(ellipse 52% 74% at 50% 52%,rgba(0,0,0,0) 40%,#000 96%);
}
/* Кадр витрины — во всю сцену: в дизайн-системе фон героя это фотография,
   которая уже чёрная, поэтому её край не должен читаться вовсе. Центрованная
   картинка в рамке давала заметный прямоугольник на фоне страницы.
   object-position смещён вниз: так верхняя треть кадра остаётся тёмной и
   заголовок ложится на неё, а не на подсвеченный бок прибора. */
/* Кадр витрины разложен на два слоя намеренно: внешний .stage__frame отвечает
   за проезд между товарами, внутренний img — за парение. Оба эффекта пишут в
   transform, и на одном элементе один затирал бы другой. */
.stage__frame{
  position:absolute;inset:0;
  opacity:0;
  transform:translateX(0) scale(.985);
  transition:opacity var(--dur-3) var(--ease-stage),
             transform var(--dur-4) var(--ease-stage);
  pointer-events:none;
}
.stage__frame.is-on{opacity:1;transform:translateX(0) scale(1)}
/* Стороны, с которых кадр приходит и в которые уходит. */
.stage__frame.is-left{opacity:0;transform:translateX(-9%) scale(.985)}
.stage__frame.is-right{opacity:0;transform:translateX(9%) scale(.985)}

.stage__product{
  position:absolute;inset:0;
  width:100%;height:100%;
  /* contain, а не cover: сцена шире кадра, и при обрезке прибор раздувался на
     весь экран — заголовку не оставалось тёмного места. Пустые поля по бокам
     не видны, потому что кадр и сцена одинаково чёрные, а край растушёван. */
  object-fit:contain;object-position:50% 100%;
}
.stage__frame.is-on .stage__product{
  animation:sudba-float-c var(--float-loop) var(--ease-standard) infinite;
}

/* ── Стрелки перелистывания ─────────────────────────────────────────────
   Сидят по краям сцены. В покое почти не видны — это слейт, как и кнопки:
   на витрине не должно быть двух конкурирующих акцентов. */
.stage__nav{
  position:absolute;top:50%;z-index:4;
  transform:translateY(-50%);
  width:52px;height:52px;padding:0;
  border:0;border-radius:var(--r-full);
  display:grid;place-items:center;
  cursor:pointer;color:var(--steel-300);
  background:linear-gradient(180deg,rgba(255,255,255,.05),rgba(255,255,255,.012));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.26),
    inset 0 0 0 1px rgba(255,255,255,.11),
    0 10px 26px -14px rgba(0,0,0,.9);
  transition:color var(--t-control),background var(--t-control),
             box-shadow var(--t-control),transform var(--dur-2) var(--ease-stage);
}
.stage__nav--prev{left:var(--gutter)}
.stage__nav--next{right:var(--gutter)}
.stage__nav:hover{
  color:var(--paper-000);
  background:linear-gradient(180deg,rgba(255,255,255,.12),rgba(255,255,255,.04));
  box-shadow:
    inset 0 1px 0 rgba(255,255,255,.5),
    inset 0 0 0 1px rgba(255,255,255,.2),
    0 14px 30px -14px rgba(0,0,0,.95);
}
.stage__nav--prev:hover{transform:translateY(-50%) translateX(-2px)}
.stage__nav--next:hover{transform:translateY(-50%) translateX(2px)}
.stage__nav:active{transform:translateY(-50%) scale(.94)}
/* Своя версия sudba-float: кадр растянут по сцене, поэтому «дышит» он лёгким
   сдвигом внутри запаса от scale, а не смещением всей картинки. */
@keyframes sudba-float-c{
  0%,100%{transform:scale(1.045) translateY(0)}
  50%{transform:scale(1.045) translateY(-8px)}
}
.stage__scrim{position:absolute;inset:0 0 auto 0;height:58%;background:var(--scrim-top);pointer-events:none;z-index:1}
/* Нижнее затемнение своё, а не токеном: токен — чистый градиент в ноль, и на
   его верхней половине прозрачность доходила до половины. Цена и кнопки лежат
   как раз там и на светлом боку прибора переставали читаться. Здесь нижняя
   треть держит почти полную плотность, а сходит на нет только выше кластера. */
.stage__scrim--b{
  inset:auto 0 0 0;height:56%;
  background:linear-gradient(0deg,
    rgba(0,0,0,.94) 0%, rgba(0,0,0,.9) 38%, rgba(0,0,0,.55) 68%, rgba(0,0,0,0) 100%);
}

.stage__inner{position:relative;z-index:2;flex:1;display:flex;flex-direction:column;padding:0 var(--gutter)}
/* Витрину собирает скрипт, и до его выполнения все три блока сцены пустые: на
   телефоне при их наполнении страница уезжала на 110 px вниз — CLS 0.321 при
   пороге 0.1. Резервируем место заранее. Значения — измеренные высоты
   заполненных блоков; список моделей всегда одной длины (FEATURED в
   page-home.js), поэтому его высота постоянна. */
.hero{text-align:center;margin-top:var(--sp-8);min-height:153px}
.models{min-height:125px}
.stage__buy{min-height:84px}
.hero__eyebrow{margin-bottom:var(--sp-4)}
.hero__title{
  font-family:var(--font-display);font-weight:var(--w-regular);
  font-size:var(--fs-display-2);line-height:var(--lh-display);
  letter-spacing:var(--tr-display);color:var(--text-display);
}
.hero__title span{color:var(--text-second)}
.hero__sub{margin-top:var(--sp-4);font-size:var(--fs-body);color:var(--steel-300)}
.hero__price{
  margin-top:0;
  font-family:var(--font-mono);font-size:var(--fs-mono-lg);color:var(--steel-200);
}
.hero__price span{color:var(--text-second);font-size:var(--fs-mono-sm)}
/* Зона наведения намеренно шире кнопок: группа должна отзываться на подходе
   курсора, а не ровно по краю. Отрицательное нижнее поле гасит собственный
   padding, чтобы раскладка от этого не поехала. */
.hero__actions{
  display:flex;gap:var(--sp-3);justify-content:center;
  width:fit-content;
  padding:var(--sp-4) var(--sp-6);
  margin:calc(var(--sp-1) * -1) auto calc(var(--sp-4) * -1);
}

.stage__footer{
  position:relative;z-index:2;
  margin-top:auto;padding:var(--sp-6) var(--gutter) var(--sp-16);
  display:grid;grid-template-columns:1fr auto 1fr;align-items:flex-end;gap:var(--sp-6);
}
/* Цена и кнопки стоят в нижнем ряду, а не под заголовком: на укороченном экране
   они ложились ровно на подсвеченный бок прибора и переставали читаться.
   Здесь же они попадают на затемнение у пола — и заодно собираются в один
   кластер с моделями и подписью, как в дизайн-системе. */
.stage__buy{display:flex;flex-direction:column;align-items:center;gap:var(--sp-2)}

/* Переключатель витрины. Он же — модельный ряд из макета: активная строка
   крупнее и с сапфировой засечкой. */
.models{display:flex;flex-direction:column;gap:var(--sp-3);align-items:flex-start}
.models__item{
  display:flex;align-items:center;gap:var(--sp-4);
  border:0;background:none;padding:0;cursor:pointer;
  font-family:var(--font-core);
  font-size:var(--fs-body-sm);font-weight:var(--w-medium);
  letter-spacing:var(--tr-wide);color:var(--text-second);
  transition:color var(--t-control);
}
.models__item::before{content:"";width:2px;height:14px;background:var(--alpha-line-strong);transition:background var(--t-control)}
.models__item:hover{color:var(--steel-200)}
.models__item--active{font-size:var(--fs-body);color:var(--text-display)}
.models__item--active::before{background:var(--sapphire-mark);box-shadow:0 0 12px 1px var(--sapphire-mark-glow)}

.stage__meta{
  text-align:right;display:flex;flex-direction:column;gap:var(--sp-1);
  font-size:var(--fs-label);font-weight:var(--w-medium);
  letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--text-second);
}


/* ══════════════════════════════════════════════════════════════════════════
   Плитка товара
   Медиа — на паперной подложке: в дизайн-системе это единственное место, где
   бренд выходит на светлый фон.
   ══════════════════════════════════════════════════════════════════════════ */
.grid{display:grid;gap:var(--grid-gap);grid-template-columns:repeat(auto-fill,minmax(280px,1fr))}
/* Одна-две карточки: колонки не растягиваем на всю ширину. Растянутая на
   1 440 px единственная плитка «Вы смотрели» выглядела как сбой раскладки. */
.grid--few{grid-template-columns:repeat(auto-fill,minmax(280px,320px));justify-content:start}

.tile{position:relative;display:flex;flex-direction:column}
.tile__media{
  position:relative;display:block;border-bottom:0;
  border-radius:var(--r-media);overflow:hidden;
  background:var(--ink-050);
  aspect-ratio:4/3;
}
/* contain, а не cover: съёмка приходит в разных пропорциях — есть и вертикальные
   кадры (увлажнители, робот-пылесос). При обрезке по кадру у высоких приборов
   срезало верх и низ, и на плитке оставалась середина корпуса. Поля по бокам не
   видны: у снимков фон такой же чёрный, что и у плитки. */
.tile__media img{
  width:100%;height:100%;object-fit:contain;
  transition:transform var(--t-stage);
}
.tile:hover .tile__media img{transform:scale(1.04)}
.tile__badge{
  position:absolute;top:var(--sp-4);left:var(--sp-4);z-index:2;
  padding:5px 10px;border-radius:var(--r-full);
  font-size:var(--fs-label-sm);font-weight:var(--w-semibold);
  letter-spacing:var(--tr-label);text-transform:uppercase;
  background:rgba(10,11,13,.72);color:var(--text-primary);
  -webkit-backdrop-filter:var(--blur-glass);backdrop-filter:var(--blur-glass);
  box-shadow:inset 0 0 0 1px var(--border-hairline);
}
.tile__badge--new{color:#DCE9FB;box-shadow:inset 0 0 0 1px rgba(77,138,232,.55)}
.tile__badge--save{color:#CFE6D6;box-shadow:inset 0 0 0 1px rgba(78,209,127,.4)}
.tile__fav{
  position:absolute;top:var(--sp-3);right:var(--sp-3);z-index:2;
  width:36px;height:36px;display:grid;place-items:center;
  border:0;border-radius:var(--r-full);cursor:pointer;
  background:rgba(10,11,13,.6);color:var(--steel-300);
  -webkit-backdrop-filter:var(--blur-glass);backdrop-filter:var(--blur-glass);
  box-shadow:inset 0 0 0 1px var(--border-hairline);
  /* Видно всегда, а не только при наведении: отложить товар — частое действие,
     и прятать его от того, кто не водит мышью по плитке, незачем. Приглушённая
     непрозрачность оставляет плитке спокойный вид, у отложенного товара
     сердечко и так залито цветом. */
  opacity:.55;transition:opacity var(--t-control),color var(--t-control);
}
.tile:hover .tile__fav,.tile__fav:focus-visible,.tile__fav.is-on{opacity:1}
.tile__fav.is-on{color:#FF6B5D}
.tile__fav.is-on svg{fill:currentColor}

.tile__body{padding-top:var(--sp-5);display:flex;flex-direction:column;flex:1}
.tile__kind{font-size:var(--fs-label);letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--text-second)}
.tile__name{margin-top:var(--sp-2);font:var(--type-h3);letter-spacing:var(--tr-tight)}
.tile__name a{color:inherit;border-bottom:0}
.tile__name a:hover{color:var(--paper-000)}
.tile__facts{
  list-style:none;margin:var(--sp-3) 0 0;padding:0;
  display:flex;flex-wrap:wrap;gap:var(--sp-2);
}
.tile__facts li{
  padding:3px 9px;border-radius:var(--r-full);
  font-family:var(--font-mono);font-size:var(--fs-mono-sm);
  color:var(--text-muted);background:var(--fill-ghost);
  box-shadow:inset 0 0 0 1px var(--border-faint);
}
.tile__rating{display:flex;align-items:center;gap:var(--sp-2);margin-top:var(--sp-4)}
.tile__reviews{font-family:var(--font-mono);font-size:var(--fs-mono-sm);color:var(--text-second)}
.tile__foot{
  margin-top:auto;padding-top:var(--sp-5);
  display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);
}
.tile__price{display:flex;flex-direction:column;gap:2px}
.tile__now{font-family:var(--font-mono);font-size:var(--fs-mono-lg);color:var(--text-display)}
.tile__old{font-family:var(--font-mono);font-size:var(--fs-mono-sm);color:var(--text-third);text-decoration:line-through}

/* Звёзды: активные белые, остальные — хайрлайном. Акцентный цвет здесь не
   используется, он занят под одну точку на странице. */
.stars{display:inline-flex;gap:2px;color:var(--ink-600)}
.stars__s{display:inline-flex}
.stars__s.is-on{color:var(--steel-100)}
.stars__s.is-on svg{fill:currentColor}

/* ══════════════════════════════════════════════════════════════════════════
   Выдвижные панели: корзина, поиск, меню
   ══════════════════════════════════════════════════════════════════════════ */
.panel-host{position:fixed;inset:0;z-index:90;pointer-events:none}
.panel-host.is-open{pointer-events:auto}
.panel__scrim{
  position:absolute;inset:0;
  background:rgba(0,0,0,.6);
  -webkit-backdrop-filter:blur(6px);backdrop-filter:blur(6px);
  opacity:0;transition:opacity var(--t-surface);
}
.panel-host.is-open .panel__scrim{opacity:1}
.panel{
  position:absolute;top:0;right:0;bottom:0;
  width:min(440px,100%);
  display:flex;flex-direction:column;
  background:var(--bg-page);
  box-shadow:var(--shadow-modal),inset 1px 0 0 var(--border-hairline);
  transform:translateX(100%);
  transition:transform var(--dur-3) var(--ease-stage);
}
.panel-host.is-open .panel{transform:none}
.panel__head{
  flex:none;height:var(--nav-h);
  display:flex;align-items:center;justify-content:space-between;
  padding:0 var(--sp-5) 0 var(--sp-6);
  box-shadow:inset 0 -1px 0 var(--border-hairline);
}
.panel__head h2{font:var(--type-h3)}
.panel__body{flex:1;overflow-y:auto;display:flex;flex-direction:column}
.panel__foot{
  margin-top:auto;position:sticky;bottom:0;
  padding:var(--sp-5) var(--sp-6) var(--sp-6);
  display:flex;flex-direction:column;gap:var(--sp-3);
  background:var(--bg-page);
  box-shadow:inset 0 1px 0 var(--border-hairline);
}
.panel__total{display:flex;justify-content:space-between;align-items:baseline;margin-bottom:var(--sp-2)}
.panel__total span{color:var(--text-muted);font-size:var(--fs-body-sm)}
.panel__total b{font-family:var(--font-mono);font-size:var(--fs-metric);font-weight:var(--w-regular);color:var(--text-display)}

.minicart{list-style:none;margin:0;padding:var(--sp-4) var(--sp-6)}
.minicart__row{display:flex;gap:var(--sp-4);padding:var(--sp-4) 0;box-shadow:inset 0 -1px 0 var(--border-faint)}
.minicart__media{flex:none;width:88px;border-radius:var(--r-sm);overflow:hidden;background:var(--ink-050);border-bottom:0}
.minicart__media img{width:100%;height:100%;object-fit:contain;aspect-ratio:4/3}
.minicart__info{flex:1;min-width:0;display:flex;flex-direction:column;gap:var(--sp-1);align-items:flex-start}
.minicart__name{font-size:var(--fs-body);color:var(--text-display);border-bottom:0}
.minicart__kind{font-size:var(--fs-body-sm);color:var(--text-second)}
.minicart__info .stepper{margin-top:var(--sp-2)}
.minicart__side{flex:none;display:flex;flex-direction:column;align-items:flex-end;justify-content:space-between;gap:var(--sp-3)}
.minicart__sum{font-family:var(--font-mono);font-size:var(--fs-mono);color:var(--text-primary);white-space:nowrap}

.empty{padding:var(--sp-20) var(--sp-6);text-align:center;display:flex;flex-direction:column;align-items:center;gap:var(--sp-3)}
.empty__title{font:var(--type-h3);color:var(--text-display)}
.empty__text{color:var(--text-muted);max-width:36ch;margin-bottom:var(--sp-4)}

.menu{display:flex;flex-direction:column;padding:var(--sp-4) var(--sp-6) var(--sp-10)}
/* Имя вошедшего над пунктами: меню — второе место после шапки, где человеку
   надо понять, под кем он на сайте. */
.menu__who{
  padding-bottom:var(--sp-4);
  font-size:var(--fs-label);letter-spacing:var(--tr-label);text-transform:uppercase;
  color:var(--text-second);
}
/* «Выйти» — кнопка, а не ссылка: она меняет состояние, а не ведёт по адресу.
   Выглядеть должна как соседние пункты. */
button.menu__main{
  border:0;border-bottom:1px solid var(--border-hairline);background:none;
  font-family:inherit;cursor:pointer;text-align:left;width:100%;
}
.menu__main{
  display:flex;align-items:center;justify-content:space-between;
  padding:var(--sp-5) 0;font:var(--type-h3);color:var(--text-display);
  border-bottom:1px solid var(--border-hairline);
}
.menu__sub{
  display:flex;align-items:center;justify-content:space-between;
  padding:var(--sp-3) 0 var(--sp-3) var(--sp-4);
  font-size:var(--fs-body);color:var(--text-muted);border-bottom:0;
}
.menu__sub span{font-family:var(--font-mono);font-size:var(--fs-mono-sm);color:var(--text-third)}
.menu__sub:hover{color:var(--paper-000)}
.menu__phone{
  margin-top:var(--sp-8);display:inline-flex;align-items:center;gap:var(--sp-3);
  font-family:var(--font-mono);font-size:var(--fs-mono-lg);color:var(--text-primary);border-bottom:0;
}

.search{padding:var(--sp-5) var(--sp-6) var(--sp-10)}
.search__field{
  display:flex;align-items:center;gap:var(--sp-3);
  padding:0 var(--sp-4);height:var(--ctl-h-lg);
  border-radius:var(--r-input);
  background:var(--surface-well);color:var(--text-second);
  box-shadow:var(--well-inset);
}
.search__field input{flex:1;border:0;background:none;outline:none;color:var(--text-primary);font-size:var(--fs-body)}
.search__field input::placeholder{color:var(--text-third)}
.search__hint{margin-top:var(--sp-4);display:flex;flex-wrap:wrap;gap:var(--sp-2);align-items:center;font-size:var(--fs-body-sm);color:var(--text-third)}
.search__hint button{
  border:0;padding:4px 10px;border-radius:var(--r-full);cursor:pointer;
  background:var(--fill-ghost);color:var(--text-muted);font-size:var(--fs-body-sm);
  box-shadow:inset 0 0 0 1px var(--border-faint);
}
.search__hint button:hover{color:var(--paper-000);background:var(--fill-ghost-hover)}
.search__out{margin-top:var(--sp-6)}
.search__count{font-size:var(--fs-label);letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--text-third);margin-bottom:var(--sp-3)}
.search__empty{color:var(--text-muted);font-size:var(--fs-body-sm)}
.srow{
  display:flex;align-items:center;gap:var(--sp-4);
  padding:var(--sp-3) 0;border-bottom:1px solid var(--border-faint);
}
.srow img{width:64px;flex:none;border-radius:var(--r-xs);aspect-ratio:4/3;object-fit:contain;background:var(--ink-050)}
.srow__t{flex:1;min-width:0;display:flex;flex-direction:column;font-size:var(--fs-body-sm);color:var(--text-second)}
.srow__t b{font-weight:var(--w-medium);color:var(--text-display);font-size:var(--fs-body)}
.srow__p{font-family:var(--font-mono);font-size:var(--fs-mono);color:var(--text-primary);white-space:nowrap}

/* ══════════════════════════════════════════════════════════════════════════
   Уведомление
   ══════════════════════════════════════════════════════════════════════════ */
/* Заголовок для скринридера и порядка уровней, невидимый глазом. Нужен там,
   где визуальная иерархия очевидна без подписи, а разметке не хватает ступени:
   сетка товаров в каталоге, содержимое вкладок карточки товара. */
.vh{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;
  clip:rect(0 0 0 0);clip-path:inset(50%);white-space:nowrap;border:0}

/* Отступы и мелкая типографика, которые раньше стояли атрибутом style прямо в
   разметке. Вынесены сюда не ради красоты: с политикой безопасности (CSP) без
   'unsafe-inline' браузер игнорирует инлайновые стили, и страницы съезжали бы
   по вертикали. Набор намеренно короткий — это не система утилит, а ровно те
   значения, что встречаются в вёрстке. */
.mt-12{margin-top:12px}
.mt-16{margin-top:16px}
.mt-20{margin-top:20px}
.mt-24{margin-top:24px}
.mt-40{margin-top:40px}
.mt-64{margin-top:64px}
.mt-96{margin-top:96px}
.mt-8{margin-top:8px}
.mt-32{margin-top:32px}
.mb-16{margin-bottom:16px}
.mb-32{margin-bottom:32px}
.m-0{margin:0}
.pt-96{padding-top:96px}
.between{justify-content:space-between}
.narrow{max-width:520px}
/* Подпись у суммы: тот же шрифт, что у текста рядом, а не табличные цифры. */
.t-core{font-family:var(--font-core)}
.pt-48{padding-top:48px}
/* Абзац сплошного текста: строки шире обычного, читать легче. */
.lede{line-height:1.75}
/* Приписка под заголовком: тише основного текста и не длиннее строки, которую
   удобно читать. */
.side-note{margin-top:12px;color:var(--text-muted);max-width:44ch}
.t-h3{font:var(--type-h3)}
/* Кнопка внутри колонки формы: тянуться во всю ширину ей не нужно. */
.self-start{align-self:flex-start}

.toast-host{position:fixed;left:0;right:0;bottom:var(--sp-6);z-index:100;display:flex;justify-content:center;pointer-events:none;padding:0 var(--gutter-sm)}
.toast{
  display:inline-flex;align-items:center;gap:var(--sp-3);
  padding:0 var(--sp-5);height:var(--ctl-h-lg);
  border-radius:var(--r-full);
  background:rgba(20,20,24,.86);color:var(--text-primary);
  -webkit-backdrop-filter:var(--blur-glass);backdrop-filter:var(--blur-glass);
  box-shadow:inset 0 1px 0 rgba(255,255,255,.16),var(--shadow-modal);
  font-size:var(--fs-body-sm);
  pointer-events:auto;
  opacity:0;transform:translateY(12px);
  transition:opacity var(--t-control),transform var(--t-control);
}
.toast.is-in{opacity:1;transform:none}
.toast .ic{color:var(--state-live)}
/* Ошибка не должна исчезать сама: человек не успевает прочитать, а повторить
   сообщение нечем. Тот же тост, но с красной кромкой, крестиком и без таймера. */
.toast--error{box-shadow:inset 0 0 0 1px rgba(255,77,61,.45),var(--shadow-modal)}
.toast--error .ic{color:var(--state-fault)}
.toast__close{margin-left:var(--sp-3);border:0;background:none;padding:2px;cursor:pointer;
  color:var(--text-second);display:inline-flex}
.toast__close:hover{color:var(--paper-000)}
.toast__act{margin-left:var(--sp-2);color:var(--text-display);border-bottom-color:var(--accent-rule)}

/* ══════════════════════════════════════════════════════════════════════════
   Подвал
   ══════════════════════════════════════════════════════════════════════════ */
.foot{margin-top:var(--section-y);background:var(--bg-stage);box-shadow:inset 0 1px 0 var(--border-hairline)}
.foot__grid{
  max-width:var(--max-w);margin:0 auto;padding:var(--sp-20) var(--gutter) var(--sp-16);
  display:grid;gap:var(--sp-10);
  grid-template-columns:1.4fr repeat(3,1fr) 1.1fr;
}
.foot__logo{height:40px;width:auto;opacity:.9}
.foot__line{margin-top:var(--sp-4);color:var(--text-muted);font-size:var(--fs-body-sm);max-width:28ch}
.foot__col h2{font-size:var(--fs-label);letter-spacing:var(--tr-label);text-transform:uppercase;color:var(--text-second);font-weight:var(--w-medium)}
.foot__col ul{list-style:none;margin:var(--sp-5) 0 0;padding:0;display:flex;flex-direction:column;gap:var(--sp-3)}
.foot__col a{font-size:var(--fs-body-sm);color:var(--text-muted);border-bottom:0}
.foot__col a:hover{color:var(--paper-000)}
.foot__phone{display:block;margin-top:var(--sp-5);font-family:var(--font-mono);font-size:var(--fs-mono-lg);color:var(--text-display);border-bottom:0}
.foot__note{margin-top:var(--sp-1);font-size:var(--fs-body-sm);color:var(--text-third)}
.foot__mail{display:block;margin-top:var(--sp-4);font-size:var(--fs-body-sm);color:var(--text-muted);border-bottom:0}
.foot__bar{
  max-width:var(--max-w);margin:0 auto;padding:var(--sp-6) var(--gutter);
  display:flex;justify-content:space-between;gap:var(--sp-6);flex-wrap:wrap;
  font-size:var(--fs-body-sm);color:var(--text-third);
  box-shadow:inset 0 1px 0 var(--border-faint);
}

/* ══════════════════════════════════════════════════════════════════════════
   Узкие экраны
   ══════════════════════════════════════════════════════════════════════════ */
@media (max-width:1080px){
  .foot__grid{grid-template-columns:1fr 1fr 1fr;gap:var(--sp-10) var(--sp-8)}
  .foot__brand{grid-column:1/-1}
}

@media (max-width:860px){
  .masthead__nav{display:none}
  .iconbtn--burger{display:inline-flex}
  .shead{flex-direction:column;align-items:flex-start;gap:var(--sp-5);margin-bottom:var(--sp-10)}
  .section{padding:var(--section-y-sm) 0}
  .foot{margin-top:var(--section-y-sm)}
}

@media (max-width:720px){
  /* Цели касания. Норма — 44×44 (она же в токенах дизайн-системы: --hit-min).
     На узких экранах иконки шапки были 38×38, сердечко на плитке 36×36,
     кнопки степпера 32×32: пальцем в них попадаешь через раз. Там, где
     увеличивать сам элемент нельзя без вреда раскладке, зону нажатия
     расширяет прозрачный псевдоэлемент. */
  .iconbtn{width:44px;height:44px}
  .tile__fav{width:44px;height:44px}
  .stepper{height:44px}
  .stepper button{width:44px;height:44px}
  .btn--sm{height:44px}
  .masthead__home{min-height:44px;display:flex;align-items:center}
  .foot__col a,.foot__col li>a,.foot__phone,.foot__mail,.menu__main,.menu__sub{
    position:relative;display:inline-flex;align-items:center;min-height:44px}
  .crumbs a,.crumbs span{position:relative;display:inline-flex;align-items:center;min-height:44px}

  .wrap{padding:0 var(--gutter-sm)}
  .masthead{padding:0 var(--gutter-sm);gap:var(--sp-4)}
  .masthead__logo{height:38px}
  .stage{min-height:auto;padding-bottom:var(--sp-16)}
  .stage__inner{padding:0 var(--gutter-sm)}
  .stage__inner{order:1}
  /* Место под кадр резервируем заранее. Блок наполняется скриптом, и до этого
     момента высота у него была нулевая: при появлении первого кадра всё, что
     ниже, уезжало вниз — CLS 0.321 при пороге 0.1. Пропорция та же, что у
     производных кадров (4:3), поэтому зарезервированная высота совпадает с
     настоящей до пикселя. */
  /* На узком экране заголовок короче: резерв меньше, чем на широком. */
  .hero{min-height:110px}
  .stage__media{position:relative;order:2;left:auto;bottom:auto;height:auto;width:100%;
    transform:none;margin:var(--sp-8) 0 0;aspect-ratio:4/3}
  .stage__footer{order:3}
  /* В потоке кадр становится обычной картинкой: сцена ужимается, и растянутый
     на всю высоту вариант обрезал бы прибор. Проезд между товарами на телефоне
     не нужен — там листают свайпом, и сдвиг в 9% только дёргает раскладку:
     показываем один активный кадр, остальные убираем совсем. */
  .stage__frame{position:static;opacity:1;transform:none;transition:none}
  .stage__frame:not(.is-on){display:none}
  .stage__product{position:static;width:100%;height:auto;aspect-ratio:4/3;
    object-position:50% 50%}
  .stage__frame.is-on .stage__product{animation:none}
  .stage__scrim,.stage__scrim--b{display:none}
  .hero{margin-top:var(--sp-6)}
  .stage__footer{padding:var(--sp-10) var(--gutter-sm) var(--sp-4);display:flex;flex-direction:column;align-items:flex-start;gap:var(--sp-8)}
  .stage__buy{align-items:flex-start;width:100%}
  .stage__buy .hero__actions{margin-left:calc(var(--sp-6) * -1)}
  .stage__meta{text-align:left}
  .grid{grid-template-columns:repeat(auto-fill,minmax(240px,1fr));gap:var(--sp-8) var(--sp-5)}
  .foot__grid{grid-template-columns:1fr 1fr;padding:var(--sp-16) var(--gutter-sm) var(--sp-10)}
  .foot__bar{padding:var(--sp-5) var(--gutter-sm)}
  .panel__head{padding:0 var(--sp-3) 0 var(--sp-5)}
  .minicart{padding:var(--sp-3) var(--sp-5)}
  .panel__foot{padding:var(--sp-4) var(--sp-5) var(--sp-5)}
}
