/* ==========================================================================
   blocks.css — секции страниц. Требует tokens.css, base.css, components.css.

   Файл написан от мобильного: база — 360, дальше min-width 768 и 1280.
   Так же устроен tokens.css, где мобильные значения лежат в :root, а
   десктопные подставляются с 768. Перестроения — ТЗ на редизайн, раздел 5.
   ========================================================================== */

/* --- Сообщение о незагруженных данных ----------------------------------- */

.load-error {
  padding: var(--space-16) var(--space-24);
  background-color: #FFE9B0;
  border-bottom: 2px solid var(--warn);
  color: var(--ink);
  font-size: var(--fs-small);
}

.load-error code {
  font-family: var(--font-mono);
  font-size: 0.95em;
}

.load-error__tech {
  color: var(--ink-60);
}

/* ==========================================================================
   Временная главная и страница 404
   Обе живут до шага 5: главная заменится настоящей, 404 останется.
   ========================================================================== */

.index__lead {
  margin-top: var(--space-16);
  max-width: var(--measure);
}

.index-list {
  display: grid;
  gap: var(--space-16);
  margin-top: var(--space-32);
  max-width: 720px;
}

.index-list__item {
  padding-top: var(--space-16);
  border-top: var(--border-width) solid var(--line);
}

.index-list__link {
  font-family: var(--font-heading);
  font-size: var(--fs-h3);
  font-weight: var(--fw-semibold);
  color: var(--ink);
  text-decoration: none;
}

.index-list__link:hover {
  color: var(--scan-blue);
  text-decoration: underline;
}

.index-list__note {
  display: block;
  margin-top: var(--space-4);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.index__note {
  margin-top: var(--space-48);
}

.index__note code {
  font-family: var(--font-mono);
  font-size: 0.95em;
}

/* ==========================================================================
   Шапка и сквозное меню

   Три состояния — ТЗ на редизайн, раздел 6:

     мобильный                логотип с дескриптором, телефон, гамбургер;
                              меню — панель под шапкой на весь экран
     десктоп, исходное        две строки: верхняя — логотип с дескриптором,
                              телефон и кнопка расчёта, нижняя — меню
                              во всю ширину контейнера
     десктоп, прилипшее       одна строка, меню уходит в гамбургер
                              и раскрывается панелью поверх контента

   Высоту верхней строки держит её собственная min-height — 56 px
   на мобильном, 72 px с 768, — а не место, зарезервированное под кнопки:
   появление кнопок при прилипании не должно сдвигать контент.

   Строка меню при прилипании выходит из потока целиком (position: fixed),
   поэтому высота шапки меняется ровно на её высоту, одним шагом.
   Промежуточных значений нет, и первый блок страницы сдвигается один раз
   и ровно на разницу высот — требование раздела 6 ТЗ на редизайн,
   проверяется стендом tools/check-menu.py.
   ========================================================================== */

.header {
  /* Высота строки дескриптора в мобильной панели: ею же панель отбивает
     себе место сверху. Не токен дизайн-системы, а размер одного узла. */
  --nav-tagline-h: 44px;
  position: sticky;
  top: 0;
  z-index: 50;
  background-color: var(--paper);
  /* Граница есть всегда: без неё шапка сливалась с первым экраном,
     который теперь тоже белый. */
  border-bottom: var(--border-width) solid var(--line);
  transition: box-shadow var(--motion-duration) var(--motion-easing);
}

/* В прилипшем состоянии — лёгкая тень: видно, что контент уходит под шапку */
.header.is-stuck {
  box-shadow: 0 2px 8px rgba(18, 22, 28, 0.1);
}

/* Верхняя строка. До 768 в ней логотип, телефон и гамбургер — всё, что
   в шапке осталось. Отступ сверху и снизу по 4 px: площадь нажатия
   у логотипа, телефона и гамбургера 44 px, и с большим отступом строка
   переросла бы заданные разделом 6 ТЗ на редизайн 56 px. С 768 отступ
   12 px, и там 44 + 24 укладываются в 72 px без натяжки. */
.header__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: var(--space-8) var(--space-12);
  min-height: 56px;
  padding-block: var(--space-4);
}

/* Слева логотип с дескриптором, справа телефон, кнопка и гамбургер —
   одной группой. Раньше телефон был прижат к краю, а кнопки висели
   между ними. */
.header__aside {
  order: 2;
  display: flex;
  align-items: center;
  gap: var(--space-8);
  margin-left: auto;
}

/* Логотип — ссылка, поэтому область нажатия не меньше 44 px по обеим
   сторонам: на мобильном сама картинка уже этого. */
.header__logo {
  flex: none;
  display: flex;
  align-items: center;
  min-width: var(--tap-min);
  min-height: var(--tap-min);
}

.header__logo img {
  height: 36px;
  width: auto;
}

.header__phone {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  margin-left: auto;
  padding-inline: var(--space-4);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: var(--fw-medium);
  color: var(--ink);
  text-decoration: none;
  white-space: nowrap;
}

.header__phone:hover {
  color: var(--scan-orange);
}

/* Дескриптор. С 768 стоит в строке шапки справа от логотипа
   и в липком состоянии не скрывается: ТЗ на прототип, 8.1 пункт 14.

   До 768 в шапке его нет. Там он занимал вторую строку целиком и держал
   шапку двухэтажной постоянно: вместе с нижней закреплённой панелью это
   около 180 px экрана, из которых дескриптор — единственное, что не
   действие и не навигация. То же самое говорит H1 строкой ниже.
   На мобильном он показывается первой строкой в панели меню — стилями,
   а не второй копией в разметке: копия читалась бы скринридером дважды
   подряд. Решение 25.08.2026. */
.header__tagline {
  display: none;
  font-size: var(--fs-small);
  line-height: 1.3;
  color: var(--ink-60);
}

/* Кнопка в шапке появляется только когда первый экран прокручен: пока он
   виден, она дублировала бы его собственные кнопки. Кнопки «Получить
   прайс» здесь больше нет — решение по меню, ТЗ на редизайн, раздел 6.

   Скрыта через display: none, а не прозрачностью, — иначе она остаётся
   в потоке и отодвигает телефон от края контейнера. Высоту шапки держит
   её собственная min-height, а не зарезервированное под кнопку место,
   поэтому при появлении шапка не подпрыгивает. */
.header__actions {
  display: none;
  align-items: center;
  gap: var(--space-16);
}

@keyframes header-actions-in {
  from { opacity: 0; transform: translateY(-4px); }
  to   { opacity: 1; transform: none; }
}

/* Гамбургер. Знак подменяется, а не поворачивается: крестик из трёх полос
   трансформацией не собрать без лишней разметки. Цвет в покое и под
   курсором — components.css, раздел 9, «Крестик закрытия — один вид
   на весь сайт»: значок в открытом состоянии и есть тот крестик. */
.header__burger {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-min);
  height: var(--tap-min);
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
}

.header__burger-icon {
  width: 24px;
  height: 24px;
}

.header__burger-icon--close,
.header.is-menu-open .header__burger-icon {
  display: none;
}

.header.is-menu-open .header__burger-icon--close {
  display: block;
}

/* --- Меню --------------------------------------------------------------

   Мобильный: панель под шапкой на весь оставшийся экран. Высота шапки
   приходит переменной --header-h: она зависит от состояния — две строки
   или одна, — и её меряет ui.js. Разметка от скрипта при этом не зависит:
   до открытия панель не видна, а открывает её тот же скрипт.

   z-index 45: выше нижней закреплённой панели (40), ниже модальных
   окон (100) и ниже самой шапки (50) — гамбургер остаётся на виду
   и работает на закрытие. */

.nav {
  position: fixed;
  inset: var(--header-h, 56px) 0 0 0;
  z-index: 45;
  display: none;
  overflow-y: auto;
  overscroll-behavior: contain;
  background-color: var(--paper);
}

.header.is-menu-open .nav {
  display: block;
}

/* Первая строка панели — дескриптор. Он выведен из потока (fixed),
   поэтому высота самой шапки при открытии панели не меняется: на 360
   она равна 56 px и в покое, и в прилипшем состоянии, и с открытым меню.
   Место под строку панель отдаёт отступом сверху — величина одна на оба
   правила, поэтому лежит в переменной. */
@media (max-width: 767px) {
  .header.is-menu-open .header__tagline {
    position: fixed;
    top: var(--header-h, 56px);
    left: 0;
    right: 0;
    z-index: 46;
    display: flex;
    align-items: center;
    height: var(--nav-tagline-h);
    padding-inline: var(--container-pad);
    background-color: var(--paper);
    border-bottom: var(--border-width) solid var(--line);
  }

  .header.is-menu-open .nav__inner {
    padding-top: calc(var(--nav-tagline-h) + var(--space-8));
  }
}

.nav__inner {
  display: flex;
  flex-direction: column;
  gap: var(--space-24);
  padding-block: var(--space-8) var(--space-32);
}

.nav__item--parent {
  /* Точка отсчёта для выпадающего списка на десктопе */
  position: relative;
}

.nav__item + .nav__item {
  border-top: var(--border-width) solid var(--line);
}

/* Пункты и подпункты — не меньше 44 px по высоте на всех ширинах.
   Полоса текущего раздела приходит переменной --nav-current: она
   загорается только у текущего пункта, и одно правило обслуживает
   и обычное состояние, и подсветку. */
.nav__link,
.nav__sublink {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  min-height: var(--tap-min);
  padding-block: var(--space-8);
  padding-inline: var(--space-12);
  color: var(--ink);
  font-weight: var(--fw-medium);
  text-decoration: none;
  box-shadow: inset var(--accent-bar) 0 0 var(--nav-current, transparent);
}

/* Под курсором пункт берёт затемнённый оранжевый. На сером фоне строки
   меню обычный --scan-orange даёт 2.78:1 при норме 4.5 из раздела 9 ТЗ
   на редизайн; затемнённый оттенок поднимает число, не меняя цвет
   по существу. Токен тот же, которым красится наведение на кнопках, —
   нового не заводим. Правка 26.08.2026. */
.nav__link:hover,
.nav__sublink:hover {
  color: var(--scan-orange-hover);
}

.nav__sublink {
  padding-left: var(--space-32);
  font-weight: var(--fw-regular);
}

/* Первый подпункт ведёт на родительский раздел и отделяется границей,
   а не отступом: отступ прочитался бы как случайный. */
.nav__sublink--parent {
  border-bottom: var(--border-width) solid var(--line);
}

.nav__sub {
  display: none;
}

.nav__item.is-open > .nav__sub {
  display: block;
}

/* Стрелка вниз — только у пункта с выпадающим списком. Правило проекта:
   вправо — переход, вниз — раскрытие. ТЗ на редизайн, раздел 5. */
.nav__chevron {
  flex: none;
  width: 20px;
  height: 20px;
  margin-left: auto;
  transition: transform var(--motion-hover) var(--motion-easing);
}

.nav__item.is-open > .nav__link .nav__chevron {
  transform: rotate(180deg);
}

/* Хвост панели: кнопка расчёта и телефон. Панель на весь экран без них
   выглядит обрубленной. На десктопе скрыт — там и то и другое стоит
   в верхней строке шапки. */
.nav__foot {
  display: flex;
  flex-direction: column;
  gap: var(--space-16);
  padding-inline: var(--space-12);
}

.nav__phone {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: var(--tap-min);
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: var(--fw-medium);
  color: var(--ink);
  text-decoration: none;
}

.nav__phone:hover {
  color: var(--scan-orange);
}

@media (min-width: 768px) {
  .header__inner {
    gap: var(--space-16);
    min-height: 72px;
    padding-block: var(--space-12);
  }

  .header__inner {
    flex-wrap: nowrap;
  }

  .header__logo img {
    height: 44px;
  }

  .header__tagline {
    order: 1;
    flex: 0 1 auto;
    display: block;
    max-width: 34ch;
  }

  .header.is-stuck .header__actions {
    display: flex;
    animation: header-actions-in var(--motion-duration) var(--motion-easing);
  }

  /* Кнопка не переносится по словам: место уступает дескриптор,
     он для этого и ограничен по ширине. */
  .header__actions .btn {
    white-space: nowrap;
  }

  /* Гамбургер нужен только там, где строка меню схлопнулась */
  .header__burger {
    display: none;
  }

  .header.is-stuck .header__burger {
    display: inline-flex;
  }

  /* Исходное состояние: меню — вторая строка шапки. Заливка --paper-alt
     идёт во всю ширину экрана, содержимое держится контейнера.

     Зачем заливка. Верхняя строка шапки, строка меню и первый блок
     страницы были залиты одним --paper и разделены линиями в 1 px:
     три белые поверхности подряд читаются как одно поле, меню
     прилипает к контенту и перестаёт читаться как навигация.

     Границы сверху у строки нет: от белой шапки её отделяет сама
     заливка, а две границы подряд — это лишняя линия. Снизу полосу
     отделяет нижняя граница шапки: строка меню — последнее, что в шапке
     лежит, и граница проходит ровно под ней. Своей границы строке
     не задаём — она встала бы вплотную к границе шапки и дала бы
     полосу в 2 px. Правка 25.08.2026. */
  .nav {
    position: static;
    display: block;
    overflow: visible;
    background-color: var(--paper-alt);
  }

  .nav__inner {
    flex-direction: row;
    align-items: center;
    gap: 0;
    padding-block: 0;
  }

  .nav__list {
    display: flex;
    flex-wrap: wrap;
  }

  .nav__item + .nav__item {
    border-top: 0;
  }

  .nav__link {
    padding-block: var(--space-12);
    padding-inline: var(--space-16);
    /* В строке текущий раздел отмечается подчёркиванием, а не полосой
       слева: слева у пункта в строке нет своей стороны. */
    box-shadow: inset 0 -2px 0 var(--nav-current, transparent);
  }

  /* Первый пункт прижат к краю контейнера: строка меню начинается там же,
     где логотип строкой выше. */
  .nav__item:first-child > .nav__link {
    padding-left: 0;
  }

  .nav__chevron {
    margin-left: 0;
  }

  .nav__foot {
    display: none;
  }

  /* Выпадающий список — поверх контента, а не в потоке строки */
  .header:not(.is-stuck) .nav__sub {
    position: absolute;
    top: 100%;
    left: 0;
    z-index: 60;
    min-width: 272px;
    padding-block: var(--space-8);
    background-color: var(--paper);
    border: var(--border-width) solid var(--line);
    box-shadow: 0 8px 20px rgba(18, 22, 28, 0.12);
  }

  .header:not(.is-stuck) .nav__sublink {
    padding-inline: var(--space-16);
  }

  /* Прилипшее состояние: строка меню выходит из потока и открывается
     панелью поверх контента. Панель светлая: на странице допускается
     один тёмный блок, и он уже занят. */
  .header.is-stuck .nav {
    position: fixed;
    inset: var(--header-h, 72px) 0 auto 0;
    display: none;
    max-height: calc(100vh - var(--header-h, 72px));
    overflow-y: auto;
    /* Панель остаётся белой: серым отмечена строка в потоке шапки,
       а панель лежит поверх контента и отделена от него тенью. */
    background-color: var(--paper);
    border-bottom: var(--border-width) solid var(--line);
    box-shadow: 0 8px 20px rgba(18, 22, 28, 0.12);
  }

  .header.is-stuck.is-menu-open .nav {
    display: block;
  }

  .header.is-stuck .nav__inner {
    flex-direction: column;
    align-items: stretch;
    padding-block: var(--space-8) var(--space-16);
  }

  .header.is-stuck .nav__list {
    display: block;
  }

  .header.is-stuck .nav__item + .nav__item {
    border-top: var(--border-width) solid var(--line);
  }

  .header.is-stuck .nav__link {
    padding-inline: var(--space-12);
    box-shadow: inset var(--accent-bar) 0 0 var(--nav-current, transparent);
  }

  .header.is-stuck .nav__chevron {
    margin-left: auto;
  }
}

/* --- Подсветка текущего раздела ----------------------------------------

   Разметка меню на всех страницах одинакова до байта, поэтому класс
   текущего пункта в неё не ставится: он развёл бы страницы между собой.
   Страница называет себя атрибутом data-page у body, а совпадение
   ищет CSS. При интеграции это делает сам компонент меню Битрикса.

   Верхний уровень ловится по началу имени страницы: все страницы аренды
   начинаются с arenda, карточка товара — с catalog. Подпункт совпадает
   с именем страницы целиком.

   Способ подсветки ровно один. Второй — по видимости блока — был заведён
   для пункта «О компании» и снят 25.08.2026 вместе с самим пунктом:
   пункт, который вместо перехода прокручивает страницу и подсвечивается
   не как соседи, читается как сбой. */

[data-page^="arenda"] [data-nav="arenda"],
[data-page^="catalog"] [data-nav="catalog"],
[data-page="contacts"] [data-nav="contacts"],
[data-page="arenda"] [data-nav-sub="arenda"],
[data-page="arenda-meropriyatiya"] [data-nav-sub="arenda-meropriyatiya"],
[data-page="arenda-kino"] [data-nav-sub="arenda-kino"],
[data-page="arenda-obekty"] [data-nav-sub="arenda-obekty"],
[data-page="arenda-podmena"] [data-nav-sub="arenda-podmena"],
[data-page="arenda-arochnye-ramki"] [data-nav-sub="arenda-arochnye-ramki"] {
  --nav-current: var(--scan-orange);
}

/* ==========================================================================
   Поиск по сайту

   Решение заказчика 12.09.2026, до запуска — ТЗ на редизайн, раздел 6.
   Три рабочие копии одной и той же функции, каждая своей видимостью:

     .nav__search        — строка меню, десктоп, обычное состояние
     .header__search     — прилипшая строка шапки, десктоп, is-stuck
     .header__search-mobile + .search-overlay — мобильный, до 768

   Видимость решает только CSS, разметка везде статична: показ и скрытие
   поведения — assets/js/ui.js, initSearch. Саму разметку полей печатают
   шаблоны компонента bitrix:search.form — introskop_field для строки
   и introskop_overlay для слоя.
   ========================================================================== */

/* Цвет в покое, при наведении и при нажатии — components.css, раздел 9,
   вместе с бургером, крестиком поиска и крестиком модальных окон: та же
   иконочная кнопка одного ряда. */
.search-toggle {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: var(--tap-min);
  height: var(--tap-min);
  padding: 0;
  background: none;
  border: 0;
  cursor: pointer;
}

.search-toggle[hidden] {
  display: none;
}

.search-toggle__icon {
  width: 20px;
  height: 20px;
}

/* Строка меню: иконка прижата к правому краю контейнера, после
   «Контактов» и до заливки --paper-alt, которая идёт во всю ширину
   окна. Скрыта на мобильном и в раскрытой панели прилипшего состояния —
   там же, где сама строка меню, только явно: [hidden] на display: none
   не полагается там, где правило конфликтует по специфичности. */
.nav__search {
  display: none;
  position: relative;
  align-items: center;
  margin-left: auto;
}

.header.is-menu-open .nav__search {
  display: none;
}

/* Прилипшая строка шапки: между кнопкой «Рассчитать стоимость»
   и гамбургером. Скрыта, пока шапка не схлопнулась, и всегда скрыта
   на мобильном — там место иконки занимает header__search-mobile. */
.header__search {
  display: none;
  position: relative;
  align-items: center;
}

@media (min-width: 768px) {
  .nav__search {
    display: flex;
  }

  .header.is-stuck .header__search {
    display: flex;
  }
}

/* Мобильная иконка — между телефоном и гамбургером (кнопка расчёта
   между ними скрыта на этой ширине, поэтому визуально они соседи).
   На десктопе не показывается ни в каком состоянии. */
.header__search-mobile {
  display: inline-flex;
}

@media (min-width: 768px) {
  .header__search-mobile {
    display: none;
  }
}

/* Поле — общая разметка для строки меню и прилипшей строки. Значок
   внутри статичный: заменяет собой иконку-кнопку, второго нажатия,
   чтобы его убрать, не нужно — сама кнопка на время разворота скрыта
   атрибутом hidden. */
.search-field[hidden] {
  display: none;
}

.search-field {
  position: relative;
}

/* Ширина. Правка 14.09.2026 по замечанию заказчика: поле было узким при
   свободном месте справа. Замер в браузере, окно 1440: в строке меню между
   «Контактами» и правым краем контейнера свободно 642 px при форме 320,
   то есть форма выдерживает до 934 px, не подходя к меню ближе 24 px.
   Взято 480 — дальше поле перестаёт читаться как элемент строки меню
   и начинает спорить с ней за внимание. Поле ввода внутри формы растёт
   с 222 px до 408. */
.search-form {
  position: relative;
  display: flex;
  align-items: center;
  gap: 0;
  width: clamp(200px, 34vw, 480px);
}

/* Прилипшая строка шапки теснее строки меню: в ней же логотип, дескриптор,
   телефон и кнопка расчёта, и места под поле остаётся заметно меньше.
   Замер 14.09.2026 двоичным поиском по ширине формы: горизонтальная
   прокрутка появляется за 347 px на окне 1280 и за 409 px на 1366 и шире
   (контейнер упирается в свои 1280 и дальше не растёт). Формула ниже
   держится под порогом на всех замеренных ширинах: 320 на 1280, 328
   на 1366, 346 на 1440, 384 на 1600 и шире. Нижняя граница 320 — прежняя
   ширина формы: уже неё прилипшая строка не становится ни на одной
   ширине. */
.header__search .search-form {
  width: clamp(320px, 24vw, 384px);
}

/* Значок в потоке, слева от поля. Правка 14.09.2026, круг 2: заказчик
   выбрал вариант 3 — подчёркивание вместо рамки, и абсолютное
   позиционирование значка поверх поля больше не нужно. Отступ
   margin-right держит зазор между значком и полем; зазор между полем
   и кнопкой снят отдельно — .search-form получил gap: 0. */
.search-form__icon {
  flex: none;
  width: 18px;
  height: 18px;
  margin-right: var(--space-8);
  color: var(--ink-60);
}

/* Подчёркивание вместо рамки. Правка 14.09.2026, круг 2 — заказчик
   посмотрел сравнение вариантов и выбрал вариант 3: поле-коробка
   коммита 2939136 снимается. Заодно снят зазор между полем и кнопкой
   «Найти» — второе требование того же решения, форма читается
   единым целым. У поля нет отдельного скругления и рамки по периметру,
   только .search-form__submit слева остаётся прямоугольной —
   правило ниже.

   padding-bottom: 1px в покое — компенсация под фокус: подчёркивание
   там толще на 1 px, и без запасного пикселя поле подрастало бы
   на эту разницу. Высота поля должна совпадать в обоих состояниях —
   замерено стендом и в отчёте задания. */
.search-form__input {
  width: 100%;
  min-height: var(--tap-min);
  padding-right: var(--space-12);
  padding-left: 0;
  padding-bottom: 1px;
  font: inherit;
  color: var(--ink);
  background: none;
  border: 0;
  border-bottom: var(--border-width) solid var(--line);
  border-radius: 0;
}

.search-form__input::placeholder {
  color: var(--ink-60);
  opacity: 0.75;
}

.search-form__input:hover {
  border-bottom-color: var(--ink-60);
}

.search-form__input:focus,
.search-form__input:focus-visible {
  outline: none;
  padding-bottom: 0;
  border-bottom-width: 2px;
  border-bottom-color: var(--scan-orange);
}

/* Кнопка «Найти», работа 1 задания estafeta-vid-poiska-bitrix-13092026.md.
   Модификатор оранжевой кнопки первого уровня .btn--primary — своего
   набора правил не заводим, только размер под три копии формы поиска.
   Образец кофемашина.онлайн даёт 64×40; здесь высота 44 — тот же довод,
   что уже есть у .btn--sm: заказчик задавал диапазон 40–44, а минимальная
   площадь нажатия 44×44 раздела 5 ТЗ на редизайн перевешивает образец.
   Ширина зафиксирована в 64 px: на неё рассчитан разворот поля в строке
   меню и в прилипшей строке шапки, стенды check-menu.py и check-search.py
   прототипа меряют высоту и ширину с этим числом. */
.search-form__submit {
  flex: none;
  width: 64px;
  min-height: 44px;
  padding-inline: 0;
  /* Левые углы прямые — стык с полем читается как единое целое,
     правка 14.09.2026, круг 2. Правые остаются скруглёнными,
     как у любой другой кнопки дизайн-системы. */
  border-radius: 0 var(--radius) var(--radius) 0;
}

/* Подсказки строки меню и прилипшей строки — плавающий список поверх
   контента, тем же приёмом, что выпадающий список «Аренды». На мобильном
   слое тот же класс раскладывается иначе — правило ниже. */
.search-hints {
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  z-index: 60;
  margin: 0;
  padding-block: var(--space-4);
  list-style: none;
  background-color: var(--paper);
  border: var(--border-width) solid var(--line);
  box-shadow: 0 8px 20px rgba(18, 22, 28, 0.12);
}

.search-hints[hidden] {
  display: none;
}

.search-hints__item {
  display: flex;
  align-items: center;
  width: 100%;
  min-height: var(--tap-min);
  padding-inline: var(--space-12);
  background: none;
  border: 0;
  font: inherit;
  text-align: left;
  color: var(--ink);
  cursor: pointer;
}

.search-hints__item:hover,
.search-hints__item:focus {
  background-color: var(--paper-alt);
  color: var(--scan-orange-hover);
}

/* «Все результаты» — последний пункт, работа 2 задания
   estafeta-vid-poiska-bitrix-13092026.md. Про действие «уйти на страницу
   результатов», а не про найденное — граница отделяет его от подсказок
   выше, а стрелка вправо у текста та же, что уводит на другую страницу
   по всему сайту (components.css, .btn__arrow): третьего стиля здесь
   не заводим, оба приёма уже есть в дизайн-системе. */
.search-hints__item--all {
  gap: var(--space-8);
  font-weight: var(--fw-medium);
  border-top: var(--border-width) solid var(--line);
}

/* Кегль поля и подсказок на десктопе. Правка 14.09.2026, замечание
   заказчика: текст в поле и в подсказках был крупен, особенно рядом
   со значком поиска в 18 px. Оба места набирались общим кеглем текста
   страницы — 17 px на десктопе; взята ступень ниже, --fs-small, то есть
   15 px. Значок остаётся 18 px.

   Условие на указатель, а не только на ширину: с 768 px начинается
   и планшет, а поле мельче 16 px iOS увеличивает масштабом при фокусе —
   тот же довод, что у токена --input-font-size. Мышь и трекпад дают
   pointer: fine, палец — coarse, и на планшете кегль остаётся прежним.
   Мобильный полноэкранный слой этой правкой не затронут: заказчик
   назвал его размер текста нормальным. */
@media (min-width: 768px) and (pointer: fine) {
  .search-form__input,
  .search-hints__item {
    font-size: var(--fs-small);
  }
}

/* Мобильный полноэкранный слой. Поверх контента, выше панели меню (45),
   ниже модальных окон (100): слой и модальные окна вместе не открываются,
   порядок нужен только на случай, если это когда-нибудь изменится. */
.search-overlay {
  position: fixed;
  inset: 0;
  z-index: 70;
  display: flex;
  flex-direction: column;
  background-color: var(--paper);
}

.search-overlay[hidden] {
  display: none;
}

.search-overlay__bar {
  display: flex;
  align-items: center;
  gap: var(--space-8);
  padding: var(--space-8) var(--container-pad);
  border-bottom: var(--border-width) solid var(--line);
}

.search-overlay .search-form {
  width: 100%;
}

/* На слое значка нет. Правка 14.09.2026, решение заказчика: поиск уже
   вызван его иконкой в шапке, второй такой же значок рядом с полем
   ничего не сообщает, а места на экране в 360 px занимает 26 px вместе
   с отступом. Замер круга 1: поле ввода 146 px было, 172 стало. Круг 2
   отдал полю ещё немного места — кнопка отмены сменилась словом
   на крестик, замер в отчёте задания. */
.search-overlay .search-form__icon {
  display: none;
}

.search-overlay .search-form__input {
  padding-left: var(--space-12);
}

/* Крестик вместо слова «Отмена» — решение заказчика 14.09.2026, круг 2:
   ради ширины поля на 360, та же цель нажатия, тот же знак, что
   у крестика модальных окон, только без своего класса — кнопка на слое
   не модальная. Слово «Отмена» в ТЗ на редизайн и в тексте была раньше —
   заказчик отменил требование прямо, вместе с выбором. Цвет в покое
   и под курсором, размер значка — components.css, раздел 9, «Крестик
   закрытия — один вид на весь сайт». */
.search-overlay__cancel {
  flex: none;
  width: 44px;
  min-height: var(--tap-min);
  padding-inline: 0;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: none;
  border: 0;
  cursor: pointer;
}

/* На слое список — не плавающая панель, а часть потока во всю ширину:
   строка ниже поля, как задано разделом 6 ТЗ на редизайн. */
.search-overlay .search-hints {
  position: static;
  flex: 1 1 auto;
  overflow-y: auto;
  margin: 0;
  padding-block: 0;
  border: 0;
  box-shadow: none;
}

.search-overlay .search-hints__item {
  padding-inline: var(--container-pad);
  border-bottom: var(--border-width) solid var(--line);
}

/* Подсказка — ссылка на найденную страницу, а не кнопка, дописывающая запрос:
   у штатного поиска адрес найденного есть, у мока прототипа его не было.
   Правило снимает подчёркивание и наследование цвета ссылки, всё остальное
   у пункта прежнее. Подсветку совпадения ядро отдаёт тегом <b>, своего
   правила ему не нужно. */
.search-hints__item {
  text-decoration: none;
}

/* ==========================================================================
   Хлебные крошки

   Полоса под шапкой, над первым блоком страницы. Своего фона у неё нет:
   она стоит на фоне страницы, и на белом первом экране, и на серой
   каталожной шапке одинаково. Границ и линий тоже нет — под шапкой уже
   есть одна, вторая в трёх пикселях от неё читалась бы как рамка.

   Отступ сверху и снизу — одинарный шаг шкалы, 8 px. Тот же счёт, что
   в перечне под схемой тоннеля, где 24 названы тройным шагом против
   одинарных 8.

   Высота нажатия у звеньев — 44 px, как у всех остальных ссылок сайта.
   Полоса от этого выходит выше самих букв, и это осознанно: ниже 768
   единственное звено цепочки — это кнопка «назад», и мелкой целью ей
   быть нельзя. Выводить её из-под правила исключением в стенде было бы
   дешевле и хуже.

   Стрелок в цепочке нет — именное исключение из правила «навигационная
   ссылка со стрелкой вправо», решение 27.08.2026. Стрелка появляется
   ровно одна и только ниже 768, влево: там звено означает возврат
   на уровень выше.
   ========================================================================== */

.crumbs {
  padding-block: var(--space-8);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

/* Перенос разрешён: на узком десктопе длинное название модели уводит
   цепочку на вторую строку, и это лучше, чем горизонтальная прокрутка
   или обрезка звена многоточием. */
.crumbs__inner {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  column-gap: var(--space-8);
}

.crumbs__link {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  color: inherit;
  text-decoration: none;
}

.crumbs__link:hover {
  color: var(--scan-orange-hover);
}

.crumbs__link:focus-visible {
  outline: var(--focus-width) solid var(--ink);
  outline-offset: var(--focus-offset);
}

/* Текущая страница ссылкой не притворяется: тот же серый, тот же кегль,
   без подчёркивания и без реакции на курсор. */
.crumbs__current {
  color: var(--ink-60);
}

/* Разделитель и текущее звено — одного цвета с цепочкой: выделять
   косую черту нечем и незачем. */
.crumbs__sep {
  color: var(--ink-60);
}

/* --- Ниже 768: одно звено вместо цепочки --------------------------------

   Показывается родительское звено, то есть последняя ссылка цепочки:
   на карточке товара это «Каталог», на пяти посадочных — «Аренда»,
   на остальных страницах — «Главная». Второй копии в разметке для этого
   не заводится: отбор делает селектор, и цепочка остаётся одна на все
   ширины.

   Правило по брейкпоинту, а не по факту переполнения. Замер 27.08.2026
   на 360: из десяти цепочек в строку не помещаются четыре — «Объекты
   на срок контракта», «Подмена на время ремонта», «Арочные
   металлодетекторы» и карточка товара с длинным названием модели;
   остальные шесть влезают. Свернуть только переполненные значило бы
   получить навигацию, которая на одной странице цепочка, а на соседней
   стрелка назад, — и это читается как сбой, а не как забота о месте.
   Поэтому ниже 768 звено одно всегда.

   Стрелка влево — псевдоэлементом, а не узлом разметки: на широком
   экране её нет вовсе, и в разметке ей там делать нечего. В скопированный
   текст она не попадает. Пустая замещающая строка после косой черты
   убирает её из озвучки: смысл «на уровень выше» несёт сама ссылка,
   а «стрелка влево» в этом месте — шум. */

@media (max-width: 767.98px) {
  .crumbs__link,
  .crumbs__sep,
  .crumbs__current {
    display: none;
  }

  .crumbs__link:last-of-type {
    display: inline-flex;
    gap: var(--space-8);
  }

  .crumbs__link:last-of-type::before {
    content: '\2190' / '';
  }
}

/* ==========================================================================
   Страница-заглушка
   H1 и строка о состоянии. Больше на заглушке ничего нет: содержимое
   приходит шагами 9 и 10, и всё собранное сверх этого там же
   и переделывалось бы.
   ========================================================================== */

.stub__note {
  margin-top: var(--space-16);
  color: var(--ink-60);
}

/* ==========================================================================
   Блок 1. Первый экран

   Две колонки на светлом фоне: слева текст, справа фотография без
   затемнения — правка 8.1 пункт 7 ТЗ на прототип. Пропорция 7 к 5.
   На мобильном сначала текст, потом снимок: человек сначала читает,
   что предлагается, и только потом видит подтверждение.

   Тёмным этот блок больше не является, поэтому единственным тёмным
   блоком страницы становится схема «Зона досмотра».
   ========================================================================== */

.hero {
  background-color: var(--paper);
  color: var(--ink);
}

.hero__inner {
  display: grid;
  gap: var(--space-32);
  padding-block: var(--space-32) var(--space-48);
}

/* Колонка не должна раздуваться под самое длинное слово: у элементов
   сетки min-width по умолчанию равен содержимому. */
.hero__text {
  min-width: 0;
}

/* «металлодетекторов» при 32 px шире экрана в 320 px. Переносим по слогам,
   разрыв посреди слова оставлен на крайний случай. С 768 переносы
   выключаются: место есть, а дефис в крупном заголовке читается
   как типографская ошибка. */
.hero h1 {
  hyphens: auto;
  overflow-wrap: break-word;
}

/* Подводка первого экрана. На главной и хабе она — голый <p> включаемой
   области (условие 9 задания В): у главной обёртка .hero__lead, у хаба
   .hero__intro — там в той же области ещё и маркеры, и предел строки обёртки
   сжал бы их ряд. На посадочных — p.hero__lead из свойства элемента. */
.hero__lead,
.hero__intro p {
  margin-top: var(--space-16);
  max-width: 60ch;
  font-size: 17px;
}

/* Маркеры. Разделителей между пунктами нет: при переносе строки такой
   разделитель повисает в её начале. Вместо него у каждого пункта
   одинаковый квадратный буллет — висеть нечему ни на одной ширине. */
/* Список маркеров с квадратной меткой. Живёт на первом экране хаба
   и в кратком блоке аренды на главной — поэтому вынесен из .hero__*
   в самостоятельный класс. Отступ сверху задаёт тот, кто его ставит.
   На главной список — голый <ul> включаемой области: классов в файле области
   нет (условие 9 задания В), вид ему даёт колонка .promo__text.
   На хабе так же — обёртка .hero__intro первого экрана. */
.markers,
.hero__markers,
.hero__intro ul,
.promo__text ul {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  font-size: var(--fs-small);
  color: var(--ink);
}

.hero__markers,
.hero__intro ul {
  margin-top: var(--space-24);
}

.markers li,
.hero__markers li,
.hero__intro li,
.promo__text li {
  display: flex;
  align-items: baseline;
  gap: var(--space-8);
}

.markers li::before,
.hero__markers li::before,
.hero__intro li::before,
.promo__text li::before {
  content: '';
  flex: none;
  width: 4px;
  height: 4px;
  background-color: var(--scan-orange);
  transform: translateY(-3px);
}

.hero__actions {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  margin-top: var(--space-32);
}

.hero__actions .btn {
  width: 100%;
}

.hero__contact {
  display: flex;
  flex-direction: column;
  gap: var(--space-4);
  margin-top: var(--space-24);
}

.hero__phone {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  min-height: var(--tap-min);
  font-family: var(--font-mono);
  font-size: 24px;
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
}

.hero__phone:hover {
  color: var(--scan-orange);
}

.hero__phone-note {
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.hero__media {
  margin: 0;
}

.hero__photo {
  width: 100%;
  height: clamp(220px, 58vw, 340px);
  object-fit: cover;
  object-position: center 62%;
  border-radius: var(--radius);
}

@media (min-width: 768px) {
  .hero__inner {
    grid-template-columns: 7fr 5fr;
    gap: var(--space-48);
    align-items: stretch;
    padding-block: var(--space-64);
  }

  /* На планшете H1 живёт в колонке шириной 7 из 12 и при 48 px рвётся
     на пять строк. Правка только для первого экрана: шкала документа
     не меняется, других H1 на странице нет. */
  .hero h1 {
    font-size: 40px;
    hyphens: manual;
  }

  .hero__lead,
  .hero__intro p {
    margin-top: var(--space-24);
    font-size: 19px;
  }

  .markers,
  .hero__markers,
  .hero__intro ul,
  .promo__text ul {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-8) var(--space-24);
  }

  .hero__markers,
  .hero__intro ul {
    margin-top: var(--space-32);
  }

  .hero__actions {
    flex-direction: row;
    flex-wrap: wrap;
    gap: var(--space-16);
    margin-top: var(--space-48);
  }

  .hero__actions .btn {
    width: auto;
  }

  /* Телефон и подпись остаются столбиком и на широком экране: в строку
     подпись читалась как случайная приписка справа. */
  .hero__contact {
    margin-top: var(--space-32);
  }

  .hero__phone {
    font-size: 28px;
  }

  /* Высота снимка равна высоте текстовой колонки. Картинку кладём
     абсолютно: иначе её собственная высота начинает управлять строкой
     сетки, и колонки перестают совпадать. */
  .hero__media {
    position: relative;
    min-height: 380px;
  }

  .hero__photo {
    position: absolute;
    inset: 0;
    height: 100%;
    border-radius: var(--radius);
  }
}

/* ==========================================================================
   Главная. Блоки, которых нет на других страницах: два направления
   на первом экране, краткий блок с кнопкой сбоку, плитки разделов
   каталога, встроенная форма быстрого вопроса.
   ========================================================================== */

/* --- Два направления ---------------------------------------------------
   Кнопка и подпись под ней. На мобильном одна колонка, с 768 — две:
   пути равны по важности как выбор, но не по оформлению — аренда
   основной кнопкой, продажа вторичной. */

.paths {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
  margin-top: var(--space-32);
}

.path {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
}

.path .btn {
  width: 100%;
}

.path__note {
  font-size: var(--fs-small);
  color: var(--ink-60);
  line-height: var(--lh-text);
}

/* --- Краткий блок с кнопкой сбоку ---------------------------------------
   Используется дважды: аренда и сервис. Текст слева, действие справа,
   на мобильном друг под другом. */

.promo {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
  align-items: start;
}

.promo__text ul {
  margin-top: var(--space-24);
}

.promo__actions {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-12);
}

.promo__actions .btn {
  width: 100%;
}

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

.cats {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-16);
  /* Категорий две, и во всю ширину контейнера снимок вырастает до 470 px —
     блок начинает весить как первый экран. Ширина ограничена по строке
     текста над ним. */
  max-width: 860px;
  margin-top: var(--space-32);
}

.cat {
  display: flex;
  flex-direction: column;
  border: var(--border-width) solid var(--line);
  color: inherit;
  text-decoration: none;
  transition: border-color var(--motion-duration) var(--motion-easing);
}

.cat:hover {
  border-color: var(--ink);
  color: inherit;
}

.cat:focus-visible {
  outline: var(--focus-width) solid var(--ink);
  outline-offset: var(--focus-offset);
}

.cat__media {
  display: block;
  aspect-ratio: var(--card-ratio);
  background-color: var(--paper);
  overflow: hidden;
}

.cat__img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  padding: var(--space-16);
}

.cat__title {
  padding: var(--space-16);
  border-top: var(--border-width) solid var(--line);
  font-family: var(--font-heading);
  font-size: var(--fs-h3);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-heading);
}

.cat:hover .cat__title {
  text-decoration: underline;
  text-underline-offset: 0.15em;
  text-decoration-thickness: 1px;
}

.cats__footer {
  margin-top: var(--space-32);
}

/* --- Быстрый вопрос -----------------------------------------------------
   Три поля, поэтому форма стоит прямо на странице, а не в модальном окне.
   Различие с брифом осознанное: длинный бриф в модалке, короткая форма
   на странице. Ширина ограничена: поля во всю ширину контейнера
   выглядят как анкета, а не как три вопроса. */

/* Две трети — форма, треть — фотография. Форму на всю ширину не тянем:
   поле ввода шириной в полэкрана читается хуже и выглядит неопрятно.
   Правую треть занимает снимок — тем же приёмом, что в блоке-призыве
   на хабе. */
.quick {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-32);
}

.quick__media {
  margin: 0;
}

.quick__photo {
  width: 100%;
  height: clamp(220px, 58vw, 340px);
  object-fit: cover;
  border-radius: var(--radius);
}

.quick__form {
  margin-top: var(--space-32);
}

.quick__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-16);
}

/* Расстояние между полями задаёт сетка. Отступ .field + .field пришёл бы
   вторым слагаемым и сдвинул бы вторую колонку вниз относительно первой. */
.quick__grid .field + .field {
  margin-top: 0;
}

.quick__footer {
  margin-top: var(--space-24);
}

/* Подтверждение вопроса на месте формы — тексты v30, раздел 9. Встаёт туда,
   где стояла форма, с тем же отступом от вводного текста. */
.quick__done {
  margin-top: var(--space-32);
}

.quick__done-title {
  margin: 0 0 var(--space-12);
}

.quick__done p {
  margin: 0 0 var(--space-8);
}

.quick__done:focus {
  outline: none;
}

.quick__footer .btn {
  width: 100%;
  margin-top: var(--space-16);
}

.quick__below {
  margin-top: var(--space-12);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

@media (min-width: 768px) {
  .paths {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .promo {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--space-48);
    align-items: center;
  }

  .promo__actions .btn {
    width: auto;
    white-space: nowrap;
  }

  .cats {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Форма и снимок: 2 к 1. Согласие и кнопка лежат внутри формы, поэтому
     под снимок не подтекают — они ограничены левой колонкой. */
  .quick {
    grid-template-columns: 2fr 1fr;
    gap: var(--space-48);
    align-items: stretch;
  }

  /* Снимок кладём абсолютно: иначе его собственная высота начинает
     управлять строкой сетки, и колонки перестают совпадать. */
  .quick__media {
    position: relative;
  }

  .quick__photo {
    position: absolute;
    inset: 0;
    height: 100%;
  }

  /* Слева «Имя», «Телефон» и «Почта» друг под другом, справа «Вопрос»
     во всю высоту всех трёх: короткие поля во всю ширину оставляли справа
     пустое место, а вопрос — единственное поле, которому высота
     действительно нужна. Почта встала третьей 10.09.2026 — решение
     заказчика, почта обязательна во всех формах. */
  .quick__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .quick__grid .field--wide {
    grid-column: 2;
    grid-row: 1 / span 3;
    display: flex;
    flex-direction: column;
  }

  /* Поле тянется до низа колонки. min-height остаётся нижней границей:
     если слева окажется меньше трёх полей, вопрос не схлопнется. */
  .quick__grid .field--wide .field__control {
    flex: 1;
  }

  .quick__footer .btn {
    width: auto;
  }
}

/* ==========================================================================
   Блок 2. Выбор сценария — вся плитка кликабельна.
   Плитки: 1 в ряд → 2 → 4.
   ========================================================================== */

.tiles {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-16);
  margin-top: var(--space-24);
}

.tile {
  display: flex;
  flex-direction: column;
  gap: var(--space-12);
  padding: var(--space-24);
  border: var(--border-width) solid var(--line);
  background-color: var(--paper);
  color: var(--ink);
  text-decoration: none;
  transition: border-color var(--motion-duration) var(--motion-easing);
}

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

.tile__icon {
  width: 32px;
  height: 32px;
  color: var(--scan-orange);
}

.tile__title {
  font-family: var(--font-heading);
  font-size: var(--fs-h3);
  font-weight: var(--fw-semibold);
  line-height: var(--lh-heading);
}

.tile__note {
  font-size: var(--fs-small);
  color: var(--ink-60);
  margin-top: auto;
}

@media (min-width: 768px) {
  .tiles {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--grid-gap);
    margin-top: var(--space-32);
  }
}

@media (min-width: 1280px) {
  .header__inner {
    gap: var(--space-24);
  }

  .header__tagline {
    max-width: none;
    font-size: var(--fs-small);
    white-space: nowrap;
  }
}

@media (min-width: 1280px) {
  .hero h1 {
    font-size: var(--fs-h1);
  }

  .tiles {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* ==========================================================================
   Блок 3. Что входит — 1 в ряд → 2 → 3
   ========================================================================== */

.features {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-32);
  margin-top: var(--space-32);
}

.feature__icon {
  width: 28px;
  height: 28px;
  color: var(--scan-orange);
  margin-bottom: var(--space-12);
}

.feature p {
  max-width: 42ch;
}

.feature__title {
  font-weight: var(--fw-medium);
}

@media (min-width: 768px) {
  .features {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-48) var(--grid-gap);
    margin-top: var(--space-48);
  }

  .feature__icon {
    margin-bottom: var(--space-16);
  }
}

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

/* --- Сокращённая раскладка для посадочной ---------------------------------
   Те же шесть пунктов и тот же источник данных, что на хабе, — сокращается
   раскладка, а не содержание. Правка 29.08.2026: блок стоит вторым, сразу
   за первым экраном, и до цены человек должен успеть его прочитать.

   Что меняется. Знак встаёт в строку слева от текста, а не отдельной
   строкой над ним: пункт перестаёт занимать три строки — знак, заголовок,
   текст — и укладывается в заголовок и текст. Колонок две вместо трёх:
   строка становится длиннее, и текст пункта чаще ложится в две строки,
   а не в три. Шаг между рядами обычный, а не отбивка между блоками.

   Полная раскладка на хабе не трогается: там блок стоит третьим, места
   в нём достаточно, и знаки над текстом читаются как перечень значков. */

.features--compact {
  gap: var(--space-24);
  margin-top: var(--space-24);
}

.features--compact .feature {
  display: flex;
  align-items: flex-start;
  gap: var(--space-12);
}

.features--compact .feature__icon {
  width: 22px;
  height: 22px;
  margin-bottom: 0;
  /* Знак смотрит на первую строку текста, а не на середину пункта:
     у пунктов разная высота, и по центру он гулял бы от строки к строке. */
  margin-top: 2px;
}

/* Ограничение в 42 знака здесь мешает: оно рассчитано на узкую колонку
   из трёх, а в двух колонках оставляет справа пустую полосу. Ширину
   строки держит общее правило для <p> — не более 72 знаков. */
.features--compact .feature p {
  max-width: none;
}

@media (min-width: 768px) {
  .features--compact {
    gap: var(--space-32) var(--grid-gap);
    margin-top: var(--space-32);
  }

  .features--compact .feature__icon {
    margin-bottom: 0;
  }
}

@media (min-width: 1280px) {
  .features--compact {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }
}

/* ==========================================================================
   Блок 4. Стоимость
   ========================================================================== */

.pricing__intro {
  margin-top: var(--space-16);
}

/* Ориентиры: без фиксированной минимальной высоты, цена сразу под заголовком.
   Правка 8.1.4 ТЗ на прототип. */
.benchmarks {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-12);
  margin-top: var(--space-24);
}

.benchmark {
  padding: var(--space-16) var(--space-24);
  background-color: var(--paper-alt);
  border-left: var(--accent-bar) solid var(--scan-orange);
}

.benchmark__label {
  font-size: var(--fs-small);
  color: var(--ink-60);
}

/* Цены-ориентиры набраны основным цветом, а не акцентным. Акцент в этом
   блоке один и стоит в таблице на строке «30 дней»: блок существует ради
   аргумента «чем длиннее срок, тем дешевле сутки», а оранжевые ориентиры
   притягивали взгляд к самым дорогим числам страницы. */
.benchmark__value {
  display: block;
  margin-top: var(--space-4);
  font-family: var(--font-mono);
  font-size: var(--fs-mono-price);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  color: var(--ink);
}

/* Ориентир без числа. У рамки доставки в прайсе нет — вместо суммы
   стоит строка «считается отдельно», а это проза, и моноширинным она
   набираться не должна: правило проекта — моноширинный только
   для числовых данных. Кегль остаётся ориентирным: строка занимает
   то же место в блоке, что сумма у соседа. */
.benchmark--text .benchmark__value {
  font-family: var(--font-text);
  font-size: var(--fs-h3);
  letter-spacing: normal;
}

.benchmark__note {
  font-family: var(--font-text);
  font-size: var(--fs-small);
  font-weight: var(--fw-regular);
  color: var(--ink-60);
  letter-spacing: normal;
}

.pricing__table-title {
  margin-top: var(--space-48);
}

.pricing__table-note {
  margin-top: var(--space-8);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

/* Таблица и график стоят рядом только на десктопе: на планшете колонка
   под график получается уже 300 px, и подписи под столбцами сливаются. */
.pricing__rates {
  display: grid;
  gap: var(--space-32);
}

/* Светлый график, не сигнатурный блок: тёмный на странице один — схема. */
.rate-chart {
  margin: 0;
}

/* Оформление то же, что у заголовков колонок таблицы */
.rate-chart__caption {
  margin-bottom: var(--space-12);
  font-size: var(--fs-small);
  font-weight: var(--fw-medium);
  color: var(--ink-60);
}

.rate-chart__svg {
  display: block;
  width: 100%;
  max-width: 420px;
  height: auto;
}

.rate-chart__base {
  stroke: var(--line);
  stroke-width: 1;
}

.rate-chart__bar {
  fill: var(--ink-60);
}

/* Последний столбец акцентный: тот же довод, что выделен в таблице */
.rate-chart__bar--accent {
  fill: var(--scan-orange);
}

.rate-chart__term,
.rate-chart__value {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-size: 13px;
  text-anchor: middle;
}

.rate-chart__term {
  fill: var(--ink-60);
}

.rate-chart__value {
  fill: var(--ink);
  font-weight: var(--fw-medium);
}

.rate-chart__value--accent {
  fill: var(--scan-orange);
}

@media (min-width: 1280px) {
  .pricing__rates {
    grid-template-columns: minmax(0, 1fr) minmax(0, 400px);
    gap: var(--space-48);
    align-items: start;
  }

  .rate-chart__svg {
    max-width: none;
  }
}

/* Таблица уже контейнера не станет: она уезжает в горизонтальный скролл
   внутри .table-scroll, первая колонка при этом остаётся на месте. */
.pricing__table-wrap {
  margin-top: var(--space-24);
  max-width: 760px;
}

/* Абзац, под ним кнопка, под кнопкой её микрокопия — колонкой, всё
   по левому краю. Кнопка встаёт на линию чтения: взгляд идёт по левому
   краю сверху вниз и упирается в неё сразу после абзаца, который её
   объясняет.

   История. До 05.09.2026 у блока стояло max-width: 760px, кнопка вставала
   на 62% ширины, а справа от неё оставалась пустая треть — она читалась
   недоделкой. Ограничение сняли, кнопку прижали к правому краю. На
   просмотре 04.09.2026 выяснилось, что там она теряется: справа над ней
   график, слева таблица, и кнопка попадает в правый нижний угол блока,
   куда взгляд при беглом просмотре не доходит. Кнопка перенесена влево
   под абзац; ограничение ширины при этом не возвращается — блок остаётся
   во всю ширину контейнера, ширину текста держит общее правило
   p { max-width: var(--measure) } из base.css.

   Блок «Тест-драйв» на карточке при этом остаётся с кнопкой у правого
   края — решение заказчика 04.09.2026: там блок из двух элементов,
   кнопка обособлена и берётся взглядом сразу, а одинаковое положение
   двух разных кнопок на одной странице стёрло бы различие между ними. */
.pricing__below {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-16);
  margin-top: var(--space-24);
}

/* Абзац про прайс — голый <p> общей включаемой области (условие 9 задания В):
   кегль и цвет даёт обёртка, абзац их наследует. До 11.09.2026 правило
   стояло на самом абзаце, `.pricing__below > p`. */
.pricing__below-text {
  font-size: var(--fs-small);
  color: var(--ink-60);
}

/* Кнопка прайса со своей микрокопией. Группой, а не двумя элементами
   блока: зазор блока отодвинул бы подпись от кнопки дальше, чем
   от абзаца слева, и она читалась бы продолжением абзаца. */
.pricing__action {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-8);
}

.pricing__cta-note {
  margin: 0;
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.pricing__factors-title {
  margin-top: var(--space-48);
}

/* Факторы — перечень, а не последовательность. Нумерации нет.
   Правка 8.1.3 ТЗ на прототип. */
.factors {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
  margin-top: var(--space-24);
}

.factor {
  padding-top: var(--space-16);
  border-top: var(--border-width) solid var(--line);
}

/* Контейнер для пунктов под сеткой, на всю ширину. Сейчас на хабе все восемь
   пунктов в одной сетке, и признак WIDE в данных не стоит ни у одного (решение
   заказчика 07.10.2026; до него под сеткой стояло «Рабочее место оператора» —
   с 29.08.2026). Механизм оставлен: он управляется данными, и пункт с WIDE
   по-прежнему уйдёт под сетку на всю ширину. Шаблон пустую группу не выводит,
   правило :empty — паритет с прототипом.

   Пустой контейнер места не занимает: без display: none его margin-top
   оставил бы под сеткой лишние 24 px (32 с 768). */
.factors--wide {
  grid-template-columns: minmax(0, 1fr);
}

.factors--wide:empty {
  display: none;
}

.factor__title {
  font-weight: var(--fw-medium);
}

@media (min-width: 768px) {
  /* Три ориентира в ряд помещаются только на десктопе: на планшете
     колонка получается 218 px, и приписка «/сутки» отрывается от цены. */
  .benchmarks {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--grid-gap);
    margin-top: var(--space-32);
  }

  .benchmark {
    padding: var(--space-24);
  }

  .pricing__table-title,
  .pricing__factors-title {
    margin-top: var(--space-64);
  }

  /* Строкой блок больше не идёт: с 768 он остаётся колонкой, и меняется
     только выравнивание. Ниже 768 элементы растянуты — кнопка там во всю
     ширину, — а с 768 каждый занимает свою ширину и стоит по левому краю.
     Задание 04.09.2026, раздел 1. */
  .pricing__below {
    align-items: flex-start;
  }

  /* Подпись держится под кнопкой и не растягивается на всю строку:
     на 72 знака она ушла бы от кнопки вправо и читалась бы отдельным
     абзацем, а не подписью к ней. */
  .pricing__action {
    align-items: flex-start;
    max-width: 320px;
  }

  .factors {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-32) var(--grid-gap);
  }

  /* Отступ сверху идёт за шагом между рядами сетки: на 768 он больше.
     Колонку приходится задавать заново: у правила выше та же
     специфичность, и медиазапрос его перебивает. */
  .factors--wide {
    grid-template-columns: minmax(0, 1fr);
    margin-top: var(--space-32);
  }
}

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

  /* Широкий пункт колонок не набирает ни на одной ширине: он и вынесен
     из сетки ради того, чтобы занять её целиком. */
  .factors--wide {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ==========================================================================
   Блок 5. Оборудование — карточки 1 → 2 → 3
   ========================================================================== */

.equipment__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-16);
  margin-top: var(--space-24);
}

.equipment__note {
  margin-top: var(--space-32);
}

@media (min-width: 768px) {
  .equipment__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--grid-gap);
    margin-top: var(--space-32);
  }
}

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

  /* Блок продажи на главной: карточек четыре, и в сетке на три колонки
     четвёртая оставалась сиротой во втором ряду. Здесь они в один ряд. */
  .equipment__grid--four {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* ==========================================================================
   Блок 6. Как проходит аренда — нумерация обязательна. 1 → 2 → 3
   ========================================================================== */

.steps {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
  margin-top: var(--space-32);
  counter-reset: step;
}

.step {
  padding-top: var(--space-16);
  border-top: 2px solid var(--ink);
}

.step__num {
  display: block;
  font-family: var(--font-mono);
  font-size: var(--fs-mono-price);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  color: var(--scan-orange);
  margin-bottom: var(--space-8);
}

.step__title {
  font-weight: var(--fw-medium);
}

.step p {
  max-width: 42ch;
}

@media (min-width: 768px) {
  .steps {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-48) var(--grid-gap);
    margin-top: var(--space-48);
  }
}

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

/* ==========================================================================
   Блок 7. Почему мы — без иконок.
   Три колонки только на десктопе: тексты длинные, в половине ширины
   планшета они рвутся на слишком узкие столбцы.
   ========================================================================== */

.advantages {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-32);
  margin-top: var(--space-32);
}

.advantage h3 {
  margin-bottom: var(--space-12);
}

.advantage p {
  max-width: var(--measure);
}

@media (min-width: 768px) {
  .advantages {
    gap: var(--space-48);
    margin-top: var(--space-48);
  }
}

@media (min-width: 1280px) {
  .advantages {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--grid-gap);
  }

  .advantage p {
    max-width: none;
  }
}

/* ==========================================================================
   Блок 8. Галерея — подписи видны без открытия снимка. 1 → 2 → 3
   ========================================================================== */

.gallery {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
  margin-top: var(--space-32);
}

.gallery__item {
  margin: 0;
  cursor: zoom-in;
}

.gallery__media {
  aspect-ratio: var(--frame-ratio, 3 / 2);
  overflow: hidden;
  background-color: var(--paper-alt);
  border: var(--border-width) solid var(--line);
  transition: border-color var(--motion-duration) var(--motion-easing);
}

.gallery__item:hover .gallery__media {
  border-color: var(--ink);
}

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

.gallery__caption {
  margin-top: var(--space-12);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

/* С 768 кадры снова приводятся к общей рамке: ряд разновысоких плиток
   на широком экране рассыпается, а окно там и так вчетверо крупнее превью.
   На мобильном рамка берёт пропорцию самого кадра — обрезанное превью
   оказывалось выше того, что открывается в окне на всю ширину экрана. */
@media (min-width: 768px) {
  .gallery__media {
    aspect-ratio: 3 / 2;
  }

}

@media (min-width: 768px) {
  .gallery {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-32) var(--grid-gap);
    margin-top: var(--space-48);
  }
}

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

/* ==========================================================================
   Блок 9. FAQ
   ========================================================================== */

/* Аккордеон и врезка. Две колонки с 768: правая треть блока иначе остаётся
   пустой на всю его высоту, а это самый высокий блок страницы. */
.faq {
  display: grid;
  gap: var(--space-32);
}

.faq-aside {
  padding: var(--space-24);
  background-color: var(--paper);
  border: var(--border-width) solid var(--line);
}

.faq-aside__text {
  margin-top: var(--space-8);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

/* Начертание то же, что у телефона в блоке-призыве */
.faq-aside__phone {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  margin-top: var(--space-16);
  font-family: var(--font-mono);
  font-size: var(--fs-mono-price);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
}

.faq-aside__phone:hover {
  color: var(--scan-orange);
}

.faq-aside__cta {
  width: 100%;
  margin-top: var(--space-16);
}

@media (min-width: 768px) {
  .faq {
    grid-template-columns: minmax(0, 1fr) 260px;
    gap: var(--space-32);
    align-items: start;
  }

  /* Липнет к верху под шапкой: 72 px её высоты плюс отступ */
  .faq-aside {
    position: sticky;
    top: var(--space-96);
  }
}

@media (min-width: 1280px) {
  .faq {
    grid-template-columns: minmax(0, 1fr) 340px;
    gap: var(--space-48);
  }
}

.faq__list {
  margin-top: var(--space-24);
  max-width: 820px;
}

@media (min-width: 768px) {
  .faq__list {
    margin-top: var(--space-32);
  }
}

/* ==========================================================================
   Блок 10. Призыв к расчёту
   Полей в блоке нет: форма-бриф существует в единственном экземпляре и
   живёт в модальном окне — ТЗ на прототип, 8.1 пункт 11. Предупреждение
   о том, что это не калькулятор, читается здесь, до открытия формы.

   Форма ниже верстается одинаково и для окна, и для инлайн-режима:
   в каком месте она окажется, решает form.mode в data/arenda.json.
   Размер шрифта в полях задан токеном --input-font-size и не опускается
   ниже 16 px: иначе iOS зумит при фокусе.
   ========================================================================== */

.brief-cta__warning {
  margin-top: var(--space-24);
}

.brief-cta__actions {
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: var(--space-16);
  margin-top: var(--space-24);
}

.brief-cta__phone {
  display: inline-flex;
  align-items: center;
  align-self: flex-start;
  min-height: var(--tap-min);
  font-family: var(--font-mono);
  font-size: var(--fs-mono-price);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
}

.brief-cta__phone:hover {
  color: var(--scan-orange);
}

.brief-cta__note {
  display: block;
  font-size: var(--fs-small);
  color: var(--ink-60);
}

/* В инлайн-режиме открывать нечего: форма уже в блоке */
[data-form-mode="inline"] .brief-cta__cta {
  display: none;
}

.brief {
  max-width: 820px;
}

/* Блок-призыв: текст и кнопка слева, фотография справа. Пропорция и радиус
   те же, что у первого экрана. На мобильном снимок уходит под кнопку. */
.brief-cta {
  display: grid;
  gap: var(--space-32);
}

.brief-cta__text {
  max-width: var(--measure);
}

.brief-cta__media {
  margin: 0;
}

.brief-cta__photo {
  width: 100%;
  height: clamp(220px, 58vw, 340px);
  object-fit: cover;
  /* Кадр вертикальный, в широкой колонке видна только полоса: держим
     в ней монитор и пульт — ради них снимок и выбран. */
  object-position: center 15%;
  border-radius: var(--radius);
}

@media (min-width: 768px) {
  .brief-cta {
    grid-template-columns: 7fr 5fr;
    gap: var(--space-48);
    align-items: stretch;
  }

  /* Снимок кладём абсолютно, чтобы его собственная высота не управляла
     строкой сетки, — так же, как на первом экране. */
  .brief-cta__media {
    position: relative;
    min-height: 320px;
  }

  .brief-cta__photo {
    position: absolute;
    inset: 0;
    height: 100%;
  }
}

.brief__form {
  margin-top: var(--space-24);
}

/* Поля встают в порядке разметки, без dense: место поля модели по сценарию
   меняет forms.js переносом узла, и порядок Tab совпадает с видимым. */
.brief__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-16);
}

.brief__grid .field + .field {
  margin-top: 0;
}

.brief__grid .field--wide {
  grid-column: 1 / -1;
}

/* Граница между обязательным и необязательным: строка «ниже — по желанию»
   под полем «Почта» — с 10.09.2026. Во всю ширину, мелким кеглем. Отступ сверху
   меньше, чем зазор сетки: строка относится к тому, что под ней, и жмётся
   к следующим полям, а не висит посередине. Задание 04.09.2026, раздел 3.5. */
.brief__optional {
  grid-column: 1 / -1;
  margin: 0;
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.brief__footer {
  margin-top: var(--space-24);
}

.brief__footer .btn {
  width: 100%;
}

.brief-cta__actions .btn {
  width: 100%;
}

.brief__below {
  margin-top: var(--space-12);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

@media (min-width: 768px) {
  .brief-cta__actions {
    flex-direction: row;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-32);
    margin-top: var(--space-32);
  }

  .brief-cta__actions .btn {
    width: auto;
  }

  .brief__form {
    margin-top: var(--space-32);
  }

  .brief__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-24);
  }

  .brief__footer {
    margin-top: var(--space-32);
  }

  .brief__footer .btn {
    width: auto;
  }
}

/* ==========================================================================
   Блок 11. Контакты — тёмный подвал. 1 → 2 → 3 колонки
   ========================================================================== */

.footer {
  background-color: var(--ink);
  color: var(--ink-on-dark);
  padding-block: var(--space-48);
}

.footer h2 {
  color: var(--ink-on-dark);
}

.footer__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
  margin-top: var(--space-24);
}

.footer__label {
  font-size: var(--fs-small);
  color: var(--ink-60-on-dark);
  margin-bottom: var(--space-4);
}

.footer__value {
  font-family: var(--font-mono);
  font-size: 20px;
  font-variant-numeric: tabular-nums;
  color: var(--ink-on-dark);
  text-decoration: none;
}

/* Телефон, почта и мессенджер в подвале — ссылки: площадь нажатия 44 px */
a.footer__value {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
}

a.footer__value:hover {
  color: var(--scan-orange);
}

.footer__value--text {
  font-family: var(--font-text);
  font-size: var(--fs-body);
}

/* Иконка мессенджера в подвале — тот же знак, что в нижней панели */
.footer__messenger {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
}

.footer__messenger-icon {
  width: 16px;
  height: 16px;
  flex: none;
}

/* ОГРН — число, поэтому моноширинный только на нём, не на подписи */
.footer__ogrn {
  margin-top: var(--space-4);
  font-size: var(--fs-small);
  color: var(--ink-60-on-dark);
}

/* Нижняя строка подвала: подпись сайта, надпись про cookie и ссылка
   на политику. Раскладка гибкая, а не одна строка текста: на 360 одна
   подпись сайта занимает две строки, и рядом с ней ничего не помещается —
   части переносятся, а не уезжают вбок. */
.footer__bottom {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 0 var(--space-24);
  margin-top: var(--space-32);
  padding-top: var(--space-24);
  border-top: var(--border-width) solid var(--line-on-dark);
  font-size: var(--fs-small);
  color: var(--ink-60-on-dark);
}

/* Части переносятся целиком, а длинная подпись сайта — ещё и внутри себя:
   min-width иначе держал бы её шире контейнера и давал горизонтальную
   прокрутку на узком экране. */
.footer__bottom-part {
  min-width: 0;
}

/* Ссылка на политику. Площадь нажатия 44 px — то же правило, что
   у ссылок сетки выше. Цвет свой: ссылочный синий на тёмном фоне
   не добирает контраста, а вторичный текст на тёмном добирает. */
.footer__policy {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  color: var(--ink-60-on-dark);
}

.footer__policy:hover {
  color: var(--scan-orange);
}

@media (min-width: 768px) {
  .footer {
    padding-block: var(--space-64);
  }

  .footer__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--grid-gap);
    margin-top: var(--space-32);
  }

  .footer__label {
    margin-bottom: var(--space-8);
  }

  .footer__bottom {
    margin-top: var(--space-48);
  }
}

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

/* ==========================================================================
   Схема «Зона досмотра» — сигнатурный «рентгеновский» блок
   Изометрия. Тёмный фон, металл синим, люди и вещи оранжевым, подписи
   моноширинным, сетка по полу. Цвета берутся из переменных: схема
   встроена как SVG, а не картинкой, именно ради этого — раздел 8 ТЗ.
   Геометрию считает tools/svg-zona-dosmotra.py, руками её не правят.
   ========================================================================== */

/* Отступ сверху не задаём: подзаголовок под H2 — общее правило base.css.
   Здесь он был на четыре пикселя меньше остальных, и разницы этой
   не объяснить ничем, кроме того, что писалась схема отдельно. */
.scheme__lead {
  max-width: 60ch;
  color: var(--ink-60-on-dark);
}

.scheme__figure {
  margin: var(--space-24) 0 0;
}

/* Схема всегда вписывается в контейнер целиком. Горизонтальной
   прокрутки здесь нет намеренно: приём не считывается, его же убирали
   у таблицы цен. Просмотр в отдельном окне по нажатию был здесь
   до 14.09.2026 — снят решением заказчика: на сенсорном экране страница
   и так масштабируется пальцами, а окно показывало схему мельче, чем
   она уже была на странице. */
.scheme__svg {
  display: block;
  width: 100%;
  height: auto;
}

@media (min-width: 768px) {
  .scheme__figure {
    margin-top: var(--space-32);
  }
}

/* Сетка пола — тонкая, читается как чертёж, а не как разлиновка */
.scheme__grid {
  fill: none;
  stroke: var(--line-on-dark);
  stroke-width: 1;
}

/* Металл — синий. Верхние грани светлее боковых: без этого изометрия
   разваливается в плоские многоугольники. */
.scheme__metal-top {
  fill: var(--scan-blue);
  fill-opacity: 0.3;
  stroke: var(--scan-blue);
  stroke-width: 1.5;
}

.scheme__metal-side {
  fill: var(--scan-blue);
  fill-opacity: 0.14;
  stroke: var(--scan-blue);
  stroke-width: 1.5;
}

.scheme__metal-line {
  fill: none;
  stroke: var(--scan-blue);
  stroke-width: 1;
  opacity: 0.55;
}

/* Интроскоп — главный объект схемы, поэтому плотнее и с линией потолще */
.scheme__device-top {
  fill: var(--scan-blue);
  fill-opacity: 0.38;
  stroke: var(--scan-blue);
  stroke-width: 2;
}

.scheme__device-side {
  fill: var(--scan-blue);
  fill-opacity: 0.2;
  stroke: var(--scan-blue);
  stroke-width: 2;
}

/* Тоннель. Ближний проём — тёмный, дальний и стенки канала штриховыми:
   под этим углом в тоннель не заглянуть, а сквозное отверстие показать
   надо. Штриховая скрытая линия — обычный приём чертежа. */
.scheme__tunnel {
  fill: var(--ink);
  stroke: var(--scan-blue);
  stroke-width: 2;
}

.scheme__tunnel-far {
  fill: none;
  stroke: var(--scan-blue);
  stroke-width: 1.5;
  stroke-dasharray: 6 5;
  opacity: 0.75;
}

/* Органика — оранжевый: люди и вещи */
.scheme__organic-top {
  fill: var(--scan-orange);
  fill-opacity: 0.55;
  stroke: var(--scan-orange);
  stroke-width: 1.5;
}

.scheme__organic-side {
  fill: var(--scan-orange);
  fill-opacity: 0.3;
  stroke: var(--scan-orange);
  stroke-width: 1.5;
}

.scheme__organic-line {
  fill: none;
  stroke: var(--scan-orange);
  stroke-width: 2;
  stroke-linejoin: round;
  stroke-linecap: round;
}

/* Потоки: сплошной штрих — люди, точки — вещи. Расшифровка типов линий
   отдельной легендой внизу, с подписями объектов не смешивается. */
.scheme__flow {
  fill: none;
  stroke: var(--scan-orange);
  stroke-width: 2;
}

.scheme__flow--people {
  stroke-dasharray: 12 8;
}

.scheme__flow--bags {
  stroke-dasharray: 2 7;
  stroke-linecap: round;
}

.scheme__arrowhead {
  fill: var(--scan-orange);
}

/* Подписи стоят у самих объектов, выноска короткая */
.scheme__leader {
  fill: none;
  stroke: var(--ink-60-on-dark);
  stroke-width: 1;
  opacity: 0.55;
}

.scheme__label {
  font-family: var(--font-mono);
  font-size: 16px;
  fill: var(--ink-on-dark);
}

.scheme__legend-text {
  font-family: var(--font-mono);
  font-size: 16px;
  fill: var(--ink-60-on-dark);
}

/* ==========================================================================
   Блок «Технику обслуживаем сами»
   ========================================================================== */

/* Текст в одной колонке на две трети ширины, снимок в правой трети.
   Разбивать текст на колонки не стали: два абзаца читались сплошняком. */
.service {
  display: grid;
  gap: var(--space-24);
  margin-top: var(--space-16);
}

/* Абзацы — голые <p> включаемой области, классов в файле области нет
   (условие 9 задания В): стиль даёт колонка .service__body. */
.service__body p {
  max-width: var(--measure);
}

.service__body p + p {
  margin-top: var(--space-16);
}

/* Абзац про вывоз и утилизацию. Это отдельная услуга, а не примечание
   к абзацу выше, и одинаковым кеглем она в нём терялась. Задание
   05.09.2026, раздел 2. Заголовком абзац при этом не становится,
   поэтому ни семейство, ни начертание не трогаем: --font-heading
   и 600 остаются у заголовков.

   Кегль --fs-lead, 20/18. Сначала бралась полная ступень шкалы вверх
   от body — H3, 24/20, — и на десктопе абзац читался вторым заголовком
   блока. Приёмка 05.09.2026: «чуть поменьше, но чтобы было крупнее
   обычного текста». Между body и H3 ступени в шкале нет, поэтому
   заведён свой токен.

   Крупнее набирается второй абзац области: класса у него нет, условие 9. */
.service__body p + p {
  font-size: var(--fs-lead);
  line-height: var(--lh-text);
}

.service__media {
  margin: 0;
}

.service__photo {
  width: 100%;
  height: clamp(220px, 58vw, 320px);
  object-fit: cover;
  /* В широкой колонке от вертикального кадра видна полоса: держим в ней
     монитор с загрузкой системы — ради него снимок и выбран. */
  object-position: center 28%;
  border-radius: var(--radius);
}

@media (min-width: 768px) {
  .service {
    grid-template-columns: 2fr 1fr;
    gap: var(--space-48);
    align-items: stretch;
    margin-top: var(--space-24);
  }

  /* Тот же приём, что в блоке-призыве хаба: картинка положена абсолютно,
     иначе её высота начинает управлять строкой сетки. */
  .service__media {
    position: relative;
    min-height: 260px;
  }

  .service__photo {
    position: absolute;
    inset: 0;
    height: 100%;
  }
}

/* ==========================================================================
   Блоки «О компании»
   Компонент A — развёрнутый блок «Кто мы»: фото слева, текст справа,
   на мобильном фото сверху. Компонент B — компактная подпись в одну строку
   по высоте. Оба берут один и тот же снимок, размеры под брейкпоинты
   выбирает браузер по srcset.
   ========================================================================== */

/* Блок отделяется от следующего тонкой границей снизу во всю ширину
   контейнера. Ни фона, ни рамки вокруг, ни сдвига содержимого.

   История: сначала блок был замкнутой карточкой на --paper-alt, но стоял
   сразу под серой секцией и читался как «блок в блоке». Потом держался
   левой полосой — синей, и это была ошибка: в дизайн-системе акцентная
   полоса оранжевая, синий отведён ссылкам. Полоса убрана целиком. */
.about {
  display: grid;
  gap: var(--space-24);
  padding-bottom: var(--space-48);
  border-bottom: var(--border-width) solid var(--line);
}

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

   Стоит на странице контактов: там за «Кто мы» идут реквизиты
   на --paper-alt. На главной следом светлый блок, и линия остаётся. */
.about--no-rule {
  padding-bottom: 0;
  border-bottom: 0;
}

.about__media {
  margin: 0;
}

.about__photo {
  width: 100%;
  max-width: 320px;
  aspect-ratio: 3 / 4;
  object-fit: cover;
  border-radius: var(--radius);
}

.about__caption {
  margin-top: var(--space-12);
}

.about__name {
  display: block;
  font-weight: var(--fw-medium);
}

.about__role {
  display: block;
  font-size: var(--fs-small);
  color: var(--ink-60);
}

/* Абзацы «Кто мы» — голые <p> включаемой области: стиль им даёт обёртка,
   классов в файле области нет (условие 9 задания В, 11.09.2026). */
.about__text p {
  max-width: var(--measure);
}

.about__text p + p {
  margin-top: var(--space-16);
}

.about__text h2 + div {
  margin-top: var(--space-16);
}

@media (min-width: 768px) {
  /* Колонка под снимок — 280 px. Имени нужно 269 px, и в такой колонке
     оно встаёт в одну строку с запасом, без захода в промежуток между
     колонками — костыль с nowrap больше не нужен. */
  .about {
    grid-template-columns: 280px minmax(0, 1fr);
    gap: var(--space-32);
    align-items: flex-start;
  }

  .about__photo {
    max-width: 280px;
  }
}

/* Компонент B. Снимок маленький и квадратноватый по месту, но пропорция
   та же 3:4 — кроп общий, отдельного файла не заводим. */
.signature {
  display: flex;
  align-items: flex-start;
  gap: var(--space-16);
  margin-top: var(--space-48);
  padding-top: var(--space-24);
  border-top: var(--border-width) solid var(--line);
  max-width: var(--measure);
}

.signature__photo {
  flex: none;
  width: 96px;
  height: 128px;
  object-fit: cover;
  border-radius: var(--radius);
}

/* Имя и текст подписи — два голых абзаца включаемой области: первый набирается
   как имя, следующие — как текст. Классов в файле области нет, условие 9
   задания В. Селектор потомка, а не дочерний: в режиме правки ядро кладёт
   абзацы в свою обёртку. */
.signature__body p:first-child {
  font-weight: var(--fw-medium);
}

.signature__body p + p {
  margin-top: var(--space-4);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.signature__phone {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
  margin-top: var(--space-8);
  font-family: var(--font-mono);
  font-size: var(--fs-mono-price);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
  letter-spacing: -0.02em;
  color: var(--ink);
  text-decoration: none;
}

.signature__phone:hover {
  color: var(--scan-orange);
}

/* ==========================================================================
   Нижняя закреплённая панель, мобильный
   «Позвонить» и «Написать в Макс», высота 56 px, появляется после
   прокрутки первого экрана — ТЗ на редизайн, раздел 5.
   ========================================================================== */

/* Место под панель резервируется у body, поэтому она не перекрывает
   ни последний блок, ни кнопки. Отступ снимается с 768, где панели нет.

   Отступ навешен классом, а не постоянным правилом: панель — отключаемый
   модуль, и решением 04.09.2026 она снята. Класс ставит render.js по
   bottomBar.enabled, вместе с самой панелью. Без класса отступа нет
   и пустой полосы внизу не остаётся; вернётся панель — вернётся и место
   под неё, править вёрстку не придётся.

   На страницах благодарности панели нет и не было: у них своя кнопка
   возврата, и две кнопки внизу экрана конкурировали бы друг с другом.
   Решение шага 10. Отдельного правила им больше не нужно — отступа
   без класса нет ни у кого. */
body.has-bottom-bar {
  padding-bottom: calc(var(--bottom-bar-height) + env(safe-area-inset-bottom, 0px));
}

.bottom-bar {
  position: fixed;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 40;
  display: grid;
  /* Колонки по числу кнопок, а не жёсткой парой: мессенджер —
     отключаемый модуль, и когда его нет, «Позвонить» занимает панель
     целиком, а не половину с пустотой рядом. Задание 04.09.2026,
     раздел 3. */
  grid-auto-flow: column;
  grid-auto-columns: minmax(0, 1fr);
  height: calc(var(--bottom-bar-height) + env(safe-area-inset-bottom, 0px));
  padding-bottom: env(safe-area-inset-bottom, 0px);
  background-color: var(--paper);
  border-top: var(--border-width) solid var(--line);
  transform: translateY(100%);
  visibility: hidden;
  transition:
    transform var(--motion-duration) var(--motion-easing),
    visibility var(--motion-duration) var(--motion-easing);
}

.bottom-bar.is-visible {
  transform: none;
  visibility: visible;
}

/* При открытом окне панель не нужна: она перекрывала бы поля формы,
   развёрнутой на весь экран. ТЗ на прототип, 8.1 пункт 11. */
.is-modal-open .bottom-bar {
  display: none;
}

.bottom-bar__btn {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: var(--space-8);
  min-height: var(--bottom-bar-height);
  font-family: var(--font-text);
  font-size: var(--fs-body);
  font-weight: var(--fw-medium);
  color: var(--ink);
  text-decoration: none;
}

.bottom-bar__btn--call {
  background-color: var(--scan-orange);
  color: var(--paper);
}

.bottom-bar__btn--call:hover {
  background-color: var(--scan-orange-hover);
  color: var(--paper);
}

.bottom-bar__btn:focus-visible {
  outline: var(--focus-width) solid var(--ink);
  outline-offset: calc(var(--focus-offset) * -1);
}

.bottom-bar__icon {
  width: 20px;
  height: 20px;
  flex: none;
}

/* Знак Макса залитый, а не линейный: при равном размере он выглядит тяжелее
   иконки телефона. Уменьшаем до оптического равенства. */
.bottom-bar__icon--max {
  width: 17px;
  height: 17px;
}

@media (min-width: 768px) {
  body.has-bottom-bar {
    padding-bottom: 0;
  }

  .bottom-bar {
    display: none;
  }
}

/* ==========================================================================
   Модальное окно и лайтбокс
   ========================================================================== */

/* Пока окно открыто, страница фиксируется на месте: body получает
   position: fixed со сдвигом на текущую прокрутку (ui.js). Через
   overflow: hidden не выйдет — iOS Safari сбрасывает страницу наверх. */
.is-modal-open {
  position: fixed;
  left: 0;
  right: 0;
  width: 100%;
  overflow: hidden;
}

.modal {
  position: fixed;
  inset: 0;
  z-index: 100;
  display: flex;
  align-items: stretch;
  justify-content: stretch;
  padding: 0;
  background-color: rgba(18, 22, 28, 0.6);
}

.modal[hidden] {
  display: none;
}

/* На мобильном окно раскрывается во весь экран, прокрутка — внутри него */
.modal__dialog {
  position: relative;
  width: 100%;
  max-width: none;
  height: 100%;
  overflow-y: auto;
  overscroll-behavior: contain;
  padding: var(--space-24) var(--space-16) var(--space-48);
  background-color: var(--paper);
  border: 0;
}

.modal__title {
  padding-right: var(--space-48);
  font-size: var(--fs-h3);
}

/* Сноска про калькулятор. Мелким кеглем: основным она занимала четверть
   окна и читалась предупреждением, а это пояснение к тому, что будет
   дальше. Правка 03.09.2026.

   С 05.09.2026 живёт внутри сетки формы, под селектором сценария, и
   занимает обе колонки. Отбивки свои сняты: расстояние вокруг задаёт
   зазор сетки, а собственные поля плашки складывались бы с ним.
   Кегль опущен на ступень — --fs-note. */
.brief__warning {
  grid-column: 1 / -1;
  margin: 0;
  /* Плашка идёт по ширине формы, вровень с полями. Общий предел .note —
     72ch, а ch считается от кегля самой плашки: на прежних 15 px он давал
     как раз ширину окна, на 13 px обрезал бы плашку на 74 px короче полей,
     и она читалась бы обрезанной. Правило длины строки при этом соблюдено
     замером: в самой длинной строке сноски 70 знаков. */
  max-width: none;
  font-size: var(--fs-note);
}

/* Длину строки держит сам текст, а не плашка: 85 знаков в строке
   на всю ширину формы — против правила «не более 72», ТЗ на редизайн,
   раздел 4. Общее правило .note p снимает предел, здесь он возвращается. */
.brief__warning p {
  max-width: var(--measure);
}

/* Плашка снимается целиком вне сценария аренды. Правило нужно явно:
   у .note задан padding, серая подложка и оранжевая полоса слева,
   и пустая плашка осталась бы видимой полосой под селектором. */
.brief__warning[hidden] {
  display: none;
}

/* Модель под заголовком окна. Стоит, только когда окно открыли кнопкой
   карточки: с шапки и из каталога подставлять нечего, и узел там снят
   атрибутом hidden. */
.modal__subtitle {
  margin-top: var(--space-4);
  padding-right: var(--space-48);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

/* Точка приземления фокуса — само окно. Рамку фокуса она не носит
   намеренно, и это не «сняли обводку с кнопки»: клавишами сюда не попасть,
   элемент нужен ровно затем, чтобы фокус при открытии оказался внутри
   окна, а не на первой кнопке, которую браузер тут же обводит. У кнопок
   внутри окна рамка фокуса на месте и работает как везде. */
.modal__dialog[data-modal-focus]:focus,
.modal__dialog[data-modal-focus]:focus-visible {
  outline: none;
}

/* z-index кнопке нужен из-за сцены просмотра: она позиционирована и стоит
   в разметке ниже, а среди позиционированных элементов без z-index
   выигрывает тот, что ниже по документу. Снимок закрывал крестик целиком —
   кнопка не только пропадала из виду, но и переставала нажиматься. Цвет
   в покое и под курсором, размер значка — components.css, раздел 9,
   «Крестик закрытия — один вид на весь сайт». */
.modal__close {
  position: absolute;
  z-index: 1;
  top: var(--space-8);
  right: var(--space-8);
  width: var(--tap-min);
  height: var(--tap-min);
  display: flex;
  align-items: center;
  justify-content: center;
}

.modal__text {
  margin-top: var(--space-12);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.modal__form {
  margin-top: var(--space-24);
}

/* Просмотр снимка. Селектор в два класса намеренно: правило .modal__dialog
   с max-width 460px стоит ниже по файлу и при равной силе перебивало это.
   Из-за него окно открывало снимок мельче превью в сетке, хотя курсор
   с лупой обещает увеличение.

   Окно отдаёт снимку почти весь экран, снимок вписывается по большей
   стороне и не растягивается сверх натуральной величины: увеличивать
   пиксели незачем, а уменьшать ниже превью нельзя. */
.modal__dialog.lightbox__dialog {
  width: auto;
  max-width: 96vw;
  height: auto;
  max-height: 96vh;
  margin: auto;
  padding: var(--space-4);
  overflow: visible;
  border: 0;
}

.lightbox__dialog img {
  display: block;
  width: auto;
  height: auto;
  max-width: 94vw;
  max-height: 78vh;
  margin: 0 auto;
}

@media (min-width: 768px) {
  .modal__dialog.lightbox__dialog {
    padding: var(--space-12);
  }

  .lightbox__dialog img {
    max-width: 92vw;
    max-height: 82vh;
  }
}

/* Сцена: снимок и две стрелки поверх него. Отдельная обёртка нужна, чтобы
   стрелки вставали по середине именно снимка, а не окна вместе с подписью.
   Схема в сцену не входит и лежит рядом: её коробка считалась браузером
   до этой правки и должна считаться так же после. */
.lightbox__stage {
  position: relative;
  width: fit-content;
  max-width: 100%;
  margin: 0 auto;
}

/* Кнопка стоит поверх снимка, а не рядом: на 360 места сбоку нет.
   Контраст держит подложка, а не тень: снимки бывают и светлые,
   и тёмные, и тень читалась бы то на одном, то на другом. Подложка —
   тот же лист, что у окна, с той же рамкой, что у полей и карточек. */
.lightbox__nav {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  width: var(--tap-min);
  height: var(--tap-min);
  display: flex;
  align-items: center;
  justify-content: center;
  color: var(--ink);
  background-color: var(--paper);
  border: var(--border-width) solid var(--line);
  border-radius: var(--radius);
}

.lightbox__nav[hidden] {
  display: none;
}

.lightbox__nav:hover {
  background-color: var(--paper-alt);
}

.lightbox__nav--prev {
  left: var(--space-8);
}

.lightbox__nav--next {
  right: var(--space-8);
}

/* До 768 стрелка — подсказка, а не главное действие: на телефоне листают
   свайпом, и свайп работает. Совсем убрать её нельзя — не всякий
   догадается свайпнуть, других подсказок в окне нет.

   Мельчает только вид. Сама кнопка остаётся 44 × 44, попасть по ней
   так же легко: видимую часть рисует ::before, вдвое меньше кнопки,
   а разницу добирает прозрачное поле вокруг. Значок той же формы,
   уменьшен в ту же меру.

   Подложка полупрозрачная — за этим и затевалось: непрозрачный белый
   квадрат читается как главное действие. Плата известна и замерена:
   контраст значка к подложке падает с 18,15 до 11,79 на самом тёмном
   кадре наборов и держится в 11,79–15,53 на остальных. Предел, ниже
   которого не опустится ни один снимок, — 11,30, это подложка над
   чёрным. Норма раздела 9 ТЗ на редизайн — 4,5:1, то есть запас
   двух с половиной кратный. Замер настоящий, стендом: средний цвет
   кадра ровно под подложкой, поверх него подложка. */
@media (max-width: 767px) {
  .lightbox__nav {
    background-color: transparent;
    border: 0;
  }

  .lightbox__nav::before {
    content: '';
    position: absolute;
    inset: 10px;
    background-color: rgba(255, 255, 255, 0.8);
    border-radius: var(--radius);
  }

  .lightbox__nav svg {
    position: relative;
    width: 14px;
    height: 14px;
  }
}

/* Подпись и счётчик — одной строкой: подпись слева, счётчик в углу окна.
   Кегль и цвет у них общие, счётчик не выделяется. */
.lightbox__bar {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-12);
  margin-top: var(--space-12);
}

.lightbox__caption {
  min-width: 0;
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.lightbox__counter {
  flex: none;
  font-size: var(--fs-small);
  color: var(--ink-60);
  white-space: nowrap;
}

.lightbox__counter[hidden] {
  display: none;
}

/* Переход между кадрами. Правило целиком лежит внутри запроса
   об уменьшенной анимации: при включённом режиме кадр просто
   сменяется, без сдвига и без появления. */
@media (prefers-reduced-motion: no-preference) {
  .lightbox__dialog img.is-step-next {
    animation: lightbox-next var(--motion-duration) var(--motion-easing);
  }

  .lightbox__dialog img.is-step-prev {
    animation: lightbox-prev var(--motion-duration) var(--motion-easing);
  }
}

@keyframes lightbox-next {
  from { opacity: 0; transform: translateX(var(--motion-shift)); }
}

@keyframes lightbox-prev {
  from { opacity: 0; transform: translateX(calc(var(--motion-shift) * -1)); }
}

@media (min-width: 768px) {
  .modal {
    align-items: center;
    justify-content: center;
    padding: var(--space-24);
  }

  .modal__dialog {
    width: 100%;
    max-width: 460px;
    height: auto;
    max-height: 90vh;
    padding: var(--space-32);
    border: var(--border-width) solid var(--line);
  }

  /* Бриф — десять полей, в две колонки, поэтому окно шире прайсового */
  .modal--brief .modal__dialog {
    max-width: 720px;
  }
}

/* ==========================================================================
   Страницы благодарности и политики
   Отдельные адреса нужны целям Метрики: цель ставится на просмотр страницы,
   а не на клик по кнопке. Разметка простая, шапка и подвал — те же.
   ========================================================================== */

.thanks,
.policy {
  max-width: var(--measure);
}

.thanks__mark {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  margin-bottom: var(--space-24);
  color: var(--signal);
  border: 2px solid var(--signal);
  border-radius: 50%;
}

.thanks__mark svg {
  width: 26px;
  height: 26px;
}

.thanks__lead {
  margin-top: var(--space-16);
  font-size: 17px;
}

.thanks__phone {
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  white-space: nowrap;
}

.thanks__actions {
  margin-top: var(--space-32);
}

/* Правила .policy .note и .policy__note сняты 07.09.2026 вместе
   с заглушкой, которую они оформляли: плашка «нет данных» и перечень
   того, что должно быть в тексте. Настоящий текст политики пришёл
   с боевого сайта, и оформлять в нём больше нечего. */

/* --- Текст политики ---------------------------------------------------
   Юридический документ с боевого сайта, перенесён дословно 07.09.2026.
   Оформление минимальное: заголовки семи разделов, отбивки между
   пунктами и маркеры у перечней. Базовые стили снимают маркеры у всех
   списков сайта — здесь они нужны, это перечни внутри прозы,
   а не карточки. */

/* Собственные названия документа и реквизиты — шапка под заголовком
   страницы. Отделена чертой: дальше идёт сплошной текст. */
.policy__head {
  padding-bottom: var(--space-24);
  border-bottom: var(--border-width) solid var(--line);
}

.policy__doc {
  font-weight: var(--fw-semibold);
}

/* Числа реквизитов набраны моноширинным через .num в разметке:
   правило проекта — моноширинный только на числовых данных. */
.policy__req,
.policy__date {
  margin-top: var(--space-4);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.policy h2 {
  margin-top: var(--space-48);
}

.policy h3 {
  margin-top: var(--space-32);
}

/* Подзаголовки третьего уровня — «Работники Оператора»,
   «Правоохранительные органы». Размер основного текста: ставить им
   кегль заголовка не за что, они делят один пункт надвое. */
.policy h4 {
  margin-top: var(--space-24);
  font-size: var(--fs-body);
  font-weight: var(--fw-semibold);
}

.policy h4 + p {
  margin-top: var(--space-8);
}

.policy p {
  margin-top: var(--space-16);
}

.policy__list {
  max-width: var(--measure);
  margin-top: var(--space-12);
  padding-left: var(--space-24);
  list-style: disc;
}

.policy__list li + li {
  margin-top: var(--space-8);
}

/* ==========================================================================
   Страница результатов поиска — /search/

   Одна колонка, без сайдбара — ТЗ на редизайн, раздел 6: перечень
   найденного единственное содержимое страницы. Трёх состояний сразу
   в разметке, в отличие от прототипа, нет: нужное собирает на сервере
   шаблон компонента bitrix:search.page, и лишнего в браузер не уезжает.
   ========================================================================== */

.search-page {
  max-width: var(--measure);
}

/* Поисковая строка на самой странице результатов — работа 3 задания
   estafeta-vid-poiska-bitrix-13092026.md. Та же разметка, что у формы поиска
   в шапке (.search-form), но не в свёрнутом поле: видна всегда, во всех
   трёх состояниях страницы, шире фиксированного clamp шапки — на всю
   доступную ширину колонки страницы. Подсказок под ней нет — решение
   прототипа, перенесено вместе с разметкой. */
.search-page__form {
  width: 100%;
  max-width: 480px;
  margin-top: var(--space-16);
}

.search-page__count {
  margin-top: var(--space-8);
  color: var(--ink-60);
}

.search-page__intro {
  margin-top: var(--space-16);
}

.search-page__empty-text {
  margin-top: var(--space-16);
}

.search-results {
  margin-top: var(--space-24);
  padding: 0;
  list-style: none;
}

.search-results__item + .search-results__item {
  margin-top: var(--space-24);
  padding-top: var(--space-24);
  border-top: var(--border-width) solid var(--line);
}

.search-results__title {
  font-size: var(--fs-h3);
  font-weight: var(--fw-medium);
  color: var(--ink);
  text-decoration: none;
}

.search-results__title:hover {
  color: var(--scan-orange-hover);
}

.search-results__excerpt {
  margin-top: var(--space-8);
  color: var(--ink-60);
}

.search-results mark,
.search-page mark {
  background-color: var(--paper-alt);
  color: var(--ink);
  font-weight: var(--fw-medium);
}

/* Постраничность мока. Своего образца в документе нет — раздел 6, документ
   не заводил ни одного пагинированного списка раньше; раскладка держится
   общих токенов дизайн-системы: 44 px цели нажатия, рамка --line, текущая
   страница акцентным цветом. */
.pagination {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-8);
  margin-top: var(--space-32);
}

.pagination__item {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: var(--tap-min);
  min-height: var(--tap-min);
  padding-inline: var(--space-8);
  border: var(--border-width) solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  text-decoration: none;
  font-variant-numeric: tabular-nums;
}

.pagination__item:hover {
  border-color: var(--scan-orange);
  color: var(--scan-orange-hover);
}

.pagination__item.is-current {
  border-color: var(--scan-orange);
  color: var(--scan-orange);
  font-weight: var(--fw-medium);
}

/* ==========================================================================
   Карточка товара
   Одиннадцать блоков карты сайта, раздел 6, в девяти секциях: блоки 1–3
   образуют один первый экран. Логическая нумерация держится в разметке
   атрибутом data-block.
   ========================================================================== */

/* --- Первый экран: галерея слева, название с кнопками справа ---------- */

.product-hero__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-32);
}

/* Кегль ниже шкального намеренно. H1 карточки — название модели плюс тип
   оборудования, и «рентгенотелевизионный» одним словом в 21 знак при 48 px
   не помещается в колонку 5 из 12 и вылезает за контейнер. Правка точечная,
   как и такая же правка первого экрана хаба: ТЗ на редизайн, раздел 6. */
.product-hero__title {
  font-size: var(--fs-h2);
  line-height: var(--lh-heading);
  /* Переноса по слогам нет: «рентгенотелевизионный» в колонку помещается
     целиком, а браузер всё равно рвал его ради выравнивания строк.
     break-word оставлен страховкой на случай названия длиннее. */
  overflow-wrap: break-word;
}

@media (min-width: 1280px) {
  .product-hero__title {
    font-size: 40px;
  }
}

/* Две кнопки первого экрана. Ниже 768 — одна под другой во всю ширину;
   с 768 — жёстко две колонки, кнопка по ширине своей колонки, под ней
   её микрокопия в той же колонке. Задание 04.09.2026, раздел 4.
   Прежде кнопки стояли столбцом на всех ширинах: микрокопия была длинной
   и в строку не вставала. Теперь она сокращена. */
.product-hero__actions {
  margin-top: var(--space-32);
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-16);
}

.product-hero__actions .btn {
  width: 100%;
}

/* Кнопка и её микрокопия — группой: подпись под своей кнопкой, а не
   под парой. У аренды и у покупки подписи разные. */
.product-hero__action {
  display: block;
}

.product-hero__note {
  margin-top: var(--space-4);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

/* Три строки, которые спрашивают раньше таблицы. Значения моноширинным:
   это числовые данные, а не проза. */
.product-hero__facts {
  margin-top: var(--space-32);
  padding-top: var(--space-24);
  border-top: var(--border-width) solid var(--line);
}

.product-hero__fact {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: var(--space-16);
  padding: var(--space-8) 0;
}

.product-hero__fact + .product-hero__fact {
  border-top: var(--border-width) solid var(--line);
}

.product-hero__fact dt {
  color: var(--ink-60);
  font-size: var(--fs-small);
}

.product-hero__fact dd {
  margin: 0;
  text-align: right;
  font-family: var(--font-mono);
  font-variant-numeric: tabular-nums;
  font-weight: var(--fw-medium);
}

/* --- Галерея модели ---------------------------------------------------- */

.product-gallery__main {
  margin: 0;
  cursor: zoom-in;
}

/* Кадр вписывается целиком, а не кадрируется: в наборе есть портретные
   снимки, и рамка 16:9 срезала их до полосы. Заодно это делает окно
   просмотра всегда крупнее превью — кадрированное превью показывает
   часть кадра, но в большем масштабе, и обещание лупы не выполнялось. */
.product-gallery__main img {
  display: block;
  width: 100%;
  aspect-ratio: var(--frame-ratio, 16 / 9);
  object-fit: contain;
  background-color: var(--paper-alt);
  border-radius: var(--radius);
}

.product-gallery__caption {
  margin-top: var(--space-12);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

/* Лента миниатюр прокручивается горизонтально: это лента, и прокрутка
   в ней ожидаема — в отличие от таблицы, где её убирали. */
.product-gallery__thumbs {
  display: flex;
  gap: var(--space-8);
  margin-top: var(--space-16);
  overflow-x: auto;
  scrollbar-width: thin;
}

.product-gallery__thumb {
  flex: none;
  width: 88px;
  height: 66px;
  padding: 0;
  background: none;
  border: var(--border-width) solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
  overflow: hidden;
}

.product-gallery__thumb img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.product-gallery__thumb.is-active {
  border-color: var(--scan-orange);
  border-width: 2px;
}

/* Наведения у миниатюр не было вовсе: рамка --line не менялась,
   и кадр не читался нажимаемым. Правило то же, что у контурных
   кнопок, — обводка уходит в --scan-orange-hover. У выбранного кадра
   рамка и так оранжевая, наведение делает её на тон темнее.
   Задание 05.09.2026, раздел 5. */
.product-gallery__thumb:hover {
  border-color: var(--scan-orange-hover);
}

.product-gallery__thumb:focus-visible {
  outline: var(--focus-width) solid var(--ink);
  outline-offset: var(--focus-offset);
}

/* Два кадра схемы. На широком экране стоят в строку, и flex-grow у каждого
   SVG равен ширине его кадра: высоты кадров генератор выравнивает, поэтому
   при таком росте масштаб у обоих одинаковый и проём в них одного размера.
   На мобильном идут друг под другом, каждый на всю ширину. */
/* Зазоры разведены по осям. Вертикальный убран в отступы самих
   элементов: с 1024 перечень встаёт в правую колонку на обе строки,
   а зона под схемами — в левую, и общий row-gap лёг бы между схемами
   и зоной лишним слоем поверх её собственной отбивки. */
.scheme__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  column-gap: var(--space-32);
  row-gap: 0;
  margin-top: var(--space-24);
  align-items: start;
}

.tunnel-figures {
  display: flex;
  flex-direction: column;
  gap: var(--space-32);
}

.tunnel-figures .scheme__figure {
  margin: 0;
}

@media (min-width: 768px) {
  .tunnel-figures {
    flex-direction: row;
    align-items: flex-start;
    gap: var(--space-32);
  }

  .tunnel-figures .scheme__figure {
    flex-basis: 0;
    min-width: 0;
  }
}

/* --- Блок 4. Перечень под схемой тоннеля -------------------------------

   Три группы, а не шесть строк подряд: что проходит, что не проходит,
   куда идти с тем, что не прошло. Между группами тройной шаг шкалы
   отступов, внутри группы одинарный — 24 против 8. Ритм и делает
   группы группами: до правки 26.08.2026 строки шли ровным столбцом
   и читались сплошняком.

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

.tunnel-list {
  margin-top: var(--space-32);
  padding-top: var(--space-16);
  border-top: var(--border-width) solid var(--line-on-dark);
}

.tunnel-list__group + .tunnel-list__group,
.tunnel-list__note {
  margin-top: var(--space-24);
}

.tunnel-list__heading {
  margin: 0 0 var(--space-8);
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  text-transform: uppercase;
  letter-spacing: 0.04em;
  color: var(--ink-60-on-dark);
}

/* Каждый предмет своей строкой, от крупнейшего к мельчайшему. Прежде
   первый стоял отдельной строкой, а остальные жались в строку через
   точки-разделители, и перечень читался как две разные сущности. */
.tunnel-list__items {
  margin: 0;
  padding: 0;
  list-style: none;
}

.tunnel-list__item + .tunnel-list__item {
  margin-top: var(--space-8);
}

.tunnel-list__name {
  display: block;
}

/* Причина отказа — строкой ниже предмета и той же формулировкой, что
   под чертежом. Приглушена: главное здесь предмет с размерами,
   причина его поясняет. */
.tunnel-list__reason,
.tunnel-list__load,
.tunnel-list__note,
.tunnel-list__ref-line--none {
  display: block;
  color: var(--ink-60-on-dark);
}

.tunnel-list__reason {
  margin-top: var(--space-4);
}

.tunnel-list__load {
  margin: var(--space-8) 0 0;
}

.tunnel-list__ref-line,
.tunnel-list__note {
  margin-bottom: 0;
  max-width: none;
}

/* Отсылка к модели покрупнее: это ссылка, и на тёмном она синей быть
   не может — синий отведён металлу в схемах и на подложке не читается.
   Ссылкой набрано только название модели: в сплошь подчёркнутой фразе
   глазу не за что зацепиться. */
.tunnel-list__ref {
  color: var(--scan-orange);
  text-decoration-color: rgba(232, 114, 28, 0.5);
}

.tunnel-list__ref:hover {
  color: var(--ink-on-dark);
}

/* --- Блок 4. Зона под схемами ------------------------------------------

   Правка 27.08.2026 по итогам полигона. Отсылка к другой модели,
   строка про нагрузку и примечание к модели переехали сюда из правой
   колонки: высоту блока задавал перечень, колонка схем была заметно
   ниже, и под схемами пустовало от 33 до 278 px на 1440 и до 556 px
   на 1024. Теперь это место занято, а блок не стал выше.

   Отбивка сверху — тройной шаг шкалы, тот же, что между группами
   перечня; внутри зоны между элементами одинарный. Отступы, доставшиеся
   элементам от перечня, здесь снимаются: там они отбивали строку внутри
   группы, тут — три самостоятельных абзаца.

   Ширина строки ограничена 72 символами — требование задания
   от 27.08.2026. Колонка схем широкая, и абзац примечания без
   ограничения растянулся бы в нечитаемую простыню на всю её ширину.

   Значение в ch, а не в пикселях: мера привязана к кеглю, и при смене
   кегля строка не поедет. Но ch — это ширина нуля, а строчные буквы
   уже, поэтому символов в строку влезает больше, чем стоит в мере:
   при 62ch замер давал 73 символа у примечания 5180i. Отсюда 60ch —
   значение подобрано замером, а не выведено из кегля. Стенд проверяет
   не его, а сами строки: пункт 8 задания. */
.tunnel-aside {
  margin-top: var(--space-24);
  max-width: 60ch;
}

.tunnel-aside > * + * {
  margin-top: var(--space-8);
}

.tunnel-aside .tunnel-list__load,
.tunnel-aside .tunnel-list__note,
.tunnel-aside .tunnel-list__ref-line {
  margin-bottom: 0;
}

.tunnel-aside > :first-child {
  margin-top: 0;
}

/* С 1024 перечень уходит вправо от чертежей: строка кадров ограничена
   по ширине, и под ней оставалась пустая полоса во всю секцию. Отбивка
   сверху снимается — иначе первая строка перечня не встаёт на одну линию
   с верхом чертежа и подписью соседнего кадра.

   Раскладка на две строки. Схемы — левая колонка, первая строка; зона
   под ними — левая колонка, вторая; перечень — правая колонка на обе
   строки, поэтому разделительная линия слева от него идёт во всю высоту
   блока и по-прежнему отделяет именно перечень, а не зону.

   В разметке зона стоит после перечня, и ставит её сюда только эта
   сетка. Ниже 1024 сетки нет, и порядок чтения остаётся тем, что
   в разметке: схемы, перечень, зона. */
@media (min-width: 1024px) {
  .scheme__body {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    grid-template-rows: auto auto;
    column-gap: var(--space-48);
  }

  .tunnel-figures {
    grid-column: 1;
    grid-row: 1;
  }

  .tunnel-aside {
    grid-column: 1;
    grid-row: 2;
  }

  .tunnel-list {
    grid-column: 2;
    grid-row: 1 / span 2;
    margin-top: 0;
    padding-top: 0;
    border-top: 0;
    border-left: var(--border-width) solid var(--line-on-dark);
    padding-left: var(--space-32);
  }
}

/* --- Блок 5. Логистика ------------------------------------------------- */

.logistics__line {
  max-width: var(--measure);
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  font-variant-numeric: tabular-nums;
}

/* Описание сценария грузовых ворот. Есть только у него: у двери и лифта
   на вопрос «пройдёт ли» отвечает сама схема, а здесь вопрос другой —
   что потребуется на объекте, — и одной картинкой он не закрывается.
   Ширина строки ограничена по той же причине, что в зоне блока тоннеля:
   колонка широкая, и абзац без ограничения растянулся бы в простыню. */
.logistics__desc {
  margin: var(--space-16) 0 0;
  max-width: 60ch;
  color: var(--ink-60);
}

.logistics__desc[hidden] {
  display: none;
}

/* Текст слева на две трети, схема справа на треть. В одну колонку схема
   уходила под текст, и справа от строки с габаритами оставалась пустота
   во всю ширину секции. На мобильном схема идёт после текста. */
/* Колонки выровнены по центру: чертёж вдвое выше текста, и при выравнивании
   по верху под текстом оставался провал во всю высоту схемы. */
.logistics__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
  align-items: center;
}

.logistics__figure {
  margin: 0;
}

@media (min-width: 768px) {
  .logistics__body {
    grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
    gap: var(--space-48);
  }
}

.logistics__svg {
  display: block;
  width: 100%;
  height: auto;
}

/* Светлая линейная схема: сигнатурный блок страницы уже занят тоннелем */
.logistics__outline {
  fill: none;
  stroke: var(--ink-60);
  stroke-width: 1.5;
}

.logistics__device {
  fill: var(--scan-blue);
  fill-opacity: 0.12;
  stroke: var(--scan-blue);
  stroke-width: 2;
}

.logistics__dim {
  fill: none;
  stroke: var(--ink-60);
  stroke-width: 1;
}

/* Кегль задан в единицах системы координат схемы, а не в пикселях экрана:
   схема живёт в колонке уже той, что схема тоннеля, и её собственный
   масштаб крупнее. Значения совпадают с FS в tools/svg-logistika.py —
   расчёт переносов там опирается на них. */
.logistics__label,
.logistics__value {
  font-family: var(--font-mono);
  font-size: 46px;
  fill: var(--ink);
}

.logistics__value {
  font-size: 40px;
  fill: var(--ink-60);
}

.logistics__label--device {
  fill: var(--scan-blue);
}

/* Подпись разницы по ширине в сценарии «грузовые ворота». Запас набран
   обычным приглушённым серым, нехватка — оранжевым. Оранжевый в этой
   схеме больше нигде не появляется: он здесь единственная тревожная
   отметка, и разбавлять его нечем. Правка 27.08.2026. */
.logistics__value--short {
  fill: var(--scan-orange);
}

/* --- Блок 6. Характеристики -------------------------------------------- */

.specs {
  max-width: 760px;
}

.specs__table th {
  width: 52%;
  font-weight: var(--fw-regular);
  color: var(--ink-60);
  text-align: left;
  vertical-align: top;
}

.specs__table td {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  font-variant-numeric: tabular-nums;
  vertical-align: top;
}

/* Значение-проза в таблице характеристик — строка «Состояние». Моноширинный
   только для числовых данных: фраза, набранная им, читается как код.
   Селектор тяжелее `.specs__table td` выше — иначе правило не сработает. */
.specs__table td.specs__value--text {
  font-family: var(--font-text);
}

.specs__note {
  margin-top: var(--space-16);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

/* --- Блок 7. Для каких задач подходит ---------------------------------- */

.suitable__paragraph {
  max-width: var(--measure);
}

.suitable__paragraph + .suitable__paragraph {
  margin-top: var(--space-16);
}

.suitable__links {
  display: flex;
  flex-wrap: wrap;
  gap: var(--space-12);
  margin-top: var(--space-24);
  padding: 0;
  list-style: none;
}

.suitable__link {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
  min-height: var(--tap-min);
  padding: 0 var(--space-16);
  border: var(--border-width) solid var(--line);
  border-radius: var(--radius);
  color: var(--ink);
  text-decoration: none;
}

/* Наведение по общему правилу контурных кнопок: меняется цвет обводки,
   текст остаётся --ink. Цвет задан явно — это ссылка, и без него общее
   a:hover уводило текст в синий; тон обводки приведён к --scan-orange-hover,
   тому же, что у прочих контурных. Задание 04.09.2026, раздел 3. */
.suitable__link:hover {
  border-color: var(--scan-orange-hover);
  color: var(--ink);
}

.suitable__spec {
  font-family: var(--font-mono);
  font-size: var(--fs-small);
  font-variant-numeric: tabular-nums;
  color: var(--ink-60);
}

/* --- Блок 8. С этой моделью обычно берут ------------------------------- */

/* Ряд карточек отбивается от заголовка шире, чем текст: вплотную заголовок
   читается как подпись к первой карточке. Значение одно на всю страницу
   и стоит здесь, а не в каждом блоке с сеткой. */
h2 + .bundle {
  margin-top: var(--space-32);
}

/* Строка-объяснение между заголовком и карточками. Ширина по мерке текста:
   строка во весь контейнер рядом с узкими карточками читается как чужая. */
.bundle__note {
  max-width: var(--measure);
  margin-top: var(--space-16);
  color: var(--ink-60);
}

.bundle__note + .bundle {
  margin-top: var(--space-32);
}

/* Одна колонка на всех ширинах. На карточке интроскопа спутник один — арка;
   ряд из двух карточек, в котором стоит одна, на широком экране читается
   как обрезанный. Ширина карточки при этом ограничена: карточка
   с картинкой 120 px и двумя строками текста, растянутая на весь
   контейнер, выглядит пустой. Правка 25.08.2026.

   Модификатор --grid ставится скриптом там, где спутников больше одного:
   на карточке рамки их четыре, и колонкой они дают список в четыре экрана.
   Правка 09.09.2026. */
.bundle {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
  max-width: var(--measure);
}

@media (min-width: 768px) {
  .bundle--grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    max-width: none;
  }
}

.bundle__card {
  display: grid;
  grid-template-columns: 120px minmax(0, 1fr);
  gap: var(--space-16);
  padding: var(--space-16);
  border: var(--border-width) solid var(--line);
  border-radius: var(--radius);
}

.bundle__media {
  display: flex;
  align-items: center;
  justify-content: center;
  aspect-ratio: 1 / 1;
  background-color: var(--paper-alt);
  border-radius: var(--radius);
  overflow: hidden;
}

/* Снимок спутника — ссылка на модель. Растянута на всю площадку кадра:
   мишенью должно быть изображение целиком. Подложка у кадра своя, серая,
   поэтому подчёркивание снимаем — иначе оно рисует полосу поперёк неё. */
.bundle__media-link {
  display: block;
  width: 100%;
  height: 100%;
  text-decoration: none;
}

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

.bundle__todo {
  padding: var(--space-8);
  text-align: center;
}

.bundle__title {
  font-size: var(--fs-h3);
}

.bundle__text {
  margin-top: var(--space-8);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.bundle__price {
  margin-top: var(--space-12);
  font-family: var(--font-mono);
  font-size: var(--fs-mono-price);
  font-weight: var(--fw-medium);
  font-variant-numeric: tabular-nums;
}

/* --- Блок 9. Тест-драйв ------------------------------------------------ */

/* Отключаемый модуль: своя секция, свой идентификатор, никаких связей
   с соседями. Левая акцентная линия — тот же приём, что у блока «Кто мы». */
/* Текст слева, кнопка справа у края блока, воздух между ними — так же,
   как устроен блок-призыв. Кнопка вторичная: основная кнопка на экране
   одна.

   До 05.09.2026 у блока стояло max-width: 900px, и кнопка вставала
   на 70% ширины, а справа от неё оставалась пустая треть — она читалась
   недоделкой, а не воздухом. Ограничение снято, и кнопка ушла к правому
   краю. Ширина самого текста при этом не изменилась: строку держит
   общее правило p { max-width: var(--measure) } из base.css, и абзац
   как занимал около 55% ширины блока, так и занимает. Воздух ушёл
   из-под правого края в промежуток между текстом и кнопкой — там он
   и читается воздухом. */
.test-drive__body {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
  align-items: center;
  padding-left: var(--space-24);
  border-left: var(--accent-bar) solid var(--scan-orange);
}

/* Ниже 768 блок в одну колонку, и кнопка стоит слева под текстом —
   растягивать её на всю ширину незачем, действие второстепенное.
   С 768 у неё своя колонка по ширине содержимого, и start в ней
   совпадает с end: колонка равна кнопке. */
.test-drive__cta {
  justify-self: start;
  white-space: nowrap;
}

@media (min-width: 768px) {
  .test-drive__body {
    grid-template-columns: minmax(0, 1fr) auto;
    gap: var(--space-32);
  }
}

/* --- Блок 10. Об аппарате ---------------------------------------------- */

/* Ширину строки держит текстовая колонка, а не весь блок: иначе снимок
   рядом с текстом упирался бы в тот же предел и справа оставалась полоса. */
.description__body {
  max-width: var(--measure);
}

.description__paragraph + .description__paragraph {
  margin-top: var(--space-16);
}

/* --- Блок 11. Форма запроса и завершение страницы ---------------------

   Два уровня. Верхний — форма на две трети и снимок на треть, ровно как
   блок быстрого вопроса на главной. Нижний — полоса во всю ширину:
   строка про гарантию и компактная подпись основателя рядом.

   В один ряд они стояли раньше и слипались: форма конкурировала с врезкой
   за внимание, а гарантия читалась как часть формы. Разведённые по уровням,
   форма остаётся действием, а гарантия с живым человеком — завершением
   страницы. */

.product-aside {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
  margin-top: var(--space-48);
  padding-top: var(--space-32);
  border-top: var(--border-width) solid var(--line);
}

.product-aside__warranty {
  max-width: none;
}

/* Подпись уже отбита сверху границей полосы, своя ей не нужна */
.signature--aside {
  margin-top: 0;
  padding-top: 0;
  border-top: 0;
  max-width: none;
}

@media (min-width: 768px) {

  .product-hero__inner {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: var(--space-48);
  }

  /* С 768 кнопки встают в две колонки. У позиции без аренды кнопка одна,
     и колонка одна — она занимает всю ширину. Задание 04.09.2026. */
  .product-hero__actions {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    align-items: start;
  }

  .product-hero__actions--single {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Полоса завершения: гарантия слева, подпись справа. Пропорция та же
     7:5, что у формы над ней, — уровни читаются одной сеткой. */
  .product-aside {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    gap: var(--space-48);
    align-items: start;
  }
}

@media (min-width: 1280px) {
  .product-hero__inner {
    gap: var(--space-64);
  }
}

/* --- Схема «Что помещается в тоннель» ----------------------------------

   Кегль подписей задан в единицах системы координат схемы, а не в пикселях
   экрана, и потому крупнее, чем у схемы зоны досмотра: у той своя система
   координат. Значение совпадает с FS в tools/svg-tonnel.py — расчёт
   переносов там опирается на него. */

.scheme__svg--tonnel .scheme__label {
  font-size: 30px;
}

.scheme__svg--tonnel .scheme__legend-text {
  font-size: 28px;
}

/* Силуэты предметов — контуром без заливки. Заливка перекрывала соседние
   силуэты, и вложенная композиция из-за неё не собиралась. */
.scheme__organic-outline {
  fill: none;
  stroke: var(--scan-orange);
  stroke-width: 2.5;
  stroke-linejoin: round;
}

/* Подложка под контуром: копия силуэта толстой линией цвета фона. Линии
   переднего предмета разрывают те, что за ним, и четыре наложенных контура
   перестают читаться клубком. */
.scheme__halo * {
  fill: none;
  stroke: var(--ink);
  stroke-width: 11;
  stroke-linejoin: round;
}

/* Ручки, лямки, швы и колёсики — тоньше контура: они помогают узнать
   предмет, но не должны спорить с его габаритом. */
.scheme__organic-detail {
  fill: none;
  stroke: var(--scan-orange);
  stroke-width: 1.5;
  stroke-linecap: round;
  stroke-linejoin: round;
  opacity: 0.75;
}

/* Проём — металл, поэтому синий; внутри темно, как в тоннеле «Зоны досмотра» */
.scheme__dim {
  fill: none;
  stroke: var(--ink-60-on-dark);
  stroke-width: 1;
}

/* Наконечник размерной линии. Правка 28.08.2026: прежде на концах стояли
   короткие перпендикулярные штрихи (.scheme__tickmark), а в схемах блока
   «Логистика» те же линии 27.08.2026 получили стрелки — два блока одной
   страницы показывали один элемент по-разному. Оформление приведено
   к принятому: ТЗ на редизайн v13, раздел 6, врезка «Устройство блока».

   Треугольник закрашен и обводки не имеет: обводка при уменьшении схемы
   до 360 съедает остриё. Цвет тот же, что у самой линии.

   Имя не .scheme__arrow: этот класс занят наконечником потока в схемах
   «Зоны досмотра» (.scheme__arrowhead, оранжевый), и рядом с ним второе
   похожее имя читалось бы как тот же элемент. Прежний .scheme__tickmark
   убран вместе со штрихами: после перегенерации восьми схем на него
   не ссылается ничто. */
.scheme__dim-arrow {
  fill: var(--ink-60-on-dark);
  stroke: none;
}

/* Выносная линия чертежа: тонкая штриховая, как принято в чертеже */
.scheme__hidden {
  fill: none;
  stroke: var(--ink-60-on-dark);
  stroke-width: 1;
  stroke-dasharray: 4 4;
  opacity: 0.6;
}

/* Непроходящий предмет: тот же силуэт, но приглушённый и штриховой —
   он показан как граница, а не как ещё один вариант. */
.scheme__no-item * {
  stroke: var(--ink-60-on-dark) !important;
  stroke-dasharray: 9 6;
  opacity: 0.9;
}

.scheme__no {
  fill: none;
  stroke: var(--ink-60-on-dark);
  stroke-width: 1.5;
  stroke-dasharray: 10 7;
}

.scheme__label--accent {
  fill: var(--scan-orange);
}

/* Настил поддона: те же штриховые линии, что и контур не проходящего */
.scheme__no-line {
  fill: none;
  stroke: var(--ink-60-on-dark);
  stroke-width: 1.2;
  stroke-dasharray: 6 5;
}

.logistics__floor {
  fill: none;
  stroke: var(--line);
  stroke-width: 1.5;
}

.logistics__leader {
  fill: none;
  stroke: var(--scan-blue);
  stroke-width: 1.2;
  stroke-dasharray: 6 5;
  opacity: 0.7;
}

/* Наконечник размерной линии. Правка 27.08.2026: прежде на концах
   стояли короткие перпендикулярные штрихи (.logistics__tickmark),
   и заказчик не опознал линии как размерные. Треугольник закрашен
   и обводки не имеет: обводка при уменьшении схемы до 360 съедает
   остриё. Цвет тот же, что у самой линии.

   Прежний класс .logistics__tickmark убран вместе со штрихами:
   после перегенерации схем на него не ссылается ничто. Схемы блока
   «Что помещается в тоннель» тогда затронуты не были и остались
   на штрихах; 28.08.2026 они переведены на стрелки тем же правилом,
   наконечник у них свой — .scheme__dim-arrow. */
.logistics__arrow {
  fill: var(--ink-60);
  stroke: none;
}

/* Наконечник у линии высоты аппарата — синий, как и её подпись:
   аппарат синий, проём серый, это различие работает и должно
   сохраниться. Отдельным классом, а не потомком подписи: наконечник
   живёт в <marker> внутри <defs>, потомком чего-либо на чертеже
   он не является, и селектор по родителю до него не достанет. */
.logistics__arrow--device {
  fill: var(--scan-blue);
}

/* --- Заполнение ширины в блоках 6, 7 и 10 ------------------------------
   Текст держится в 72 символах, а освободившееся место занимает
   содержимое: каталожный вид рядом с таблицей, ссылки на модели рядом
   с текстом, снимок ряда аппаратов рядом с описанием. Пустая полоса
   справа — это недоделанный блок, ТЗ на редизайн, раздел 4. */

.specs {
  max-width: none;
}

.specs__media,
.description__media {
  margin: 0;
}

.specs__media img,
.description__media img {
  display: block;
  width: 100%;
  height: auto;
  border-radius: var(--radius);
}

.specs__media img {
  background-color: var(--paper-alt);
}

.specs__media figcaption,
.description__media figcaption {
  margin-top: var(--space-12);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.suitable__aside-title {
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.suitable__aside .suitable__links {
  flex-direction: column;
  align-items: stretch;
  margin-top: var(--space-12);
}

.suitable__aside .suitable__link {
  justify-content: space-between;
}

@media (min-width: 768px) {
  .specs,
  .suitable,
  .description {
    display: grid;
    grid-template-columns: minmax(0, 7fr) minmax(0, 4fr);
    gap: var(--space-48);
    align-items: start;
  }

  .specs__body,
  .suitable__text,
  .description__body {
    min-width: 0;
  }

  /* Блок 7, когда в нём осталась одна колонка: у позиции нет врезки —
     моделей с заметно большим тоннелем в каталоге не нашлось, — либо
     наоборот, стёрт текст. Сетка в две колонки прижала бы оставшееся
     к 7fr и оставила справа пустые 4fr. Класс ставит render.js. */
  .suitable--solo {
    display: block;
  }

  /* То же у блока 10: свой снимок есть не у каждой позиции, а чужой
     ставить нельзя. Без фигуры сетка прижала бы текст к 7fr, оставив
     справа пустоту на 4fr. Класс ставит шаблон карточки. */
  .description--solo {
    display: block;
  }
}

.logistics__caption {
  margin-top: var(--space-12);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.logistics__caption-key {
  color: var(--scan-blue);
}

/* Общая рамка кадра с 768. Стоит в конце файла намеренно: базовые правила
   галереи карточки объявлены ниже галереи объектов, и переопределение
   рядом с ними не срабатывало. */
@media (min-width: 768px) {
  .product-gallery__main img {
    aspect-ratio: 16 / 9;
  }
}

/* ==========================================================================
   Каталожная страница

   Три блока плюс подвал: заголовок с вводным текстом и две группы моделей.
   Тёмных блоков нет — их роль на странице играет подвал.

   Ритм фона. Блок заголовка стоит на --paper-alt, группы карточек —
   на белом. Правка 24.08.2026: страница была белой целиком, и на фоне
   главной и хаба, где серые полосы чередуются с белыми, читалась плоско.
   Серым началом заголовок получает вес, а страница — ритм.

   Между группами фон не чередуется намеренно. Группы приходят из данных,
   и при третьей группе чередование пришлось бы считать по индексу: белая,
   серая, белая. Схема, которая ломается от строчки в JSON, хуже, чем
   её отсутствие.
   ========================================================================== */

/* Обёртка групп. display: contents убирает саму обёртку из раскладки,
   и секции остаются детьми <main>, как на остальных страницах: иначе
   полоса фона у секции обрезалась бы по ширине контейнера, а отбивки
   между секциями считались бы от обёртки.

   Обёртка нужна рендеру: renderList складывает копии в один контейнер,
   а групп на странице столько, сколько их в данных. Копипастить секцию
   группы в разметку нельзя — ТЗ на прототип, 4.1. */
.catalog__groups {
  display: contents;
}

/* Заголовок страницы и вводный абзац.

   На узком экране — одной колонкой. С 1280 — двумя: заголовок слева,
   абзац справа. Одной колонкой абзац упирается в предел длины строки
   в 72 знака, и справа остаётся пустая полоса в половину контейнера.
   Двумя колонками ширина занята содержимым, а строка остаётся
   в том же пределе. */
.catalog-head__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-16);
}

/* Обёртка абзаца, а не абзац: внутри — включаемая область, а её обёртка
   в режиме правки — div. Предел строки поэтому задан здесь, у абзаца он шёл
   из base.css. */
.catalog-head__text {
  max-width: var(--measure);
  color: var(--ink-60);
}

@media (min-width: 1280px) {
  .catalog-head__inner {
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--grid-gap);
    align-items: start;
  }

  /* Отбивку от заголовка в две колонки задаёт сетка, а не общее правило
     «h1 + *»: там она вертикальная и здесь сдвинула бы абзац вниз. */
  .catalog-head__inner > h1 + .catalog-head__lead {
    margin-top: 0;
  }

  /* Абзац в правой колонке шире предела в 72 знака не станет, но и уже
     колонки быть не должен: предел здесь задаёт сетка. */
  .catalog-head__text {
    max-width: none;
  }
}

/* Строка под заголовком группы. Печатается, только если у группы есть
   ключ note: у интроскопов его нет — одиннадцать карточек заполняют блок
   сами, и пояснение там было бы без надобности. Если ключа нет, рендер
   убирает узел целиком, а не оставляет пустой абзац с отбивкой. */
.catalog-group__note {
  margin-top: var(--space-16);
  color: var(--ink-60);
}

/* Ряд карточек отбивается от строки под заголовком так же, как отбивался
   бы от самого заголовка: расстояние принадлежит ряду, а не тому, что
   стоит над ним. */
.catalog-group__note + .equipment__grid {
  margin-top: var(--space-24);
}

@media (min-width: 768px) {
  .catalog-group__note + .equipment__grid {
    margin-top: var(--space-32);
  }
}

/* ==========================================================================
   Сегментная посадочная.

   Своих блоков у шаблона два: «Ситуация клиента» и плашки, приходящие
   из данных сегмента. Всё остальное на странице — те же компоненты, что
   на хабе, и своих правил не требует: первый экран, «Что входит», цены,
   карточки, таймлайн, «Почему мы», аккордеон и блок-призыв берут стили
   отсюда же, сверху.
   ========================================================================== */

/* --- Блоки 2 и 4а. Ситуация клиента и «Как арендовать рамки выгоднее» ---
   Текстовые блоки из абзацев. Ширину строки держит общее правило
   для <p> из base.css — не более 72 символов.

   С 1024 абзацы встают в две колонки. Одной колонкой на широком экране
   текст занимал бы чуть больше половины контейнера, и справа оставалась
   бы пустая полоса во всю высоту блока — ровно то, что стенд ширины
   ловит на других страницах. В двух колонках строка выходит около
   55 символов: норма соблюдена с запасом, а блок заполняет ширину.

   Правило общее на оба блока: раскладка у них одна, различается только
   то, откуда приходит текст. Классы разные, потому что «Ситуация» есть
   у всех пяти сегментов, а «Как выгоднее» — только у арок, и правки
   одного блока не должны молча доставаться другому. */

.situation__text,
.howto__text {
  margin-top: var(--space-24);
}

.situation__paragraph + .situation__paragraph,
.howto__paragraph + .howto__paragraph {
  margin-top: var(--space-16);
}

@media (min-width: 1024px) {
  .situation__text,
  .howto__text {
    display: grid;
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--space-24) var(--grid-gap);
  }

  .situation__paragraph + .situation__paragraph,
  .howto__paragraph + .howto__paragraph {
    margin-top: 0;
  }
}

/* --- Блок 4б. Характеристики арки ---------------------------------------
   Есть только у сегмента арок. Раскладка блока — компонент .specs
   карточки товара: с 768 таблица слева, каталожный вид справа. Своего
   здесь только строка маркеров над таблицей и строка ссылки под ней. */

.landing-specs__markers {
  margin-top: var(--space-16);
}

@media (min-width: 768px) {
  .landing-specs__markers {
    flex-direction: row;
    flex-wrap: wrap;
    align-items: center;
    gap: var(--space-8) var(--space-24);
  }
}

/* Отбивка перед таблицей. Своя, а не общая с .specs: у блока характеристик
   карточки товара над таблицей стоит заголовок, и отступ там уже есть.
   Соседним селектором её не задать — между списком маркеров и таблицей
   в разметке лежит <template> с образцом строки. */
.landing-specs {
  margin-top: var(--space-24);
}

/* Ссылка на полную таблицу. Навигационная, но стрелки не несёт: правило
   про стрелку — про кнопку-ссылку .btn, а это строка текста под таблицей. */
.landing-specs__full {
  margin-top: var(--space-24);
  font-size: var(--fs-small);
}

/* --- Плашки из данных сегмента ------------------------------------------
   Пример типового срока стоит между ориентирами и кнопкой прайса
   и выводится, только если у сегмента есть данные: у подмены типовой
   срок не задан, и узла на странице нет вовсе, отступ вместе с ним.

   Плашка графика смены после таймлайна снята 28.08.2026: тот же абзац
   выводится третьим аргументом в «Почему мы», а после перестановки
   блоков расстояние между повторами сократилось. Класс .landing-note
   остался: на нём же держится плашка блока «Что входит». */

.landing-note {
  margin-top: var(--space-48);
}

/* Строка про состояние техники под шестью пунктами блока «Что входит» —
   на хабе аренды и пяти посадочных. Курсив и увеличенный отступ: она читается
   примечанием к блоку, а не седьмым пунктом списка; тем же начертанием и кеглем
   она прилипала к последнему пункту. Решение заказчика 21.09.2026. */
.includes-condition {
  margin-top: var(--space-32);
  font-style: italic;
}

.pricing__example {
  margin-top: var(--space-32);
}

/* Строка о цене прайса при заказе за 10 дней — под таблицей цен на посадочных
   с общим блоком цен. Оформление то же, что у примера срока: обычный абзац.
   Под таблицей, когда примера нет (подмена), — тот же отступ, что у примера;
   под видимым примером — абзацем к абзацу, шаг поменьше. Решение заказчика
   05.10.2026, реестр v41. */
.pricing__order-terms {
  margin-top: var(--space-32);
}

.pricing__example + .pricing__order-terms {
  margin-top: var(--space-16);
}

/* --- Что ещё влияет на сумму ---------------------------------------------
   Строка под кнопкой прайса на посадочных. Списка факторов в сокращённом
   блоке нет и не будет — он остаётся на хабе, — и строка называет
   факторы перечислением, не разворачивая их в шесть пунктов прозы.

   До 05.09.2026 на этом месте стояла ссылка на хаб с якорем #pricing.
   Снята заданием: уводила с посадочной и вела не туда, куда обещала.
   Теперь это обычный текст, поэтому и приглушённый: подпись под
   действием, а не само действие. */

.pricing__sum-note {
  margin-top: var(--space-24);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.link-arrow {
  display: inline-flex;
  align-items: baseline;
  gap: var(--space-8);
}

.link-arrow__sign {
  flex: none;
  /* Приподнят к середине строчных — как знак в кнопке-ссылке. */
  transform: translateY(-0.04em);
}

/* --- Свой блок цен сегмента арок -----------------------------------------
   Общий блок ориентиров на этой странице не выводится вовсе: он построен
   на интроскопе, а человек пришёл за рамкой. Таблица берёт компонент хаба
   целиком — вместе с липкой первой колонкой, горизонтальной прокруткой
   и акцентом на самой выгодной ячейке. Своего здесь только строка под
   таблицей про доставку.

   «Как арендовать рамки выгоднее» живёт в той же секции и своего отступа
   сверху не имеет: он объясняет цифру, стоящую над ним, и в отрыве
   от неё не работает. До 29.08.2026 он стоял отдельной секцией через два
   блока от таблицы. Расстояние здесь — обычный шаг внутри блока,
   а не отбивка между блоками: разрыва в 64 px читатель не должен
   увидеть вовсе. */

/* Ширину строки держит общее правило для <p> — не более 72 знаков.
   Своей max-width здесь нет намеренно: 760 px таблицы при мелком кегле
   дают 82 знака в строке, и стенд ширины ловит это как норму. */
.pricing__below-table {
  margin-top: var(--space-24);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.howto {
  margin-top: var(--space-32);
}

.howto__title {
  font-size: var(--fs-h3);
}

/* ==========================================================================
   Страница контактов
   Четыре блока: способы связи, как мы работаем, кто мы, реквизиты.
   Своих компонентов у страницы два — сетка способов связи и перечень
   реквизитов; остальное берётся готовым: плашка .note, перечень .factors
   из блока цен и блок .about с главной.
   ========================================================================== */

/* Способы связи. Сетка та же, что в подвале: подпись мелким кеглем,
   значение под ней. Второй раз она описана здесь, а не переиспользована
   из подвала, потому что подвал тёмный и половина его правил — про цвета
   на тёмном фоне. */
.contacts-ways {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-24);
  margin-top: var(--space-32);
}

.contacts-ways__label {
  margin-bottom: var(--space-4);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.contacts-ways__value {
  font-family: var(--font-mono);
  font-size: 20px;
  font-variant-numeric: tabular-nums;
  color: var(--ink);
  text-decoration: none;
}

/* Телефон и почта — ссылки, и им нужна площадь нажатия */
a.contacts-ways__value {
  display: inline-flex;
  align-items: center;
  min-height: var(--tap-min);
}

a.contacts-ways__value:hover {
  color: var(--scan-orange-hover);
}

/* Моноширинный только на числовых данных: у мессенджера, склада
   и режима работы значение — проза, и шрифт у неё текстовый. */
.contacts-ways__value--text {
  font-family: var(--font-text);
  font-size: var(--fs-body);
}

.contacts-ways__messenger {
  display: inline-flex;
  align-items: center;
  gap: var(--space-8);
}

.contacts-ways__messenger-icon {
  width: 16px;
  height: 16px;
  flex: none;
}

/* Плашка про склад стоит сразу под адресными данными: она объясняет
   строку «Склад», а не блок целиком. */
.contacts-note {
  margin-top: var(--space-32);
}

/* Четыре кадра склада. Компонент галереи объектов, но раскладка своя:
   по умолчанию с 1280 галерея идёт в три колонки, и четвёртый кадр
   уезжал бы во второй ряд один. С 1280 кадры встают в ряд по четыре,
   до этого работает общее правило — две колонки с 768 и одна ниже.

   Отбивка сверху здесь меньше, чем у галереи: кадры относятся
   к плашке над ними, а не к блоку целиком. */
.gallery--four {
  margin-top: var(--space-24);
}

/* Общая галерея берёт на мобильном пропорцию самого кадра, здесь — нет.
   Причина того правила — обещание лупы: обрезанное превью не должно
   оказаться крупнее того, что открывается в окне. У этих четырёх кадров
   оно не нарушается, окно на 360 показывает их заметно крупнее превью.

   А причина исключения в том, что эта сетка стоит не отдельным блоком,
   а внутри первого: под ней ещё строка про зону работы и единственная
   кнопка страницы. Два вертикальных кадра в полную высоту уводили
   кнопку почти на полтора экрана вниз. */
.gallery--four .gallery__media {
  aspect-ratio: 3 / 2;
}

@media (min-width: 768px) {
  .gallery--four {
    margin-top: var(--space-32);
  }
}

@media (min-width: 1280px) {
  .gallery--four {
    grid-template-columns: repeat(4, minmax(0, 1fr));
  }
}

/* Строка про зону работы. Карты на странице нет, и эта строка стоит
   на её месте — отсюда отбивка, равная шагу внутри блока, а не абзацу. */
.contacts-zone {
  margin-top: var(--space-24);
}

.contacts-actions {
  margin-top: var(--space-32);
}

/* Реквизиты в развёрнутом виде. В подвале те же три строки стоят
   свёрнутыми — документ с текстами, раздел 2, блок 12.

   Раскладка та же, что у подвала: колонкой три коротких строки занимают
   четверть контейнера, и справа остаётся пустая полоса во всю высоту
   блока — ровно то, что стенд ширины ловит как ошибку раскладки. */
.requisites {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-8);
  margin-top: var(--space-24);
}

/* Отбивку между строками задаёт gap сетки. Общее правило «абзац
   за абзацем» добавляло к нему свои 16 px сверху, и в ряду это
   превращалось в сдвиг: название ИП стояло строкой выше, чем ОГРН
   и ИНН. В колонку на мобильном тот же отступ удваивал зазор. */
.requisites > p + p {
  margin-top: 0;
}

.requisites__name {
  font-weight: var(--fw-medium);
}

.requisites__line {
  color: var(--ink-60);
}

@media (min-width: 768px) {
  .contacts-ways {
    grid-template-columns: repeat(2, minmax(0, 1fr));
    gap: var(--grid-gap);
  }

  .contacts-ways__label {
    margin-bottom: var(--space-8);
  }

  .requisites {
    grid-template-columns: repeat(3, minmax(0, 1fr));
    gap: var(--grid-gap);
  }
}

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

/* ==========================================================================
   Схема «Несколько точек входа» — хаб аренды, блок «Чем мы отличаемся»

   Четвёртая схема проекта, ТЗ на редизайн v14, раздел 10, строка 4.
   Светлая линейная: тёмный блок на хабе занят схемой зоны досмотра,
   а двух сигнатурных блоков на одной странице быть не может.

   До 28.08.2026 эти правила лежали в теге стилей на полигоне: схема была
   разведочной, на страницах её не было, и держать её тремя файлами было
   дешевле. Схема принята и стоит на хабе — правила переехали сюда,
   к остальным схемам. На полигоне своей копии не осталось: он берёт
   их отсюда, и разойтись двум наборам негде.

   Разметку схемы пишет tools/svg-tochki-vhoda.py между метками
   TOCHKI:START / TOCHKI:END в arenda.html и в tochki-vhoda-poligon.html.
   На хабе выводится сокращённый вариант — без заголовка схемы и без
   шести пунктов, — на полигоне полный.
   ========================================================================== */

/* Ширина схемы ограничена и во всю колонку не тянется. Половина широкая
   и низкая, отношение кадра около трёх с половиной к одному; растянутые
   на 1280 px две половины встают полосой в треть экрана высотой.
   Ограничение стоит на всей схеме, а не на одном чертеже: подписи,
   перечни и строка под ними должны стоять по краям чертежей.

   По центру колонки схема не ставится: тогда её содержимое уезжает вправо
   от заголовка блока и от трёх колонок над ней, и схема читается вставкой,
   а не частью блока. */
/* Отступ сверху несёт сама схема: на хабе она встаёт после трёх колонок
   блока, и без него её чертёж упирается в конец самой короткой колонки. */
.entries {
  max-width: 900px;
  margin-top: var(--space-48);
}

.entries__title {
  margin-bottom: var(--space-24);
}

.entries__figure {
  margin: 0;
}

/* Половины. Ниже 768 — друг под другом, во всю ширину: рядом на 360
   на вход приходилось 53 px, и разнобой силуэтов, ради которого схема
   и сделана, переставал читаться. Порядок сохраняется — сначала «как
   бывает», потом «как делаем мы»: в столбик это читается как «было —
   стало». */
.entries__parts {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-32);
}

.entries__part {
  position: relative;
  display: flex;
  flex-direction: column;
}

/* Разделитель половин. Ниже 768 он горизонтальный, с 768 вертикальный.
   Нарисован псевдоэлементом в середине зазора, а не рамкой на второй
   половине: рамка с отступом сузила бы вторую колонку против первой,
   половины отрисовались бы в разном масштабе, и сравнивать силуэты
   стало бы нельзя.

   Цвет — приглушённый прозрачностью серый, а не цвет разделителей:
   блок «Чем мы отличаемся» стоит на сером фоне, и --line на нём
   ложится на фон почти без разницы. */
.entries__part + .entries__part::before {
  content: '';
  position: absolute;
  left: 0;
  right: 0;
  top: calc(var(--space-32) / -2);
  height: 1px;
  background-color: var(--ink-60);
  opacity: 0.25;
}

/* Подпись половины. Ниже 768 стоит НАД своим чертежом: в столбик подпись
   снизу отрывается от своего рисунка и липнет к следующему. С 768 чертёж
   поднимается над ней свойством order, и выходит принятая раскладка.

   Обе подписи разбиты на две строки генератором, а не браузером. Отдай
   перенос браузеру — и на узкой колонке левая подпись встанет в одну
   строку, правая в две, а перечни под ними разъедутся на строку. */
.entries__caption {
  margin: 0 0 var(--space-12);
  font-family: var(--font-mono);
  font-size: var(--fs-h3);
  line-height: 1.3;
  color: var(--ink);
  text-align: center;
}

.entries__caption span {
  display: block;
}

/* Ниже 768 половина получает всю ширину колонки, и без потолка чертёж
   вырастал бы вдвое против того, каким он стоит рядом: на 767 вход
   выходил в 227 px против 104 px на 768. Схема начинала перевешивать
   блок, а подпись под таким чертежом казалась подписью не к нему.
   Потолок держит переход через брейкпоинт соразмерным; на 360 он
   не срабатывает — там колонка и так уже. */
.entries__chart {
  display: block;
  width: 100%;
  max-width: 480px;
  margin-inline: auto;
  height: auto;
}

/* Светлая линейная схема, те же толщины, что у схемы логистики:
   контур 1.5, аппарат 2, пол 1.5.

   Три уровня яркости, и они не случайны. Проём и пол — обстановка,
   они одинаковы во всех шести входах и в сравнении не участвуют.
   Арка — предмет на входе, приглушённый серый. Аппарат — то, ради чего
   схема, — синий. Раскрасить проём наравне с аппаратом значило бы
   утроить число заметных фигур в ряду.

   Обстановка приглушена прозрачностью штриха, а не цветом разделителей:
   на сером фоне блока --line ложится на фон почти без разницы,
   и проёмы пропадают вовсе. */
.entries__portal {
  fill: none;
  stroke: var(--ink-60);
  stroke-opacity: 0.45;
  stroke-width: 1.5;
}

.entries__arch {
  fill: var(--ink-60);
  fill-opacity: 0.10;
  stroke: var(--ink-60);
  stroke-width: 1.5;
}

.entries__device {
  fill: var(--scan-blue);
  fill-opacity: 0.12;
  stroke: var(--scan-blue);
  stroke-width: 2;
}

/* Тоннель набран поверх корпуса той же синей заливкой, а не белым:
   белый проём читался бы дырой на сером фоне блока. Наложение двух
   полупрозрачных заливок даёт проём темнее корпуса на любом фоне. */
.entries__tunnel {
  fill: var(--scan-blue);
  fill-opacity: 0.18;
  stroke: var(--scan-blue);
  stroke-width: 1.5;
}

.entries__floor {
  fill: none;
  stroke: var(--ink-60);
  stroke-opacity: 0.35;
  stroke-width: 1.5;
}

/* Перечень под половиной. Выводится только в полном варианте — на хабе
   шести пунктов нет: они пересказывают абзац средней колонки того же
   блока.

   Метка списка — тот же квадрат 4 × 4, что у .markers, но серый.
   Оранжевый в этой схеме не появляется намеренно: разницу между
   половинами держат форма и ритм, а цветом её добиваться нельзя —
   цвет в проекте занят другими значениями. */
.entries__list {
  display: flex;
  flex-direction: column;
  gap: var(--space-8);
  margin-top: var(--space-24);
  font-size: var(--fs-small);
  color: var(--ink);
}

.entries__list li {
  display: flex;
  align-items: baseline;
  gap: var(--space-8);
}

.entries__list li::before {
  content: '';
  flex: none;
  width: 4px;
  height: 4px;
  background-color: var(--ink-60);
  transform: translateY(-3px);
}

.entries__note {
  margin-top: var(--space-24);
  color: var(--ink-60);
}

@media (min-width: 768px) {
  .entries__parts {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .entries__part + .entries__part::before {
    left: calc(var(--space-32) / -2);
    right: auto;
    top: 0;
    bottom: 0;
    width: 1px;
    height: auto;
  }

  .entries__chart {
    order: -1;
    max-width: none;
    margin-inline: 0;
  }

  .entries__caption {
    margin: var(--space-16) 0 0;
  }
}

/* --- Строка о ручных металлодетекторах со снимком ------------------------
   Под рядом карточек хаба аренды и под блоком спутников на карточке товара.
   Снимок обрезан по прибору: 200 px от 768, 160 px уже, слева, по центру
   по вертикали, на всех ширинах. Решение заказчика 01.10.2026. */
.handheld-note {
  display: flex;
  align-items: center;
  gap: var(--space-12);
  margin-top: var(--space-24);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

.handheld-note__img {
  flex: none;
  width: 160px;
  height: auto;
}

@media (min-width: 768px) {
  .handheld-note__img {
    width: 200px;
  }
}

/* Ответ FAQ со снимком (посадочная арок, свойство FAQ_IMAGE): от 768 px снимок
   слева от текста, уже — над текстом. Снимок обрезан по прибору, 160 px. */
.accordion__panel--media {
  flex-direction: column;
  align-items: flex-start;
  gap: var(--space-16);
}

.accordion__item.is-open .accordion__panel--media {
  display: flex;
}

.accordion__img {
  flex: none;
  width: 160px;
  height: auto;
}

@media (min-width: 768px) {
  .accordion__panel--media {
    flex-direction: row;
  }
}

/* ==========================================================================
   Страница выкупа — карта сайта v33, раздел 5а.
   Своих компонентов почти нет: первый экран — .hero посадочных, шаги и
   вопросы — хаба, поля формы — общие. Здесь только то, чего в готовых нет:
   шапка без меню, снимок вертикальной раскладки, пиктограммы шагов,
   раскладка полей формы в окне, поле «Фото».
   ========================================================================== */

/* Шапка страницы: логотип, телефон, кнопка. Меню, поиска и гамбургера
   нет, поэтому с 768 кнопка появляется в шапке, когда кнопка первого
   экрана ушла с экрана, и прячется, когда та вернулась (ui.js,
   initHeaderCta). До 768 логотип, телефон
   и кнопка в 375 px в одну строку не помещаются (шапка вырастала до 105 px),
   и кнопки там нет, как нет её в мобильной шапке остальных страниц. */
.header--bare .header__actions {
  display: none;
}

@media (min-width: 768px) {
  /* Общее правило шапки показывает кнопку с прилипанием; здесь её показывает
     только уход кнопки первого экрана. */
  .header--bare.is-stuck:not(.is-cta-shown) .header__actions {
    display: none;
  }

  .header--bare.is-cta-shown .header__actions {
    display: flex;
    animation: header-actions-in var(--motion-duration) var(--motion-easing);
  }
}

.header--bare .header__actions .btn {
  white-space: nowrap;
}

/* Первый экран со снимком справа. Снимок вертикальный: кадр держит
   пропорцию 3:4, а не высоту текстовой колонки, иначе аппарат и монитор
   обрезались бы. Колонка снимка поэтому уже, чем у посадочных. */
.hero--vykup .hero__photo {
  object-position: center 30%;
}

@media (min-width: 768px) {
  .hero--vykup .hero__inner {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
    align-items: center;
  }

  .hero--vykup .hero__media {
    min-height: 0;
    max-width: 360px;
    aspect-ratio: 3 / 4;
    justify-self: end;
    width: 100%;
  }
}

/* «Частые вопросы»: горизонтальный снимок склада. С 1280 стоит в левой
   колонке под заголовком, вопросы — справа; на узких экранах идёт после
   вопросов, не шире 560 px. */
.vykup-photo {
  margin: var(--space-24) 0 0;
  max-width: 560px;
}

.vykup-photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 3 / 2;
  object-fit: cover;
  border-radius: var(--radius);
}

/* Абзацы блока «Что покупаем»: между ними — обычный ритм текста */
.vykup-text p + p {
  margin-top: var(--space-16);
}

/* Пиктограмма шага стоит на месте цифры: слева над текстом шага.
   Цифр у шагов страницы выкупа нет, порядок держит <ol>. */
.step__icon {
  display: block;
  width: 28px;
  height: 28px;
  margin-bottom: var(--space-8);
  color: var(--scan-orange);
}

/* С 1280 заголовок блока слева, содержимое справа — раскладка шапки
   каталога, 4 к 7. Одной колонкой строка упирается в предел в 72 знака,
   и справа остаётся пустая полоса в половину контейнера. */
@media (min-width: 1280px) {
  .vykup-split {
    display: grid;
    grid-template-columns: minmax(0, 4fr) minmax(0, 7fr);
    gap: var(--grid-gap);
    align-items: start;
  }

  /* Отбивку между колонками задаёт сетка, а не общее правило «h2 + *» */
  .vykup-split > h2 + *,
  .vykup-split .faq__list {
    margin-top: 0;
  }

  .vykup-split--faq > h2 {
    grid-column: 1;
    grid-row: 1;
  }

  .vykup-split--faq .faq__list {
    grid-column: 2;
    grid-row: 1 / span 2;
  }

  .vykup-split--faq .vykup-photo {
    grid-column: 1;
    grid-row: 2;
    margin-top: 0;
    max-width: none;
  }
}

.vykup-form__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-16);
}

.vykup-form__grid .field + .field {
  margin-top: 0;
}

@media (min-width: 768px) {
  .vykup-form__grid {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  .vykup-form__grid .field--wide {
    grid-column: 1 / -1;
  }

  .quick__footer .btn {
    width: auto;
  }
}

/* Поле выбора файлов: тот же вид, что у остальных полей, кнопка выбора
   браузера внутри — без своего оформления. */
.field__control--file {
  padding-block: var(--space-8);
  cursor: pointer;
}

.field__control--file::file-selector-button {
  margin-right: var(--space-12);
  padding: var(--space-4) var(--space-12);
  font: inherit;
  color: var(--ink);
  background-color: var(--paper);
  border: var(--border-width) solid var(--line);
  border-radius: var(--radius);
  cursor: pointer;
}

.vykup-form__files {
  margin: var(--space-8) 0 0;
  padding: 0;
  list-style: none;
  font-size: var(--fs-small);
  color: var(--ink);
}

.vykup-form__files:empty {
  display: none;
}

.vykup-form__files li {
  overflow-wrap: anywhere;
}


/* Окно выкупа: подтверждение стоит на месте всего содержимого, и верхняя
   отбивка, нужная ему под заголовком на странице, здесь не нужна —
   заголовок окна на это время скрыт. Справа от него крестик закрытия. */
.modal--vykup .quick__done {
  margin-top: 0;
  padding-right: var(--space-48);
}

/* Слова-ссылки на окно выкупа в тексте шага и ответа — обычная ссылка
   `<a href="#vykup-modal">`: классов и `data-*` в тексте, который правит владелец,
   быть не может (решение 04.10.2026, `decisions.md`). Вид — общий вид ссылки
   из base.css, как у `.text-action` прототипа. В прототипе это кнопка, а кнопка
   — строчный блок и по словам не рвётся: без этого правила в шаге 1 на 1280
   формулировка переносилась посередине и шаг выходил ниже на строку,
   чем в утверждённом прототипе. */
a[href="#vykup-modal"] {
  white-space: nowrap;
}

/* Слова-ссылка на окно брифа в тексте первого экрана страницы «Как выбрать
   интроскоп» («опишите, что будете досматривать»). В прототипе это кнопка
   `.text-action`: по словам она не рвётся, и на 375 абзац выходит выше на строку,
   чем у ссылки, которая переносится. Правило повторяет неразрывность — тот же
   приём и та же причина, что у ссылки окна выкупа выше. */
a[href="#brief-modal"] {
  white-space: nowrap;
}

/* Страница-гид /kak-vybrat-introskop/ — правила прототипа (коммит 3e99a27,
   blocks.css, раздел «Как выбрать интроскоп») перенесены без изменений.
   Разметку печатают шаблоны компонентов `introskop_gid_*` и `gid_*`;
   `decisions.md`, раздел 25. */
/* ==========================================================================
   Страница «Как выбрать интроскоп» — карта сайта v35, раздел 5б.

   Своего здесь три вещи: четыре группы «снимок + модели», пометка модели
   («в аренду» / «только продажа») и строка со ссылкой на страницу, которая
   стоит на хабе, в каталоге и на карточке. Остальное — готовые компоненты:
   первый экран хаба, таблица цен, перечень .factors, аккордеон, блок-призыв.
   Отступы и цвета — только токены.
   ========================================================================== */

/* Блок 2. Группа: снимок и текст. На узком экране снимок сверху, кадром
   4:3 — вертикальный кадр на телефоне занял бы целый экран. */
.gid-groups {
  display: grid;
  gap: var(--space-48);
  margin-top: var(--space-32);
}

.gid-group {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: var(--space-16);
}

.gid-group + .gid-group {
  padding-top: var(--space-48);
  border-top: var(--border-width) solid var(--line);
}

.gid-group__media {
  margin: 0;
}

.gid-group__photo {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  object-position: center 30%;
  border-radius: var(--radius);
}

.gid-group__lead {
  margin-top: var(--space-8);
}

.gid-models {
  margin: var(--space-16) 0 0;
  padding: 0;
  list-style: none;
}

.gid-model {
  max-width: var(--measure);
}

.gid-model + .gid-model {
  margin-top: var(--space-12);
}

.gid-model__name {
  font-weight: var(--fw-medium);
}

/* Пометка стоит после названия и не спорит с ним: по ней посетитель,
   пришедший арендовать, отличает модель, которую только продаём. */
.gid-model__mark {
  color: var(--ink-60);
}

@media (min-width: 768px) {
  .gid-group {
    grid-template-columns: 220px minmax(0, 1fr);
    gap: var(--space-32);
    align-items: start;
  }

  .gid-group__photo {
    aspect-ratio: 3 / 4;
  }
}

@media (min-width: 1280px) {
  .gid-group {
    grid-template-columns: 280px minmax(0, 1fr);
    gap: var(--space-48);
  }
}

/* Блок 3. Таблица сравнения шире таблицы цен хаба: шесть столбцов
   в 760 px не помещаются. Уже контейнера она не станет и уезжает
   в прокрутку внутри .table-scroll. Столбец «Аренда» не рвётся:
   «от 124 000 ₽/сутки» в две строки читается как две ячейки. */
.gid-table-wrap {
  max-width: none;
}

.gid-table {
  font-size: var(--fs-small);
}

.gid-table th,
.gid-table td {
  padding-inline: var(--space-12);
}

.gid-table th:first-child,
.gid-table td:first-child {
  white-space: nowrap;
}

.gid-table td:last-child {
  white-space: nowrap;
}

.gid-table-note {
  margin-top: var(--space-16);
  font-size: var(--fs-small);
  color: var(--ink-60);
}

/* Блок 4 */
.gid-factors-lead {
  margin-top: var(--space-16);
}

.gid-factors-below {
  margin-top: var(--space-24);
}

.gid-photo {
  margin: var(--space-32) 0 0;
}

.gid-photo img {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 16 / 9;
  object-fit: cover;
  border-radius: var(--radius);
}

@media (min-width: 768px) {
  .gid-photo img {
    aspect-ratio: 21 / 9;
  }
}

/* Строка со ссылкой на страницу: хаб, каталог, карточка. Фраза приглушена,
   ссылка — обычная со стрелкой (.link-arrow). */
.gid-link {
  margin-top: var(--space-24);
  color: var(--ink-60);
}

/* Цель нажатия не меньше 44 px по высоте */
.gid-link .link-arrow {
  align-items: center;
  min-height: var(--tap-min);
}

/* Каталог: строка стоит под вводным текстом, в той же колонке. На 1280
   сетка шапки двухколонная — строка уходит под абзац, в правую колонку. */
.catalog-head__gid {
  margin-top: 0;
}

@media (min-width: 1280px) {
  .catalog-head__gid {
    grid-column: 2;
  }
}

/* Карточка: строка внутри тёмного блока тоннеля. Синий отведён металлу
   в схемах и на подложке не читается — ссылка оранжевая, как отсылка
   к другой модели. */
.scheme__gid {
  margin-top: var(--space-32);
  color: var(--ink-60-on-dark);
}

.scheme__gid a {
  color: var(--scan-orange);
  text-decoration-color: rgba(232, 114, 28, 0.5);
}

.scheme__gid a:hover {
  color: var(--ink-on-dark);
}
