/* ==========================================================================
   1-я Лифтовая компания — оформление сайта

   Подача журнальная: чёрно-белая база, крупные заголовки в верхнем
   регистре, много воздуха, нумерованные карточки. Цвет один — фирменный
   бирюзовый; он расставляет акценты и больше нигде не спорит с фотографиями.

   Структура файла: шрифт → токены → база → типографика → кнопки →
   шапка → главная → страницы разделов → карточка товара → формы →
   подвал → адаптив.
   ========================================================================== */

/* --- Шрифты ---------------------------------------------------------------
   Tenor Sans — заголовки, Montserrat — текст. Оба под лицензией OFL,
   лежат в theme/fonts/ и отдаются с нашего сервера: сайт не зависит
   от доступности сторонних сервисов. Подробности — theme/fonts/README.txt

   unicode-range делит файлы на кириллицу и латиницу: браузер скачивает
   только то, что реально встретилось на странице. */

@font-face {
  font-family: "Tenor Sans";
  src: url("/assets/fonts/tenor-sans-cyrillic.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Tenor Sans";
  src: url("/assets/fonts/tenor-sans-latin.woff2") format("woff2");
  font-weight: 400; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2192, U+2212;
}

/* Цифры в заголовках берутся не из Tenor Sans, а из Montserrat: у Tenor
   Sans семёрка перечёркнутая, и год «1978» читался как «1.9.7̶.8». Семейство
   покрывает только сами цифры (U+0030–0039), остальные знаки берутся
   из Tenor Sans — она идёт следующей в списке --display.
   Начертание светлое: так цифры не выбиваются из тонких заголовков. */
@font-face {
  font-family: "Display Digits";
  src: url("/assets/fonts/montserrat-latin.woff2") format("woff2");
  font-weight: 300; font-style: normal; font-display: swap;
  unicode-range: U+0030-0039;
}

/* Montserrat вариативный: один файл покрывает начертания от 300 до 700. */
@font-face {
  font-family: "Montserrat";
  src: url("/assets/fonts/montserrat-cyrillic.woff2") format("woff2");
  font-weight: 300 700; font-style: normal; font-display: swap;
  unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
}
@font-face {
  font-family: "Montserrat";
  src: url("/assets/fonts/montserrat-latin.woff2") format("woff2");
  font-weight: 300 700; font-style: normal; font-display: swap;
  unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+2000-206F, U+2192, U+2212;
}

/* --- Токены -------------------------------------------------------------- */

:root {
  /* Бирюзовый взят пипеткой из логотипа FEC — цвет сайта и знака совпадают. */
  --brand: #16999f;
  --brand-600: #12858a;
  --brand-700: #0e6d72;
  --brand-050: #f0fafa;

  /* Тона шапки сняты пипеткой с макета.
     Линия под шапкой — не ровное золото, а переход: к середине почти белая,
     к краям янтарная. Поэтому цвета два, а не один. */
  --gold: #d9a45e;
  --gold-bright: #fff3b8;
  --header-bg: #080a0a;
  --cta: #1d7378;          /* заливка кнопки «Оставить заявку» */
  --cta-hover: #23888e;

  --ink: #0e0e0e;
  --ink-800: #1c1c1c;
  --text: #23262a;
  --muted: #7c8288;
  --line: #e5e6e7;
  --line-soft: #efefef;
  --bg: #ffffff;
  --soft: #f6f6f6;
  --soft-2: #ededed;

  /* Подложка под надзаголовком раздела: тот же бирюзовый, разбавленный
     почти до фона. Она отделяет метку раздела от текста, но не спорит
     с заголовком, который стоит следом. */
  --tint: rgba(22, 153, 159, .10);
  --tint-line: rgba(22, 153, 159, .24);
  /* Тень «объёма» при наведении на кликабельный блок */
  --lift: 0 18px 38px -18px rgba(14, 40, 42, .42);

  /* Содержимое идёт от края до края: предел выше любого монитора, так что
     ширину задаёт не он, а поля. Шапка и страница делят одну ширину —
     заголовки встают ровно под логотипом.
     Длину строки это не рвёт: у сплошного текста свой предел в символах. */
  --container: 2200px;
  --container-wide: 2200px;
  --gutter: clamp(20px, 2.6vw, 56px);
  --radius: 2px;          /* углы почти прямые — так строже */
  --radius-lg: 4px;
  --radius-card: 16px;    /* скругление снимка в карточке раздела */

  --shadow: 0 20px 50px -30px rgba(0, 0, 0, .5);
  --shadow-lg: 0 30px 80px -40px rgba(0, 0, 0, .6);

  --header-h: 76px;
  --ease: cubic-bezier(.4, 0, .2, 1);
  /* Мягкое затухание для вступления: быстро трогается, долго досыпает.
     На длинных появлениях выглядит заметно плавнее обычного. */
  --ease-soft: cubic-bezier(.16, 1, .3, 1);

  /* Заголовки — светлые и широкие, набираются в верхнем регистре.
     Текст — геометричный гротеск. Свой шрифт впишите первым в список. */
  --display: "Display Digits", "Tenor Sans", "Segoe UI", system-ui, Arial, sans-serif;
  --body: "Montserrat", "Segoe UI", system-ui, Arial, sans-serif;
}

/* --- База ---------------------------------------------------------------- */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; scroll-behavior: smooth; }

body {
  margin: 0;
  background: var(--bg);
  color: var(--text);
  font: 400 15.5px/1.7 var(--body);
  overflow-x: hidden;
  -webkit-font-smoothing: antialiased;
}

img { max-width: 100%; height: auto; display: block; }
/* Скрытое скрыто всегда. Без этой строки любое наше правило с display
   перебивает атрибут hidden, и спрятанный скриптом блок остаётся на виду:
   так было с выбором направления в форме заявки. */
[hidden] { display: none !important; }
a { color: inherit; text-decoration: none; }
button { font: inherit; color: inherit; }
::selection { background: var(--brand); color: #fff; }
:focus-visible { outline: 2px solid var(--brand); outline-offset: 3px; }

.container { width: 100%; max-width: var(--container); margin-inline: auto; padding-inline: var(--gutter); }

/* Шапка шире основной колонки: логотип уходит ближе к краю экрана,
   а телефон и кнопка — к правому. На узких экранах разницы нет. */
.container--wide { max-width: var(--container-wide); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; overflow: hidden;
  clip: rect(0 0 0 0); clip-path: inset(50%); white-space: nowrap;
}

/* --- Типографика ---------------------------------------------------------
   Заголовки крупные, в верхнем регистре, с плотным межбуквенным просветом —
   это главный узнаваемый приём оформления. */

/* Заголовки: Tenor Sans существует только в одном начертании, поэтому
   вес им не задаётся — выразительность даёт размер и разрядка.
   Искусственное утолщение (font-weight: 700) такой шрифт портит. */
h1, h2, h3, h4 { margin: 0; color: var(--ink); font-family: var(--display); font-weight: 400; line-height: 1.08; }

h1, .h1 {
  font-size: clamp(32px, 5vw, 68px);
  text-transform: uppercase;
  letter-spacing: .035em;
}
h2, .h2 {
  font-size: clamp(25px, 3.4vw, 46px);
  text-transform: uppercase;
  letter-spacing: .04em;
}
h3 { font-size: clamp(18px, 1.6vw, 23px); letter-spacing: .02em; }
p { margin: 0 0 1em; }

/* Название раздела: крупные заглавные с бирюзовой чертой над ними.
   Черта — метка того, что начался новый раздел; по ней видно границу
   между блоками страницы, даже когда фон везде одинаковый. */
.sec__name {
  position: relative; margin: 0; padding-top: clamp(18px, 2vw, 26px);
  font-size: clamp(27px, 3.4vw, 50px);
}
.sec__name::before {
  content: ""; position: absolute; left: 0; top: 0;
  width: 56px; height: 3px; background: var(--brand);
}

/* Строка под названием — о чём раздел. Обычно это подпись к перечню
   («Продукция», «Стоимость работ»), поэтому она набрана мельче и
   приглушённо: спорить с названием ей незачем. */
.sec__lead {
  margin: clamp(12px, 1.4vw, 18px) 0 0; max-width: 62ch;
  color: var(--muted); font-size: 16.5px; line-height: 1.7;
}
/* Исключение — разделы, где под названием не подпись, а собственное
   утверждение компании. Там строка крупная и в шрифте заголовков. */
.sec__lead--big {
  max-width: 26ch;
  color: var(--ink); font-family: var(--display);
  font-size: clamp(19px, 1.9vw, 31px); font-weight: 400;
  text-transform: uppercase; letter-spacing: .03em; line-height: 1.25;
}

/* --- Секции -------------------------------------------------------------- */

/* Поля разделов одинаковые и умеренные: страница читается плотнее,
   разделы выходят близкими по высоте. */
.section { position: relative; padding-block: clamp(40px, 4.8vw, 84px); }
.section > .container { position: relative; z-index: 1; }
.section--soft { background: var(--soft); }
.section--dark { background: var(--ink); color: rgba(255, 255, 255, .72); }
.section--dark h2, .section--dark h3 { color: #fff; }
.section--tight { padding-block: clamp(40px, 5vw, 80px); }
/* Раздел без полей сверху и снизу — для полосы во всю ширину, которая
   сама себе фон и должна вставать вплотную к соседним разделам. */
.section--flush { padding-block: 0; }
/* Плотнее обычного — строки списка вопросов. */
.section--compact .faq__q { padding: 18px 0; }
.section--compact .faq__a-inner > div { padding-bottom: 20px; }

/* Шапка раздела отделена от содержимого волосяной линией: название
   с подписью читаются как заголовок, а не как первая строка списка. */
.section__head {
  display: flex; align-items: flex-end; justify-content: space-between; gap: 32px;
  margin-bottom: clamp(22px, 2.6vw, 36px);
  padding-bottom: clamp(16px, 1.8vw, 24px);
  border-bottom: 1px solid var(--line);
}
.section__head-text { max-width: 60%; }
.section__actions { display: flex; flex-wrap: wrap; gap: 12px; }
.section--dark .sec__lead { color: rgba(255, 255, 255, .6); }
.section--dark .sec__lead--big { color: #fff; }
.section--dark .section__head { border-bottom-color: rgba(255, 255, 255, .16); }

/* --- Места под фотографии -------------------------------------------------
   Пока снимка нет, на его месте стоит рамка с подписью и размером, под
   который свёрстано место. Появится фотография — рамка исчезнет сама:
   она рисуется только на пустой обёртке (класс is-empty). */

.slot {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 6px; width: 100%; height: 100%; padding: 12px; text-align: center;
}
.slot__label {
  color: var(--muted); font-size: 11.5px; font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase;
}
.slot__size {
  color: var(--brand-700); font-family: var(--display);
  font-size: 15px; letter-spacing: .08em;
}
.is-empty {
  border: 1px dashed #d2d5d7;
  background: repeating-linear-gradient(135deg, #f7f8f8 0 12px, #f0f1f2 12px 24px);
}

/* --- Фоновая подложка раздела ---------------------------------------------
   Снимок во всю ширину раздела; поверх него вуаль, иначе текст на
   фотографии не прочитать. Пустая подложка показывает нужный размер
   в углу, а не по центру, — чтобы не спорить с содержимым раздела. */

.section__bg { position: absolute; inset: 0; overflow: hidden; }
.section__bg img { width: 100%; height: 100%; object-fit: cover; }
/* Вуаль повторяет фон раздела, а не осветляет его: иначе раздел с
   фотографией выбивался бы по тону из соседних. */
.section__bg::after {
  content: ""; position: absolute; inset: 0;
  background: rgba(255, 255, 255, .82);
}
.section--soft .section__bg::after { background: rgba(246, 246, 246, .84); }
.section__bg.is-empty { background: none; border: 1px dashed #dcdfe1; }
.section__bg.is-empty::after { content: none; }
.section__bg .slot {
  flex-direction: row; align-items: flex-start; justify-content: flex-end;
  gap: 10px; padding: 14px 18px;
}
/* На тёмной полосе с телефоном вуаль, наоборот, тёмная. */
.callout--photo { position: relative; overflow: hidden; }
/* Вуаль плотнее слева, где текст, и светлее справа — там видно снимок. */
.callout--photo .section__bg::after {
  background: linear-gradient(90deg, rgba(10, 13, 13, .86) 0%, rgba(10, 13, 13, .62) 45%, rgba(10, 13, 13, .38) 100%);
}
.callout--photo .section__bg.is-empty {
  border-color: rgba(255, 255, 255, .28);
  background: repeating-linear-gradient(135deg,
    rgba(255, 255, 255, .04) 0 12px, rgba(255, 255, 255, .09) 12px 24px);
}
.callout--photo .section__bg.is-empty .slot__label { color: rgba(255, 255, 255, .6); }
.callout--photo .section__bg.is-empty .slot__size { color: rgba(255, 255, 255, .82); }
.callout__inner { position: relative; z-index: 1; }
/* Полоса во всю ширину окна: поля по бокам даёт колонка .container,
   поэтому у самого блока их нет — текст встаёт вровень с разделами выше. */
.callout--bleed > .container { position: relative; z-index: 1; }
.callout--bleed .callout__inner { padding-inline: 0; padding-block: clamp(24px, 2.8vw, 42px); }
/* Снизу — та же золотая линия, что под шапкой: отделяет полосу от подвала. */
.callout--bleed::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px; z-index: 2;
  background: linear-gradient(90deg,
    rgba(217, 164, 94, .25) 0%,
    var(--gold) 12%,
    var(--gold-bright) 48%,
    var(--gold) 88%,
    rgba(217, 164, 94, .25) 100%);
}

/* --- Кнопки -------------------------------------------------------------- */

.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 12px;
  padding: 17px 34px;
  border: 1px solid var(--ink); border-radius: var(--radius);
  background: var(--ink); color: #fff;
  font-size: 13px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
  cursor: pointer;
  transition: background .2s var(--ease), color .2s var(--ease),
              border-color .2s var(--ease), transform .2s var(--ease);
}
.btn:hover { background: var(--brand); border-color: var(--brand); color: #fff; }
.btn:active { transform: translateY(1px); }

.btn--brand { background: var(--brand); border-color: var(--brand); }
.btn--brand:hover { background: var(--brand-700); border-color: var(--brand-700); }

.btn--ghost { background: transparent; color: var(--ink); }
.btn--ghost:hover { background: var(--ink); border-color: var(--ink); color: #fff; }

.btn--light { background: transparent; border-color: rgba(255, 255, 255, .45); color: #fff; }
.btn--light:hover { background: #fff; border-color: #fff; color: var(--ink); }

/* Кнопка в шапке: бирюзовая заливка и тонкая золотая рамка. */
.btn--cta {
  padding: 15px 30px;
  background: var(--cta);
  border-color: var(--gold);
  color: #fff;
  font-size: 12px; letter-spacing: .14em;
}
.btn--cta:hover { background: var(--cta-hover); border-color: var(--gold-bright); color: #fff; }
.cta__short { display: none; }
/* Телефон: короткая надпись и узкие поля, чтобы рядом поместилась
   кнопка меню. Полная надпись остаётся для программ чтения экрана. */
@media (max-width: 560px) {
  .cta__full {
    position: absolute; width: 1px; height: 1px; overflow: hidden;
    clip: rect(0 0 0 0); white-space: nowrap;
  }
  .cta__short { display: inline; }
  .header .btn--cta { padding: 11px 16px; font-size: 11px; letter-spacing: .1em; }
  .header__actions { gap: 10px; }
  .header__inner { gap: 12px; }
}

/* Кнопка в блоках первого экрана: крупная, скруглённая, полупрозрачная —
   сквозь неё просвечивает кадр, поэтому она не спорит с фоном.

   Цвет бирюзовый, как у логотипа и кнопки в шапке. Правило простое:
   бирюзовый — действия, тёплое золото — только тонкая отделка
   (линия под шапкой, разделитель, трубка телефона, год в подзаголовке). */
.btn--soft {
  padding: 17px 38px;
  border-radius: 999px;
  background: rgba(22, 153, 159, .20);
  border-color: rgba(22, 153, 159, .70);
  color: #d9f7f8;
  font-size: 12.5px;
  -webkit-backdrop-filter: blur(6px);   /* Safari до 18-й версии понимает только так */
  backdrop-filter: blur(6px);
}
.btn--soft:hover {
  background: rgba(22, 153, 159, .42);
  border-color: var(--brand);
  color: #fff;
}

.btn--sm { padding: 12px 22px; font-size: 11.5px; }
.btn--wide { width: 100%; }

/* Ссылка со стрелкой и подчёркиванием, растущим при наведении */
.arrow-link {
  display: inline-flex; align-items: center; gap: 10px;
  color: var(--ink); font-size: 12.5px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
}
.arrow-link::after { content: ""; width: 0; height: 1px; background: var(--brand); transition: width .25s var(--ease); }
.arrow-link:hover { color: var(--brand-700); }
.arrow-link:hover::after { width: 20px; }
.section--dark .arrow-link { color: #fff; }

/* --- Шапка ---------------------------------------------------------------- */

/* Шапка полупрозрачная и размытая: сквозь неё видно, что под ней,
   поэтому она не отрезает страницу, а лежит на ней. Тон — тёмный или
   светлый — ставит скрипт по тому, что сейчас под шапкой (см. app.js).
   Цвет букв, значков и черты берётся из currentColor, поэтому весь
   набор переключается одним свойством. */
.header {
  position: sticky; top: 0; z-index: 90;
  color: #fff;
  background: rgba(9, 12, 12, .66);
  backdrop-filter: blur(16px) saturate(1.4);
  -webkit-backdrop-filter: blur(16px) saturate(1.4);
  transition: transform .42s var(--ease-soft), background .4s var(--ease),
              color .4s var(--ease), box-shadow .4s var(--ease);
}
/* Уезжает вверх целиком — вместе с чертой и тенью. */
.header.is-hidden { transform: translateY(-102%); }
/* Первый кадр после загрузки — без переходов, см. app.js (is-tuning). */
.header.is-tuning, .header.is-tuning * { transition: none !important; }

/* Над светлым разделом шапка светлеет. Не белая: лёгкая дымка, чтобы
   было видно, что это отдельная полоса, но она не спорила с разделом. */
.header.on-light {
  color: var(--ink);
  background: rgba(255, 255, 255, .72);
  box-shadow: 0 1px 0 rgba(18, 36, 42, .07), 0 14px 34px -30px rgba(18, 36, 42, .55);
}

/* Линия под шапкой. Не ровная золотая полоска, а переход: к середине
   разгорается почти до белого золота, к краям гаснет до янтарного. */
.header::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 1px;
  background: linear-gradient(90deg,
    rgba(217, 164, 94, .25) 0%,
    var(--gold) 12%,
    var(--gold-bright) 48%,
    var(--gold) 88%,
    rgba(217, 164, 94, .25) 100%);
  opacity: 1; transition: opacity .4s var(--ease);
}
/* На светлом золото выглядит грубо — черта гаснет, её роль берёт тень. */
.header.on-light::after { opacity: 0; }

.header__inner { display: flex; align-items: center; gap: 28px; min-height: var(--header-h); }

/* На главной шапка лежит поверх ролика: он начинается от самого верха
   страницы, а сквозь полупрозрачный фон видна его фактура — как в макете. */
.page-hero .header { position: fixed; left: 0; right: 0; top: 0; }

/* Логотип сдвинут за левую границу колонки: так знак зрительно
   выравнивается по краю экрана, а не по тексту под ним. */
.logo { flex: none; display: block; margin-left: -14px; position: relative; }
.logo img { display: block; width: 168px; height: auto; }
/* Два знака: светлый для тёмной шапки, тёмный для светлой. Меняются
   плавно, поэтому второй лежит поверх первого. */
.logo__alt { position: absolute; inset: 0; opacity: 0; transition: opacity .4s var(--ease); }
.header.on-light .logo__alt { opacity: 1; }

.nav { flex: 1 1 auto; min-width: 0; }
.nav__list { display: flex; align-items: center; gap: 2px; margin: 0; padding: 0; list-style: none; }
.nav__item { position: relative; }
.nav__link {
  display: inline-flex; align-items: center; gap: 8px;
  padding: 12px 16px;
  /* Пункт меню не переносится: «О НАС» в две строки ломает высоту шапки.
     Если места мало, его отбирают медиазапросы ниже. */
  white-space: nowrap;
  color: inherit; font-size: 12.5px; font-weight: 700;
  letter-spacing: .14em; text-transform: uppercase;
  transition: color .18s var(--ease);
}
.nav__link::after {
  content: ""; position: absolute; left: 16px; right: 16px; bottom: 4px;
  height: 1px; background: var(--gold);
  transform: scaleX(0); transform-origin: left; transition: transform .25s var(--ease);
}
.nav__link:hover, .nav__item.is-open > .nav__link { color: var(--gold-bright); }
.header.on-light .nav__link:hover,
.header.on-light .nav__item.is-open > .nav__link { color: var(--brand-700); }
.header.on-light .nav__link::after { background: var(--brand); }
.nav__link:hover::after, .nav__item.is-open > .nav__link::after,
.nav__link[aria-current="page"]::after, .nav__link.is-current::after { transform: scaleX(1); }
/* На главной — пункт раздела, который сейчас на экране (см. app.js). */
.nav__link.is-current { color: var(--gold-bright); }
.header.on-light .nav__link.is-current { color: var(--brand-700); }
.nav__caret { opacity: .75; transition: transform .22s var(--ease); }
.nav__item.is-open .nav__caret { transform: rotate(180deg); }

.nav__panel {
  position: absolute; top: 100%; left: 0;
  min-width: 300px; max-width: min(780px, 82vw);
  padding: 18px;
  background: #fff; border: 1px solid var(--line);
  box-shadow: var(--shadow-lg);
  opacity: 0; visibility: hidden; transform: translateY(-8px);
  transition: opacity .2s var(--ease), transform .2s var(--ease), visibility .2s;
}
.nav__item.is-open .nav__panel { opacity: 1; visibility: visible; transform: translateY(0); }
.nav__panel--wide { columns: 2; column-gap: 18px; }
.nav__panel-link {
  display: block; padding: 9px 12px;
  color: var(--text); font-size: 14.5px;
  break-inside: avoid;
  transition: background .16s var(--ease), color .16s var(--ease);
}
.nav__panel-link:hover { background: var(--soft); color: var(--brand-700); }
.nav__panel-all {
  display: block; margin-top: 10px; padding: 12px;
  border-top: 1px solid var(--line-soft);
  color: var(--brand-700); font-size: 11.5px; font-weight: 700;
  letter-spacing: .12em; text-transform: uppercase;
}

.header__actions { flex: none; display: flex; align-items: center; gap: 20px; }

/* Телефон: золотая трубка, номер в цвет шапки, режим работы приглушённый. */
.header__phone { display: flex; align-items: center; gap: 12px; line-height: 1.25; color: inherit; }
.header__phone-icon { flex: none; display: grid; place-items: center; color: var(--gold); }
.header.on-light .header__phone-icon { color: var(--brand); }
.header__phone-body { display: flex; flex-direction: column; }
.header__phone-num { font-size: 17px; font-weight: 700; color: inherit; white-space: nowrap; }
.header__phone-note {
  margin-top: 3px;
  font-size: 11px; opacity: .62;
  letter-spacing: .06em; text-transform: uppercase; white-space: nowrap;
}
.header__phone:hover .header__phone-num { color: var(--gold-bright); }
.header.on-light .header__phone:hover .header__phone-num { color: var(--brand-700); }
/* Два номера рядом: основной с режимом работы и номер для заявок о поломках. */
.header__phones { display: flex; align-items: center; gap: 24px; }

/* Тонкая золотая черта между телефоном и кнопкой. */
.header__divider {
  width: 1px; height: 40px; flex: none;
  background: linear-gradient(180deg,
    rgba(217, 164, 94, 0) 0%,
    var(--gold) 35%,
    var(--gold) 65%,
    rgba(217, 164, 94, 0) 100%);
  transition: opacity .4s var(--ease);
}
.header.on-light .header__divider { opacity: .45; }

.icon-btn {
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: #fff; cursor: pointer;
  transition: border-color .18s var(--ease), background .18s var(--ease), color .18s var(--ease);
}
.icon-btn:hover { border-color: var(--ink); background: var(--ink); color: #fff; }

/* Кнопка меню подстраивается под тон шапки. */
.burger { display: none; background: transparent; border-color: rgba(255, 255, 255, .3); color: inherit; }
.burger:hover { background: rgba(255, 255, 255, .1); border-color: var(--gold); color: var(--gold-bright); }
.header.on-light .burger { border-color: rgba(18, 36, 42, .18); }
.header.on-light .burger:hover { background: rgba(18, 36, 42, .06); border-color: var(--brand); color: var(--brand-700); }

/* --- Мобильное меню ------------------------------------------------------ */

.mobile-menu { position: fixed; inset: 0; z-index: 120; display: none; flex-direction: column; background: #fff; }
.mobile-menu.is-open { display: flex; }
.mobile-menu__top { display: flex; align-items: center; justify-content: space-between; gap: 16px; padding: 14px var(--gutter); border-bottom: 1px solid var(--line); }
.mobile-menu__body { flex: 1 1 auto; overflow-y: auto; padding: 4px var(--gutter) 28px; -webkit-overflow-scrolling: touch; }
.m-item { border-bottom: 1px solid var(--line-soft); }
.m-item__row { display: flex; align-items: center; }
.m-item__link { flex: 1 1 auto; padding: 18px 0; font-size: 15px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--ink); }
.m-item__toggle { flex: none; width: 46px; height: 46px; display: grid; place-items: center; border: 0; background: none; cursor: pointer; color: var(--muted); }
.m-item__toggle svg { transition: transform .22s var(--ease); }
.m-item.is-open .m-item__toggle svg { transform: rotate(180deg); }
.m-item__sub { display: none; padding: 0 0 14px; }
.m-item.is-open .m-item__sub { display: block; }
.m-item__sub a { display: block; padding: 10px 0; font-size: 15px; color: var(--text); }
.mobile-menu__foot { padding: 22px var(--gutter) 30px; border-top: 1px solid var(--line); background: var(--soft); }

/* --- Первый экран -------------------------------------------------------- */

/* Высота привязана к ширине: так кадр ролика попадает в экран целиком,
   а не срезается сверху и снизу. Потолок в 94vh не даёт первому экрану
   перерасти окно, пол в 420px — схлопнуться на узком телефоне. */
/* --hero-ratio и --hero-k — пропорция кадра ролика. Их проставляет сборка,
   прочитав размер прямо из видеофайла; здесь только запасное значение. */
.hero {
  --hero-ratio: 16 / 9; --hero-k: 1.7778;
  position: relative; min-height: clamp(420px, 50vw, 94vh); display: flex; align-items: stretch; background: var(--ink); color: #fff; overflow: hidden;
}
/* container-type: size — чтобы ролик мог мерить себя по размеру первого
   экрана (единицы cqw и cqh), а не по окну браузера. */
.hero__bg { position: absolute; inset: 0; background: var(--ink); display: grid; place-items: center; container-type: size; }
.hero__bg img { width: 100%; height: 100%; object-fit: cover; object-position: center; display: block; }
/* По умолчанию скрыты; каждый включается там, где нужен, — см. ниже.
   .hero__fill — полоса пола под кадром на компьютере, .hero__still —
   последний кадр, .hero__flip — раскадровка на телефоне.
   Селектор с .hero__bg нарочно: иначе картинку перебило бы общее правило
   .hero__bg img выше, и на компьютере за роликом всплыл бы постер. */
.hero__bg .hero__fill, .hero__bg .hero__still, .hero__bg .hero__flip { display: none; }

/* Подложка по бокам от ролика.
   Цвета сняты пипеткой с края последнего кадра: там тёмный мрамор, почти
   чёрный сверху и чуть тёплый у пола, где на него ложится свет. Повторяем
   этот переход по высоте — тогда граница кадра не читается, и экран
   выглядит одной картинкой. Сменят ролик — цвета нужно снять заново. */
.hero__bg::before {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background:
    /* К самым краям страницы тон уходит в чёрный, а у границы кадра
       гашение сходит на нет — поэтому стык не читается. */
    linear-gradient(90deg,
      rgba(4, 5, 7, .9) 0%,
      rgba(4, 5, 7, .45) 6%,
      rgba(4, 5, 7, .1) 11%,
      rgba(4, 5, 7, 0) 15%,
      rgba(4, 5, 7, 0) 85%,
      rgba(4, 5, 7, .1) 89%,
      rgba(4, 5, 7, .45) 94%,
      rgba(4, 5, 7, .9) 100%),
    linear-gradient(180deg,
      #06080b 0%,
      #07090c 22%,
      #0c0c0e 40%,
      #130f0d 56%,
      #2a1d16 78%,
      #2c1f18 100%);
}

/* Ролик лежит поверх подложки. */
.hero__bg video { z-index: 1; }

/* Ролик вписывается в первый экран целиком — ни одна сторона кадра
   не срезается.

   Ширина — меньшее из двух: ширина экрана или высота экрана,
   умноженная на пропорцию кадра. Экран шире ролика — кадр во всю высоту,
   по бокам подложка. Экран уже — кадр во всю ширину, сверху и снизу
   та же подложка, а края кадра растворяются в ней маской. */
.hero__bg video {
  position: absolute;
  top: 0; bottom: 0; left: 50%;
  transform: translateX(-50%);
  height: 100%;
  width: auto;
  max-width: 100%;
  object-fit: contain;
  display: block;
}
@supports (width: 1cqw) {
  .hero__bg video {
    top: 50%; bottom: auto;
    transform: translate(-50%, -50%);
    width: min(100cqw, calc(100cqh * var(--hero-k)));
    height: auto;
    aspect-ratio: var(--hero-ratio);
    -webkit-mask-image: linear-gradient(180deg, transparent 0, #000 7%, #000 93%, transparent 100%);
    mask-image: linear-gradient(180deg, transparent 0, #000 7%, #000 93%, transparent 100%);
  }
}

/* На компьютере кадр приподнят: низ кабины лифта оказывается над двумя
   блоками внизу экрана, а не под ними. Сдвиг — отдельным свойством
   translate: оно складывается с центрированием через transform, а не
   заменяет его. Срезается только тёмный потолок холла над дверями. */
@media (min-width: 761px) {
  .hero { --hero-lift: 7%; }
  .hero__bg video,
  .hero__bg .hero__still { translate: 0 calc(-1 * var(--hero-lift)); }

  /* Полоса под приподнятым кадром — продолжение пола. Лежит под роликом
     и видна сквозь растворённый нижний край кадра и ниже него. Ширина та
     же, что у ролика, поэтому проценты по горизонтали совпадают с кадром:
     на 75 % — отражение открытой кабины, по бокам тёплая темнота.
     Цвета сняты с нижнего края последнего кадра. */
  .hero__bg .hero__fill {
    display: block; position: absolute; z-index: 0;
    left: 50%; bottom: 0; transform: translateX(-50%);
    width: 100%; height: 18%;
    background:
      /* к самому низу экрана пол уходит в тень */
      linear-gradient(180deg, rgba(8, 6, 5, 0) 0%, rgba(8, 6, 5, .35) 55%, rgba(8, 6, 5, .8) 100%),
      /* отражение света из кабины: узкое и вытянутое вниз, как на полу в ролике */
      radial-gradient(ellipse 13% 130% at 75% 0%,
        rgba(248, 199, 136, .9) 0%, rgba(202, 144, 81, .5) 45%, rgba(162, 111, 66, 0) 100%),
      linear-gradient(90deg,
        #3d2a1f 0%, #3b281e 15%, #432d20 25%, #4f3526 35%, #6e492b 45%,
        #60402a 55%, #a26f42 65%, #b88350 75%, #8a5c38 85%, #34241c 100%);
    /* края растворяются в подложке по бокам */
    -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 12%, #000 88%, transparent 100%);
    mask-image: linear-gradient(90deg, transparent 0, #000 12%, #000 88%, transparent 100%);
  }
  @supports (width: 1cqw) {
    .hero__bg .hero__fill { width: min(100cqw, calc(100cqh * var(--hero-k))); }
  }
  /* Во время вступления свет на полу разгорается вместе с дверями:
     до их открытия низ кадра тёмный, и светлая полоса под ним была бы чужой. */
  html.intro .hero__bg .hero__fill { opacity: 0; }
  html.intro.intro-s2 .hero__bg .hero__fill,
  html.intro.intro-done .hero__bg .hero__fill { opacity: 1; transition: opacity 3s var(--ease-soft); }
}

/* ПОВТОРНЫЙ ЗАХОД НА КОМПЬЮТЕРЕ (вступление в этом сеансе уже видели)
   и запасной случай hero-still, когда ролик не пошёл вовсе: автозапуск
   запрещён, файл не скачался, машина не тянет декодирование
   (см. heroFallback в app.js).
   В обоих случаях на месте ролика стоит его последний кадр — открытые
   светящиеся двери, — и ролик не грузится.

   Разметка кадра намеренно простая: рамка во весь блок и object-fit.
   Раньше ширина считалась контейнерными единицами, а края растворяла
   маска — на старых браузерах и слабых видеокартах и то и другое
   срабатывает не всегда: ширина схлопывалась в ноль, и вместо кадра
   оставалась пустая тёмная подложка. Теперь кадр вписывается в блок
   целиком приёмом, который работает везде, а край гасит вуаль вокруг. */
@media (min-width: 761px) {
  html:not(.intro) .hero__bg video,
  html.hero-still .hero__bg video { visibility: hidden; }
  html:not(.intro) .hero__bg .hero__still,
  html.hero-still .hero__bg .hero__still {
    /* z-index: 1 — выше вуали вокруг кадра, но не выше текста первого
       экрана: у него своя колонка с z-index: 1 и он идёт следом. */
    display: block; position: absolute; z-index: 1;
    top: 0; right: 0; bottom: 0; left: 0;
    width: 100%; height: 100%;
    object-fit: contain; object-position: center;
  }
}

/* Затемнение только слева — там текст. Центр, где идёт действие,
   почти не притушен. */
.hero__bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(95deg,
    rgba(8, 8, 8, .95) 0%,
    rgba(8, 8, 8, .88) 22%,
    rgba(8, 8, 8, .55) 38%,
    rgba(8, 8, 8, .12) 52%,
    rgba(8, 8, 8, 0) 66%);
}
/* Первый экран делится на две части: верхний блок стоит по центру
   свободного места, два нижних прижаты к низу экрана. */
.hero > .container { position: relative; z-index: 1; display: flex; }
.hero__inner {
  position: relative; z-index: 1; flex: 1 1 auto; width: 100%;
  display: grid; grid-template-rows: 1fr auto;
  /* Отступы считаются от высоты окна, а не только от ширины: на невысоком
     экране первый экран сжимается сам, и кнопки в нижних блоках остаются
     видны, не уезжая за край. */
  gap: clamp(18px, 3vh, 48px);
  padding-block: calc(var(--header-h) + clamp(16px, 3vh, 48px)) clamp(18px, 3vh, 46px);
  /* Тот же сдвиг, что у логотипа: текст и блоки начинаются ровно от его
     левого края, а не от края колонки. */
  margin-left: -14px;
}
/* Шире — значит меньше строк в заголовке, а это тоже экономит высоту. */
.hero__content { align-self: center; max-width: min(780px, 46vw); }

/* Отметка под текстом: круглый значок и подпись заглавными. */
/* Подпись стоит по левому краю текста первого экрана — без значка
   перед ней: круглый знак с лифтом отвлекал от заголовка. */
.hero__mark { margin-top: clamp(16px, 2.8vh, 38px); }
.hero__mark span:last-child {
  font-family: var(--display); font-size: clamp(14px, 1.2vw, 18px);
  letter-spacing: .1em; text-transform: uppercase; color: #fff; line-height: 1.3;
}

/* Два блока внизу экрана. */
.hero__cards { display: grid; grid-template-columns: repeat(2, 1fr); gap: clamp(14px, 1.6vw, 26px); }
.hero-card {
  display: flex; flex-direction: column;
  padding: clamp(18px, 2.6vh, 34px);
  background: rgba(9, 11, 12, .62);
  -webkit-backdrop-filter: blur(10px);  /* Safari до 18-й версии */
  backdrop-filter: blur(10px);
  border: 1px solid rgba(255, 255, 255, .09);
  border-radius: 10px;
}
.hero-card__title {
  font-family: var(--display); font-size: clamp(16px, 1.5vw, 22px);
  letter-spacing: .05em; text-transform: uppercase; color: #fff; line-height: 1.25;
}
.hero-card__text {
  margin: clamp(10px, 1.6vh, 18px) 0 0;
  color: rgba(255, 255, 255, .66);
  font-size: clamp(13px, 1.7vh, 14.5px); line-height: 1.6;
}
.hero-card__text p:last-child { margin-bottom: 0; }
.hero-card__action {
  display: flex; flex-wrap: wrap; gap: 12px;
  margin-top: auto; padding-top: clamp(14px, 2.2vh, 28px);
}
/* Двум кнопкам в блоке первого экрана нужен кегль поменьше — иначе они
   не встают в строку и блок перестаёт помещаться в экран. */
.hero-card__action .btn--soft + .btn--soft,
.hero-card__action .btn--soft:first-child:not(:last-child) {
  padding: 15px 26px; font-size: 11.5px;
}
/* Строка над заголовком. Набрана тем же шрифтом, что и заголовок, —
   поэтому читается как его продолжение, а не как отдельная подпись.
   Год выделен тёплым тоном: он здесь главное слово. */
.hero__lead {
  margin-bottom: clamp(8px, 1.2vh, 18px);
  font-family: var(--display);
  font-size: clamp(17px, min(2vw, 3vh), 32px);
  letter-spacing: .05em; text-transform: uppercase;
  color: rgba(255, 255, 255, .92); line-height: 1.15;
}
.hero__year { color: var(--gold); }

/* Размер заголовка ограничен и высотой окна тоже: иначе на невысоком
   экране он съедает место у блоков внизу. */
.hero h1 { color: #fff; font-size: clamp(28px, min(4.8vw, 7vh), 64px); }
.hero__text {
  margin: clamp(14px, 2.4vh, 26px) 0 0; max-width: 52ch;
  color: rgba(255, 255, 255, .72);
  font-size: clamp(14.5px, 1.9vh, 17px); line-height: 1.65;
}
.hero__text p { margin: 0 0 .7em; }
.hero__text p:last-child { margin-bottom: 0; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 14px; margin-top: 38px; }

/* --- Цифры --------------------------------------------------------------- */

/* Ряд с показателями под блоком о компании, в той же секции. */
.facts-band { margin-top: clamp(26px, 2.8vw, 46px); }
.facts { display: grid; grid-template-columns: repeat(4, 1fr); border-top: 1px solid var(--line); }
.fact { padding: clamp(20px, 2.4vw, 34px) 0 0; }
.fact + .fact { border-left: 1px solid var(--line); padding-left: clamp(20px, 3vw, 40px); }
.fact__value { font-family: var(--display); font-size: clamp(34px, 4vw, 56px); font-weight: 400; color: var(--ink); line-height: .95; letter-spacing: .01em; }
.fact__label { margin-top: 10px; max-width: 26ch; color: var(--muted); font-size: 14.5px; line-height: 1.5; }
.section--dark .fact__value { color: #fff; }
.section--dark .facts, .section--dark .fact + .fact { border-color: rgba(255, 255, 255, .16); }

/* --- Преимущества ---------------------------------------------------------
   Верх: слева надзаголовок, крупное утверждение и текст, справа большое
   фото, уходящее за правый край экрана. Под ними — полоса партнёра
   (знак производителя, рассказ, кнопка, фото) и ряд плиток с значками.
   Ниже, на светлой подложке, — бегущая строка «в деталях».
   Шрифты — основные шрифты сайта: заголовки Tenor Sans, текст Montserrat. */

/* Раздел длинный — четыре блока подряд, — поэтому поля сверху и снизу
   меньше обычных: иначе до каталога приходится долго листать. */
.advantages { padding-block: clamp(32px, 3vw, 54px) clamp(24px, 2.2vw, 38px); overflow: hidden; }

/* Колонки растягиваются на одну высоту: фото справа занимает ровно
   столько, сколько текст со снимком слева, и не раздувается на широком
   экране. */
.adv-head {
  display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, .92fr);
  align-items: stretch; column-gap: clamp(20px, 2vw, 34px);
}
.adv-head__text { display: flex; flex-direction: column; }
/* Снимок под текстом занимает всю ширину колонки — иначе между ним
   и снимком справа зияла пустота. Кадр шире исходника (16 : 9 против
   3 : 2): лишнее срезается сверху и снизу, люди остаются в кадре,
   а раздел не вытягивается в длину. Высота этого снимка задаёт высоту
   всего ряда — снимок справа подстраивается под неё. */
.adv-head__extra {
  margin: clamp(12px, 1.3vw, 20px) 0 0;
  width: 100%; aspect-ratio: 21 / 9;
  position: relative; overflow: hidden; border-radius: 16px; background: var(--soft);
  box-shadow: 0 24px 46px -36px rgba(15, 40, 45, .45);
}
.adv-head__extra img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 42%;
}
/* Абзац и кнопка в одну строку. На узкой колонке кнопка переносится
   под текст — за это отвечает flex-wrap, а не отдельное правило. */
.adv-head__intro {
  display: flex; flex-wrap: wrap; align-items: center;
  gap: clamp(18px, 2vw, 40px); margin-top: clamp(14px, 1.4vw, 22px);
}
.adv-lead {
  /* Меньше 360 px абзац не сжимается: ниже этого кнопка переносится
     под него — так текст не превращается в узкий столбик. */
  flex: 1 1 360px; max-width: 46ch;
  color: var(--text); font-size: 16px; line-height: 1.68;
}
.adv-lead p:last-child { margin-bottom: 0; }

/* Снимок стоит в своей колонке и кончается на общей правой границе —
   как все остальные блоки. Раньше он уходил за край экрана: ширину ему
   давало окно, и при сужении страницы кадр расползался по горизонтали.
   Высоту задаёт соседняя колонка, а не пропорция кадра: снимок лежит
   в рамке отдельным слоем (position: absolute ниже), поэтому сам высоту
   не набирает и доходит ровно до низа левой колонки — ни сверху,
   ни снизу пустоты не остаётся. Нижняя граница — для страниц,
   где текста мало. */
.adv-head__photo {
  margin: 0;
  position: relative;
  min-height: clamp(240px, 23vw, 380px); overflow: hidden;
  border-radius: 16px; background: var(--soft);
  box-shadow: 0 30px 60px -40px rgba(15, 40, 45, .5);
}
.adv-head__photo img {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; object-position: 50% 42%; display: block;
}

/* Полоса партнёра: знак, рассказ и снимок в одной светлой плашке. */
.adv-partner {
  display: grid; grid-template-columns: minmax(180px, .7fr) minmax(0, 1.5fr) minmax(200px, .9fr);
  align-items: stretch; gap: clamp(18px, 2vw, 34px);
  margin-top: clamp(14px, 1.4vw, 24px);
  padding: clamp(14px, 1.2vw, 20px);
  border: 1px solid var(--line); border-radius: 18px;
  background: linear-gradient(180deg, #fbfcfc 0%, #f4f7f8 100%);
}
/* Знак партнёра с подписью — по центру своей колонки: прижатые влево,
   они висели в пустоте рядом с широкой разделительной чертой. */
.adv-partner__brand {
  display: flex; flex-direction: column; align-items: center; justify-content: center;
  gap: 16px; text-align: center;
}
/* Подпись выделена: бирюзовая, на светлой плашке в тон — иначе она
   терялась рядом со знаком. */
.adv-partner__over {
  display: inline-block; margin: 0; padding: 6px 14px;
  border: 1px solid var(--tint-line); border-radius: 999px; background: var(--tint);
  font-size: 11px; font-weight: 700; letter-spacing: .16em;
  text-transform: uppercase; color: var(--brand-700);
}
.adv-partner__logo { width: 100%; max-width: 250px; }
.adv-partner__logo img { width: 100%; height: auto; display: block; }
.adv-partner__logo.is-empty { aspect-ratio: 21 / 8; }

.adv-partner__body {
  display: flex; flex-direction: column; justify-content: center;
  padding-left: clamp(20px, 2.4vw, 44px); border-left: 1px solid var(--line);
}
.adv-partner__title {
  font-family: var(--display); font-weight: 400;
  font-size: clamp(17px, 1.6vw, 25px); line-height: 1.25; color: var(--ink);
}
.adv-partner__text { margin-top: 10px; color: var(--muted); font-size: 15px; line-height: 1.65; }
.adv-partner__text p:last-child { margin-bottom: 0; }
.adv-partner__action { margin-top: clamp(14px, 1.4vw, 20px); }
.adv-partner__btn { gap: 14px; padding: 12px 20px; font-size: 11.5px; }
.adv-partner__btn svg { transition: transform .25s var(--ease); }
.adv-partner__btn:hover svg { transform: translateX(4px); }

/* Снимок производителя показывается целиком: это общий план площадки,
   обрезка съедала бы половину кадра. */
.adv-partner__photo {
  display: flex; align-items: center; justify-content: center;
  max-height: 160px; overflow: hidden; border-radius: 12px;
}
.adv-partner__photo img {
  max-width: 100%; max-height: 160px; width: auto; height: auto;
  display: block; border-radius: 12px;
}
/* Подложка нужна, только пока снимка нет: тогда на её месте рамка
   с нужным размером. Под самим снимком белый фон давал поля по бокам —
   кадр уже белого прямоугольника. */
.adv-partner__photo.is-empty { background: #fff; }

/* Ряд плиток: значок, короткое название, подпись. Колонок столько,
   сколько влезает, — раскладка не ломается от числа пунктов. */
.adv-tiles {
  display: grid; grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: clamp(10px, 1vw, 14px);
  margin-top: clamp(10px, 1vw, 16px);
}
.adv-tile {
  padding: clamp(12px, 1.1vw, 16px);
  border: 1px solid var(--line); border-radius: 14px; background: #fff;
  transition: border-color .25s var(--ease), box-shadow .3s var(--ease), transform .3s var(--ease);
}
.adv-tile:hover { border-color: var(--tint-line); box-shadow: var(--lift); transform: translateY(-4px); }
.adv-tile__icon {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; margin-bottom: clamp(8px, .8vw, 11px);
  border-radius: 9px; background: var(--tint); color: var(--brand-700);
}
.adv-tile__title { font-size: 13.5px; font-weight: 700; line-height: 1.3; color: var(--ink); }
.adv-tile__text { margin-top: 5px; color: var(--muted); font-size: 12.5px; line-height: 1.45; }
.adv-tile__text p:last-child { margin-bottom: 0; }
/* На компьютере все плитки — в один ряд, сколько бы их ни было: значки
   меньше, тексты короткие, тезисом (см. preimushchestva.txt). В узком
   окне 1025–1199 px слова в один ряд не помещаются — там по пять в ряд. */
@media (min-width: 1025px) {
  .adv-tiles { grid-template-columns: repeat(5, minmax(0, 1fr)); gap: clamp(6px, .6vw, 10px); }
}
@media (min-width: 1200px) {
  .adv-tiles { grid-template-columns: none; grid-auto-flow: column; grid-auto-columns: minmax(0, 1fr); }
}
@media (min-width: 1025px) {
  .adv-tile { padding: clamp(9px, .8vw, 13px) clamp(8px, .7vw, 12px); border-radius: 12px; }
  .adv-tile__icon { width: 26px; height: 26px; margin-bottom: 8px; border-radius: 7px; }
  .adv-tile__icon svg { width: 15px; height: 15px; }
  /* Длинное слово в узкой плитке переносится только там, где в тексте
     стоит мягкий перенос (невидимый символ, например «Видео­наблюдение»). */
  .adv-tile__title { font-size: clamp(11px, .82vw, 13px); line-height: 1.25; -webkit-hyphens: manual; hyphens: manual; }
  .adv-tile__text { margin-top: 4px; font-size: clamp(10.5px, .74vw, 12px); line-height: 1.4; }
}

.adv-cta {
  display: flex; align-items: center; flex-wrap: wrap; gap: 14px 26px;
  margin-top: clamp(20px, 2.2vw, 32px);
}
/* В строке с абзацем отступ сверху не нужен — расстояние даёт сам ряд.
   Кнопка стоит сразу за текстом и по его середине, шириной не растёт. */
.adv-head__intro .adv-cta { flex: 0 0 auto; margin-top: 0; }
.adv-cta__btn { gap: 18px; }
.adv-cta__btn svg { transition: transform .25s var(--ease); }
.adv-cta__btn:hover svg { transform: translateX(4px); }
.adv-cta__slogan {
  display: flex; align-items: center; gap: 18px;
  font-size: 12.5px; letter-spacing: .12em; text-transform: uppercase; color: var(--muted);
}
.adv-cta__slogan::before { content: ""; width: 44px; height: 1px; background: var(--brand); opacity: .6; }

/* Бегущая строка. Два одинаковых набора пунктов подряд: когда первый
   уезжает на всю свою ширину (−50 % общей дорожки), анимация начинается
   сначала, и стык не виден. Края растворяются, при наведении — пауза. */
.adv-marquee {
  position: relative; overflow: hidden;
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 5%, #000 95%, transparent 100%);
}
.adv-marquee__track {
  display: flex; width: max-content;
  animation: adv-marquee var(--marquee-time, 70s) linear infinite;
}
.adv-marquee:hover .adv-marquee__track { animation-play-state: paused; }
.adv-marquee__set { display: flex; }
@keyframes adv-marquee {
  from { transform: translateX(0); }
  to { transform: translateX(-50%); }
}
/* Плитки преимуществ бегут строкой: вместо сетки — лента плиток одной
   ширины. Отступ справа у каждой плитки, а не зазор между ними, — так
   стык двух наборов не отличается от остальных промежутков. Сверху и
   снизу запас, чтобы приподнятая при наведении плитка не обрезалась. */
.adv-tiles.adv-tiles--run { display: block; padding-block: 6px 10px; }
.adv-tiles--run .adv-tile {
  flex: none; width: clamp(200px, 14.5vw, 250px); margin-right: clamp(10px, .9vw, 14px);
}
@media (max-width: 760px) {
  .adv-tiles--run .adv-tile { width: 62vw; }
}

/* --- Карточки разделов ---------------------------------------------------- */

/* Две карточки в ряд, между ними воздух, а не общая сетка с рамкой:
   снимок здесь крупный, и разделительные линии рядом с ним выглядели бы
   как клетка таблицы.

   Ровно две в ряд, как в образце. */
.cards {
  display: grid; gap: clamp(18px, 2vw, 34px);
  grid-template-columns: repeat(2, minmax(0, 1fr));
}
.cards--3 { display: grid; gap: 1px; grid-template-columns: repeat(auto-fit, minmax(340px, 1fr)); background: var(--line); border: 1px solid var(--line); }

/* Лента проектов: тот же вид, что у ряда из трёх карточек (стык в один
   пиксель поверх линии), только лишние карточки уходят вправо и
   пролистываются стрелками или пальцем. Подъём карточки при наведении
   здесь выключен — лента обрезает всё, что выходит за её край. */
.prj-track {
  --prj-per: 3;
  display: grid; grid-auto-flow: column; gap: 1px;
  grid-auto-columns: calc((100% - (var(--prj-per) - 1) * 1px) / var(--prj-per));
  overflow-x: auto; scroll-snap-type: x mandatory; overscroll-behavior-x: contain;
  scrollbar-width: none; background: var(--line); border: 1px solid var(--line);
}
.prj-track::-webkit-scrollbar { display: none; }
.prj-track.is-moving { scroll-snap-type: none; }
.prj-track > .post-card { scroll-snap-align: start; }
.prj-track > .post-card:hover, .prj-track > .post-card:active { transform: none; box-shadow: none; }

/* Стрелки лежат поверх ленты по бокам, по высоте — на середине фото.
   Фото в карточке 16:10, ширина карточки считается от ширины ленты
   (единицы cqw), отсюда и высота центра: колонка × 10/16 / 2. */
.prj-carousel {
  --prj-per: 3;
  --prj-col: calc((100cqw - (var(--prj-per) - 1) * 1px) / var(--prj-per));
  position: relative; container-type: inline-size;
}
.prj-carousel .prj-track { --prj-per: inherit; }
.prj-nav__btn {
  position: absolute; z-index: 3; top: calc(1px + var(--prj-col) * 10 / 32);
  translate: 0 -50%;
  display: grid; place-items: center; width: 48px; height: 48px; padding: 0;
  border: 0; border-radius: 50%; background: rgba(255, 255, 255, .92); color: var(--ink);
  box-shadow: 0 8px 24px -8px rgba(14, 40, 42, .45); cursor: pointer;
  -webkit-backdrop-filter: blur(6px); backdrop-filter: blur(6px);
  transition: background .2s var(--ease), color .2s var(--ease), opacity .25s var(--ease), visibility .25s;
}
.prj-nav__btn[data-prj="-1"] { left: 14px; }
.prj-nav__btn[data-prj="1"] { right: 14px; }
.prj-nav__btn svg { width: 20px; height: 20px; fill: none; stroke: currentColor; stroke-width: 2; stroke-linecap: round; stroke-linejoin: round; }
.prj-nav__btn:hover:not(:disabled) { background: var(--brand); color: #fff; }
.prj-nav__btn:focus-visible { outline: 2px solid var(--brand); outline-offset: 2px; }
.prj-nav__btn:disabled { opacity: 0; visibility: hidden; }
@media (max-width: 1024px) { .prj-carousel { --prj-per: 2; } }
@media (max-width: 760px) {
  .prj-carousel { --prj-per: 1; --prj-col: 86cqw; }
  .prj-track { grid-auto-columns: 86%; }
  .prj-nav__btn { width: 40px; height: 40px; }
  .prj-nav__btn[data-prj="-1"] { left: 8px; }
  .prj-nav__btn[data-prj="1"] { right: 8px; }
}

/* Подпись слева, снимок справа. Карточка при этом втрое ниже, чем когда
   текст стоял под снимком: весь раздел из четырёх позиций умещается
   в один экран.

   Сама ячейка — приподнятая панель: тонкая светлая грань сверху,
   волосяная рамка и мягкая тень под низом. Панель полупрозрачная,
   поэтому на разделе с фотографией под ней виден фон, а текст всё
   равно читается. */
/* Подписи отдана треть плашки, снимку — всё остальное. Раньше снимок
   был узким и фиксированным, и между текстом и кадром в широких ячейках
   мозаики зияла пустота. Теперь кадр дотягивается до подписи.

   Высота снимка одна на все плашки — ряды мозаики остаются ровными,
   даже когда ячейки в них разной ширины. Широкая ячейка просто даёт
   более панорамный кадр. */
.card {
  --photo-h: clamp(230px, 16vw, 320px);
  display: grid; grid-template-columns: minmax(210px, 36%) minmax(0, 1fr);
  gap: clamp(16px, 1.6vw, 30px); align-items: start;
  padding: clamp(16px, 1.4vw, 24px);
  /* Матовое стекло. Полностью прозрачная плашка сливалась с фотографией:
     сквозь неё были видны все детали фона, и край ячейки терялся.
     Размытие под плашкой гасит эти детали — фон остаётся виден пятнами
     цвета, а плашка читается отдельным слоем.

     Кромка двойная: светлая рамка заметна на тёмных участках фото,
     тонкое тёмное кольцо снаружи — на светлых. Сверху светлый блик,
     снизу глубокая мягкая тень — это и даёт объём. */
  border: 1px solid rgba(255, 255, 255, .85);
  border-radius: calc(var(--radius-card) + 4px);
  background: linear-gradient(135deg, rgba(255, 255, 255, .7), rgba(255, 255, 255, .38));
  -webkit-backdrop-filter: blur(18px) saturate(1.25);
  backdrop-filter: blur(18px) saturate(1.25);
  box-shadow:
    inset 0 1px 0 rgba(255, 255, 255, .95),
    0 0 0 1px rgba(20, 30, 32, .07),
    0 26px 50px -30px rgba(14, 40, 42, .55);
}
.card__media {
  position: relative; height: var(--photo-h);
  align-self: start; overflow: hidden;
  border-radius: var(--radius-card); background: var(--soft);
}
.card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--ease); }
.card:hover .card__media img { transform: scale(1.04); }
/* Подложка плашки — фото во всю ячейку позади подписи и снимка.
   Слой лежит внутри плашки (isolation), поэтому z-index: -1 уводит его
   под содержимое, но не под соседние блоки страницы.

   Поверх подложки — светлая вуаль. В левой половине фото проступает
   бледно, а от середины к правому краю вуаль уплотняется почти до
   белого, и подложка там практически исчезает. */
.card--bg { overflow: hidden; isolation: isolate; }
.card__bg { position: absolute; inset: 0; z-index: -1; }
.card__bg img { width: 100%; height: 100%; object-fit: cover; }
.card__bg::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg,
    rgba(255, 255, 255, .82) 0%,
    rgba(255, 255, 255, .82) 40%,
    rgba(255, 255, 255, .95) 58%,
    rgba(255, 255, 255, .98) 100%);
  transition: opacity .3s var(--ease);
}
.card--bg:hover .card__bg::after { opacity: .92; }
/* На фотографии обычный приглушённый серый теряется — описание темнее. */
.card--bg .card__text { color: #4b5257; }

/* Снимок чуть приподнят над стеклом — своя короткая тень. */
.card__media { box-shadow: 0 14px 28px -18px rgba(14, 40, 42, .5); }

/* «Подробнее» — единственный цветной акцент в плашке: бирюзовый текст
   и черта, которая вытягивается при наведении на всю ячейку. */
.card .arrow-link { color: var(--brand-700); }
.card .arrow-link::after { width: 16px; }
.card:hover .arrow-link::after { width: 34px; }
.card__media--contain { background: #fff; }
.card__media--contain img { object-fit: contain; padding: 26px; }

/* Подпись ровно в высоту снимка: название встаёт вровень с верхним краем
   кадра, «Подробнее» — с нижним. Длинный текст просто её удлинит. */
.card__body {
  display: flex; flex-direction: column; gap: 10px; padding: 0; min-width: 0;
  min-height: var(--photo-h);
}
.card__title {
  margin-top: -.12em;   /* снимаем верхний интерлиньяж: буквы ровно по краю кадра */
  font-family: var(--display); font-weight: 400;
  font-size: clamp(18px, 1.5vw, 25px);
  text-transform: uppercase; letter-spacing: .03em;
  color: var(--ink); line-height: 1.2;
}
.card:hover .card__title { color: var(--brand-700); }
.card__text { max-width: 52ch; color: var(--muted); font-size: 15px; line-height: 1.65; }
.card__foot { margin-top: auto; padding-top: 6px; line-height: 1; }
/* Плашка с количеством прижата к правому верхнему углу снимка: у левого
   она висела бы в пустоте между подписью и кадром. */
.card__count {
  position: absolute; right: 0; top: 0;
  padding: 8px 14px; background: var(--ink); color: #fff;
  font-size: 11px; font-weight: 700; letter-spacing: .1em; text-transform: uppercase;
  border-top-right-radius: var(--radius-card);
  border-bottom-left-radius: var(--radius-card);
}

/* --- Каталог: мозаика -----------------------------------------------------
   Двенадцать колонок. Ширину каждой ячейки задаёт сборка через --span:
   ряды 5 + 7, 6 + 6, 7 + 5. Вводный блок с названием и кнопками стоит
   в левом верхнем углу, дальше плашки разделов. */

.cat-grid {
  display: grid; grid-template-columns: repeat(12, minmax(0, 1fr));
  gap: clamp(16px, 1.6vw, 28px);
}
/* Ячейка — только место в сетке; плашка внутри растягивается на всю
   высоту ряда, чтобы соседи по ряду были одного роста. */
.cat-cell { grid-column: span var(--span, 6); display: flex; min-width: 0; }
.cat-cell > * { flex: 1 1 auto; min-width: 0; }

/* Вводный блок выровнен по верху ряда, а не по середине: название
   «Каталог» стоит вровень с заголовком соседней плашки. Своего отступа
   сверху у блока нет — его роль играет поле над чертой в .sec__name,
   оно почти равно внутреннему полю плашки. */
.cat-intro {
  display: flex; flex-direction: column; justify-content: flex-start;
  padding-right: clamp(8px, 2vw, 40px);
}
/* Название встаёт вровень с заголовком соседней плашки: поле над чертой
   берём такое же, как внутреннее поле плашки, и тем же приёмом снимаем
   верхний интерлиньяж — иначе крупная строка садится ниже соседней. */
.cat-intro .sec__name { padding-top: clamp(16px, 1.4vw, 24px); margin-top: -.12em; }
.cat-intro .sec__lead { margin-bottom: clamp(18px, 2vw, 28px); }
/* Кнопки во вводном блоке компактнее обычных: блок узкий, и полноразмерные
   переносились в две строки, вытягивая весь первый ряд мозаики. */
.cat-intro .btn { padding: 13px 22px; font-size: 11.5px; letter-spacing: .1em; }

/* --- Услуги: мозаика ------------------------------------------------------
   Десять колонок. Первый ряд: заголовок на четыре, две услуги по три.
   Второй: две услуги по три, текстовый блок на четыре. Текстовые блоки
   оказываются по разным углам, и раздел перестаёт читаться как полоса
   одинаковых плиток. */

.srv-grid {
  display: grid; grid-template-columns: repeat(10, minmax(0, 1fr));
  gap: clamp(12px, 1.1vw, 18px);
}
.srv-intro { grid-column: span 4; display: flex; flex-direction: column; }
.srv-card { grid-column: span 3; }
.srv-note { grid-column: span 4; display: flex; flex-direction: column; }

.srv-intro__text {
  margin-top: clamp(18px, 2vw, 30px); max-width: 52ch;
  color: var(--muted); font-size: 15.5px; line-height: 1.75;
}
.srv-intro__text p:last-child { margin-bottom: 0; }
.srv-intro__action { margin-top: clamp(20px, 2.2vw, 34px); }

.srv-card {
  display: flex; flex-direction: column;
  padding: clamp(16px, 1.25vw, 20px);
  border-radius: var(--radius-card);
  background: var(--soft);
  transition: background .25s var(--ease), transform .3s var(--ease),
              box-shadow .3s var(--ease);
}
.srv-card:hover { transform: translateY(-6px); box-shadow: var(--lift); background: #f1f2f2; }
.srv-card:active { transform: translateY(-2px); transition-duration: .08s; }
.srv-card__title {
  font-family: var(--display); font-size: clamp(16px, 1.35vw, 23px);
  text-transform: uppercase; letter-spacing: .03em;
  color: var(--ink); line-height: 1.2;
}
.srv-card:hover .srv-card__title { color: var(--brand-700); }
.srv-card__text {
  margin-top: 10px; color: var(--muted); font-size: 14px; line-height: 1.6;
}
/* Услуги на главной меняются местами случайно, а высота раздела меняться
   не должна — иначе прыгает вся страница ниже. Поэтому у заголовка
   и анонса место ровно на две строки: короткий текст оставляет строку
   пустой, длинный обрезается многоточием. Снимки одной высоты (16:9),
   так что и карточки, и раздел всегда одного размера. */
@media (min-width: 761px) {
  .srv-card__title, .srv-card__text {
    display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2;
    line-clamp: 2; overflow: hidden;
  }
  .srv-card__title { min-height: 2.4em; }
  .srv-card__text { min-height: 3.2em; }
}
/* Снимок прижат к низу карточки: высота у всех снимков одна (рамка 16:9,
   см. ниже), поэтому в ряду они совпадают и верхом, и низом, даже если
   у соседа заголовок в две строки. */
.srv-card__media {
  margin-top: auto; padding-top: clamp(14px, 1.3vw, 20px);
  position: relative; overflow: hidden;
}
/* У всех снимков одна рамка 16:9: услуги на главной выбираются и
   расставляются случайно, и снимки разной пропорции (1,6 : 1 и 2 : 1)
   в одном ряду выходили разной высоты. Кадр заполняет рамку целиком
   и чуть подрезается по краям — без искажений и узких полос. */
.srv-card__media img {
  display: block; width: 100%; height: auto; border-radius: 10px;
  aspect-ratio: 16 / 9; object-fit: cover;
}
/* Рамка на месте снимка — под рекомендуемый размер 1600 × 1000. Общее
   правило растягивает её по родителю (height: 100%) — здесь родителя нет,
   высоту задаёт пропорция, поэтому растяжку снимаем. */
.srv-card__media.is-empty { border: 0; background: none; }
.srv-card__media.is-empty .slot {
  height: auto; aspect-ratio: 16 / 10; border-radius: 10px;
  border: 1px dashed #d2d5d7;
  background: repeating-linear-gradient(135deg, #fbfbfb 0 12px, #f2f3f4 12px 24px);
}

.srv-note__title {
  font-family: var(--display); font-size: clamp(17px, 1.5vw, 25px);
  text-transform: uppercase; letter-spacing: .03em;
  color: var(--ink); line-height: 1.25;
}
.srv-note__text {
  margin-top: clamp(12px, 1.4vw, 20px);
  color: var(--muted); font-size: 14.5px; line-height: 1.7;
}
.srv-note__text p:last-child { margin-bottom: 0; }
.srv-note__slogan {
  margin-top: auto; padding-top: clamp(24px, 3vw, 54px);
  font-family: var(--display); font-size: clamp(17px, 1.5vw, 26px);
  text-transform: uppercase; letter-spacing: .03em;
  color: var(--ink); line-height: 1.25;
}

/* --- Конфигуратор чертежей ------------------------------------------------
   Слева — выбор, справа — лист с чертежом. Лист «липкий»: при длинном
   списке параметров чертёж остаётся на виду. */

.cfg-layout {
  display: grid; grid-template-columns: minmax(0, 340px) minmax(0, 1fr);
  gap: clamp(24px, 3vw, 56px); align-items: start;
}
.cfg-side { position: sticky; top: calc(var(--header-h) + 24px); }

.cfg-form { display: grid; gap: 18px; }
.cfg-field { display: block; }
.cfg-field__label {
  display: block; margin-bottom: 8px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted);
}
.cfg-field__control {
  width: 100%; padding: 13px 14px;
  border: 1px solid var(--line); border-radius: var(--radius);
  background: #fff; color: var(--ink);
  font-family: inherit; font-size: 15px;
  transition: border-color .2s var(--ease);
}
.cfg-field__control:hover { border-color: #cfd2d4; }
.cfg-field__control:focus-visible { border-color: var(--brand); }
.cfg-field__control:disabled { background: var(--soft); color: var(--muted); }
.cfg-field__note { display: block; margin-top: 6px; font-size: 12px; color: var(--muted); }

.cfg-actions { display: flex; flex-direction: column; gap: 12px; margin-top: 26px; }
.cfg-actions .btn { width: 100%; }

/* Лист чертежа: намеренно похож на бумагу — его и будут печатать. */
.cfg-sheet {
  padding: clamp(20px, 2.4vw, 40px);
  border: 1px solid var(--line); background: #fff;
}
.cfg-sheet__head {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 20px; padding-bottom: 16px; margin-bottom: clamp(20px, 2.4vw, 34px);
  border-bottom: 1px solid var(--line);
}
.cfg-sheet__title {
  font-size: 12px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink);
}
.cfg-sheet__company { font-size: 12px; color: var(--muted); }

/* Пока выбраны не все параметры: вместо чертежа — что осталось выбрать. */
.cfg-empty { padding: clamp(30px, 5vw, 80px) 0; text-align: center; }
.cfg-empty__text {
  max-width: 46ch; margin: 0 auto;
  color: var(--muted); font-size: 15.5px; line-height: 1.7;
}
.cfg-empty__label {
  margin: clamp(26px, 3vw, 44px) 0 14px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .14em;
  text-transform: uppercase; color: var(--ink);
}
.cfg-empty__list {
  display: flex; flex-wrap: wrap; justify-content: center; gap: 10px;
  margin: 0; padding: 0; list-style: none;
}
.cfg-empty__list li {
  padding: 8px 16px;
  border: 1px solid var(--tint-line); border-radius: 999px;
  background: var(--tint); color: var(--brand-700);
  font-size: 12.5px; font-weight: 700;
}
.cfg-empty__list:empty::before {
  content: "готово"; color: var(--muted); font-size: 13px;
}

/* Заблокированная кнопка видна, но не нажимается: скачивание никуда
   не делось, оно откроется, когда выбор будет закончен. */
.btn:disabled {
  opacity: .42; cursor: not-allowed;
  transform: none !important; box-shadow: none !important;
}

.cfg-views { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: clamp(18px, 2vw, 36px); }
.cfg-view { margin: 0; }
.cfg-view figcaption {
  margin-bottom: 12px;
  font-size: 11.5px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--muted);
}
.cfg-view__box { border: 1px solid var(--line-soft); background: var(--soft); padding: 12px; }
.cfg-dwg { display: block; width: 100%; height: auto; max-height: 460px; color: var(--ink); }
.cfg-dwg text { font-family: var(--body); }

.cfg-specs { width: 100%; border-collapse: collapse; margin-top: clamp(24px, 3vw, 44px); }
.cfg-specs th, .cfg-specs td {
  padding: 11px 0; border-bottom: 1px solid var(--line-soft);
  font-size: 14.5px; text-align: left; vertical-align: top;
}
.cfg-specs th { width: 46%; font-weight: 400; color: var(--muted); }
.cfg-specs td { color: var(--ink); font-weight: 700; }
.cfg-note { margin: 18px 0 0; font-size: 12.5px; line-height: 1.6; color: var(--muted); }

/* --- Спецпредложение ------------------------------------------------------ */

.promo { display: grid; grid-template-columns: 1.1fr .9fr; gap: 0; border: 1px solid var(--line); }
.promo__body { padding: clamp(32px, 4.5vw, 68px); }
.promo__label { display: inline-block; margin-bottom: 22px; padding: 8px 15px; background: var(--brand); color: #fff; font-size: 11px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; }
.promo__title { font-size: clamp(24px, 2.8vw, 40px); }
.promo__text { margin: 22px 0 0; color: var(--muted); font-size: 16.5px; line-height: 1.7; max-width: 48ch; }
.promo__actions { margin-top: 34px; }
.promo__side { display: grid; place-items: center; padding: clamp(30px, 4vw, 60px); background: var(--ink); color: #fff; }

.countdown { display: flex; gap: 12px; }
.countdown__cell { min-width: 84px; padding: 18px 10px; border: 1px solid rgba(255, 255, 255, .18); text-align: center; }
.countdown__num { font-family: var(--display); font-size: clamp(26px, 3vw, 40px); font-weight: 400; line-height: 1; color: #fff; }
.countdown__cap { margin-top: 9px; font-size: 10.5px; letter-spacing: .12em; text-transform: uppercase; color: rgba(255, 255, 255, .5); }

/* --- Отзывы --------------------------------------------------------------- */

.reviews { display: grid; gap: 1px; grid-template-columns: repeat(auto-fit, minmax(330px, 1fr)); background: var(--line); border: 1px solid var(--line); }
.review { display: flex; flex-direction: column; padding: clamp(28px, 3vw, 44px); background: var(--bg); }
.review__quote { font-family: var(--display); font-size: 58px; line-height: .6; color: var(--brand); }
.review__text { margin: 22px 0 26px; color: var(--text); font-size: 16px; line-height: 1.7; flex: 1 1 auto; }
.review__person { display: flex; align-items: center; gap: 14px; padding-top: 22px; border-top: 1px solid var(--line); }
.review__photo { flex: none; width: 52px; height: 52px; border-radius: 50%; overflow: hidden; background: var(--soft); }
.review__photo img { width: 100%; height: 100%; object-fit: cover; }
/* Кружок мал для подписи — на пустом месте остаётся только штриховка. */
.review__photo .slot { display: none; }
.review__name { font-size: 15px; font-weight: 700; color: var(--ink); }
.review__role { margin-top: 3px; color: var(--muted); font-size: 13.5px; line-height: 1.4; }

/* --- Вопросы и ответы ------------------------------------------------------ */

.faq { border-top: 1px solid var(--line); max-width: 940px; }
.faq__item { border-bottom: 1px solid var(--line); }
.faq__q {
  display: flex; align-items: flex-start; justify-content: space-between; gap: 24px;
  width: 100%; padding: 26px 0; border: 0; background: none; cursor: pointer; text-align: left;
  font-size: clamp(16px, 1.4vw, 19px); font-weight: 700; color: var(--ink); line-height: 1.4;
  transition: color .18s var(--ease);
}
.faq__q:hover { color: var(--brand-700); }
.faq__sign { flex: none; width: 22px; height: 22px; position: relative; margin-top: 3px; }
.faq__sign::before, .faq__sign::after {
  content: ""; position: absolute; left: 50%; top: 50%; background: var(--brand);
  transform: translate(-50%, -50%); transition: transform .25s var(--ease), opacity .25s var(--ease);
}
.faq__sign::before { width: 16px; height: 2px; }
.faq__sign::after { width: 2px; height: 16px; }
.faq__item.is-open .faq__sign::after { transform: translate(-50%, -50%) rotate(90deg); opacity: 0; }
/* Раскрытие ответа анимируется — правила в разделе «Анимации». */
.faq__a { color: var(--muted); font-size: 16px; line-height: 1.75; max-width: 78ch; }

/* --- Цены ----------------------------------------------------------------- */

.prices { border-top: 1px solid var(--line); }
.price-row { display: grid; grid-template-columns: 1fr auto; gap: 20px 40px; align-items: baseline; padding: 26px 0; border-bottom: 1px solid var(--line); }
.price-row__name { font-size: clamp(16px, 1.4vw, 19px); font-weight: 700; color: var(--ink); }
.price-row__note { margin-top: 8px; color: var(--muted); font-size: 14.5px; line-height: 1.55; max-width: 70ch; }
.price-row__value { font-size: clamp(18px, 1.7vw, 24px); font-weight: 700; color: var(--brand-700); white-space: nowrap; }
.price-row__unit { margin-top: 6px; color: var(--muted); font-size: 13px; text-align: right; }

/* --- Блок «О компании» ----------------------------------------------------- */

.split { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(32px, 5vw, 90px); align-items: center; }
/* Потолок по высоте — чтобы блок о компании не перерастал каталог. */
.split__media { aspect-ratio: 16 / 10; max-height: 520px; overflow: hidden; border-radius: var(--radius-card); }
.split__media img { width: 100%; height: 100%; object-fit: cover; }
/* Колонка широкая — строку ограничиваем по числу символов, иначе на
   большом мониторе глаз теряет начало следующей строки. */
.split__text { margin-top: clamp(16px, 1.8vw, 24px); max-width: 68ch; color: var(--muted); font-size: 16px; line-height: 1.7; }
.split__text p:first-of-type { color: var(--text); }
.split__actions { margin-top: 24px; }

/* --- Бренды ---------------------------------------------------------------- */

.brands { display: grid; gap: 1px; grid-template-columns: repeat(auto-fit, minmax(170px, 1fr)); background: var(--line); border: 1px solid var(--line); }
.brands__item { display: grid; place-items: center; min-height: 122px; padding: 22px; background: var(--bg); }
.brands__item img { max-height: 54px; width: auto; object-fit: contain; filter: grayscale(1); opacity: .5; transition: filter .3s var(--ease), opacity .3s var(--ease); }
.brands__item:hover img { filter: none; opacity: 1; }

/* --- Галерея работ --------------------------------------------------------- */

.works { display: grid; gap: 1px; grid-template-columns: repeat(auto-fit, minmax(250px, 1fr)); background: var(--line); border: 1px solid var(--line); }
.works__item { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--soft); cursor: zoom-in; }
.works__item img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--ease); }
.works__item:hover img { transform: scale(1.07); }
.works__item::after { content: ""; position: absolute; inset: 0; background: rgba(0, 154, 159, 0); transition: background .3s var(--ease); }
.works__item:hover::after { background: rgba(0, 154, 159, .22); }

/* --- Тёмный баннер --------------------------------------------------------- */

.callout { background: var(--ink); color: #fff; }
.callout__inner { display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between; gap: 34px; padding: clamp(34px, 4.5vw, 66px); }
.callout__title { font-family: var(--display); font-size: clamp(22px, 2.6vw, 36px); font-weight: 400; text-transform: uppercase; letter-spacing: .04em; color: #fff; line-height: 1.15; }
.callout__text { margin-top: 16px; color: rgba(255, 255, 255, .62); max-width: 54ch; }
.callout__phones { display: flex; flex-wrap: wrap; gap: 16px 40px; }
.callout__phone { display: block; font-size: clamp(20px, 2.1vw, 29px); font-weight: 700; color: #fff; white-space: nowrap; }
.callout__phone:hover { color: var(--brand); }
.callout__phone span { display: block; margin-top: 7px; font-size: 11px; font-weight: 400; letter-spacing: .1em; text-transform: uppercase; color: rgba(255, 255, 255, .45); }

/* --- Текстовые блоки ------------------------------------------------------- */

.prose { color: var(--text); font-size: 16.5px; line-height: 1.8; max-width: 78ch; }
.prose > *:first-child { margin-top: 0; }
.prose > *:last-child { margin-bottom: 0; }
.prose h2 { margin: 1.7em 0 .6em; font-size: clamp(21px, 2vw, 28px); }
.prose h3 { margin: 1.5em 0 .5em; font-size: clamp(18px, 1.6vw, 22px); text-transform: none; }
.prose ol { margin: 0 0 1.2em; padding-left: 1.3em; }
.prose ul { margin: 0 0 1.2em; padding-left: 0; list-style: none; }
.prose li { margin-bottom: .5em; }
.prose ul > li { position: relative; padding-left: 26px; }
.prose ul > li::before { content: ""; position: absolute; left: 2px; top: .75em; width: 12px; height: 1px; background: var(--brand); }
.prose a { color: var(--brand-700); text-decoration: underline; text-underline-offset: 3px; }
.prose a:hover { color: var(--brand); }
.prose strong { color: var(--ink); }
.prose img { margin: .5em 0; }
.prose blockquote { margin: 1.6em 0; padding: 4px 0 4px 26px; border-left: 2px solid var(--brand); color: var(--muted); }
.prose figure { margin: 1.6em 0; }
.prose .table-scroll { overflow-x: auto; margin: 1.6em 0; -webkit-overflow-scrolling: touch; }
.prose table { border-collapse: collapse; width: 100%; min-width: 520px; font-size: 15px; }
.prose th, .prose td { padding: 13px 16px; border: 1px solid var(--line); text-align: left; vertical-align: top; }
.prose th { background: var(--soft); font-weight: 700; color: var(--ink); }
.prose--wide { max-width: none; }

.readmore__body { position: relative; overflow: hidden; }
.readmore.is-collapsed .readmore__body { max-height: 320px; }
.readmore.is-collapsed .readmore__body::after {
  content: ""; position: absolute; left: 0; right: 0; bottom: 0; height: 150px;
  background: linear-gradient(180deg, rgba(255, 255, 255, 0), var(--bg));
}
.section--soft .readmore.is-collapsed .readmore__body::after { background: linear-gradient(180deg, rgba(246, 246, 246, 0), var(--soft)); }
.readmore__btn { margin-top: 24px; }

/* --- Хлебные крошки и шапка страницы --------------------------------------- */

.crumbs { padding: 18px 0; border-bottom: 1px solid var(--line-soft); }
.crumbs__list { display: flex; flex-wrap: wrap; align-items: center; gap: 8px; font-size: 12px; letter-spacing: .06em; text-transform: uppercase; color: var(--muted); }
.crumbs a:hover { color: var(--brand-700); }
.crumbs__sep { opacity: .4; }
.crumbs__current { color: var(--ink); }

.page-head { padding-block: clamp(34px, 5vw, 72px) clamp(24px, 3vw, 42px); }
.page-head__lead { margin-top: 26px; color: var(--muted); font-size: 17px; line-height: 1.75; max-width: 80ch; }
.page-head__lead p:last-child { margin-bottom: 0; }

/* --- Каталог: сайдбар + сетка ---------------------------------------------- */

.catalog { display: grid; gap: 44px; grid-template-columns: 280px minmax(0, 1fr); align-items: start; }
.side { position: sticky; top: calc(var(--header-h) + 20px); }
.side__title { margin-bottom: 16px; font-size: 11.5px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); }
.side__list { margin: 0; padding: 0; list-style: none; border-top: 1px solid var(--line); }
.side__list li { border-bottom: 1px solid var(--line); }
.side__link { display: flex; align-items: center; justify-content: space-between; gap: 12px; padding: 15px 0; font-size: 14.5px; color: var(--text); transition: color .16s var(--ease), padding .2s var(--ease); }
.side__link:hover { color: var(--brand-700); padding-left: 8px; }
.side__link.is-active { color: var(--brand-700); font-weight: 700; }
.side__link b { font-weight: 400; opacity: .45; font-size: 12.5px; }

/* Список товаров: ширину колонок задаёт сетка, поэтому рядом с боковым
   меню их три, на широком мониторе четыре, на узком экране две. */
.cards--goods { grid-template-columns: repeat(auto-fill, minmax(290px, 1fr)); gap: clamp(16px, 1.6vw, 26px); }

.product-card {
  display: flex; flex-direction: column; background: var(--bg);
  border-radius: var(--radius-card); overflow: hidden;
  transition: background .25s var(--ease), box-shadow .3s var(--ease), transform .3s var(--ease);
}
.product-card:hover { background: var(--soft); transform: translateY(-4px); box-shadow: var(--lift); }
/* Снимки кабин вертикальные и разной пропорции, поэтому кадр высокий,
   а картинка вписывается целиком: обрезанная по квадрату кабина
   читалась как брак. Белая подложка за снимком — вместо полей. */
.product-card__media {
  aspect-ratio: 3 / 4; max-height: 430px;
  background: #fff; overflow: hidden;
}
.product-card__media img { width: 100%; height: 100%; object-fit: contain; transition: transform .6s var(--ease); }
.product-card:hover .product-card__media img { transform: scale(1.05); }
.product-card__body { display: flex; flex-direction: column; flex: 1 1 auto; padding: 14px 4px 16px; }
.product-card__name { font-size: 15.5px; font-weight: 700; color: var(--ink); line-height: 1.35; }
.product-card:hover .product-card__name { color: var(--brand-700); }
.product-card__text { margin-top: 8px; color: var(--muted); font-size: 13.5px; line-height: 1.5; display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }
.product-card__foot { display: flex; align-items: center; justify-content: space-between; gap: 12px; margin-top: auto; padding-top: 16px; }
.product-card__price { font-size: 15.5px; font-weight: 700; color: var(--ink); }
.product-card__price--empty { font-size: 12px; font-weight: 700; letter-spacing: .08em; text-transform: uppercase; color: var(--muted); }

.empty-note { padding: 44px; border: 1px solid var(--line); background: var(--soft); color: var(--muted); text-align: center; }
.empty-note__text { max-width: 56ch; margin: 0 auto 22px; line-height: 1.6; }

/* Снимок над текстом на простой странице: целиком, но не во всю ширину —
   иначе он перевешивает сам текст, ради которого страница и сделана. */
.page-photo {
  margin: 0 0 clamp(26px, 3vw, 44px); max-width: 760px;
  overflow: hidden; border-radius: var(--radius-card); background: var(--soft);
}
.page-photo img { display: block; width: 100%; height: auto; }

/* Лента фотографий: едет по кругу, при наведении останавливается,
   чтобы можно было рассмотреть. По краям растворяется. */
.photo-row {
  position: relative; overflow: hidden;
  margin-top: clamp(30px, 3.4vw, 54px);
  -webkit-mask-image: linear-gradient(90deg, transparent 0, #000 4%, #000 96%, transparent 100%);
  mask-image: linear-gradient(90deg, transparent 0, #000 4%, #000 96%, transparent 100%);
}
.photo-row__track {
  display: flex; width: max-content;
  animation: adv-marquee var(--marquee-time, 40s) linear infinite;
}
.photo-row:hover .photo-row__track { animation-play-state: paused; }
.photo-row__set { display: flex; }
.photo-row__item {
  flex: none; width: clamp(240px, 26vw, 420px); margin-right: clamp(12px, 1.4vw, 22px);
  aspect-ratio: 16 / 10; overflow: hidden; border-radius: 12px; background: var(--soft);
}
.photo-row__item img { width: 100%; height: 100%; object-fit: cover; display: block; }

/* --- Страница «Преимущества» ------------------------------------------------
   Группы пунктов колонками: на широком экране две, дальше одна. Каждая —
   светлая панель с номером, заголовком и списком с галочками. */

.adv-page__lead { margin-bottom: clamp(26px, 3vw, 44px); }
.adv-groups { display: grid; gap: clamp(18px, 2vw, 30px); grid-template-columns: repeat(auto-fit, minmax(420px, 1fr)); align-items: start; }
.adv-group {
  padding: clamp(24px, 2.4vw, 38px);
  border: 1px solid var(--line); border-radius: var(--radius-card); background: #fff;
  box-shadow: 0 24px 56px -40px rgba(15, 40, 45, .35);
}
.adv-group__head { display: flex; align-items: flex-start; gap: 16px; padding-bottom: clamp(16px, 1.6vw, 24px); border-bottom: 1px solid var(--line-soft); }
.adv-group__n {
  flex: none; font-family: var(--display); font-size: clamp(22px, 2vw, 30px);
  line-height: 1; color: var(--brand); opacity: .85;
}
.adv-group__title {
  margin: 0; font-family: var(--display); font-weight: 400; text-transform: uppercase;
  font-size: clamp(17px, 1.5vw, 23px); letter-spacing: .03em; line-height: 1.25; color: var(--ink);
}
.adv-group__lead { margin: 8px 0 0; color: var(--muted); font-size: 14px; line-height: 1.5; }

.adv-list { margin: 0; padding: 0; list-style: none; }
.adv-list__item {
  display: flex; align-items: flex-start; gap: 14px;
  padding: clamp(12px, 1.2vw, 16px) 0;
  color: var(--text); font-size: 15px; line-height: 1.6;
}
.adv-list__item + .adv-list__item { border-top: 1px solid var(--line-soft); }
.adv-list__mark {
  flex: none; display: grid; place-items: center;
  width: 26px; height: 26px; margin-top: 1px;
  border-radius: 50%; background: var(--tint); color: var(--brand-700);
}

/* --- Карточка товара -------------------------------------------------------- */

/* Снимок и описание — левой колонкой, название с характеристиками —
   правой. Описание стоит прямо под фотографией: список характеристик
   обычно длиннее снимка, и место под ним иначе пустует. На узком экране
   порядок другой: сперва фото, потом название, потом описание. */
.product {
  display: grid; gap: clamp(26px, 3vw, 44px) 54px;
  grid-template-columns: minmax(0, 1.05fr) minmax(0, 1fr);
  grid-template-areas: "media info" "desc info";
  align-items: start;
}
.product__media { grid-area: media; }
.product__info { grid-area: info; }
.product__desc { grid-area: desc; }
/* Высоту главного снимка задаёт он сам: кабины снимают вертикально, и в
   жёсткой рамке 4:3 такой кадр висел бы в широких белых полях. Потолок
   по высоте — чтобы очень вытянутый снимок не занял весь экран. */
.gallery__main {
  position: relative; display: flex; align-items: center; justify-content: center;
  overflow: hidden; background: #fff; cursor: zoom-in;
}
/* Ширина колонки и пропорции из атрибутов width/height — браузер оставляет
   место под снимок до загрузки, и описание под ним не съезжает вниз.
   contain вписывает кадр целиком: вертикальный встаёт по центру на белом. */
.gallery__main img { width: 100%; height: auto; max-height: 620px; object-fit: contain; display: block; }
.gallery__thumbs { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 12px; }
/* Рамка у миниатюр нужна: по ней видно, какой снимок сейчас открыт. */
.gallery__thumb { width: 72px; height: 90px; padding: 3px; border: 1px solid var(--line); overflow: hidden; background: #fff; cursor: pointer; transition: border-color .18s var(--ease); }
.gallery__thumb img { width: 100%; height: 100%; object-fit: contain; }
.gallery__thumb.is-active { border-color: var(--brand); }

/* Описание отступает от снимка заметнее, чем на обычный шаг сетки:
   иначе заголовок «Описание» читается как подпись к фотографии. */
.product__desc { padding-top: clamp(16px, 1.6vw, 28px); }
.product__desc-title { margin: 0 0 16px; font-size: clamp(20px, 1.8vw, 26px); }
.product__desc p { color: var(--muted); }
.product__desc p:last-child { margin-bottom: 0; }

.product__cat { display: inline-block; margin-bottom: 16px; color: var(--brand-700); font-size: 11.5px; font-weight: 700; letter-spacing: .14em; text-transform: uppercase; }
.product__title { margin-bottom: 24px; font-size: clamp(24px, 2.8vw, 40px); }
.product__price { font-size: 28px; font-weight: 700; color: var(--ink); margin-bottom: 24px; }
.product__actions { display: flex; flex-wrap: wrap; gap: 14px; margin-bottom: 36px; }

.specs__title { margin: 0 0 14px; font-size: 19px; }
.specs { border-top: 1px solid var(--line); }
.specs__row { display: grid; grid-template-columns: minmax(120px, 36%) 1fr; gap: 20px; padding: 15px 0; border-bottom: 1px solid var(--line-soft); }
/* Название характеристики выделено, значение — обычным текстом. */
.specs__key { color: var(--ink); font-size: 14.5px; font-weight: 700; }
.specs__val { color: var(--text); font-size: 14.5px; }

.product__note { display: flex; gap: 14px; margin-top: 30px; padding: 20px 22px; background: var(--soft); color: var(--text); font-size: 14.5px; line-height: 1.6; }
.product__note svg { flex: none; margin-top: 2px; color: var(--brand); }

/* --- Объекты и статьи -------------------------------------------------------- */

.post-card { display: flex; flex-direction: column; background: var(--bg); transition: background .25s var(--ease); }
.post-card:hover { background: var(--soft); }
.post-card__media { aspect-ratio: 16 / 10; background: var(--soft); overflow: hidden; }
.post-card__media img { width: 100%; height: 100%; object-fit: cover; transition: transform .6s var(--ease); }
.post-card:hover .post-card__media img { transform: scale(1.05); }
.post-card__body { display: flex; flex-direction: column; flex: 1 1 auto; padding: 26px; }
.post-card__title { font-size: 17.5px; font-weight: 700; color: var(--ink); line-height: 1.35; }
.post-card:hover .post-card__title { color: var(--brand-700); }
.post-card__text { margin-top: 12px; color: var(--muted); font-size: 14.5px; line-height: 1.6; display: -webkit-box; -webkit-line-clamp: 3; -webkit-box-orient: vertical; overflow: hidden; }
.post-card__foot { margin-top: auto; padding-top: 20px; }

.article { display: grid; gap: 54px; grid-template-columns: minmax(0, 1fr) 320px; align-items: start; }
.aside-card { padding: 30px; background: var(--soft); }
.aside-card__title { font-size: 18px; font-weight: 700; color: var(--ink); }
.aside-card__text { margin: 12px 0 22px; color: var(--muted); font-size: 14.5px; line-height: 1.6; }
.aside-sticky { position: sticky; top: calc(var(--header-h) + 20px); display: grid; gap: 20px; }

.photo-grid { display: grid; gap: 1px; grid-template-columns: repeat(auto-fit, minmax(220px, 1fr)); background: var(--line); border: 1px solid var(--line); margin-top: 34px; }
.photo-grid__item { position: relative; aspect-ratio: 4 / 3; overflow: hidden; background: var(--soft); cursor: zoom-in; }
.photo-grid__item img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s var(--ease); }
.photo-grid__item:hover img { transform: scale(1.06); }
/* Страница проекта: под описанием снимки кабин в ряд. Снимки вертикальные
   и разной формы (1:2, 3:4, квадрат), поэтому без общей рамки: каждый
   целиком, в своей форме, все одной высоты — ни обрезки, ни серых полей. */
.gallery-portrait .photo-grid {
  display: flex; flex-wrap: wrap; gap: 14px; margin-top: clamp(24px, 2.4vw, 34px);
  background: none; border: 0;
}
.gallery-portrait .photo-grid__item {
  width: auto; aspect-ratio: auto; border-radius: 12px; background: var(--soft);
}
.gallery-portrait .photo-grid__item img {
  display: block; width: auto; height: clamp(300px, 28vw, 420px); max-width: 100%;
  object-fit: cover; border-radius: 12px;
}
.gallery-portrait .photo-grid__item:hover img { transform: scale(1.03); }
@media (max-width: 760px) {
  .gallery-portrait .photo-grid { gap: 10px; }
  .gallery-portrait .photo-grid__item img { height: 260px; }
}

/* --- Контакты ----------------------------------------------------------------- */

.contacts { display: grid; gap: 44px; grid-template-columns: minmax(0, 400px) minmax(0, 1fr); align-items: start; }
.contact-block { padding-bottom: 28px; border-bottom: 1px solid var(--line); }
.contact-block + .contact-block { margin-top: 28px; }
.contact-block__label { font-size: 11.5px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--muted); }
.contact-block__value { margin-top: 12px; font-size: 19px; font-weight: 700; color: var(--ink); line-height: 1.5; }
.contact-block__value a:hover { color: var(--brand-700); }
.contact-block__note { margin-top: 8px; color: var(--muted); font-size: 14.5px; }
.map-frame { aspect-ratio: 16 / 12; overflow: hidden; border: 1px solid var(--line); background: var(--soft); }
.map-frame iframe { width: 100%; height: 100%; border: 0; display: block; }

/* --- Формы --------------------------------------------------------------------- */

.field { display: block; margin-bottom: 18px; }
.field__label { display: block; margin-bottom: 9px; font-size: 11.5px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--muted); }
/* Пометка необязательного поля — маленькая плашка в фирменном цвете.
   Серым примечанием её не замечали и заполняли всё подряд. */
.field__opt {
  display: inline-block; margin-left: 8px; padding: 2px 8px 3px; vertical-align: 1px;
  border-radius: 999px; background: rgba(22, 153, 159, .12); color: var(--brand-700);
  font-size: 11px; font-weight: 600; line-height: 1.3; letter-spacing: .02em; text-transform: none;
}
.field__input {
  width: 100%; padding: 15px 0;
  border: 0; border-bottom: 1px solid var(--line); border-radius: 0;
  background: transparent; color: var(--ink); font: inherit; font-size: 16px;
  transition: border-color .2s var(--ease);
}
.field__input::placeholder { color: #b4b9bd; }
.field__input:focus { outline: none; border-bottom-color: var(--brand); }
.field__input[aria-invalid="true"] { border-bottom-color: #d64545; }
.field__error { display: none; margin-top: 7px; color: #d64545; font-size: 13px; }
.field__input[aria-invalid="true"] ~ .field__error { display: block; }

.check { display: flex; flex-wrap: wrap; gap: 11px; align-items: flex-start; margin: 6px 0 22px; font-size: 12.5px; line-height: 1.55; color: var(--muted); }
.check input { flex: none; width: 18px; height: 18px; margin: 1px 0 0; accent-color: var(--brand); }
/* Текст согласия остаётся рядом с квадратиком: без этого он от переноса
   строки с ошибкой уезжал под него целиком. */
.check span:not(.check__error) { flex: 1 1 200px; min-width: 0; }
.check a { color: var(--brand-700); text-decoration: underline; }
/* Галочку забыли — её видно так же, как незаполненное поле: сам квадратик
   обведён красным, под ним строка с причиной. */
.check input[aria-invalid="true"] { outline: 2px solid #d64545; outline-offset: 2px; }
.check__error { display: none; width: 100%; color: #d64545; }
.check input[aria-invalid="true"] ~ .check__error { display: block; }

/* Строка преимуществ под заголовком окна. Пункты разделены точкой:
   она рисуется стилями, чтобы в разметке остался чистый список. */
.form__perks {
  display: flex; flex-wrap: wrap; align-items: center; gap: 6px 14px;
  margin: 16px 0 22px; padding-bottom: 16px;
  border-bottom: 1px solid var(--line);
  font-size: 12.5px; letter-spacing: .04em; color: var(--brand-700);
}
.form__perks span { display: flex; align-items: center; gap: 14px; }
.form__perks span + span::before {
  content: ""; width: 4px; height: 4px; border-radius: 50%;
  background: var(--brand); opacity: .55;
}

/* Плашка перед кнопкой: что будет после отправки. Здесь же единственный
   в форме значок — он держит взгляд на обещании, а не на кнопке. */
.form__promise {
  display: flex; gap: 12px; align-items: flex-start;
  margin: 4px 0 20px; padding: 14px 16px;
  border: 1px solid var(--tint-line); border-radius: 12px; background: var(--tint);
}
.form__promise-icon { flex: none; display: grid; place-items: center; color: var(--brand-700); }
.form__promise-title {
  display: block; font-size: 12px; font-weight: 700; letter-spacing: .12em;
  text-transform: uppercase; color: var(--brand-700);
}
.form__promise-text {
  display: block; margin-top: 5px; font-size: 13px; line-height: 1.55; color: var(--muted);
}

/* Длинная форма идёт в две колонки: пять полей столбиком вытягивают
   окно так, что кнопка уходит под нижний край экрана. Поля, которым
   нужна вся ширина (адрес объекта), помечены field--wide. */
.form__set--two {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(18px, 2vw, 28px);
}
.form__set--two .field--wide { grid-column: 1 / -1; }
@media (max-width: 620px) {
  .form__set--two { grid-template-columns: minmax(0, 1fr); }
}

/* Выбор направления заявки: две кнопки в ряд, выбранная — бирюзовая.
   Сами переключатели скрыты, но доступны с клавиатуры: рамка обводит
   кнопку, когда переключатель в фокусе. */
.kinds { display: grid; grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 8px; }
.kind { position: relative; display: block; cursor: pointer; }
.kind input {
  position: absolute; inset: 0; width: 100%; height: 100%;
  margin: 0; opacity: 0; cursor: pointer;
}
.kind span {
  display: flex; align-items: center; justify-content: center; min-height: 46px;
  padding: 8px 12px; text-align: center;
  border: 1px solid var(--line); border-radius: 10px; background: #fff;
  font-size: 13px; line-height: 1.25; color: var(--muted);
  transition: border-color .2s var(--ease), background .2s var(--ease), color .2s var(--ease);
}
.kind input:hover + span { border-color: var(--tint-line); }
.kind input:focus-visible + span { outline: 2px solid var(--brand); outline-offset: 2px; }
.kind input:checked + span {
  border-color: var(--brand); background: var(--tint);
  color: var(--brand-700); font-weight: 700;
}
/* «Рассчитать монтаж» в окне заявки — не переключатель, а переход в окно
   расчёта. Выглядит как соседняя кнопка, стрелка показывает переход. */
.kind--link { padding: 0; border: 0; background: none; font: inherit; text-align: inherit; }
.kind--link span { gap: 6px; }
.kind--link span::after { content: "→"; color: var(--brand); }
.kind--link:hover span { border-color: var(--tint-line); color: var(--brand-700); }
.kind--link:focus-visible span { outline: 2px solid var(--brand); outline-offset: 2px; }
/* В окне расчёта: «Рассчитать монтаж» — текущий выбор, выглядит как отмеченный. */
.kind--current span {
  border-color: var(--brand); background: var(--tint);
  color: var(--brand-700); font-weight: 700;
}

/* --- Окно расчёта монтажа -------------------------------------------------
   Оформление взято у окна обслуживания: те же подписи, поля с чертой,
   кнопки выбора и плашка. Своё здесь только то, чего там нет: ползунки,
   списки, отметки и сводка второго шага. */
.calc__step { animation: calc-in .5s var(--ease-soft) both; }
@keyframes calc-in { from { opacity: 0; transform: translateY(12px); } to { opacity: 1; transform: none; } }
.calc__section { margin: 26px 0 14px; }

/* Тип оборудования — те же кнопки выбора, только с пояснением под названием. */
.calc__types { grid-template-columns: repeat(3, minmax(0, 1fr)); }
.calc__types--two { grid-template-columns: repeat(2, minmax(0, 1fr)); }
.kind--card span {
  flex-direction: column; align-items: flex-start; justify-content: flex-start;
  gap: 5px; min-height: 0; padding: 14px 14px 13px; text-align: left;
}
.kind--card svg { margin-bottom: 4px; color: var(--brand-700); }
.kind--card b { font-size: 13.5px; color: var(--ink); }
.kind--card small { font-size: 12px; line-height: 1.4; font-weight: 400; color: var(--muted); }

/* Ползунки: тонкая черта, как у полей, заливка до бегунка бирюзовая. */
.calc__ranges { display: grid; gap: 20px; margin-top: 24px; }
.calc-range__head { display: flex; justify-content: space-between; align-items: baseline; gap: 16px; }
.calc-range__head .field__label { margin: 0; }
.calc-range__value { font-family: var(--display); font-size: 20px; color: var(--ink); white-space: nowrap; }
.calc-range__value small { font-family: var(--body); font-size: 12px; color: var(--muted); }
.calc-range input[type="range"] {
  width: 100%; height: 20px; margin: 8px 0 0;
  -webkit-appearance: none; appearance: none; background: transparent; cursor: pointer;
}
.calc-range input[type="range"]::-webkit-slider-runnable-track {
  height: 2px; background: linear-gradient(90deg, var(--brand) var(--pct, 50%), var(--line) var(--pct, 50%));
}
.calc-range input[type="range"]::-webkit-slider-thumb {
  -webkit-appearance: none; width: 18px; height: 18px; margin-top: -8px;
  border: 2px solid var(--brand); border-radius: 50%; background: #fff;
  box-shadow: 0 2px 8px rgba(14, 40, 42, .18);
}
.calc-range input[type="range"]::-moz-range-track { height: 2px; background: var(--line); }
.calc-range input[type="range"]::-moz-range-progress { height: 2px; background: var(--brand); }
.calc-range input[type="range"]::-moz-range-thumb {
  width: 14px; height: 14px; border: 2px solid var(--brand); border-radius: 50%; background: #fff;
}
.calc-range input[type="range"]:focus-visible { outline: 2px solid var(--brand); outline-offset: 4px; }
.calc-range__marks { display: flex; justify-content: space-between; margin-top: 2px; font-size: 11.5px; color: #a7adb2; }

/* Список — то же поле с чертой, со стрелкой справа. */
.calc__select {
  -webkit-appearance: none; appearance: none; cursor: pointer; padding-right: 26px;
  background: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%237c8288' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='m6 9 6 6 6-6'/%3E%3C/svg%3E") no-repeat right 2px center / 16px;
}
.calc__comment { resize: vertical; min-height: 54px; line-height: 1.5; }

.calc__opts {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(18px, 2vw, 28px); margin-top: 2px;
}
.calc-opt { margin: 0 0 12px; font-size: 13.5px; color: var(--text); }

/* Сводка второго шага: строки с чертой, как поля первого. */
.calc-sum {
  display: grid; grid-template-columns: repeat(2, minmax(0, 1fr));
  column-gap: clamp(18px, 2vw, 28px); margin-bottom: 22px;
}
.calc-sum .calc__section { margin-top: 0; }
.calc-sum dl { margin: 0; }
.calc-sum__row {
  display: flex; justify-content: space-between; gap: 16px;
  padding: 11px 0; border-bottom: 1px solid var(--line); font-size: 14px; line-height: 1.45;
}
.calc-sum__row dt { color: var(--muted); }
.calc-sum__row dd { margin: 0; text-align: right; color: var(--ink); font-weight: 600; overflow-wrap: anywhere; }

.calc__actions { display: flex; gap: 12px; }
.calc__actions .btn--ghost { flex: none; }
.calc__actions .btn--wide { flex: 1 1 auto; width: auto; }

@media (max-width: 620px) {
  .calc__types, .calc__opts, .calc-sum { grid-template-columns: minmax(0, 1fr); }
  .calc__actions { flex-direction: column-reverse; }
}

/* Ловушка для роботов: поле есть в разметке, но человеку не показывается
   и в обход по клавише не попадает. Скрываем так, чтобы робот, читающий
   стили, не догадался: не display:none, а вынос за пределы экрана. */
.trap {
  position: absolute; left: -9999px; top: auto;
  width: 1px; height: 1px; overflow: hidden;
}

.form__status { margin-top: 16px; font-size: 14.5px; }
.form__status--ok { color: var(--brand-700); }
.form__status--err { color: #d64545; }

.modal { position: fixed; inset: 0; z-index: 140; display: none; align-items: center; justify-content: center; padding: 20px; }
.modal.is-open { display: flex; }
.modal__backdrop { position: absolute; inset: 0; background: rgba(8, 8, 8, .7); }
.modal__box { position: relative; width: 100%; max-width: 470px; max-height: 90vh; overflow-y: auto; padding: 44px 40px; background: #fff; box-shadow: var(--shadow-lg); }
/* Окно под форму в две колонки. Ширину меняет скрипт вместе с набором
   полей — см. applyKind в app.js. */
.modal__box--wide { max-width: 760px; }
.modal__close { position: absolute; top: 16px; right: 16px; width: 40px; height: 40px; display: grid; place-items: center; border: 0; background: none; color: var(--muted); cursor: pointer; }
.modal__close:hover { color: var(--ink); }
.modal__title { font-family: var(--display); font-size: clamp(22px, 2.2vw, 30px); font-weight: 400; text-transform: uppercase; letter-spacing: .04em; color: var(--ink); line-height: 1.15; }
.modal__text { margin: 16px 0 30px; color: var(--muted); font-size: 15px; line-height: 1.6; }

/* --- Отправка заявки: кнопка с прогрессом → «Спасибо» → растворение ------
   Порядок задаёт submitForm в app.js:
   1. .is-sending — кнопку заполняет тёмная полоса до ~85% и бежит блик;
   2. .is-sent    — полоса добегает до конца, выпрыгивает галочка;
   3. окно заявки уходит (.is-leaving), всплывает «Спасибо» — галочка
      прорисовывается линией, внизу идёт полоска отсчёта;
   4. через 4 с «Спасибо» растворяется целиком, вместе с затемнением. */

.btn.is-sending, .btn.is-sent {
  position: relative; overflow: hidden; isolation: isolate;
  pointer-events: none; transform: none !important; box-shadow: none !important;
}
.btn.is-sending > *, .btn.is-sent > * { position: relative; z-index: 1; }
/* полоса прогресса */
.btn.is-sending::before, .btn.is-sent::before {
  content: ""; position: absolute; inset: 0 auto 0 0; z-index: 0; width: 0;
  background: linear-gradient(90deg, var(--brand-700), #0a5559);
}
.btn.is-sending::before { animation: btn-progress 1.6s cubic-bezier(.25, .7, .3, 1) forwards; }
.btn.is-sent::before { animation: btn-finish .35s var(--ease) forwards; }
/* блик, пока ждём ответа */
.btn.is-sending::after {
  content: ""; position: absolute; inset: 0; z-index: 0;
  background: linear-gradient(105deg, transparent 35%, rgba(255, 255, 255, .22) 50%, transparent 65%);
  animation: btn-shine 1.1s linear infinite;
}
.btn.is-sent { background: var(--brand-700); border-color: var(--brand-700); }
.btn__tick {
  display: inline-grid; place-items: center; width: 22px; height: 22px;
  border-radius: 50%; background: #fff; color: var(--brand-700);
  animation: tick-pop .6s cubic-bezier(.34, 1.56, .64, 1) both;
}
.btn__tick svg { width: 13px; height: 13px; }
.btn.is-sent .btn__txt { animation: txt-in .35s .1s var(--ease) both; }

@keyframes btn-progress { from { width: 0; } to { width: 85%; } }
@keyframes btn-finish { from { width: 85%; } to { width: 100%; } }
@keyframes btn-shine { from { transform: translateX(-100%); } to { transform: translateX(100%); } }
@keyframes tick-pop {
  0% { transform: scale(.1); opacity: 0; }
  70% { transform: scale(1.2); opacity: 1; }
  100% { transform: scale(1); }
}
@keyframes txt-in { from { opacity: 0; transform: translateX(-6px); } to { opacity: 1; transform: none; } }

/* окно заявки уходит */
.modal.is-leaving .modal__box { animation: modal-out .32s var(--ease) forwards; }
@keyframes modal-out { to { opacity: 0; transform: translateY(10px) scale(.97); } }

/* «Спасибо» */
.thanks { text-align: center; overflow: hidden; }
#modal-thanks.is-open .modal__box { animation: modal-in .5s cubic-bezier(.2, .8, .2, 1) both; }
@keyframes modal-in { from { opacity: 0; transform: translateY(16px) scale(.95); } to { opacity: 1; transform: none; } }
.thanks__mark {
  position: relative; width: 64px; height: 64px; margin: 6px auto 20px;
  display: grid; place-items: center;
  border: 1px solid var(--brand); color: var(--brand);
}
/* галочка прорисовывается линией, рамка один раз «расходится» волной */
#modal-thanks.is-open .thanks__mark svg path {
  stroke-dasharray: 24; stroke-dashoffset: 24;
  animation: draw-check .55s .3s cubic-bezier(.65, 0, .35, 1) forwards;
}
#modal-thanks.is-open .thanks__mark::after {
  content: ""; position: absolute; inset: -1px; border: 1px solid var(--brand);
  animation: mark-ring .9s .45s var(--ease) both;
}
@keyframes draw-check { to { stroke-dashoffset: 0; } }
@keyframes mark-ring { from { opacity: .8; transform: scale(1); } to { opacity: 0; transform: scale(1.45); } }
.thanks__timer {
  position: absolute; left: 0; bottom: 0; width: 100%; height: 3px;
  background: var(--brand); transform: scaleX(0); transform-origin: left;
}
#modal-thanks.is-auto .thanks__timer { animation: thanks-timer var(--thanks-ms, 4000ms) linear forwards; }
@keyframes thanks-timer { from { transform: scaleX(1); } to { transform: scaleX(0); } }
/* растворение целиком, вместе с затемнением */
#modal-thanks.is-leaving { animation: fade-away .5s var(--ease) forwards; }
@keyframes fade-away { to { opacity: 0; } }

@media (prefers-reduced-motion: reduce) {
  .btn.is-sending::after { animation: none; }
  #modal-thanks.is-open .modal__box, .modal.is-leaving .modal__box { animation-duration: .01s; }
}

.lightbox { position: fixed; inset: 0; z-index: 150; display: none; align-items: center; justify-content: center; padding: 24px; background: rgba(6, 6, 6, .95); }
.lightbox.is-open { display: flex; }
.lightbox img { max-width: 100%; max-height: 88vh; width: auto; }
.lightbox__close, .lightbox__nav {
  position: absolute; display: grid; place-items: center;
  width: 52px; height: 52px; border: 1px solid rgba(255, 255, 255, .2);
  background: transparent; color: #fff; cursor: pointer;
  transition: background .18s var(--ease), border-color .18s var(--ease);
}
.lightbox__close:hover, .lightbox__nav:hover { background: rgba(255, 255, 255, .12); border-color: rgba(255, 255, 255, .5); }
.lightbox__close { top: 24px; right: 24px; }
.lightbox__nav--prev { left: 24px; }
.lightbox__nav--next { right: 24px; }
.lightbox__counter { position: absolute; bottom: 24px; left: 50%; transform: translateX(-50%); color: rgba(255, 255, 255, .6); font-size: 12px; letter-spacing: .12em; }

/* --- Подвал ---------------------------------------------------------------------- */

.footer { background: var(--ink); color: rgba(255, 255, 255, .55); font-size: 14.5px; }
.footer__top { display: grid; gap: 36px; grid-template-columns: minmax(0, 1.4fr) repeat(3, minmax(0, 1fr)); padding-block: clamp(32px, 3.6vw, 52px); }
.footer__logo img { width: 190px; }
.footer__about { margin-top: 16px; max-width: 34ch; line-height: 1.6; }
.footer__col-title { margin-bottom: 14px; color: #fff; font-size: 11.5px; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; }
.footer__list { margin: 0; padding: 0; list-style: none; display: grid; gap: 8px; }
.footer__list a:hover { color: var(--brand); }
.footer__contact { display: grid; gap: 16px; }
.footer__phone { font-size: 22px; font-weight: 700; color: #fff; }
.footer__phone:hover { color: var(--brand); }
.footer__bottom {
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 12px 34px; padding-block: 18px;
  border-top: 1px solid rgba(255, 255, 255, .1);
  font-size: 12.5px; color: rgba(255, 255, 255, .38);
}
/* Кто сделал сайт — строкой под знаком охраны прав, тем же тоном,
   но мельче: это служебная подпись, а не часть реквизитов. */
.footer__made { display: block; margin-top: 6px; font-size: 11.5px; color: rgba(255, 255, 255, .28); }
.footer__legal { display: flex; flex-wrap: wrap; gap: 10px 26px; }
.footer__legal a:hover { color: rgba(255, 255, 255, .8); }

.to-top {
  position: fixed; right: 24px; bottom: 24px; z-index: 80;
  width: 48px; height: 48px; display: grid; place-items: center;
  border: 0; background: var(--ink); color: #fff; cursor: pointer;
  opacity: 0; visibility: hidden; transform: translateY(10px);
  transition: opacity .25s var(--ease), transform .25s var(--ease), visibility .25s, background .18s var(--ease);
}
.to-top.is-visible { opacity: 1; visibility: visible; transform: translateY(0); }
.to-top:hover { background: var(--brand); }

/* Уведомление живёт в правом нижнем углу: по центру оно накрывало бы
   кнопки первого экрана — то самое, ради чего человек на сайт и пришёл. */
.cookie-bar {
  position: fixed; right: 20px; bottom: 20px; left: auto; z-index: 100;
  display: none; align-items: flex-start; flex-direction: column;
  gap: 14px; width: min(380px, calc(100vw - 40px));
  padding: 20px 22px; background: #fff; border: 1px solid var(--line); box-shadow: var(--shadow-lg);
  font-size: 13.5px; line-height: 1.6; color: var(--muted);
}
.cookie-bar .btn { align-self: flex-end; }
.cookie-bar.is-shown { display: flex; }
.cookie-bar a { color: var(--brand-700); text-decoration: underline; }

/* --- Анимации ---------------------------------------------------------------------
   Движение здесь служебное: подсказывает, что блок появился, и связывает
   наведение с результатом. Ничего не мигает и не прыгает.

   Всё, что прячется, прячется только при работающем JavaScript (класс .js
   ставится в <head> до отрисовки). Если скрипты отключены или не загрузились,
   страница просто показывается целиком — без пустых экранов. */

.js .reveal {
  opacity: 0;
  transform: translateY(26px);
  transition: opacity .75s var(--ease), transform .75s var(--ease);
  transition-delay: var(--delay, 0ms);
  will-change: opacity, transform;
}
.js .reveal.is-visible { opacity: 1; transform: none; }

/* Появление слева — для текстовой половины парных блоков */
.js .reveal--left { transform: translateX(-28px); }
.js .reveal--right { transform: translateX(28px); }

/* Содержимое первого экрана проявляется сразу при загрузке, по очереди.
   Это для повторного захода, когда вступление уже смотрели: страница
   открывается целиком, но не рывком. */
.hero__content > *, .hero-card { animation: hero-in .9s var(--ease) both; }
.hero__content > *:nth-child(2) { animation-delay: .10s; }
.hero__content > *:nth-child(3) { animation-delay: .20s; }
.hero__content > *:nth-child(4) { animation-delay: .30s; }
.hero__cards > :first-child { animation-delay: .42s; }
.hero__cards > :nth-child(2) { animation-delay: .54s; }
@keyframes hero-in {
  from { opacity: 0; transform: translateY(22px); }
  to { opacity: 1; transform: none; }
}

/* --- Вступление на главной ---------------------------------------------------
   При входе виден только ролик. Пока в нём открываются двери лифта,
   по очереди проявляются текст и плашки первого экрана, а когда двери
   открылись — шапка и остальная страница.

   Состояние ставится классом на <html> ещё в шапке документа, до первой
   отрисовки: иначе текст успел бы мелькнуть. При отключённых скриптах класс
   не ставится вовсе — страница открывается обычным образом.

   Системная настройка «не показывать анимации» здесь не отменяет сам порядок
   показа: это не украшение, а задуманная подача первого экрана. Учитывается
   она ниже — сдвиг убирается, остаётся только проявление. */

html.intro body { background: var(--ink); }

/* Страховка на случай, если скрипт не загрузится: через 15 секунд всё
   проявляется само. Иначе страница осталась бы скрытой навсегда.
   Прокрутку блокирует скрипт, а не эти правила — по той же причине. */
@keyframes intro-failsafe { to { opacity: 1; transform: none; filter: none; } }
html.intro .header,
html.intro .hero__content > *,
html.intro .hero-card,
html.intro main > :not(.hero),
html.intro .footer { animation: intro-failsafe .8s var(--ease) 15s forwards; }

/* Первый экран во всю высоту окна: шапка лежит поверх него и места
   в потоке не занимает, поэтому вычитать её высоту не нужно. */
html.intro .hero { min-height: 100vh; }
.hero { transition: min-height .9s var(--ease); }

/* Обычное проявление первого экрана здесь лишнее — его вытесняет
   правило страховки выше, у него выше приоритет.

   pointer-events обязателен: прозрачный элемент всё равно ловит нажатия.
   Без этого клик по невидимой шапке попадал в логотип, страница
   перезагружалась и ролик начинался заново. */
html.intro .hero__content > *,
html.intro .hero-card {
  opacity: 0;
  transform: translateY(30px);
  pointer-events: none;
}
html.intro .hero__content > * { filter: blur(8px); }
html.intro main > :not(.hero),
html.intro .footer { opacity: 0; pointer-events: none; }

/* По мере появления возвращаем отзывчивость. */
html.intro.intro-s1 .hero__content > *,
html.intro.intro-s2 .hero__cards > :first-child,
html.intro.intro-s3 .hero__cards > :nth-child(2),
html.intro.intro-done .hero-card { pointer-events: auto; }
html.intro.intro-done main > :not(.hero),
html.intro.intro-done .footer { pointer-events: auto; }

/* Пока идёт вступление, по первому экрану можно щёлкнуть и пропустить его. */
html.intro:not(.intro-done) .hero { cursor: pointer; }

/* Шапка ждёт конца ролика: пока идёт вступление, её не видно вовсе.
   Прячем только цветом — место она занимает по-прежнему, поэтому при
   появлении ничего не сдвигается. Нажатия при этом не ловит: иначе клик
   попадал бы в невидимый логотип. */
html.intro .header { opacity: 0; pointer-events: none; }
html.intro.intro-done .header { pointer-events: auto; }
/* Плашку про cookie придерживаем до конца вступления. Условие именно
   «пока не закончилось» — иначе после она показывалась бы всегда,
   даже если её уже закрыли. */
html.intro:not(.intro-done) .cookie-bar { display: none !important; }

/* Шаги привязаны к дверям в ролике — время каждого шага в app.js (STEPS).
   Каждый следующий трогается, пока предыдущий ещё доходит, — поэтому всё
   сливается в одно движение вместе с дверями, а не в череду вспышек. */

/* 1 — в дверях появилась полоска света: верхний блок. Строки проступают
   друг за другом из лёгкой дымки, как будто их высвечивает этот свет. */
html.intro.intro-s1 .hero__content > * {
  opacity: 1; transform: none; filter: none;
  transition: opacity 1.8s var(--ease-soft), transform 1.8s var(--ease-soft),
              filter 1.8s var(--ease-soft);
}
html.intro.intro-s1 .hero__content > *:nth-child(2) { transition-delay: .22s; }
html.intro.intro-s1 .hero__content > *:nth-child(3) { transition-delay: .44s; }
html.intro.intro-s1 .hero__content > *:nth-child(4) { transition-delay: .66s; }

/* 2 — двери открыты наполовину: левый блок внизу.
   3 — двери почти открыты: правый блок. Дымки у плашек нет: у них своё
   размытие подложки, и фильтр поверх него в части браузеров его гасит. */
html.intro.intro-s2 .hero__cards > :first-child,
html.intro.intro-s3 .hero__cards > :nth-child(2),
html.intro.intro-done .hero-card {
  opacity: 1; transform: none;
  transition: opacity 1.6s var(--ease-soft), transform 1.6s var(--ease-soft);
}

/* Двери открылись полностью: шапка и вся страница под первым экраном.
   Шапка проявляется первой и медленнее остальных: она приходит на
   готовый экран, и резкое появление читалось бы как рывок. Правило
   трогает только прозрачность — сдвиг шапки при прокрутке ему
   не мешает, он задаётся отдельным свойством. */
html.intro.intro-done .header {
  opacity: 1;
  transition: opacity 1.6s var(--ease-soft),
              transform .42s var(--ease-soft), background .4s var(--ease),
              color .4s var(--ease), box-shadow .4s var(--ease);
}
html.intro.intro-done main > :not(.hero),
html.intro.intro-done .footer {
  opacity: 1;
  transition: opacity 2s var(--ease-soft) .25s;
}

/* Прокрутку на время вступления блокирует скрипт — здесь её нет намеренно:
   при отказе скриптов страница осталась бы запертой. */
html.intro.intro-done body { background: var(--bg); }

/* Стрелка в ссылке уезжает вперёд при наведении на карточку */
.post-card:hover .arrow-link::after { width: 20px; }

/* Цифры в блоке показателей чуть подрастают, когда доезжают до экрана */
.fact__value { transition: transform .5s var(--ease); }
.fact:hover .fact__value { transform: translateY(-4px); }

/* Плавное раскрытие ответа: анимируем строку сетки, а не высоту,
   поэтому не нужно знать размер содержимого заранее. */
.faq__a {
  display: grid; grid-template-rows: 0fr;
  transition: grid-template-rows .4s var(--ease);
}
.faq__item.is-open .faq__a { grid-template-rows: 1fr; }
.faq__a-inner { overflow: hidden; }
.faq__a-inner > div { padding: 0 46px 28px 0; }

/* --- Объём при наведении ---------------------------------------------------
   На что можно нажать, то приподнимается и отбрасывает тень. Приём один
   на все кликабельные блоки и кнопки, поэтому правило читается одинаково
   в любом месте сайта: поднялось — значит, кликается.

   Карточки лежат в сетке с зазором в один пиксель поверх общей подложки,
   и тень соседа перекрывала бы поднятую карточку. Поэтому на время
   наведения карточка выносится слоем выше. */

.card, .post-card, .product-card,
.works__item, .photo-grid__item {
  position: relative;
  transition: background .25s var(--ease), transform .3s var(--ease),
              box-shadow .3s var(--ease);
}
.post-card:hover, .product-card:hover,
.works__item:hover, .photo-grid__item:hover {
  z-index: 2;
  transform: translateY(-6px);
  box-shadow: var(--lift);
}
/* При наведении стекло плотнеет, кромка окрашивается в фирменный цвет,
   плашка поднимается и тень под ней уходит глубже. */
.card:hover {
  z-index: 2;
  transform: translateY(-6px);
  border-color: rgba(255, 255, 255, .95);
  background: linear-gradient(135deg, rgba(255, 255, 255, .88), rgba(255, 255, 255, .6));
  box-shadow:
    inset 0 1px 0 #fff,
    0 0 0 1px rgba(22, 153, 159, .45),
    0 34px 60px -30px rgba(14, 40, 42, .6);
}

/* Нажали — блок опускается обратно: отклик на само нажатие. */
.card:active, .post-card:active, .product-card:active,
.works__item:active, .photo-grid__item:active {
  transform: translateY(-2px);
  transition-duration: .08s;
}

/* Кнопки: тот же подъём, только короче — они мельче блоков. */
.btn { transition: background .2s var(--ease), color .2s var(--ease),
                   border-color .2s var(--ease), transform .2s var(--ease),
                   box-shadow .2s var(--ease); }
.btn:hover { transform: translateY(-3px); box-shadow: var(--lift); }
.btn:active { transform: translateY(0); box-shadow: none; transition-duration: .08s; }
/* Кнопка на первом экране лежит на кадре — тень там сливается с фоном,
   поэтому объём даёт подсветка рамки. */
.btn--soft:hover { box-shadow: 0 0 0 4px rgba(22, 153, 159, .18); }

/* --- Недоступный раздел ---------------------------------------------------
   Серая «кнопка» закрытого раздела: не нажимается и не реагирует на
   наведение. Под названием мелкая подпись, почему, — иначе посетитель
   решит, что сайт сломался. Правила стоят после всех состояний кнопок,
   чтобы наведение не возвращало ей цвет и подъём. */
.btn--off,
.btn--off:hover,
.btn--off:active {
  flex-direction: column; gap: 3px;
  background: #eceef0; border-color: #d5d8da; color: #8b9196;
  cursor: not-allowed; transform: none; box-shadow: none;
}
.btn__note {
  font-size: 9.5px; font-weight: 600; letter-spacing: .04em;
  text-transform: none; opacity: .9; line-height: 1.2;
}
/* На тёмном первом экране серый — полупрозрачный светлый. */
.btn--soft.btn--off,
.btn--soft.btn--off:hover {
  background: rgba(255, 255, 255, .07);
  border-color: rgba(255, 255, 255, .2);
  color: rgba(255, 255, 255, .5);
}

.nav__panel-link.is-off,
.nav__panel-link.is-off:hover {
  color: #9aa0a5; background: none; cursor: not-allowed;
}
.nav__panel-link.is-off small,
.m-item__sub .is-off small {
  display: block; margin-top: 2px;
  font-size: 11.5px; color: #b0b5b9;
}
.m-item__sub .is-off { display: block; padding: 10px 0; font-size: 15px; color: #9aa0a5; }

/* Страница закрытого конфигуратора. */
.cfg-closed__box { max-width: 720px; }
.cfg-closed__status {
  display: inline-block; margin: 22px 0 0; padding: 8px 16px;
  border-radius: 999px; background: #eceef0; color: #6f767b;
  font-size: 12px; font-weight: 700; letter-spacing: .12em; text-transform: uppercase;
}
.cfg-closed__text { margin: 22px 0 30px; color: var(--muted); font-size: 16.5px; line-height: 1.75; }

/* --- Адаптив ---------------------------------------------------------------------- */

/* Между широким монитором и планшетом шапке становится тесно: меню,
   телефон и кнопка сходятся вплотную. Сначала ужимаем их, и только
   потом, ниже, убираем телефон и прячем меню под кнопку. */
@media (max-width: 1460px) {
  .nav__link { padding: 12px 10px; font-size: 11.5px; }
  .nav__link::after { left: 10px; right: 10px; }
  .header__actions { gap: 14px; }
  .btn--cta { padding: 14px 22px; letter-spacing: .1em; }
  .logo img { width: 152px; }
}

/* Два номера в шапке занимают место меню: до 1680 px они компактнее,
   у второго нет трубки; до 1366 px ещё и меню плотнее. */
@media (max-width: 1680px) {
  .header__phones { gap: 16px; }
  .header__phone { gap: 9px; }
  .header__phone--alt .header__phone-icon { display: none; }
  .header__phone-num { font-size: 15px; }
  .header__phone-note { font-size: 10px; letter-spacing: .04em; }
}
@media (max-width: 1366px) {
  .nav__link { padding: 12px 8px; font-size: 11px; letter-spacing: .1em; }
  .nav__link::after { left: 8px; right: 8px; }
  .header__inner { gap: 20px; }
  .header__phones { gap: 14px; }
}
/* Самое узкое окно, где номера ещё в шапке (до 1240 px они прячутся). */
@media (min-width: 1241px) and (max-width: 1300px) {
  .logo img { width: 136px; }
  .nav__link { padding: 12px 6px; }
  .nav__link::after { left: 6px; right: 6px; }
  .header__inner { gap: 16px; }
  .header__actions { gap: 10px; }
  .header__phones { gap: 12px; }
  .btn--cta { padding: 13px 16px; letter-spacing: .06em; }
}

@media (max-width: 1240px) {
  .nav__link { padding: 12px 9px; font-size: 11px; }
  .header__phone { display: none; }
  .footer__top { grid-template-columns: minmax(0, 1.2fr) repeat(2, minmax(0, 1fr)); }
  .hero__content { max-width: 78%; }
  .section__head-text { max-width: 68%; }
}

@media (max-width: 1024px) {
  :root { --header-h: 64px; }
  .nav { display: none; }
  .burger { display: inline-flex; }
  /* Телефон с режимом работы занимает слишком много места — оставляем кнопку. */
  .header__phone, .header__divider { display: none; }
  .header__inner { justify-content: space-between; gap: 16px; }
  /* Отступ за край нужен только широким экранам: на узких он прижмёт
     логотип вплотную к границе экрана. */
  .logo { margin-left: 0; }
  .logo img { width: 140px; }
  .catalog, .article { grid-template-columns: 1fr; }
  .side, .aside-sticky { position: static; }
  .product { grid-template-columns: 1fr; gap: 36px; grid-template-areas: "media" "info" "desc"; }
  .contacts { grid-template-columns: 1fr; }
  /* Карточка раздела остаётся горизонтальной, но в ряду одна: на две
     колонка сузилась бы так, что и снимок, и текст стали бы марками. */
  .cards { grid-template-columns: 1fr; }
  /* Товары — исключение: они узкие и в ряду их по-прежнему несколько. */
  .cards--goods { grid-template-columns: repeat(auto-fill, minmax(240px, 1fr)); }
  .adv-groups { grid-template-columns: minmax(0, 1fr); }
  /* Мозаика каталога на планшете: вводный блок во всю ширину, плашки
     парами, непарная последняя — тоже во всю ширину. */
  .cat-cell { grid-column: span 6; }
  .cat-cell:first-child,
  .cat-cell:last-child:nth-child(even) { grid-column: 1 / -1; }
  /* Мозаика услуг складывается в две колонки: заголовок и текстовый блок
     занимают целый ряд, услуги идут парами. */
  .srv-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .srv-intro, .srv-note { grid-column: span 2; }
  .srv-card { grid-column: span 1; }
  /* Преимущества на планшете: всё в одну колонку. Фото идёт под текстом
     и по-прежнему уходит за правый край — так полоса не «зависает». */
  .adv-head { grid-template-columns: minmax(0, 1fr); }
  /* Кадр почти квадратный: исходник вертикальный, в широкой рамке
     от кабины оставалась бы полоса. Потолок — чтобы снимок не занимал
     целый экран телефона. */
  .adv-head__photo { margin-top: clamp(18px, 2.2vw, 28px); aspect-ratio: 4 / 3; max-height: 420px; min-height: 0; }
  .adv-head__extra { width: 100%; aspect-ratio: 16 / 9; min-height: 0; flex: none; }
  /* Полоса партнёра: знак и рассказ в одну колонку, фото под ними. */
  .adv-partner { grid-template-columns: minmax(0, 1fr); gap: 22px; }
  .adv-partner__body { padding-left: 0; padding-top: 22px; border-left: 0; border-top: 1px solid var(--line); }
  .adv-partner__photo { aspect-ratio: 16 / 9; min-height: 0; }
  .split { grid-template-columns: 1fr; }
  .split__media { order: -1; }
  .promo { grid-template-columns: 1fr; }
  .hero__content { max-width: 100%; }
  .section__head-text { max-width: 100%; }
  /* Два блока рядом уже не помещаются — ставим друг под друга. */
  .hero__cards { grid-template-columns: 1fr; }
  /* Сдвиг к краю логотипа нужен только широким экранам: на узких логотип
     и так стоит у границы колонки. */
  .hero__inner { grid-template-rows: auto auto; gap: 34px; margin-left: 0; }
}

@media (max-width: 760px) {
  :root { --gutter: 18px; }
  .hero { min-height: auto; }
  /* На телефоне экран узкий и высокий, а кадр ролика очень широкий.

     Полноэкранной заставки на телефоне нет: сайт открывается сразу,
     им можно пользоваться. Под шапкой во всю ширину стоит полный кадр
     сцены, и в нём открываются двери лифта.

     Видео здесь не играется: многие телефоны не запускают ролик без
     касания экрана. Открывание дверей показывает раскадровка
     (canvas .hero__flip) — кадры из ролика, которые скрипт сменяет
     с плавными переходами. Пока она грузится, в рамке виден постер
     с закрытыми дверями. Когда двери открылись, раскадровка гаснет,
     и остаётся чёткий неподвижный последний кадр .hero__still. */
  .hero__bg .hero__still,
  .hero__bg .hero__flip {
    display: block; position: absolute;
    top: var(--header-h); left: 0;
    width: 100%; height: calc(100vw / var(--hero-k));
  }
  .hero__bg .hero__still { z-index: 2; object-fit: cover; object-position: 50% 50%; }
  /* Ролик на телефоне не показываем вовсе, если есть раскадровка. */
  .hero[data-flip] .hero__bg video { display: none; }
  .hero__bg .hero__flip {
    z-index: 3;
    background: #0c0906 var(--hero-poster, none) 50% 50% / cover no-repeat;
    transition: opacity .9s var(--ease-soft);
  }
  .hero__bg .hero__flip.is-done { opacity: 0; }
  /* Текст начинается под картинкой: её высота = ширина экрана / пропорция. */
  .hero__inner { padding-top: calc(var(--header-h) + 100vw / var(--hero-k) + 22px); }
  .facts { grid-template-columns: repeat(2, 1fr); }
  .fact { padding-top: 28px; }
  .fact + .fact { padding-left: 0; border-left: 0; }
  .fact:nth-child(even) { padding-left: 20px; border-left: 1px solid var(--line); }
  .section__head { flex-direction: column; align-items: flex-start; gap: 22px; }
  .section__head .btn { align-self: stretch; }
  .srv-grid { grid-template-columns: 1fr; }
  .srv-intro, .srv-note, .srv-card { grid-column: span 1; }
  .cat-cell, .cat-cell:first-child,
  .cat-cell:last-child:nth-child(even) { grid-column: 1 / -1; }
  /* На телефоне всё в одну колонку, снимки — горизонтальные:
     вертикальные заняли бы целый экран каждый. */
  /* Внутри плашки на телефоне фото над текстом, кадр горизонтальный. */
  /* На планшете плитки по две в ряд: в одну колонку их семь штук,
     и раздел растягивался на два экрана. Совсем узкий экран —
     ниже, в правиле для 460 px. */
  .adv-tiles { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .adv-tile { padding: 14px 16px; }
  .adv-tile__icon { width: 32px; height: 32px; margin-bottom: 10px; }
  .adv-cta__btn { width: 100%; justify-content: space-between; }
  .footer__top { grid-template-columns: 1fr; gap: 34px; }
  .modal__box { padding: 32px 24px; }
  .callout__inner { flex-direction: column; align-items: flex-start; }
  .specs__row { grid-template-columns: 1fr; gap: 5px; }
  .price-row { grid-template-columns: 1fr; }
  .price-row__unit { text-align: left; }
  .lightbox__nav { width: 44px; height: 44px; }
  .lightbox__nav--prev { left: 10px; }
  .lightbox__nav--next { right: 10px; }
  .countdown__cell { min-width: 68px; padding: 14px 8px; }
}

@media (max-width: 460px) {
  .cards, .cards--3 { grid-template-columns: 1fr; }
  /* На телефоне плитки друг под другом: в двух колонках подписи
     рассыпались бы по одному слову в строку. */
  .adv-tiles { grid-template-columns: minmax(0, 1fr); }
  /* Товары и на телефоне по две в ряд: карточка узкая, снимок вертикальный. */
  .cards--goods { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 12px; }
  .cards--goods .product-card__body { padding: 11px 12px 13px; }
  .cards--goods .product-card__name { font-size: 13.5px; }
  .cards--goods .product-card__text { display: none; }
  /* На телефоне снимок и подпись друг под другом, кадр горизонтальный:
     иначе одна карточка занимает весь экран. */
  .card { grid-template-columns: 1fr; }
  .card__media { width: 100%; height: auto; aspect-ratio: 16 / 9; }
  .card__body { min-height: 0; }
  .card__foot { margin-top: 0; }
  .works, .photo-grid { grid-template-columns: repeat(2, 1fr); }
  .hero__actions .btn { width: 100%; }
  .logo img { width: 150px; }
  .countdown { flex-wrap: wrap; }
}

@media (max-width: 1024px) {
  /* Чертёж под выбором, а не сбоку: в узкой колонке размеры не прочитать. */
  .cfg-layout { grid-template-columns: 1fr; }
  .cfg-side { position: static; }
  .cfg-actions { flex-direction: row; flex-wrap: wrap; }
  .cfg-actions .btn { width: auto; flex: 1 1 240px; }
}

@media (max-width: 620px) {
  .cfg-views { grid-template-columns: 1fr; }
}

/* --- Ноутбуки и невысокие окна компьютера ---------------------------------
   Реальная высота страницы на ноутбуке меньше экрана: вкладки, адресная
   строка и панель задач съедают 110–180 px. На экране 1366 × 768 странице
   остаётся около 650 px, на 1920 × 1080 с масштабом Windows 150% — около
   590. Первый экран там не помещался: блоки внизу уходили за край, строка
   над заголовком прилипала к шапке. Размеры здесь считаются от высоты окна.
   Телефоны (до 760 px) не затрагиваются. */
@media (min-width: 761px) and (max-height: 820px) {
  .hero__inner {
    gap: clamp(12px, 2.2vh, 22px);
    padding-block: calc(var(--header-h) + clamp(12px, 2.6vh, 24px)) clamp(12px, 2.4vh, 22px);
  }
  .hero__lead { margin-bottom: 4px; font-size: clamp(15px, 2.6vh, 22px); }
  .hero h1 { font-size: clamp(26px, 6.4vh, 50px); }
  .hero__text { margin-top: clamp(8px, 1.6vh, 14px); font-size: 14px; line-height: 1.55; }
  .hero__mark { margin-top: clamp(8px, 1.8vh, 16px); }
  .hero__mark span:last-child { font-size: 13.5px; }
  .hero-card { padding: clamp(12px, 2vh, 20px) clamp(16px, 1.6vw, 24px); }
  .hero-card__title { font-size: clamp(14px, 1.2vw, 18px); }
  .hero-card__text { margin-top: 6px; font-size: 12.5px; line-height: 1.5; }
  .hero-card__action { padding-top: clamp(10px, 1.6vh, 16px); }
  .hero-card__action .btn.btn--soft { padding: 12px 22px; font-size: 11px; }
}
/* Совсем невысокое окно: подпись под текстом убираем — важнее блоки с кнопками. */
@media (min-width: 761px) and (max-height: 640px) {
  .hero__mark { display: none; }
  .hero__text { font-size: 13.5px; }
}

/* Узкое окно компьютера (761–1024 px): блоки первого экрана и проекты
   остаются в два ряда. В одну колонку первый экран вырастал выше окна,
   а три карточки проектов друг под другом растягивали раздел на 2,5 тыс. px. */
@media (min-width: 761px) and (max-width: 1024px) {
  .hero__cards { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .cards--3 { grid-template-columns: repeat(2, minmax(0, 1fr)); }
}

/* Если человек попросил систему убрать анимации — убираем. Важно при этом
   вернуть видимость всему, что прячется перед появлением: иначе экран
   останется пустым. */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }

  /* Гасим именно ДВИЖЕНИЕ: перемещения, наезды и увеличения. Плавность
     проявления при этом сохраняется — смена прозрачности к движению
     не относится и дискомфорта не вызывает, а без неё блоки просто
     щёлкают на месте, и сайт выглядит топорно. */

  /* Появление блоков и первого экрана — только прозрачность, без сдвига. */
  .js .reveal,
  .hero__content > *, .hero-card { transform: none !important; }
  .hero__content > * { filter: none !important; }

  /* Бегущие строки здесь намеренно не трогаем. Системная настройка
     «убрать анимации» на рабочих машинах часто включена заодно с общим
     ускорением Windows, и строка на сайте просто вставала — а она несёт
     содержание, а не украшает. Движение в ней медленное и без рывков. */

  /* Подъём при наведении оставляем, но укорачиваем до пары пикселей.
     Это не самостоятельное движение, а ответ на действие самого
     посетителя, и без него не видно, что на блок можно нажать.
     Основную работу берёт на себя тень. */
  .btn:hover,
  .card:hover, .product-card:hover, .post-card:hover,
  .works__item:hover, .photo-grid__item:hover { transform: translateY(-2px); }
  .btn:active,
  .card:active, .product-card:active, .post-card:active,
  .works__item:active, .photo-grid__item:active { transform: none; }
  .card:hover .card__media img,
  .post-card:hover .post-card__media img,
  .product-card:hover .product-card__media img,
  .works__item:hover img,
  .photo-grid__item:hover img { transform: none; }
  .fact:hover .fact__value { transform: none; }
}

@media print {
  .header, .footer, .to-top, .cookie-bar, .modal, .lightbox { display: none !important; }

  /* Конфигуратор: на бумагу уходит только лист с чертежом. Заголовок
     страницы, поля выбора и кнопки в распечатке не нужны — печать здесь
     и есть «скачать PDF», и лишнее на листе только мешает. */
  .cfg .section__head, .cfg-side { display: none !important; }
  .cfg { padding: 0 !important; }
  .cfg-layout { display: block !important; }
  .cfg-sheet { border: 0; padding: 0; }
  .cfg-view__box { background: none; border: 0; padding: 0; }
  .cfg-dwg { max-height: none; }
  /* Таблица параметров не должна разрываться между страницами. */
  .cfg-specs { break-inside: avoid; }
  .cfg-specs th, .cfg-specs td { font-size: 11pt; padding: 6px 0; }
}
