/* Hallmark · macrostructure: Portfolio Grid (адаптирован) · genre: editorial
 * theme: studied-DNA (source: url) · studied: yes
 * source-url: https://www.zenvoautomotive.com/ (назван владельцем)
 * второй источник: https://performance-spb.ru/ (зелёный, логотип, видео)
 * observed-h1: 72px вес 300 обычный регистр, трекинг -1px, инт 1.04
 * observed-buttons: ВСЕ прозрачные, рамка 1px, радиус 40px
 * observed-container: 1152px · observed-section-padding: 120px
 * observed-paper: rgb(255,255,255) · observed-accent: rgb(0,255,21)
 * observed-fonts: BankGothic, заголовки 28px UPPERCASE вес 600
 * observed-hero: video 1920x1080 autoplay loop (92 МБ)
 * observed-buttons: пилюля r20 зелёная с чёрным текстом, r8 серые
 * accent: #00FF15 их · display: Tektur (BankGothic лицензионный)
 * nav: N1b · footer: Ft1 mast headed
 * hero: разворот, видео слева, цены справа (выбор владельца из трёх)
 * contrast: pass (40-41) · honest: pass (46) · chrome: pass (47)
 * tokens: pass (48) · responsive: pass (49) · mobile: pass (34, 50-57)
 * slop: pass (42-45) кроме 42: меню намеренно N1b канонический,
 *   потому что минимальное меню владелец назвал «непонятно», а у них
 *   на сайте меню полное. Отклонение осознанное, не пропуск.
 * аудит 10.09: исправлено 9 замечаний - чистый белый и нулевая
 *   насыщенность бумаги (7, 22), ровный ритм секций (9), два эффекта
 *   при наведении (13), видео без кнопки паузы (18, WCAG 2.2.2),
 *   мера строки 42ch и 84ch (25), нет :active у ссылок (26),
 *   постер без preload (28), симметричные отступы героя (44),
 *   зелёный квадратик без смысла (45), сырой oklch в тени (48),
 *   заголовок и подпись в две колонки (54)
 * pre-emit critique: P5 H5 E5 S5 R5 V5
 *
 * ПОЧЕМУ СВЕТЛАЯ. Владелец отверг пять версий, последнюю словами
 * «слишком простой, тёмный и некрасивый». Все пять были тёмными,
 * и тёмное я выбрал сам, ни разу не посмотрев их собственный сайт.
 * Посмотрел: блок заставки у них белый, шрифт капсом, кнопка
 * зелёной пилюлей с чёрным текстом, заставка видео. Здесь то же.
 */

/* Клип по горизонтали именно clip, а не hidden: hidden создаёт свой
   скролл-контейнер и ломает sticky у потомков. */
html { overflow-x: clip; }
body { overflow-x: clip; }

*, *::before, *::after { box-sizing: border-box; }

body {
  margin: 0;
  background: var(--color-paper);
  color: var(--color-ink);
  font-family: var(--font-body);
  font-weight: 400;
  font-size: var(--text-md);
  /* 1.7 - у ориентира текст 14 px при интерлиньяже 24. Мелкий кегль
     с большим интерлиньяжем и даёт то ощущение воздуха. */
  line-height: var(--инт-текста);
  -webkit-font-smoothing: antialiased;
  text-rendering: optimizeLegibility;
}

img { max-width: 100%; }

h1, h2, h3 {
  font-family: var(--font-display);
  /* ВЕС 300 и ОБЫЧНЫЙ регистр - ровно как у ориентира, где h1 идёт
     весом 300 без капса. Капсом весом 600 было в прошлой версии,
     и это была моя догадка про их BankGothic; сам BankGothic остаётся
     в логотипе, а страница набрана по ориентиру. */
  font-weight: var(--вес-заголовка);
  letter-spacing: var(--track-display);
  margin: 0;
  /* Длинные слова вроде «полиуретановая» на 320 px рвут сетку,
     если им не разрешить перенос внутри слова. */
  overflow-wrap: anywhere;
  min-width: 0;
}

p { margin: 0; }

a { color: inherit; }

:focus-visible {
  outline: 2px solid var(--color-focus);
  outline-offset: 3px;
  border-radius: var(--radius-chip);
}

/* ============================================================
   Общее
   ============================================================ */

.полоса {
  padding-inline: var(--page-gutter);
  /* 1152 px, как у ориентира внутри окна 1440. Было 1440: страница
     распирала весь экран, и от этого читалась дешевле. */
  max-width: var(--контейнер);
  margin-inline: auto;
}

/* 120 px сверху и снизу - ровно отступ секции у ориентира. Было 64,
   и секции стояли вплотную. */
.секция { padding-block: var(--space-3xl); }
.секция--тесно { padding-block: var(--space-2xl); }
/* Одна секция на другой поверхности, во всю ширину экрана. Без неё
   все секции шли ровным ритмом без единого перебоя: ни линии,
   ни смены фона. У них на сайте блоки тоже чередуются.
   Фон во всю ширину, содержимое по сетке страницы. */
.секция--фон {
  background: var(--color-paper-2);
  max-width: none;
  padding-inline: max(var(--page-gutter),
                      calc((100% - var(--контейнер)) / 2 + var(--page-gutter)));
}

/* Промо-блок: скруглённая карточка-секция, всё по центру. У ориентира
   таких два в хвосте страницы - мелкая надстрочная метка по центру,
   крупный заголовок по центру, строка текста и пилюля внутри блока.
   Блок вписан в страницу, а не растянут во всю ширину: именно это
   и отличает его от полосы. */
.промо {
  display: grid;
  justify-items: center;
  gap: var(--space-md);
  text-align: center;
  padding: var(--space-2xl) var(--space-xl);
  border-radius: var(--radius-card);
  background: var(--color-paper-2);
}
.промо--тьма {
  background: var(--color-paper-inv);
  color: var(--color-ink-inv);
}
.промо h2 { font-size: var(--text-2xl); line-height: var(--инт-заголовка); }
.промо__лид {
  color: var(--color-muted-inv);
  font-size: var(--text-md);
  max-width: 52ch;
}
.промо--тьма .метка-раздела { color: var(--color-muted-inv); }
.промо--тьма .кнопка--контур {
  color: var(--color-ink-inv);
  border-color: oklch(100% 0 0 / .38);
}
.промо--тьма .кнопка--контур:hover { border-color: var(--color-ink-inv); }
.действия--центр { justify-content: center; }

/* Тёмная полоса во всю ширину. У Koenigsegg и Zenvo страница идёт
   светлая полоса, тёмная, снова светлая - без этого белая простыня
   читается одинаково от начала до конца. Машины на чёрном к тому же
   выглядят лучше, это вся автомобильная съёмка знает.
   Правило само переключает ВСЕ чернила внутри: полоса, где сменили
   фон и забыли текст, это самая частая поломка. */
.секция--тьма {
  background: var(--color-paper-inv);
  color: var(--color-ink-inv);
  max-width: none;
  padding-inline: max(var(--page-gutter),
                      calc((100% - var(--контейнер)) / 2 + var(--page-gutter)));
}
/* Специфичность важнее порядка: .работа figcaption имеет ту же силу,
   что .секция--тьма figcaption, и стоит в файле НИЖЕ, поэтому
   перебивала инверсию. Подписи в галерее выходили 2.58:1, то есть
   тёмное на тёмном. Ровно та поломка, от которой я себя предупреждал
   в комментарии двумя строками выше. */
.секция--тьма .тише,
.секция--тьма .метка-раздела,
.секция--тьма .работа figcaption,
.секция--тьма figcaption { color: var(--color-muted-inv); }
.секция--тьма .кнопка--контур {
  color: var(--color-ink-inv);
  border-color: oklch(100% 0 0 / .38);
}
.секция--тьма .кнопка--контур:hover { border-color: var(--color-ink-inv); }

/* Заголовок секции и подпись СТОЛБИКОМ. Стояли в две колонки на одной
   строке, и это ровно тот шаблонный приём «заголовок слева, описание
   справа», который узнаётся за секунду. Кегль скромный: у WrapStyle
   заголовки секций всего 32 px, и это правильно - заголовок не должен
   спорить с фотографиями. */
.глава {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-xs);
  margin-bottom: var(--space-lg);
}
.глава h2 { font-size: var(--text-2xl); line-height: var(--инт-заголовка); }
.глава > p { max-width: 56ch; }

.тише { color: var(--color-neutral); font-size: var(--text-sm); }

/* Надстрочная метка: мелкий капс с разрядкой над заголовком. У обоих
   ориентиров она есть («TECHNOLOGICAL ACHIEVEMENTS», «ABOUT US»),
   но стоит СТОЛБИКОМ над заголовком, а не рядом с ним - рядом это
   шаблонный приём, который узнаётся за секунду.
   Две на страницу, не больше. */
.метка-раздела {
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--text-eyebrow);
  letter-spacing: var(--track-eyebrow);
  text-transform: uppercase;
  color: var(--color-neutral);
}

/* ============================================================
   N1b · канонический трёхчастный
   Марка слева, разделы посередине, телефон и действие справа.
   Прошлая версия несла N9: марка слева, кнопка справа, между ними
   пустота. Пустота была осмысленной ровно для меня: человек не видел,
   что на странице есть разделы, и говорил «непонятно».
   ============================================================ */

.шапка {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-lg);
  flex-wrap: wrap;
  padding: var(--space-md) var(--page-gutter);
  max-width: var(--контейнер);
  margin-inline: auto;
  border-bottom: var(--rule-hair) solid var(--color-rule);
}

/* Меню плавающей капсулой поверх кадра - приём ориентира. Полоса
   с волосяной линией под ней прижимает страницу к верху экрана,
   а капсула оставляет кадр целым. */
.шапка--капсула {
  position: absolute;
  inset: var(--space-md) 0 auto 0;
  z-index: var(--z-raised);
  width: calc(100% - 2 * var(--page-gutter));
  max-width: var(--контейнер);
  padding: var(--space-sm) var(--space-lg);
  border: 0;
  border-radius: var(--radius-pill);
  background: var(--color-paper);
  box-shadow: var(--тень-карточки);
}
body { position: relative; }

/* Лок марки: знак и наборная надпись студии, векторы владельца.
   Подпись «Detailing · Санкт-Петербург» вынесена ИЗ ссылки: внутри неё
   она делала кликабельный текст двухстрочным на любой ширине, гейт 49.

   Пропорции у знака 3:1, у надписи 21:1, поэтому задаются они разными
   мерами: знаку высота, надписи ширина. Одинаковой мерой один из двух
   получался вдвое мельче другого. */
.марка { display: grid; gap: var(--space-xs); }
/* Лок одной строкой: знак, надпись, волосяной разделитель, город.
   Двухстрочный лок внутри пилюли выглядит скошенным - подпись висит
   у нижнего края и ломает вертикальный ритм капсулы. */
.марка--строкой {
  display: flex;
  align-items: center;
  gap: var(--space-sm);
}
.марка--строкой span {
  padding-left: var(--space-sm);
  border-left: var(--rule-hair) solid var(--color-rule);
}
.марка > a {
  display: inline-flex;
  align-items: center;
  gap: 0.7rem;
  text-decoration: none;
  justify-self: start;
}
/* aspect-ratio прямо из viewBox файлов: у вектора нет собственного
   размера в пикселях, и без этой строки браузер до загрузки считает
   его 300x150, а после загрузки пересчитывает - строка дёргается. */
.марка__знак {
  display: block;
  height: 1.375rem;
  width: auto;
  aspect-ratio: 351.22 / 117.07;
}
.марка__слово {
  display: block;
  width: 10.5rem;
  height: auto;
  aspect-ratio: 1020.39 / 48.27;
}
.марка span {
  font-size: var(--text-xs);
  color: var(--color-neutral);
  white-space: nowrap;
}

/* Разделы. На широком экране details ведёт себя как обычная обёртка:
   кнопка спрятана, ссылки всегда в строке. На телефоне наоборот. */
.разделы { position: relative; }
.разделы > summary { display: none; }

.шапка__разделы {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-lg);
  font-size: var(--text-sm);
}
.шапка__разделы a {
  text-decoration: none;
  color: var(--color-muted);
  padding-block: 0.35rem;
  border-bottom: var(--rule-hair) solid transparent;
  transition: color var(--dur-micro) var(--ease-out),
              border-color var(--dur-micro) var(--ease-out);
  white-space: nowrap;
}
.шапка__разделы a:hover {
  color: var(--color-ink);
  border-color: var(--color-accent-text);
}

.шапка__право {
  display: flex;
  align-items: center;
  gap: var(--space-md);
}
.шапка__тел {
  font-size: var(--text-sm);
  text-decoration: none;
  color: var(--color-muted);
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.шапка__тел:hover { color: var(--color-ink); }

/* ============================================================
   Кнопки и ссылки
   ============================================================ */

.кнопка {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap-min);
  padding: 0 var(--space-lg);
  background: var(--color-accent);
  /* Текст на акценте ТЁМНЫЙ: белый по этому зелёному даёт 1.37:1. */
  color: var(--color-accent-ink);
  font-family: var(--font-body);
  font-weight: 500;
  font-size: var(--text-sm);
  text-decoration: none;
  border: 0;
  /* Пилюля: у них кнопка телефона радиусом 20 px при такой же
     высоте, то есть полукруглые торцы. */
  border-radius: var(--radius-pill);
  white-space: nowrap;
  cursor: pointer;
  transition: background var(--dur-micro) var(--ease-out),
              transform var(--dur-micro) var(--ease-out);
}
.кнопка:hover { background: var(--color-accent-hi); }

/* Кнопка-контур. У Koenigsegg и Zenvo ВСЕ кнопки такие: волосяная
   пилюля со стрелкой, мелкий кегль, никакой заливки. Цветная заливка
   на странице остаётся ровно одна, в герое: пять неоновых плашек,
   как было у меня, спорят и с фотографиями, и друг с другом. */
.кнопка--контур {
  background: transparent;
  color: var(--color-ink);
  border: var(--rule-hair) solid var(--color-rule);
  font-weight: 500;
}
.кнопка--контур:hover {
  background: transparent;
  border-color: var(--color-ink);
}
.кнопка--контур::after { content: " →"; white-space: pre; }
.кнопка:active { transform: translateY(1px); }
.кнопка--мелкая { min-height: 2.25rem; padding: 0 var(--space-md); }
.кнопка[aria-disabled="true"] {
  background: var(--color-paper-3);
  color: var(--color-neutral);
  pointer-events: none;
}

.ссылка {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  color: var(--color-ink);
  text-decoration: none;
  font-size: var(--text-sm);
  border-bottom: var(--rule-hair) solid var(--color-rule);
  transition: color var(--dur-micro) var(--ease-out),
              border-color var(--dur-micro) var(--ease-out);
}
.ссылка:hover { color: var(--color-accent-text); border-color: var(--color-accent-text); }
/* :active обязателен наравне с :hover и :focus-visible - восемь
   состояний это правило, а не пожелание. */
.ссылка:active { transform: translateY(1px); }
.шапка__разделы a:active,
.подвал__ссылки a:active { transform: translateY(1px); }

.действия {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-md) var(--space-lg);
}
.действия--сноска {
  margin-top: var(--space-xl);
  gap: var(--space-md) var(--space-xl);
}
.действия--сноска p { max-width: 52ch; }

/* ============================================================
   Герой: кадр во всю ширину, текст поверх него слева внизу.

   Форма снята с ориентира, названного владельцем. Прошлая форма
   (видео в левой половине, текст в правой) была моей выдумкой,
   и он назвал её убогой - справедливо, она читается коробкой
   с виджетом, а не кадром.

   Белый текст поверх ролика держится на замере, а не на удаче:
   контраст мерен внутри настоящей рамки заголовка при спрятанных
   буквах - худший 10.59 при норме 4.5, ниже нормы ноль процентов
   площади. Ролик тёмный, затемнение подобрано под замер.

   Высота 84vh, а не 100: под кадром обязана быть видна полоса цен,
   иначе возвращается самая частая претензия - «цен не видно».
   ============================================================ */

.герой {
  position: relative;
  min-height: 84vh;
  display: grid;
  align-items: end;
  background: var(--color-paper-inv);
}
.герой__видео,
.герой__кадр {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: 50% 55%;
}
.герой__кадр { display: none; }
@media (prefers-reduced-motion: reduce) {
  .герой__видео { display: none; }
  .герой__кадр { display: block; }
}

/* Затемнение двумя остановками: снизу под текст и сверху под капсулу
   меню. Середина кадра не тронута - там машина, и её не надо гасить. */
.герой__тень {
  position: absolute;
  inset: 0;
  background:
    linear-gradient(to bottom,
      oklch(12% 0.01 143 / .55) 0%,
      oklch(12% 0.01 143 / 0) 22%,
      oklch(12% 0.01 143 / 0) 46%,
      oklch(12% 0.01 143 / .82) 100%);
}

.герой__низ {
  position: relative;
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: end;
  gap: var(--space-lg) var(--space-2xl);
  max-width: var(--контейнер);
  width: 100%;
  margin-inline: auto;
  padding: var(--space-2xl) var(--page-gutter);
}
.герой__низ h1 {
  font-size: var(--text-3xl);
  line-height: var(--инт-заголовка);
  max-width: 20ch;
  color: var(--color-ink-inv);
}

/* Кнопка на кадре: светлый контур. Тёмный контур на видео не виден. */
.кнопка--светлая {
  color: var(--color-ink-inv);
  border-color: oklch(100% 0 0 / .5);
}
.кнопка--светлая:hover {
  border-color: var(--color-ink-inv);
  background: oklch(100% 0 0 / .08);
}

/* Кнопка паузы поверх видео, в нижнем левом углу кадра. */
.герой__пауза {
  position: absolute;
  inset: auto auto var(--space-md) var(--space-md);
  min-height: 2rem;
  padding: 0 var(--space-sm);
  border: var(--rule-hair) solid oklch(100% 0 0 / .45);
  border-radius: var(--radius-pill);
  background: var(--color-подложка);
  color: var(--color-ink-inv);
  font-family: var(--font-body);
  font-size: var(--text-xs);
  cursor: pointer;
  transition: border-color var(--dur-micro) var(--ease-out);
}
.герой__пауза:hover { border-color: oklch(100% 0 0 / .9); }
.герой__пауза:active { transform: translateY(1px); }
.герой__пауза:focus-visible {
  outline: 2px solid var(--color-ink-inv);
  outline-offset: 2px;
}
@media (prefers-reduced-motion: reduce) {
  .герой__пауза { display: none; }
}

/* ============================================================
   Полоса цен под кадром. Четыре суммы в строку, крупными цифрами.
   Идёт вплотную к кадру и попадает в первый экран: «цен не видно»
   было первой и самой частой претензией к этой странице.
   ============================================================ */

.ценник {
  display: grid;
  gap: var(--space-lg);
  padding-block: var(--space-xl);
}
.ценник__цены {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-lg) var(--space-xl);
  margin: 0;
}
.ценник__цены > div { display: grid; gap: var(--space-2xs); }
.ценник__цены dt { color: var(--color-neutral); font-size: var(--text-sm); }
.ценник__цены dd {
  margin: 0;
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-price);
  line-height: 1.1;
  letter-spacing: var(--track-display);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}
.ценник__низ {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: var(--space-md) var(--space-xl);
  padding-top: var(--space-md);
  border-top: var(--rule-hair) solid var(--color-rule);
}
.ценник__низ .тише { max-width: 52ch; }

/* ============================================================
   Услуги карточками. Ядро этой версии.
   У Topaz услуги идут четырьмя карточками с фотографией у каждой,
   у Sydney Detail Studio - пакетами с ценой и кнопкой. У меня стояла
   голая таблица, и понять, что студия делает, можно было только
   прочитав её целиком. Карточка отвечает на «что это» за одну секунду:
   картинка, название, цена, две строки чем это полезно.
   ============================================================ */

.услуги {
  display: grid;
  /* minmax(0, 1fr), а не 1fr: на треке с картинкой обычный 1fr
     выдавливает сетку за экран. */
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-md);
  list-style: none;
  margin: 0;
  padding: 0;
}
.услуга {
  display: grid;
  /* Строки заданы явно, чтобы цена во всех карточках ряда стояла
     на одной линии: без этого длинное название сдвигает цену вниз
     и ряд рассыпается. */
  grid-template-rows: auto auto auto 1fr;
  gap: var(--space-2xs);
  /* Карточка светлее бумаги на шесть процентов светлоты - ровно эта
     разница делает её предметом, а не куском фона. */
  background: var(--color-paper);
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-card);
  overflow: hidden;
  padding-bottom: var(--space-md);
  transition: border-color var(--dur-short) var(--ease-out),
              box-shadow var(--dur-short) var(--ease-out);
}
/* На белой бумаге карточку поднимает тень, и ТОЛЬКО тень. Раньше при
   наведении менялись сразу рамка и тень - два эффекта одновременно
   читаются как «наведение ради наведения». Цвет тени взят из токена,
   а не задан сырым oklch в правиле. */
.услуга:hover { box-shadow: var(--тень-карточки); }
/* Картинка скруглена только сверху, как у карточек новостей
   у ориентира: снизу её держит текст, и там угол лишний. */
.услуга img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  background: var(--color-paper-3);
  margin-bottom: var(--space-md);
  border-radius: calc(var(--radius-card) - 1px) calc(var(--radius-card) - 1px) 0 0;
}
/* Название работы и цена поменялись местами по громкости. Было:
   название 20 px, цена под ним 15 px зелёным - карточка читалась
   заголовком со сноской. Стало: название 17 px, цена 26 px чернилами.
   На странице про то, сколько стоит, цена не бывает сноской. */
.услуга h3 {
  font-size: var(--text-md);
  line-height: 1.32;
  padding-inline: var(--space-md);
  color: var(--color-muted);
}
.услуга b {
  padding-inline: var(--space-md);
  font-family: var(--font-display);
  font-weight: 700;
  font-size: var(--text-price-s);
  line-height: 1.05;
  letter-spacing: var(--track-display);
  font-variant-numeric: tabular-nums;
}
.услуга p {
  padding-inline: var(--space-md);
  color: var(--color-muted);
  font-size: var(--text-sm);
  line-height: 1.45;
}

/* ============================================================
   Прайс. Таблица, а не три равные карточки с иконками.
   Цены с табличными цифрами: без них колонка справа дрожит.
   ============================================================ */

.прайс {
  display: grid;
  /* Ширины разные намеренно: три равные колонки это «ИИ-грид фич». */
  grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr) minmax(0, 0.9fr);
  gap: var(--space-xl);
}
.группа { display: grid; gap: var(--space-sm); align-content: start; }
.группа h3 {
  font-size: var(--text-md);
  line-height: 1.32;
  letter-spacing: var(--track-tight);
  color: var(--color-neutral);
}
.цены { display: grid; }
.цены > div {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-md);
  padding-block: var(--space-sm);
  border-bottom: var(--rule-hair) solid var(--color-rule);
}
.цены > div:last-child { border-bottom: 0; }
.цены span:first-child { color: var(--color-muted); font-size: var(--text-sm); }
/* Цена в таблице на кегль тела и весом 600: 15 px весом 500 читались
   как примечание к названию, а не как цена. */
.цены b {
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-md);
  letter-spacing: var(--track-tight);
  font-variant-numeric: tabular-nums;
  white-space: nowrap;
}

/* ============================================================
   Работы: кладка колонками, а не сетка спанов.
   Сеткой не вышло: кадры у студии разной пропорции, и рядом
   с вертикальным X4 под горизонтальным Range Rover зияла дыра
   в полэкрана. Колонки с break-inside:avoid укладывают разновысокие
   кадры без дыр, а разнообразие размеров даёт сама съёмка.
   ============================================================ */

/* РОВНАЯ СЕТКА, а не кладка колонками. columns: 3 укладывает кадры
   разной высоты и оставляет рваный низ - именно это и читается
   кривизной. Одинаковая пропорция 4:3 у всех плиток делает раздел
   спокойным, а разнообразие даёт сама съёмка. */
.работы {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-md);
}
.работа { margin: 0; display: grid; gap: var(--space-2xs); }
/* height auto, а не 100%: с aspect-ratio они спорят, и подписи
   в галерее уже один раз из-за этого уехали под соседний ряд. */
.работа img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: var(--radius-card);
}
.работа figcaption { font-size: var(--text-xs); color: var(--color-neutral); }

/* ============================================================
   Примерка: текст слева, пара до/после справа.
   ============================================================ */

.примерка .глава { grid-template-columns: minmax(0, 1fr); }
.примерка {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 6fr);
  gap: var(--space-xl) var(--space-2xl);
  align-items: start;
}
.примерка .глава { grid-column: 1; margin-bottom: 0; display: grid; gap: var(--space-md); }
.примерка .глава > p { color: var(--color-muted); }

/* Живое сравнение до/после: одна машина, ползунок между кадрами.

   Это единственное на странице, чего нет ни у одной студии в городе:
   примерка на 813 цветов в боте. Раньше стояло двумя картинками
   рядом, то есть как иллюстрация. Ползунок делает из неё показ:
   человек сам двигает границу и видит, что цвет меняется на ЕГО
   ракурсе, а не на чужом рендере.

   Работает без скриптов: ползунок это обычный input[type=range],
   и при выключенном JS «после» просто показано наполовину. */
.сравнение { margin: 0; display: grid; gap: var(--space-md); }
.сравнение__рамка {
  --делитель: 50%;
  position: relative;
  border-radius: var(--radius-card);
  overflow: hidden;
  background: var(--color-paper-3);
}
.сравнение__рамка img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
/* Кадр «после» лежит поверх и подрезан по делителю. Класс висит
   на <div>, а не на <picture>: сборщик одним файлом тег picture
   выбрасывает вместе с классом. */
.сравнение__после {
  position: absolute;
  inset: 0;
  clip-path: inset(0 0 0 var(--делитель));
}
.сравнение__после picture,
.сравнение__после img { display: block; width: 100%; height: 100%; }
.сравнение__после img { object-fit: cover; }
.сравнение__линия {
  position: absolute;
  top: 0;
  bottom: 0;
  left: var(--делитель);
  width: 2px;
  margin-left: -1px;
  background: var(--color-ink-inv);
  pointer-events: none;
}
/* Ползунок растянут на весь кадр и сам невидим: видно линию и метки.
   Так граница двигается там, где палец, а не в отдельной полосе. */
.сравнение__ручка {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  margin: 0;
  appearance: none;
  background: transparent;
  cursor: ew-resize;
}
.сравнение__ручка::-webkit-slider-thumb {
  appearance: none;
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-pill);
  border: var(--rule-hair) solid oklch(100% 0 0 / .7);
  background: var(--color-подложка);
  cursor: ew-resize;
}
.сравнение__ручка::-moz-range-thumb {
  width: 2.75rem;
  height: 2.75rem;
  border-radius: var(--radius-pill);
  border: var(--rule-hair) solid oklch(100% 0 0 / .7);
  background: var(--color-подложка);
  cursor: ew-resize;
}
.сравнение__ручка:focus-visible {
  outline: 2px solid var(--color-ink-inv);
  outline-offset: -4px;
}
.сравнение__метка {
  position: absolute;
  bottom: var(--space-sm);
  padding: 0.25rem var(--space-sm);
  border-radius: var(--radius-pill);
  background: var(--color-подложка);
  color: var(--color-ink-inv);
  font-size: var(--text-xs);
  pointer-events: none;
}
.сравнение__метка--лево { left: var(--space-sm); }
.сравнение__метка--право { right: var(--space-sm); }
.сравнение figcaption {
  font-size: var(--text-xs);
  color: var(--color-neutral);
  max-width: 62ch;
}

/* Нумерованная дорога: шаги записи и проезда. */
.дорога {
  display: grid;
  gap: var(--space-md);
  counter-reset: шаг;
  margin: 0;
  padding: 0;
  list-style: none;
}
.дорога li {
  counter-increment: шаг;
  display: grid;
  grid-template-columns: 1.5rem minmax(0, 1fr);
  gap: var(--space-md);
  color: var(--color-muted);
  font-size: var(--text-sm);
}
.дорога li::before {
  content: counter(шаг);
  color: var(--color-neutral);
  font-family: var(--font-display);
  font-weight: 600;
}

/* ============================================================
   Оценка, доводы, отзывы и карта.

   Всё на настоящих данных: рейтинг снят из виджета Яндекса
   (10.09.2026: 5,0 при 107 отзывах), отзывы показывает их же виджет,
   карта - их организация по тому же ID. Ни одной выдуманной цифры
   и ни одного придуманного отзыва.
   ============================================================ */

/* Оценка строкой под ценами: цифра крупно, пояснение тихо. */
.оценка {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  gap: var(--space-xs) var(--space-md);
  padding-top: var(--space-md);
  border-top: var(--rule-hair) solid var(--color-rule);
}
.оценка b {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-xl);
  line-height: 1;
  letter-spacing: var(--track-display);
  font-variant-numeric: tabular-nums;
}
.оценка span { color: var(--color-neutral); font-size: var(--text-sm); }

/* Доводы: четыре штуки, у каждого короткая шапка и две строки. */
.доводы {
  display: grid;
  grid-template-columns: repeat(4, minmax(0, 1fr));
  gap: var(--space-lg) var(--space-xl);
  list-style: none;
  margin: 0;
  padding: 0;
}
.довод {
  display: grid;
  gap: var(--space-2xs);
  align-content: start;
  padding-top: var(--space-md);
  border-top: var(--rule-hair) solid var(--color-rule);
}
.довод b {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-xl);
  line-height: 1.1;
  letter-spacing: var(--track-display);
}
.довод p { color: var(--color-muted); font-size: var(--text-sm); }

/* Виджет отзывов. Высота задана: у виджета внутри своя прокрутка,
   и без высоты он схлопывается в ноль. */
/* Раздел отзывов в две колонки, как раздел примерки. Причина
   не в красоте: виджет Яндекса рисует карточку не шире ~660 px,
   и на всю полосу в 1152 px справа оставался его серый фон -
   треть блока пустой заплатой. Колонка 7fr даёт виджету ~690 px,
   то есть ровно его ширину. */
.раздел-отзывов {
  display: grid;
  grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
  gap: var(--space-xl) var(--space-2xl);
  align-items: start;
}
.раздел-отзывов .глава {
  grid-column: 1;
  margin-bottom: 0;
  display: grid;
  gap: var(--space-md);
  grid-template-columns: minmax(0, 1fr);
}
.раздел-отзывов .глава > p { color: var(--color-muted); }

.отзывы { display: grid; gap: var(--space-md); }

/* Окно, в котором рамка лежит поверх запаса. Рамке фон НЕ ставим:
   белым её закрасит сам виджет, когда нарисуется, а пока она
   прозрачная - через неё читается запас. */
.отзывы__окно, .карта__окно { position: relative; }
.отзывы__запас, .карта__запас {
  position: absolute;
  inset: 0;
  z-index: 0;
  display: grid;
  align-content: center;
  justify-items: center;
  gap: var(--space-2xs);
  padding: var(--space-xl);
  border-radius: var(--radius-card);
  /* Бумага, а не серая подложка. При загруженном виджете по краям
     остаётся тонкое кольцо запаса (замерено: 1.2% кадра у отзывов,
     2.9% у карты) - серым оно читалось как грязная кромка,
     а на бумаге совпадает с белым полотном виджета. */
  background: var(--color-paper);
  text-align: center;
}
.отзывы__запас b {
  font-family: var(--font-display);
  font-weight: 400;
  font-size: var(--text-2xl);
  line-height: 1.1;
  letter-spacing: var(--track-display);
}
.отзывы__запас p, .карта__запас p { color: var(--color-muted); }
.отзывы__рамка {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 34rem;
  border: var(--rule-hair) solid var(--color-rule);
  border-radius: var(--radius-card);
  background: transparent;
}

/* Карта. Тоже с заданной высотой и ссылкой под ней: если виджет
   не загрузился, человек всё равно попадёт на карту. */
.карта { display: grid; gap: var(--space-md); margin-top: var(--space-xl); }
.карта__рамка {
  position: relative;
  z-index: 1;
  width: 100%;
  height: 22rem;
  border: 0;
  border-radius: var(--radius-card);
  background: transparent;
}

/* ============================================================
   Материалы и марки
   ============================================================ */

.материалы {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: var(--space-lg);
}
.материал {
  display: grid;
  gap: var(--space-xs);
  align-content: start;
  padding-top: var(--space-md);
  border-top: var(--rule-hair) solid var(--color-rule);
}
.материал h3 { font-size: var(--text-md); letter-spacing: var(--track-tight); }
.материал p { color: var(--color-muted); font-size: var(--text-sm); }

.марки-блок {
  display: grid;
  gap: var(--space-md);
  margin-top: var(--space-xl);
  padding-top: var(--space-lg);
  border-top: var(--rule-hair) solid var(--color-rule);
}
.марки-блок h3 { font-size: var(--text-xl); line-height: 1.24; max-width: 30ch; }
.марки-блок > p { color: var(--color-muted); max-width: var(--measure); font-size: var(--text-sm); }
.марки {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-sm) var(--space-lg);
  list-style: none;
  margin: 0;
  padding: 0;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-lg);
  letter-spacing: var(--track-tight);
}
.марки li { color: var(--color-neutral); }
/* Каждая третья ярче: ряд из девяти одинаковых слов читается списком,
   а с перебоем читается набором. */
.марки li:nth-child(3n+1) { color: var(--color-ink); }

/* ============================================================
   Шаги работы
   ============================================================ */

.шаги {
  display: grid;
  /* Ширины разные намеренно: четыре равные карточки это шаблон. */
  grid-template-columns:
    minmax(0, 1.2fr) minmax(0, 1fr) minmax(0, 1fr) minmax(0, 0.85fr);
  gap: var(--space-xl);
  padding-top: var(--space-md);
  border-top: var(--rule-hair) solid var(--color-rule);
}
.шаг { display: grid; gap: var(--space-xs); align-content: start; }
.шаг > b {
  font-family: var(--font-display);
  font-weight: 500;
  font-size: var(--text-xl);
  line-height: 1;
  /* НЕ --color-rule: на цвете линии номер давал 1.46:1 к бумаге,
     то есть его физически не было видно. Замерено, не на глаз. */
  color: var(--color-neutral);
}
.шаг h3 {
  font-family: var(--font-body);
  font-weight: 600;
  font-size: var(--text-md);
  letter-spacing: 0;
}
.шаг p { color: var(--color-muted); font-size: var(--text-sm); }

/* ============================================================
   Вопросы
   ============================================================ */

.вопросы { display: grid; max-width: 68rem; }
.вопрос { border-bottom: var(--rule-hair) solid var(--color-rule); }
.вопрос:first-child { border-top: var(--rule-hair) solid var(--color-rule); }
.вопрос summary {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: var(--space-md);
  min-height: var(--tap-min);
  padding-block: var(--space-sm);
  cursor: pointer;
  list-style: none;
  font-family: var(--font-display);
  font-weight: 600;
  font-size: var(--text-md);
  letter-spacing: var(--track-tight);
}
.вопрос summary::-webkit-details-marker { display: none; }
.вопрос summary:hover { color: var(--color-accent-text); }
.вопрос summary::after {
  content: "+";
  color: var(--color-neutral);
  font-weight: 400;
}
.вопрос[open] summary::after { content: "\2212"; }
.вопрос p {
  color: var(--color-muted);
  font-size: var(--text-sm);
  max-width: var(--measure);
  padding-bottom: var(--space-md);
}

/* ============================================================
   Контакты
   ============================================================ */

.контакты {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: var(--space-xl) var(--space-2xl);
  align-items: start;
}
.паспорт { display: grid; margin: 0; }
.паспорт > div {
  display: grid;
  grid-template-columns: 6rem minmax(0, 1fr);
  gap: var(--space-md);
  padding-block: var(--space-sm);
  border-top: var(--rule-hair) solid var(--color-rule);
}
.паспорт > div:last-child {
  border-bottom: var(--rule-hair) solid var(--color-rule);
}
.паспорт > div { align-items: baseline; }
.паспорт dt { color: var(--color-neutral); font-size: var(--text-sm); }
.паспорт dd { margin: 0; font-size: var(--text-sm); line-height: 1.45; }
/* У .ссылка стоит min-height 44 px - это требование к цели нажатия,
   и для кнопки оно верное. Но внутри строки паспорта такая ссылка
   раздувала строку, и телефон с ником бота сидели ниже своих ярлыков,
   а строки шли разной высоты. Здесь ссылка - часть текста. */
.паспорт .ссылка {
  min-height: 0;
  display: inline;
  font-size: inherit;
}

/* ============================================================
   Ft1 · марка и подпись держат полосу, ссылки рядом, реквизиты ниже.
   Прошлая версия несла Ft4, плотный колофон одним абзацем.
   Колонок «Resources» тут нет: у студии есть адрес, часы и ИП.
   ============================================================ */

.подвал {
  border-top: var(--rule-hair) solid var(--color-rule);
  padding: var(--space-xl) var(--page-gutter) var(--space-lg);
  max-width: var(--контейнер);
  margin-inline: auto;
}
.подвал__верх {
  display: flex;
  flex-wrap: wrap;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-lg);
}
.подвал__ссылки {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-lg);
  font-size: var(--text-sm);
}
.подвал__ссылки a {
  color: var(--color-muted);
  text-decoration: none;
  white-space: nowrap;
  border-bottom: var(--rule-hair) solid transparent;
}
.подвал__ссылки a:hover { color: var(--color-ink); border-color: var(--color-accent-text); }
.подвал__низ {
  margin-top: var(--space-xl);
  padding-top: var(--space-md);
  border-top: var(--rule-hair) solid var(--color-rule);
  color: var(--color-neutral);
  font-size: var(--text-xs);
  line-height: 1.6;
  /* 74ch, а не 84: длиннее 75 знаков глаз теряет начало строки. */
  max-width: 74ch;
}
.подвал__низ a { border-bottom: var(--rule-hair) solid var(--color-rule); }
.подвал__низ a:hover { color: var(--color-accent-text); border-color: var(--color-accent-text); }

/* ============================================================
   Настоящие фото студии.
   Взяты с их же сайта performance-spb.ru. Тильда их уже пережала,
   поэтому у Алексея надо просить оригиналы: на тёмной странице
   пережатое небо и лак сыпятся полосами.
   ============================================================ */

/* ============================================================
   Узкие экраны. От широкого к узкому, по одному блоку на порог.
   Порядок важен: за правки тут уже успевали заводиться два блока
   на один порог, и на 700 px побеждал не тот, что нужно.
   Проверено на 320 / 375 / 414 / 768 / 1200.
   ============================================================ */

@media (max-width: 78rem) {
  .услуги { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .работы { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .шаги { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Шкала отступов на узких экранах. 120 px между секциями снято
   с ориентира, и на десктопе это верно, но на экране 390 px даёт
   240 px пустоты подряд - четверть высоты экрана ни на что.
   Меняем сами ТОКЕНЫ, а не отдельные секции: пропорции между
   блоками при этом сохраняются. */
@media (max-width: 62rem) {
  :root {
    --space-3xl: 4rem;
    --space-2xl: 2.75rem;
    --space-xl: 2rem;
  }
}
@media (max-width: 30rem) {
  :root {
    --space-3xl: 3rem;
    --space-2xl: 2.25rem;
    --space-xl: 1.75rem;
  }
}

@media (max-width: 62rem) {
  /* На узком заголовок и кнопка встают друг под друга: рядом кнопка
     выдавливает заголовок в четыре строки. */
  .герой { min-height: 72vh; }
  .герой__низ { grid-template-columns: minmax(0, 1fr); }
  .ценник__цены { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .доводы { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  /* Разделы уходят под марку отдельной строкой: втроём в одну строку
     они начинали ломать телефон и кнопку на две строки, а это гейт 49. */
  .шапка { gap: var(--space-sm) var(--space-md); }
  /* На телефоне разделы прячутся ПОД КНОПКУ, а не исчезают. Пять
     ссылок строкой переносились в три строки и раздували шапку
     до 193 пикселей - четверти экрана до начала видео. Кнопка
     занимает столько же, сколько одна ссылка. */
  .разделы > summary {
    display: inline-flex;
    align-items: center;
    gap: var(--space-2xs);
    min-height: var(--tap-min);
    padding: 0 var(--space-md);
    border: var(--rule-hair) solid var(--color-rule);
    border-radius: var(--radius-pill);
    font-size: var(--text-sm);
    cursor: pointer;
    list-style: none;
    white-space: nowrap;
  }
  .разделы > summary::-webkit-details-marker { display: none; }
  .разделы > summary::after {
    content: "\25BE";
    color: var(--color-neutral);
    transition: transform var(--dur-micro) var(--ease-out);
  }
  .разделы[open] > summary::after { transform: rotate(180deg); }
  .разделы > summary:hover { border-color: var(--color-ink); }
  .разделы > summary:focus-visible {
    outline: 2px solid var(--color-focus);
    outline-offset: 2px;
  }

  /* Закрытое меню не занимает места, открытое падает под кнопку
     карточкой. z-index выше видео, иначе список уедет под кадр. */
  .разделы:not([open]) > .шапка__разделы { display: none; }
  .разделы[open] > .шапка__разделы {
    position: absolute;
    top: calc(100% + var(--space-xs));
    left: 0;
    z-index: var(--z-sticky);
    display: grid;
    gap: 0;
    min-width: 12rem;
    padding: var(--space-2xs) 0;
    border: var(--rule-hair) solid var(--color-rule);
    border-radius: var(--radius-card);
    background: var(--color-paper);
    box-shadow: var(--тень-карточки);
  }
  .разделы[open] > .шапка__разделы a {
    padding: var(--space-sm) var(--space-md);
    border-bottom: 0;
  }
  .разделы[open] > .шапка__разделы a:hover {
    background: var(--color-paper-2);
    border-color: transparent;
  }
  .примерка { grid-template-columns: minmax(0, 1fr); }
  .примерка .глава { grid-column: auto; }
  .раздел-отзывов { grid-template-columns: minmax(0, 1fr); }
  .раздел-отзывов .глава { grid-column: auto; }
  .прайс { grid-template-columns: minmax(0, 1fr); gap: var(--space-lg); }
  .материалы { grid-template-columns: minmax(0, 1fr); }
  .контакты { grid-template-columns: minmax(0, 1fr); }
  .глава { grid-template-columns: minmax(0, 1fr); }
}

@media (max-width: 48rem) {
  .услуги { grid-template-columns: minmax(0, 1fr); }
  .работы { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .герой { min-height: 66vh; }
}

@media (max-width: 30rem) {
  .марка__знак { height: 1.125rem; }
  .марка__слово { width: 8.25rem; }
  .герой { min-height: 60vh; }
  .ценник__цены { grid-template-columns: minmax(0, 1fr); }
  .работы { grid-template-columns: minmax(0, 1fr); }
  .доводы { grid-template-columns: minmax(0, 1fr); }
  /* На телефоне у виджета своя шапка (название, 5,0, кнопка «Оставить
     отзыв») - она съедает ~330 px, и на 30rem первый отзыв обрывался
     на середине фразы. Замерено на 390 px. */
  .отзывы__рамка { height: 38rem; }
  .карта__рамка { height: 17rem; }
  /* Капсула на 320 px разъезжается: возвращаем обычную полосу. */
  .шапка--капсула {
    position: static;
    width: auto;
    border-radius: 0;
    box-shadow: none;
    border-bottom: var(--rule-hair) solid var(--color-rule);
  }
  .шаги { grid-template-columns: minmax(0, 1fr); }
  .марки { font-size: var(--text-md); }
  /* Телефон в шапке прячем: он строкой ниже в кнопке и в контактах,
     а на 320 px он выдавливал кнопку на вторую строку. */
  .шапка__тел { display: none; }
  .паспорт > div { grid-template-columns: 5rem minmax(0, 1fr); }
  /* Кнопки в одну колонку, чтобы надпись не ломалась на две строки. */
  .действия { flex-direction: column; align-items: stretch; }
  .действия .кнопка { justify-content: center; }
  /* Ссылку не растягиваем: её подчёркивание во всю ширину экрана
     читается как разделитель секции, а не как ссылка. */
  .действия .ссылка { align-self: flex-start; }
}

/* ============================================================
   Движение. Рассчитано на телефон: наведения мышкой там нет,
   поэтому работает вход при загрузке и появление при прокрутке.

   ПЕРВЫЙ ЭКРАН ВИДЕН СРАЗУ. Скрывается только то, что лежит НИЖЕ
   сгиба, и только когда скрипт поставил на корневой элемент класс «движение».
   Без скрипта страница показывает всё - ничего не висит на нуле
   прозрачности в ожидании наблюдателя.

   Двигаем только transform и opacity: остальное браузер считает
   с пересчётом раскладки, и на телефоне это заметно.
   ============================================================ */

/* Вход первого экрана: заголовок и кнопка поднимаются один раз. */
.вход {
  animation: подняться var(--dur-long) var(--ease-out) both;
  animation-delay: calc(var(--шаг, 0) * 60ms + 120ms);
}
@keyframes подняться {
  from { opacity: 0; transform: translateY(14px); }
  to   { opacity: 1; transform: none; }
}

/* Появление при прокрутке. */
.движение .всплыть { opacity: 0; transform: translateY(18px); }
.движение .всплыть.видно {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-long) var(--ease-out),
              transform var(--dur-long) var(--ease-out);
}
/* Лестница внутри блока: карточки и плитки по 45 мс друг за другом. */
.движение .всплыть .лестница { opacity: 0; transform: translateY(14px); }
.движение .всплыть.видно .лестница {
  opacity: 1;
  transform: none;
  transition: opacity var(--dur-short) var(--ease-out)
                calc(var(--шаг, 0) * 45ms + 90ms),
              transform var(--dur-short) var(--ease-out)
                calc(var(--шаг, 0) * 45ms + 90ms);
}

/* Плитка работ приближается под курсором. Только здесь и только
   на устройствах с настоящим наведением: на телефоне hover
   срабатывает по касанию и картинка «залипает» приближенной. */
@media (hover: hover) and (pointer: fine) {
  .работа picture {
    display: block;
    overflow: hidden;
    border-radius: var(--radius-card);
  }
  .работа img { transition: transform var(--dur-long) var(--ease-out); }
  .работа:hover img { transform: scale(1.04); }
}

/* Подсказка у ползунка: на телефоне не догадаться, что можно тянуть. */
.сравнение__подсказка {
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, calc(-50% - 2.6rem));
  padding: 0.25rem var(--space-sm);
  border-radius: var(--radius-pill);
  background: var(--color-подложка);
  color: var(--color-ink-inv);
  font-size: var(--text-xs);
  white-space: nowrap;
  pointer-events: none;
  transition: opacity var(--dur-short) var(--ease-out);
}
/* Ручка один раз сама уезжает и возвращается, когда блок дошёл
   до экрана. Дальше не повторяется: повторяющийся намёк раздражает. */
/* БЕЗ both и forwards. С ними последний кадр анимации (50%) залипает
   навсегда и перебивает inline-значение, которое ставит скрипт: после
   намёка ползунок визуально перестаёт двигаться, хотя value меняется.
   Замер это и поймал: делитель 51%, а значение 17. */
.сравнение--намекнуть { animation: намекнуть 1.6s var(--ease-in-out) 1; }
@keyframes намекнуть {
  0%   { --делитель: 50%; }
  35%  { --делитель: 26%; }
  70%  { --делитель: 62%; }
  100% { --делитель: 50%; }
}
/* После первого касания подсказка уходит. */
.сравнение--тронут .сравнение__подсказка { opacity: 0; }

/* Всё движение выключается, если человек попросил об этом систему. */
@media (prefers-reduced-motion: reduce) {
  *, *::before, *::after {
    animation-duration: 0.01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: 0.01ms !important;
  }
  .движение .всплыть,
  .движение .всплыть .лестница { opacity: 1; transform: none; }
  .сравнение__подсказка { display: none; }
}
