/* ===== Reset & base ===== */
*,
*::before,
*::after {
  box-sizing: border-box;
}

html {
  margin: 0;
  padding: 0;
}

/* Горизонтального `overflow-x: hidden` здесь нет сознательно: он маскировал
   переполнение desktop-only раскладок на малых ширинах. Источники переполнения
   исправлены в самих компонентах (адаптив в конце файла); страница, которая всё
   же выйдет за viewport, должна это показывать, а не прятать. */
body {
  margin: 0;
  padding: 0;
  font-family: "Roboto", Arial, sans-serif;
  color: #3c3732;
  background: #ffffff;
  -webkit-font-smoothing: antialiased;
}

ul {
  list-style: none;
  margin: 0;
  padding: 0;
}

a {
  text-decoration: none;
  color: inherit;
}

img {
  display: block;
  max-width: 100%;
}

button {
  font-family: inherit;
  cursor: pointer;
}

h1,
h2,
p {
  margin: 0;
}

.visually-hidden {
  position: absolute;
  width: 1px;
  height: 1px;
  padding: 0;
  margin: -1px;
  overflow: hidden;
  clip: rect(0, 0, 0, 0);
  white-space: nowrap;
  border: 0;
}

/* ===== Colors (design tokens) ===== */
:root {
  --color-text-dark: #3c3732;
  --color-text-black: #000000;
  --color-border-muted: #a7a098;
  --color-icon-dark: #141b34;
  --color-icon-account: #1f4d5e;
  --color-orange: #ff9900;
  --color-orange-active: #ff8300;
  --color-bg-light: #f4f3f1;
  --color-footer-text: #f3efe4;
  --color-table-highlight: #cfcbc5;
  --color-accent-mint: #48e1c2;
  --color-accent-amber: #ffbe00;
  --color-accent-orange-strong: #ff8300;
  --color-link: #128ff5;

  --container-width: 1440px;
  --container-padding: 20px;
  --container-padding-content: 80px;

  --radius-card: 25px;

  --gradient-hero-primary: linear-gradient(241.15deg, #ffbe00 2.58%, #ff9900 30.03%, #ff8e00 47.58%, #ff8300 64.23%, #ff561a 98.10%);
  --gradient-hero-secondary: linear-gradient(90deg, #007396 0%, #1f4d5e 48.53%, #003241 94.33%);
  /* Тот же «testo gradient 2», но зеркально: светлый край справа.
     Направление задаёт дизайнер поштучно — у каталога (502:871) светлый край слева,
     у контактов (544:788) справа; проверено рендером обоих фреймов. */
  --gradient-hero-secondary-reverse: linear-gradient(90deg, #003241 5.67%, #1f4d5e 51.47%, #007396 100%);
  /* Тот же оранжевый градиент, но зеркально: жёлтый угол слева сверху.
     Баннер «Валидации» (525:1003) — жёлтый угол справа, «Сервиса и поддержки»
     (528:1122) — слева; оба положения проверены рендером фреймов. Зеркало
     линейного градиента — это угол 360° − 241.15° при тех же стопах. */
  --gradient-hero-primary-reverse: linear-gradient(118.85deg, #ffbe00 2.58%, #ff9900 30.03%, #ff8e00 47.58%, #ff8300 64.23%, #ff561a 98.10%);
  --shadow-soft: 0 4px 30px 2px rgba(31, 77, 94, 0.49);
  --shadow-elevated: 0 4px 30px 2px rgba(31, 77, 94, 0.7);
}

.container {
  width: 100%;
  max-width: var(--container-width);
  margin: 0 auto;
  padding: 0 var(--container-padding);
}

/* ===== Buttons ===== */
.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 12px;
  height: 48px;
  padding: 0 24px;
  border-radius: 999px;
  border: none;
  font-family: "Roboto", Arial, sans-serif;
  font-size: 14px;
  font-weight: 400;
  color: var(--color-text-dark);
  white-space: nowrap;
  transition: background-color 0.2s ease, opacity 0.2s ease, box-shadow 0.2s ease;
}

.btn__icon {
  width: 24px;
  height: 24px;
  flex-shrink: 0;
}

/* Disabled — общее состояние для всех типов кнопок.
   В макетах его нет: приглушение прозрачностью, без нового цвета.
   Первое применение — «Отправить» на contacts.html до отметки «Условия и положения». */
.btn:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.btn--compare,
.btn--cart {
  width: 160px;
  background-color: var(--color-orange);
}

.btn--compare:hover,
.btn--cart:hover {
  background-color: #e88a00;
}

.btn--compare:focus-visible,
.btn--cart:focus-visible,
.btn--catalog:focus-visible,
.btn--home:focus-visible,
.btn--orders:focus-visible {
  outline: 2px solid #003241;
  outline-offset: 2px;
}

.btn--compare:active,
.btn--cart:active {
  background-color: #cc7a00;
}

.btn--cart.is-active {
  background-color: var(--color-orange-active);
}

.btn--cart.is-active:hover {
  background-color: #e87700;
}

.btn--cart.is-active:active {
  background-color: #cc6900;
}

/*
 * Капсула с крупной подписью: оранжевый фон, чёрный текст 16px.
 * .btn--orders (кнопка «К заказам», order-success.html) и .btn--home (кнопка
 * «На главную», 404.html) — алиасы того же вида.
 * Собственных визуальных стилей и состояний у них нет: default / hover /
 * active / focus-visible полностью наследуются отсюда.
 */
.btn--catalog,
.btn--orders,
.btn--home {
  background-color: var(--color-orange);
  color: var(--color-text-black);
  font-size: 16px;
  font-weight: 400;
  padding: 0 32px;
}

/* :not(:disabled) — недоступная кнопка не должна реагировать на курсор */
.btn--catalog:hover:not(:disabled),
.btn--home:hover:not(:disabled),
.btn--orders:hover:not(:disabled) {
  background-color: #e88a00;
}

.btn--catalog:active:not(:disabled),
.btn--home:active:not(:disabled),
.btn--orders:active:not(:disabled) {
  background-color: #cc7a00;
}

/* ===== Header ===== */
.header {
  background: #ffffff;
  position: relative;
  z-index: 30;
}

.header__inner {
  max-width: var(--container-width);
  margin: 0 auto;
  padding: 15px var(--container-padding);
  display: flex;
  align-items: center;
  gap: 7px;
}

.header__logo {
  position: relative;
  display: block;
  width: 127px;
  height: 72px;
  aspect-ratio: 127 / 72;
  overflow: hidden;
  flex-shrink: 0;
}

.header__logo-img {
  position: absolute;
  top: -16.67%;
  left: -9.45%;
  width: 118.11%;
  height: 138.89%;
  max-width: none;
}

.header__nav {
  display: flex;
  align-items: center;
  gap: 25px;
  flex: 1 1 auto;
  min-width: 0;
  margin-left: 54px;
}

.header__nav-list {
  display: flex;
  align-items: center;
  gap: 42px;
  flex-shrink: 0;
}

.header__nav-link {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-size: 16px;
  font-weight: 400;
  color: var(--color-text-dark);
  white-space: nowrap;
  padding: 4px 0;
  border-bottom: 1px solid transparent;
  transition: color 0.2s ease, border-color 0.2s ease;
}

.header__nav-chevron {
  flex: 0 0 auto;
  transform: rotate(90deg);
  transition: transform 0.2s ease;
}

.header__nav-link:hover,
.header__nav-link:focus-visible {
  color: var(--color-orange-active);
}

.header__nav-link:active {
  color: #cc7a00;
}

/* ── Выпадающие меню навигации (desktop) ──
   Раскрытая панель в Figma не нарисована (FRONTEND-SPEC §11): оформление
   собрано из утверждённых токенов — как у `.dropdown__menu` (белая панель,
   --radius-card, --shadow-soft), текст — шрифт навигации 16px Regular.
   Панели раскрываются только от 1200px (см. блок min-width: 1200px);
   мобильное меню — отдельный этап. */
.header__nav-item {
  position: relative;
}

/* Триггер без страницы раздела — кнопка, внешне как ссылка пункта */
.header__nav-link--trigger {
  margin: 0;
  background: none;
  border: none;
  border-bottom: 1px solid transparent;
  line-height: inherit;
}

/* «Знания» — раздела пока нет: пункт виден, но не реагирует */
.header__nav-link--inactive {
  cursor: default;
}

.header__nav-link--inactive:hover,
.header__nav-link--inactive:active {
  color: var(--color-text-dark);
}

/* padding-top — прозрачный «мост» между пунктом и панелью: курсор не
   покидает пункт по пути вниз. left выравнивает текст панели с пунктом. */
.header__dropdown {
  display: none;
  position: absolute;
  top: 100%;
  left: -24px;
  padding-top: 8px;
}

.header__dropdown-list {
  width: max-content;
  padding: 8px;
  background: #ffffff;
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
}

/* Вложенные списки позиционируются от панели, а не от своего пункта */
.header__dropdown > .header__dropdown-list {
  position: relative;
}

.header__dropdown-link {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 10px 16px;
  border-radius: 16px;
  font-size: 16px;
  font-weight: 400;
  line-height: 24px;
  color: var(--color-text-dark);
  white-space: nowrap;
  transition: color 0.2s ease;
}

.header__dropdown-link:hover,
.header__dropdown-link:focus-visible,
.header__dropdown-item--parent.is-active > .header__dropdown-link,
.header__dropdown-item--parent:focus-within > .header__dropdown-link {
  color: var(--color-orange-active);
}

.header__dropdown-link:active {
  color: #cc7a00;
}

.header__dropdown-link:focus-visible {
  outline: 2px solid var(--color-icon-dark);
  outline-offset: -2px;
}

/* Шеврон без поворота смотрит вправо — туда, где раскрывается вложенный список */
.header__dropdown-chevron {
  flex: 0 0 auto;
}

/* Вложенный список — вторая колонка панели: открывается от её верха и на всю
   её высоту. Путь курсора к любому вложенному пункту не выходит за панель, а
   списки разных разделов занимают одно и то же место и одного размера.
   left и padding-left — «мост» поверх правого поля панели и зазор 8px. */
.header__submenu {
  position: absolute;
  top: 0;
  bottom: 0;
  left: calc(100% - 8px);
  z-index: 1;
  padding-left: 16px;
  visibility: hidden;
}

/* Ширина одна на все списки и помещается в окно 1200px; от 1280px её хватает,
   чтобы самая длинная подпись шла в одну строку. */
.header__submenu > .header__dropdown-list {
  width: 352px;
  min-height: 100%;
}

.header__submenu .header__dropdown-link {
  white-space: normal;
}

@media (min-width: 1280px) {
  .header__submenu > .header__dropdown-list {
    width: 424px;
  }
}

/* Фокус внутри раздела показывает список сразу, не дожидаясь перерисовки:
   иначе Tab проскочил бы ещё скрытые ссылки. */
.header__dropdown-item--parent:focus-within > .header__submenu {
  z-index: 2;
  visibility: visible;
}

/* Открытый список выбирает шапка (`is-active`): пока курсор движется к нему
   по диагонали, строки на пути его не подменяют (Header.tsx). */
.header__dropdown-item--parent.is-active > .header__submenu {
  z-index: 3;
  visibility: visible;
}

.header__search {
  position: relative;
  display: flex;
  align-items: center;
  flex: 1 1 260px;
  max-width: 260px;
  height: 48px;
  margin-left: 35px;
}

.header__search-input {
  width: 100%;
  height: 100%;
  border: 2px solid var(--color-border-muted);
  border-radius: 999px;
  background: transparent;
  padding: 0 44px 0 19px;
  font-family: inherit;
  font-size: 14px;
  font-weight: 500;
  color: var(--color-text-dark);
  outline: none;
  transition: border-color 0.2s ease;
}

.header__search-input::placeholder {
  color: var(--color-text-dark);
  opacity: 1;
}

.header__search-input:focus {
  border-color: var(--color-icon-dark);
}

.header__search-btn {
  position: absolute;
  right: 14px;
  top: 50%;
  transform: translateY(-50%);
  background: none;
  border: none;
  padding: 0;
  display: flex;
  align-items: center;
  justify-content: center;
}

.header__search-icon {
  width: 20px;
  height: 20px;
  transform: scaleY(-1);
}

.header__actions {
  display: flex;
  align-items: center;
  gap: 25px;
  flex-shrink: 0;
}

.header__account {
  display: flex;
  align-items: center;
  justify-content: center;
  width: 48px;
  height: 48px;
  flex-shrink: 0;
  border-radius: 50%;
  transition: opacity 0.2s ease;
}

.header__account:hover,
.header__account:focus-visible {
  opacity: 0.7;
}

.header__account-icon {
  width: 48px;
  height: 48px;
}

.header__burger {
  display: none;
  flex-direction: column;
  justify-content: center;
  align-items: center;
  gap: 5px;
  width: 40px;
  height: 40px;
  padding: 0;
  border: none;
  background: none;
  flex-shrink: 0;
  margin-left: auto;
}

.header__burger span {
  display: block;
  width: 24px;
  height: 2px;
  background: var(--color-text-dark);
  border-radius: 1px;
  transition: transform 0.25s ease, opacity 0.25s ease;
}

.header__burger[aria-expanded="true"] span:nth-child(1) {
  transform: translateY(7px) rotate(45deg);
}

.header__burger[aria-expanded="true"] span:nth-child(2) {
  opacity: 0;
}

.header__burger[aria-expanded="true"] span:nth-child(3) {
  transform: translateY(-7px) rotate(-45deg);
}

.header__backdrop {
  position: fixed;
  inset: 0;
  background: rgba(20, 27, 52, 0.4);
  z-index: 20;
}

/* ===== Page title ===== */
.page-title {
  background: var(--color-bg-light);
  height: 70px;
  margin-top: 14.24px;
  display: flex;
  align-items: center;
}

/* Размер заголовка — утверждённые 32px. Если конкретный текст в полосу не
   помещается, PageTitleBar подставляет сюда меньшее значение через
   --page-title-fs: полоса, шрифт, начертание, цвет и выключка не меняются,
   уменьшается только кегль и ровно настолько, насколько нужно. Короткий
   заголовок переменную не получает и остаётся 32px.
   overflow-wrap страхует от горизонтального переполнения на длинных
   обозначениях без пробелов в названиях товаров. */
.page-title__text {
  max-width: var(--container-width);
  width: 100%;
  margin: 0 auto;
  padding: 0 var(--container-padding-content);
  font-size: var(--page-title-fs, 32px);
  font-weight: 500;
  color: var(--color-text-dark);
  overflow-wrap: break-word;
}

/* ===== Empty cart ===== */
.cart-empty {
  background: var(--color-bg-light);
  margin-top: 36px;
  padding: 40px var(--container-padding) 41px;
}

.cart-empty__inner {
  max-width: var(--container-width);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.cart-empty__title {
  font-size: 32px;
  font-weight: 400;
  color: #000000;
  width: 100%;
}

.cart-empty__image {
  width: 277px;
  height: auto;
  margin-top: 23px;
}

.cart-empty__subtitle {
  font-size: 24px;
  font-weight: 300;
  line-height: 40px;
  color: #000000;
  margin-top: 15px;
  max-width: 630px;
  width: 100%;
}

.cart-empty__inner .btn--catalog {
  margin-top: 15px;
  min-width: 166.5px;
}

/* ===== Cart with items (cart.html) ===== */
/* Нижний отступ — постоянный зазор, а не остаток прямоугольника из макета:
   серая секция обтягивает содержимое и сокращается при удалении позиций.
   Предел сокращения — высота блока итогов, он должен помещаться целиком. */
.cart {
  background: var(--color-bg-light);
  margin-top: 36px;
  padding: 29px 0 41px;
}

.cart__inner {
  display: grid;
  grid-template-columns: minmax(0, 1fr) 411px;
  gap: 24px;
  align-items: start;
}

.cart__list {
  display: flex;
  flex-direction: column;
  gap: 48px;
}

/* ===== Cart Item ===== */
.cart-item {
  display: grid;
  grid-template-columns: 302px minmax(0, 1fr) auto;
  column-gap: 24px;
  align-items: start;
}

.cart-item__media {
  width: 302px;
  height: 200px;
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}

.cart-item__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.cart-item__info {
  min-height: 200px;
  padding-top: 25px;
  display: flex;
  flex-direction: column;
}

.cart-item__title {
  margin: 0;
  font-size: 20px;
  font-weight: 400;
  color: var(--color-text-dark);
}

.cart-item__article {
  margin-top: 5px;
  font-size: 16px;
  line-height: 24px;
  color: var(--color-text-dark);
}

.cart-item__note {
  margin-top: 36px;
  margin-left: 25px;
  font-size: 16px;
  line-height: 24px;
  color: var(--color-text-dark);
}

.cart-item__controls {
  margin-top: auto;
  display: flex;
  align-items: center;
  gap: 19px;
}

/* Степпер корзины — существующий компонент, размеры по фрейму корзины */
.cart-item__controls .product-card__stepper--large {
  width: 150px;
  gap: 5px;
}

.cart-item__controls .product-card__stepper-btn {
  width: 41px;
  font-size: 16px;
}

.cart-item__pricing {
  margin-top: 25px;
  display: flex;
  align-items: center;
  gap: 12px;
}

.cart-item__total {
  display: inline-flex;
  align-items: center;
  font-size: 20px;
  color: var(--color-text-dark);
}

.cart-item__discount[hidden],
.discount-badge[hidden] {
  display: none;
}

/* Discount Badge — общий компонент: корзина (.cart-item__discount)
   и мини-карточка товара в обзоре заказа (.discount-badge) */
.cart-item__discount,
.discount-badge {
  height: 27px;
  padding: 0 7px 0 9px;
  display: inline-flex;
  align-items: center;
  background: var(--color-orange);
  border-radius: 14px;
  font-size: 20px;
  color: var(--color-text-dark);
}

.cart-item__currency {
  flex-shrink: 0;
}

/* ===== Блок итогов ===== */
.cart-summary {
  width: 411px;
  padding: 26px 17px 31px;
  background: #fffefe;
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
}

.cart-summary__title {
  font-size: 24px;
  font-weight: 400;
  line-height: 32px;
  color: var(--color-text-dark);
}

.cart-summary__rows {
  margin: 28px 0 0;
  display: flex;
  flex-direction: column;
  gap: 18px;
}

.cart-summary__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}

.cart-summary__label {
  font-size: 16px;
  line-height: 28px;
  color: var(--color-text-dark);
}

.cart-summary__value {
  margin: 0;
  display: inline-flex;
  align-items: center;
  font-size: 20px;
  line-height: 28px;
  color: var(--color-text-dark);
}

.cart-summary__currency {
  flex-shrink: 0;
}

.cart-summary__divider {
  height: 2px;
  margin: 49px 17px 0;
  border: none;
  background: var(--color-text-dark);
}

.cart-summary__row--total {
  margin-top: 38px;
}

.cart-summary__label--total {
  font-size: 20px;
}

.cart-summary__promo {
  width: 367px;
  margin: 40px auto 0;
  display: flex;
  justify-content: space-between;
  gap: 34px;
}

.cart-summary__promo-input {
  width: 166.5px;
  height: 48px;
  padding: 0 8px 0 17px;
  border: 2px solid var(--color-border-muted);
  border-radius: 999px;
  background: transparent;
  font-family: inherit;
  font-size: 16px;
  color: var(--color-text-dark);
  transition: border-color 0.2s ease;
}

.cart-summary__promo-input::placeholder {
  color: var(--color-text-dark);
  opacity: 1;
}

/* Обводка подсвечивается акцентным оранжевым при наведении, фокусе и введённом тексте */
.cart-summary__promo-input:hover,
.cart-summary__promo-input:focus,
.cart-summary__promo-input:not(:placeholder-shown) {
  border-color: var(--color-orange);
}

/* Индикатор фокуса — оранжевая обводка самого поля, без второй рамки поверх */
.cart-summary__promo-input:focus,
.cart-summary__promo-input:focus-visible {
  outline: none;
}

.cart-summary__promo-submit {
  width: 166.5px;
  height: 48px;
  padding: 0;
  border: none;
  border-radius: 999px;
  background: var(--color-table-highlight);
  font-family: inherit;
  font-size: 16px;
  color: var(--color-text-dark);
  cursor: pointer;
  transition: filter 0.2s ease;
}

.cart-summary__promo-submit:hover {
  filter: brightness(0.92);
}

.cart-summary__promo-submit:active {
  filter: brightness(0.85);
}

.cart-summary__promo-submit:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

.cart-summary__promo-status {
  margin-top: 12px;
  font-size: 14px;
  line-height: 17px;
  color: var(--color-orange);
}

.cart-summary__checkout {
  width: 367px;
  margin: 41px auto 0;
  display: flex;
}

/* Сообщение о промокоде занимает зазор над кнопкой, кнопка не смещается */
.cart-summary__promo-status:not([hidden]) + .cart-summary__checkout {
  margin-top: 12px;
}

/* ===== Сопутствующие товары ===== */
.cart-related {
  padding-top: 41px;
}

.cart-related .product-grid {
  margin-top: 36px;
}

/* ===== Юридический текст корзины ===== */
.cart-legal {
  max-width: 1172px;
  margin-top: 41px;
  font-size: 16px;
  font-weight: 300;
  line-height: 24px;
  color: var(--color-text-dark);
}

.cart-legal__link {
  font-weight: 400;
  color: var(--color-link);
  text-decoration: none;
}

.cart-legal__link:hover {
  text-decoration: underline;
}

.cart-legal__link:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

/* Тот же блок на странице контактов (544:870): 14px Medium/20 на всю ширину
   контейнера, ссылки подчёркнуты в покое. Цвет ссылок общий — --color-link. */
.cart-legal--contacts {
  max-width: 1280px;
  font-size: 14px;
  font-weight: 500;
  line-height: 20px;
}

.cart-legal--contacts .cart-legal__link {
  font-weight: 500;
  text-decoration: underline;
}

.page-cart .footer,
.page-checkout .footer,
.page-404 .footer,
.page-contacts .footer,
.page-verification .footer,
.page-service-support .footer,
.page-news .footer {
  margin-top: 41px;
}

/* ===== Footer ===== */
.footer {
  margin-top: 75px;
  padding: 48px 0;
  background: var(--color-text-dark);
  color: var(--color-footer-text);
}

.footer__inner {
  max-width: var(--container-width);
  margin: 0 auto;
  padding: 0 var(--container-padding);
  display: grid;
  grid-template-columns: minmax(240px, 2fr) 1fr 1.15fr 0.75fr;
  gap: 40px 32px;
}

.footer__col--about {
  max-width: 390px;
}

.footer__heading {
  font-size: 20px;
  font-weight: 500;
  line-height: 24px;
  margin-bottom: 24px;
}

.footer__heading-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: inherit;
  text-decoration: none;
}

.footer__heading-icon {
  flex: 0 0 auto;
  transform: rotate(-90deg);
}

.footer__text {
  font-size: 16px;
  font-weight: 500;
  line-height: 24px;
}

.footer__copy {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.footer__contact-text {
  font-size: 16px;
  font-weight: 400;
  line-height: 24px;
}

.footer__contact-block {
  display: flex;
  flex-direction: column;
  gap: 24px;
}

.footer__list {
  display: flex;
  flex-direction: column;
  gap: 16px;
  margin-bottom: 24px;
}

.footer__link {
  display: block;
  font-size: 16px;
  font-weight: 400;
  line-height: 24px;
  transition: color 0.2s ease;
}

.footer__link:hover,
.footer__link:focus-visible {
  color: var(--color-orange);
}

.footer__link:active {
  color: var(--color-orange-active);
}

.footer__contact-link {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  color: inherit;
  text-decoration: none;
  transition: color 0.2s ease;
}

.footer__contact-link:hover,
.footer__contact-link:focus-visible {
  color: var(--color-orange);
}

.footer__contact-link:active {
  color: var(--color-orange-active);
}

.footer__social {
  display: flex;
  align-items: center;
  gap: 14px;
  margin-top: 24px;
}

.footer__social-link {
  display: flex;
}

/* ===== Hero Slider ===== */
.hero-slider {
  position: relative;
  width: 100%;
  height: 500px;
  overflow: hidden;
  background: var(--gradient-hero-primary);
}

.hero-slider__track {
  display: flex;
  width: 100%;
  height: 100%;
  transition: transform 0.6s ease;
}

.hero-slide {
  position: relative;
  flex: 0 0 100%;
  width: 100%;
  height: 100%;
}

.hero-slide__inner {
  position: relative;
  max-width: var(--container-width);
  height: 100%;
  margin: 0 auto;
}

.hero-slider__inner {
  position: absolute;
  inset: 0;
  max-width: var(--container-width);
  margin: 0 auto;
  pointer-events: none;
}

.hero-slider__inner > * {
  pointer-events: auto;
}

.hero-slide__media {
  position: absolute;
  top: 55px;
  right: 0;
  width: 623px;
  height: 389px;
  overflow: hidden;
}

.hero-slide--1 .hero-slide__media {
  border-radius: 320.5px 0 0 320.5px;
}

.hero-slide--2 .hero-slide__media,
.hero-slide--3 .hero-slide__media,
.hero-slide--4 .hero-slide__media {
  border-radius: 231px 0 0 231px;
}

.hero-slide__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.hero-slide__eyebrow,
.hero-slide__title,
.hero-slide__text,
.hero-slide__models {
  position: absolute;
  left: 80px;
  margin: 0;
  color: var(--color-text-dark);
}

.hero-slide__eyebrow {
  font-weight: 300;
}

.hero-slide__title {
  font-size: 36px;
  font-weight: 400;
}

.hero-slide__text {
  font-size: 20px;
  font-weight: 300;
  line-height: 28px;
}

.hero-slide__models {
  font-size: 20px;
  font-weight: 400;
  line-height: 24px;
  letter-spacing: 0.2px;
}

.hero-slide--1 .hero-slide__eyebrow {
  top: 74px;
  width: 652px;
  font-size: 16px;
  line-height: 24px;
}

.hero-slide--1 .hero-slide__title {
  top: 129px;
  width: 655px;
}

.hero-slide--1 .hero-slide__text {
  top: 241px;
  width: 652px;
}

.hero-slide--2 .hero-slide__eyebrow,
.hero-slide--4 .hero-slide__eyebrow {
  top: 122px;
  width: 403px;
  font-size: 16px;
  line-height: 32px;
  letter-spacing: 0.32px;
}

.hero-slide--2 .hero-slide__title,
.hero-slide--4 .hero-slide__title {
  top: 199px;
  width: 298px;
}

.hero-slide--2 .hero-slide__text,
.hero-slide--4 .hero-slide__text {
  top: 286px;
  width: 652px;
  letter-spacing: 0.2px;
}

.hero-slide--3 .hero-slide__eyebrow {
  top: 115px;
  width: 285px;
  font-size: 16px;
  line-height: 32px;
  letter-spacing: 0.32px;
}

.hero-slide--3 .hero-slide__title {
  top: 192px;
  width: 431px;
  line-height: 42px;
  letter-spacing: 0.18px;
}

.hero-slide--3 .hero-slide__models {
  top: 321px;
  width: 391px;
}

.btn--hero {
  position: absolute;
  top: 376px;
  left: 80px;
  width: 283px;
  justify-content: space-between;
  padding: 0 15px 0 19px;
  background-color: #ffffff;
  color: var(--color-text-dark);
}

.btn--hero:hover {
  background-color: #f4f3f1;
}

.btn--hero:active {
  background-color: #e5e3df;
}

.hero-slide__cta-icon {
  width: 21px;
  height: 21px;
  flex-shrink: 0;
  transform: rotate(-90deg);
}

.hero-slider__disclaimer {
  position: absolute;
  left: 842px;
  top: 473px;
  width: 518px;
  margin: 0;
  font-size: 14px;
  font-weight: 500;
  color: var(--color-text-dark);
  z-index: 2;
}

.hero-slider__nav {
  position: absolute;
  left: 27px;
  bottom: -40px;
  width: 289px;
  height: 66px;
  display: flex;
  align-items: flex-start;
  justify-content: center;
  gap: 13px;
  padding-top: 21px;
  background: #ffffff;
  border-radius: 25px;
  z-index: 2;
}

.hero-slider__indicator {
  width: 50px;
  height: 5px;
  padding: 0;
  border: none;
  border-radius: 2.5px;
  background: var(--color-table-highlight);
  cursor: pointer;
  transition: background-color 0.2s ease;
}

.hero-slider__indicator.is-active {
  background: var(--color-text-dark);
}

.hero-slider__indicator:hover {
  background: var(--color-border-muted);
}

.hero-slider__indicator.is-active:hover {
  background: var(--color-text-dark);
}

.hero-slider__indicator:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

/* ===== Shared section layout ===== */
.section-container {
  max-width: var(--container-width);
  margin: 0 auto;
  padding: 0 var(--container-padding-content);
}

.section-title {
  font-size: 32px;
  font-weight: 400;
  color: var(--color-text-dark);
  margin: 0;
}

.section-title--light {
  font-weight: 300;
}

/* Название страницы в макете «Поверка» (518:865) — 32px Medium. Отличается от
   базового .section-title только весом, поэтому отдельного класса не заводим. */
.section-title--medium {
  font-weight: 500;
}

.section-title--center {
  text-align: center;
}

.section-subtitle {
  font-size: 20px;
  font-weight: 400;
  letter-spacing: -0.2px;
  color: var(--color-text-dark);
  margin: 24px 0 0;
}

.section-tagline {
  font-size: 32px;
  font-weight: 300;
  color: var(--color-text-dark);
  text-align: center;
  margin: 70px 0;
}

/* ===== Categories ===== */
.categories {
  margin-top: 60px;
}

.category-grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 35px 24px;
  margin-top: 48px;
}

.category-card {
  display: flex;
  /* min-height, а не height: длина заголовка и текста у карточек разная, и
     фиксированная высота вместе с overflow: hidden срезала нижнюю часть
     колонки — CTA уходила за край карточки. Ряд grid выравнивается по самой
     высокой карточке (align-items: stretch по умолчанию). */
  min-height: 298px;
  background: #ffffff;
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}

.category-card__content {
  flex: 0 0 363px;
  display: flex;
  flex-direction: column;
  padding: 35px 34px 35px 33px;
  min-width: 0;
}

.category-card__title {
  font-size: 20px;
  font-weight: 400;
  color: var(--color-text-dark);
  margin: 0 0 32px;
}

.category-card__text {
  font-size: 14px;
  line-height: 20px;
  color: var(--color-text-dark);
  margin: 0;
}

.category-card__cta {
  align-self: flex-start;
  width: 150px;
  margin-top: auto;
}

.category-card__media {
  flex: 1 1 auto;
  min-width: 0;
}

.category-card__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.btn--category {
  width: 150px;
  background-color: var(--color-orange);
}

.btn--category:hover {
  background-color: #e88a00;
}

.btn--category:active {
  background-color: #cc7a00;
}

/* ===== Bestsellers / Product Card ===== */
.bestsellers {
  margin-top: 70px;
  padding: 41px 0 66px;
  background: var(--color-bg-light);
}

.product-grid {
  display: grid;
  grid-template-columns: repeat(4, 302px);
  gap: 44px 24px;
  justify-content: space-between;
  margin-top: 42px;
}

.product-card {
  width: 302px;
  /* min-height: карточки с длинным названием и длинными ключевыми
     характеристиками не помещались в 399px, и футер с ценой, счётчиком и
     кнопками срезался overflow: hidden. gap задаёт минимальный отступ от
     текста до футера, когда контент занимает всю карточку; у коротких
     карточек футер по-прежнему прижат к низу через margin-top: auto. */
  min-height: 399px;
  display: flex;
  flex-direction: column;
  gap: 12px;
  background: var(--color-bg-light);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-elevated);
  overflow: hidden;
}

.product-card__media {
  position: relative;
  flex-shrink: 0;
  width: 100%;
  height: 175px;
}

.product-card__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.product-card__badge {
  position: absolute;
  left: 15px;
  bottom: -24px;
  width: 150px;
  height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-orange);
  color: var(--color-text-dark);
  font-size: 14px;
  border-radius: var(--radius-card);
}

.product-card__link {
  display: flex;
  flex-direction: column;
  color: inherit;
  text-decoration: none;
}

.product-card__link:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: -2px;
  border-radius: var(--radius-card) var(--radius-card) 0 0;
}

.product-card__body {
  padding: 36px 15px 0;
}

.product-card__article {
  font-size: 14px;
  color: var(--color-text-dark);
  margin: 0 0 8px;
}

.product-card__title {
  font-size: 16px;
  font-weight: 500;
  color: var(--color-text-dark);
  margin: 0 0 11px;
}

/* Три ключевые характеристики (isKey + keyOrder) выводятся целиком: обрезка по
   двум строкам прятала до 90% строки — у части товаров значения занимают
   10+ строк. Текст переносится естественно, карточка растёт по высоте.
   overflow-wrap страхует от горизонтального выхода на длинных обозначениях
   без пробелов (единицы измерения, артикулы). */
.product-card__specs {
  font-size: 14px;
  line-height: 22px;
  color: var(--color-text-dark);
  margin: 0;
  overflow-wrap: break-word;
}

.product-card__footer {
  margin-top: auto;
  padding: 0 15px 15px;
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 8px;
}

.product-card__price {
  font-size: 16px;
  color: var(--color-icon-account);
  margin: 0;
  white-space: nowrap;
}

.product-card__stepper {
  display: flex;
  align-items: center;
  gap: 3px;
  flex-shrink: 0;
}

.product-card__stepper-btn {
  width: 24px;
  height: 30px;
  margin: 0;
  padding: 0;
  border: none;
  background: var(--color-table-highlight);
  font-family: inherit;
  font-size: 16px;
  color: #000000;
  cursor: pointer;
  display: flex;
  align-items: center;
  justify-content: center;
}

.product-card__stepper-btn--minus {
  border-radius: 25px 0 0 25px;
  box-shadow: 0 4px 30px 2px rgba(31, 77, 94, 0.25);
}

.product-card__stepper-btn--plus {
  border-radius: 0 25px 25px 0;
  background: var(--color-accent-mint);
}

.product-card__stepper-btn:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

.product-card__stepper-value {
  width: 34px;
  height: 30px;
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--color-table-highlight);
  font-size: 16px;
  color: #000000;
}

.product-card__actions {
  display: flex;
  align-items: center;
  gap: 8px;
  flex-shrink: 0;
}

.icon-circle {
  width: 31px;
  height: 31px;
  padding: 0;
  border: none;
  border-radius: 50%;
  background: none;
  cursor: pointer;
  display: flex;
  transition: filter 0.2s ease;
}

.icon-circle--lg {
  width: 48px;
  height: 48px;
}

.icon-circle img {
  display: block;
  width: 100%;
  height: 100%;
}

.icon-circle:hover {
  filter: brightness(0.92);
}

.icon-circle:active {
  filter: brightness(0.85);
}

.icon-circle:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
  border-radius: 50%;
}

/* ===== News ===== */
.news {
  margin-top: 47px;
  padding: 43px 0 36px;
  background: var(--color-bg-light);
}

.news-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 36px 24px;
  margin-top: 43px;
}

.news-card {
  display: flex;
  flex-direction: column;
}

.news-card__media {
  width: 100%;
  height: 242px;
  border-radius: var(--radius-card) var(--radius-card) 0 0;
  overflow: hidden;
  box-shadow: var(--shadow-soft);
}

.news-card__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.news-card__title {
  font-size: 16px;
  font-weight: 500;
  color: var(--color-text-dark);
  margin: 19px 15px 0;
}

.news-card__text {
  font-size: 14px;
  line-height: 20px;
  color: var(--color-text-dark);
  margin: 8px 15px 0;
  overflow-wrap: break-word;
}

.news-card__link {
  display: block;
  margin: 16px 15px 0;
  font-size: 14px;
  color: var(--color-icon-account);
  text-decoration: none;
}

.news-card__link:hover,
.news-card__link:focus-visible {
  color: var(--color-orange-active);
  text-decoration: underline;
}

.news__more {
  display: flex;
  margin: 53px auto 0;
}

/* ===== Trust ===== */
.trust {
  margin-top: 29px;
}

.trust-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 24px;
  margin-top: 48px;
}

.trust-tile {
  height: 260px;
  background: var(--color-bg-light);
  border-radius: var(--radius-card);
}

/* ===== Legal note (pre-footer) ===== */
.legal-note {
  max-width: var(--container-width);
  margin: 41px auto 0;
  padding: 0 var(--container-padding-content);
  font-size: 16px;
  font-weight: 300;
  line-height: 24px;
  color: var(--color-text-dark);
}

.legal-note a {
  color: var(--color-link);
  font-weight: 400;
  text-decoration: none;
}

.legal-note a:hover,
.legal-note a:focus-visible {
  text-decoration: underline;
}

/* ===== Hero Banner (Secondary — каталог/инфо/контакты) ===== */
.hero-banner {
  position: relative;
  width: 100%;
  height: 500px;
  overflow: hidden;
  background: var(--gradient-hero-secondary);
}

.hero-banner__inner {
  position: relative;
  max-width: var(--container-width);
  min-width: 760px;
  height: 100%;
  margin: 0 auto;
}

.hero-banner__media {
  position: absolute;
  top: 55px;
  left: 0;
  width: 623px;
  height: 389px;
  overflow: hidden;
  border-radius: 0 320.5px 320.5px 0;
}

.hero-banner__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
  object-position: left center;
}

.hero-banner__eyebrow,
.hero-banner__title,
.hero-banner__text {
  position: absolute;
  right: var(--container-padding-content);
  margin: 0;
  color: var(--color-footer-text);
}

.hero-banner__eyebrow {
  top: 169px;
  width: 598px;
  max-width: calc(100% - 2 * var(--container-padding-content));
  font-size: 20px;
  font-weight: 300;
  line-height: 32px;
  text-align: right;
}

.hero-banner__title {
  top: 224px;
  width: max-content;
  max-width: calc(100% - 2 * var(--container-padding-content));
  font-size: 36px;
  font-weight: 400;
  line-height: 52px;
  white-space: nowrap;
}

.hero-banner__text {
  top: 310px;
  width: 598px;
  max-width: calc(100% - 2 * var(--container-padding-content));
  font-size: 24px;
  font-weight: 400;
  line-height: 28px;
  text-align: right;
}

/* ===== New arrivals (Актуальные новинки) ===== */
.new-arrivals {
  margin-top: 74px;
  padding: 34px 0 65px;
  background: var(--color-bg-light);
}

/* ===== Section title/subtitle — centered variant (Лидеры продаж / Обзор всех товаров) ===== */
.section-subtitle--center {
  text-align: center;
}

.section-title--center + .section-subtitle--center {
  margin-top: 9px;
}

/* ===== Bestsellers carousel (Лидеры продаж) ===== */
.bestsellers-carousel {
  margin-top: 41px;
}

.bestsellers-carousel .section-subtitle {
  font-size: 14px;
}

.carousel-wide {
  width: 100%;
  padding: 0 var(--container-padding-content);
  margin-top: 53px;
}

.carousel {
  position: relative;
}

.carousel__viewport {
  overflow: hidden;
  padding: 30px 32px;
  margin: -30px -32px;
}

.carousel__track {
  display: flex;
  gap: 24px;
  transition: transform 0.4s ease;
}

.carousel__track > .product-card {
  flex-shrink: 0;
}

.carousel__nav {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 24px;
  margin-top: 24px;
}

.carousel__arrow {
  position: relative;
  z-index: 2;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-shrink: 0;
  width: 44px;
  height: 44px;
  padding: 0;
  border: none;
  background: none;
  cursor: pointer;
  transition: opacity 0.2s ease;
}

.carousel__arrow-icon {
  width: 20px;
  height: 20px;
}

.carousel__arrow--prev .carousel__arrow-icon {
  transform: rotate(-90deg);
}

.carousel__arrow--next .carousel__arrow-icon {
  transform: rotate(90deg);
}

.carousel__arrow:hover:not(:disabled) {
  opacity: 0.6;
}

.carousel__arrow:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

.carousel__arrow:disabled {
  opacity: 0.3;
  cursor: default;
}

.carousel__track-line {
  position: relative;
  flex: 1 1 auto;
  height: 10px;
  background: var(--color-table-highlight);
  border-radius: 5px;
  cursor: pointer;
  touch-action: none;
}

.carousel__track-line-fill {
  position: absolute;
  top: 0;
  left: 0;
  height: 100%;
  background: var(--color-text-dark);
  border-radius: 5px;
  transition: left 0.4s ease, width 0.4s ease;
  pointer-events: none;
}

.carousel__track-line.is-dragging .carousel__track-line-fill {
  transition: none;
}

/* ===== Catalog overview (Обзор всех товаров) ===== */
.catalog-overview {
  margin-top: 36px;
  padding: 41px 0 107px;
  background: var(--color-bg-light);
}

.catalog-overview .section-subtitle {
  font-size: 16px;
}

.category-tile-grid {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 36px 24px;
  margin-top: 36px;
}

.category-tile {
  display: flex;
  flex-direction: column;
  background: #ffffff;
  border-radius: var(--radius-card) var(--radius-card) 0 0;
  box-shadow: var(--shadow-soft);
  overflow: hidden;
  color: inherit;
}

.category-tile__media {
  position: relative;
  flex-shrink: 0;
  width: 100%;
  height: 302px;
}

.category-tile__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.category-tile__label {
  position: absolute;
  left: 50%;
  bottom: 8px;
  transform: translateX(-50%);
  width: 345px;
  max-width: calc(100% - 32px);
  min-height: 48px;
  display: flex;
  align-items: center;
  justify-content: center;
  padding: 3px 8px;
  background: #1f4d5e;
  color: var(--color-footer-text);
  font-size: 16px;
  font-weight: 400;
  line-height: 21px;
  text-align: center;
  border-radius: var(--radius-card);
  transition: color 0.2s ease;
}

.category-tile__text {
  flex: 1 1 auto;
  margin: 0;
  padding: 18px 16px 24px;
  font-size: 16px;
  line-height: 24px;
  color: var(--color-text-dark);
  text-align: center;
  overflow-wrap: break-word;
}

.category-tile:hover .category-tile__label,
.category-tile:focus-visible .category-tile__label {
  color: var(--color-orange);
}

.category-tile:focus-visible {
  outline: 2px solid var(--color-icon-dark);
  outline-offset: 4px;
}

/* ===== Category page — controls panel ===== */
.catalog-products {
  padding: 37px 0 0;
}

.catalog-products__row {
  display: flex;
  align-items: center;
  justify-content: space-between;
}

.catalog-count {
  margin: 26px 0 0;
  font-size: 16px;
  font-weight: 400;
  color: var(--color-text-dark);
}

/* Описание категории (`Categories.description`). Собственной типографики не
   вводит: кегль, начертание, интерлиньяж и цвет — существующий .text-section__text,
   которым набран текст новостей и информационных страниц. Здесь задаётся только
   отбивка — тот же шаг 26px, что у .catalog-count и .product-grid этой секции. */
.catalog-description {
  margin-top: 26px;
}

.catalog-products .product-grid {
  margin-top: 26px;
}

/* ===== Outline button ===== */
.btn--outline {
  min-width: 190px;
  padding: 0 20px;
  gap: 10px;
  background: transparent;
  border: 2px solid var(--color-border-muted);
  color: var(--color-text-dark);
  font-size: 12px;
}

.btn--outline:hover,
.btn--outline:focus-visible {
  border-color: var(--color-orange);
}

.btn--outline:active {
  background: var(--color-bg-light);
}

.btn--filters {
  justify-content: flex-start;
}

/* ===== Sort dropdown ===== */
.dropdown {
  position: relative;
}

.dropdown__trigger {
  justify-content: space-between;
}

.dropdown__chevron {
  flex-shrink: 0;
  transform: rotate(90deg);
  transition: transform 0.2s ease;
}

.dropdown[data-open] .dropdown__chevron {
  transform: rotate(-90deg);
}

.dropdown__menu {
  position: absolute;
  top: calc(100% + 8px);
  left: 0;
  width: 190px;
  margin: 0;
  padding: 8px;
  list-style: none;
  background: #ffffff;
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
  z-index: 10;
}

.dropdown__menu[hidden] {
  display: none;
}

.dropdown__option {
  display: block;
  width: 100%;
  padding: 10px 12px;
  border: none;
  border-radius: 16px;
  background: none;
  font-family: inherit;
  font-size: 12px;
  color: var(--color-text-dark);
  text-align: left;
  cursor: pointer;
  transition: color 0.2s ease;
}

.dropdown__option:hover,
.dropdown__option:focus-visible,
.dropdown__option.is-selected {
  color: var(--color-orange);
}

.dropdown__option:focus-visible {
  outline: 2px solid var(--color-icon-dark);
  outline-offset: -2px;
}

/* ===== Dropdown как поле формы (contacts.html, «Причина обращения:»)
   Тот же компонент и тот же JS, что у сортировки каталога — меняются только
   габариты: триггер повторяет `.field__input` (48px, обводка 2px, капсула),
   меню растягивается на ширину поля. Оформление меню в Figma не задано —
   взято из уже утверждённого дропдауна сортировки. ===== */
.dropdown--field .dropdown__trigger {
  width: 100%;
  min-width: 0;
  height: 48px;
  padding: 0 17px;
  gap: 12px;
  border: 2px solid var(--color-border-muted);
  border-radius: 999px;
  background: transparent;
  font-size: 16px;
  font-weight: 400;
  color: var(--color-text-dark);
  text-align: left;
  transition: border-color 0.2s ease;
}

/* Оранжевый = «поле требует внимания» — тот же смысл, что у `.field` */
.dropdown--field .dropdown__trigger:hover,
.dropdown--field .dropdown__trigger:focus-visible,
.dropdown--field[data-open] .dropdown__trigger,
.dropdown--field.is-error .dropdown__trigger {
  border-color: var(--color-orange);
}

.dropdown--field .dropdown__trigger:focus-visible {
  outline: none;
}

/* Шеврон 26×13 в макете — тот же ассет, что у сортировки, повёрнут на 90° */
.dropdown--field .dropdown__chevron {
  width: 13px;
  height: 26px;
}

.dropdown--field .dropdown__menu {
  width: 100%;
}

.dropdown--field .dropdown__option {
  font-size: 16px;
  line-height: 24px;
}

/* ===== Category page — recommended categories ===== */
.category-recommend {
  margin-top: 66px;
  padding: 41px 0 116px;
  background: var(--color-bg-light);
}

.category-recommend .category-tile-grid {
  margin-top: 76px;
}

/* ===== Product page (PDP) ===== */
.product-dealer {
  margin-top: 38px;
}

.product-hero {
  margin-top: 34px;
}

.product-hero__main {
  width: 1063px;
  display: flex;
  flex-direction: column;
  gap: 30px;
  padding: 33px 18px 24px;
  background: var(--color-bg-light);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
}

.product-hero__top {
  display: flex;
  gap: 27px;
}

/* Sticky zone — wraps hero through Области применения so the purchase
   panel can travel the full length of the product content, not just
   the hero row. display:flow-root keeps child margins from collapsing
   out of the zone, which would misalign the rail's top offset. */
.product-sticky-zone {
  position: relative;
  display: flow-root;
}

.product-sidebar__rail {
  position: absolute;
  top: 34px;
  bottom: 0;
  right: calc(max(0px, (100% - 1440px) / 2) + 80px);
  width: 193px;
}

/* Product Gallery */
.product-gallery {
  flex: 0 0 610px;
  min-width: 0;
}

.product-gallery__main {
  width: 610px;
  height: 336px;
  border-radius: var(--radius-card);
  overflow: hidden;
  box-shadow: var(--shadow-soft);
}

.product-gallery__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/* Миниатюр у товара может быть много (в текущей базе — до 16), поэтому ряд
   переносится. Без `flex-wrap` все миниатюры вставали в одну строку, выходили
   за левую колонку, перекрывали `.product-info` и растягивали страницу по
   горизонтали. Ширина ряда равна ширине `.product-gallery__main` (610px) —
   миниатюры не выходят за блок большой фотографии; `gap` задаёт и отступ
   между строками. */
.product-gallery__thumbs {
  display: flex;
  flex-wrap: wrap;
  gap: 22px;
  margin-top: 22px;
  padding: 0;
  list-style: none;
}

.product-gallery__thumb {
  width: 100px;
  height: 100px;
  padding: 0;
  border: none;
  border-radius: var(--radius-card);
  overflow: hidden;
  box-shadow: var(--shadow-soft);
  background: none;
  cursor: pointer;
  transition: outline-color 0.2s ease, filter 0.2s ease;
}

.product-gallery__thumb-image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.product-gallery__thumb:hover {
  filter: brightness(0.95);
}

.product-gallery__thumb.is-active {
  outline: 3px solid var(--color-orange);
  outline-offset: -3px;
}

.product-gallery__thumb:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

/* Product info column */
.product-info {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  flex-direction: column;
}

.product-info__article {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
  color: var(--color-text-dark);
}

.product-info__summary {
  margin: 33px 0 0;
  max-width: 400px;
  font-size: 14px;
  line-height: 20px;
  color: var(--color-text-dark);
}

.pdp-badge {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 150px;
  height: 48px;
  margin-top: 28px;
  border-radius: var(--radius-card);
  background: var(--color-orange);
  color: var(--color-text-dark);
  font-size: 14px;
}

.product-info__price {
  margin: 24px 0 0;
  font-size: 24px;
  font-weight: 600;
  color: var(--color-icon-account);
}

.product-info__delivery {
  margin: 22px 0 0;
  max-width: 220px;
  font-size: 16px;
  font-weight: 500;
  color: var(--color-text-dark);
}

/* Advantages */
.product-advantages__title {
  margin: 0;
  font-size: 20px;
  font-weight: 400;
  color: var(--color-text-dark);
}

/* Marker list — shared by Ваши преимущества, Описание, Области применения */
.marker-list {
  display: flex;
  flex-direction: column;
  gap: 11px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.marker-list__item {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  color: var(--color-text-dark);
}

/*
 * Иконка выравнивается по центру первой строки текста, а не по её верху.
 * В Figma верх иконки стоит на +2px от верха текстового блока и в «Описании»
 * (502:744 y=1242 при тексте 502:743 y=1240), и в «Областях применения»
 * (502:835 y=3818 при тексте 502:825 y=3816). При line-height 24px и иконке
 * 20px это ровно центр строки: (24 − 20) / 2 = 2. Прежние 4px опускали
 * уголок на 2px ниже текста.
 */
.marker-list__icon {
  flex: 0 0 auto;
  margin-top: 2px;
}

/*
 * Модификаторы размера и ритма списка. Базовые значения (gap 11px, размер
 * шрифта по наследству) остаются за PDP, где компонент появился; страницы с
 * другим шагом и кеглем подключают модификаторы, а не переопределяют базу.
 * Кегль задаётся на .marker-list — .marker-list__item его наследует.
 */
.marker-list--spaced {
  gap: 16px;
}

.marker-list--sm {
  font-size: 14px;
  line-height: 20px;
}

/*
 * При 14/20 иконка (20px + базовый margin-top: 2px) выше строки текста и
 * растянула бы пункт до 22px — в макете высота пункта ровно 20px, а на длинном
 * списке лишние 2px накапливаются. Тот же сдвиг задаём relative-позицией: она
 * на высоту строки не влияет. Базовый margin-top у более крупных кеглей
 * (16/24 здесь, 16/24 и 16/32 на PDP) в высоту не упирается и остаётся как есть.
 */
.marker-list--sm .marker-list__icon {
  position: relative;
  top: 2px;
  margin-top: 0;
}

.marker-list--md {
  font-size: 16px;
  line-height: 24px;
}

.marker-list--light {
  font-weight: 300;
}

.product-advantages__list {
  margin-top: 28px;
  font-size: 14px;
  line-height: 20px;
}

/* Sticky purchase panel */
.product-sidebar {
  position: sticky;
  top: 24px;
  display: flex;
  flex-direction: column;
  align-items: stretch;
  gap: 16px;
  width: 193px;
  padding: 24px 16px;
  background: var(--color-bg-light);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
}

.product-sidebar__title {
  margin: 0;
  font-size: 13px;
  line-height: 18px;
  text-align: center;
  color: var(--color-text-dark);
  overflow-wrap: normal;
  word-break: normal;
  hyphens: none;
}

.product-sidebar__article {
  margin: 0;
  font-size: 12px;
  text-align: center;
  color: var(--color-text-dark);
}

.product-sidebar__stock {
  margin: 0;
  font-size: 14px;
  text-align: center;
  color: var(--color-text-dark);
}

.product-sidebar__phone {
  display: block;
  font-size: 16px;
  font-weight: 300;
  text-align: center;
  color: var(--color-text-dark);
  transition: color 0.2s ease;
}

.product-sidebar__phone:hover,
.product-sidebar__phone:focus-visible {
  color: var(--color-orange-active);
}

.product-sidebar__request {
  display: block;
  font-size: 16px;
  text-align: center;
  color: var(--color-text-dark);
  transition: color 0.2s ease;
}

.product-sidebar__request:hover,
.product-sidebar__request:focus-visible {
  color: var(--color-orange);
}

.btn--accent-strong,
.btn--sidebar-compare {
  width: 100%;
  padding: 0 16px;
  gap: 8px;
  font-weight: 500;
}

.btn--accent-strong .btn__icon,
.btn--sidebar-compare .btn__icon {
  width: 14px;
  height: 14px;
}

.btn--accent-strong {
  background-color: var(--color-accent-orange-strong);
}

.btn--accent-strong:hover {
  background-color: #e87700;
}

.btn--accent-strong:focus-visible {
  outline: 2px solid #003241;
  outline-offset: 2px;
}

.btn--accent-strong:active {
  background-color: #cc6900;
}

.btn--sidebar-compare {
  background-color: var(--color-orange);
}

.btn--sidebar-compare:hover {
  background-color: #e88a00;
}

.btn--sidebar-compare:focus-visible {
  outline: 2px solid #003241;
  outline-offset: 2px;
}

.btn--sidebar-compare:active {
  background-color: #cc7a00;
}

.product-card__stepper--large {
  width: 100%;
  justify-content: center;
}

.product-card__stepper--large .product-card__stepper-btn,
.product-card__stepper--large .product-card__stepper-value {
  height: 48px;
}

.product-card__stepper--large .product-card__stepper-btn {
  width: 40px;
  font-size: 20px;
}

.product-card__stepper--large .product-card__stepper-value {
  flex: 1 1 auto;
  font-size: 20px;
}

/* Светлый вариант степпера (фрейм корзины: сегменты «−» и значение — белые) */
.product-card__stepper--light .product-card__stepper-btn,
.product-card__stepper--light .product-card__stepper-value {
  background: #ffffff;
}

.product-card__stepper--light .product-card__stepper-btn--minus {
  box-shadow: none;
}

.product-card__stepper--light .product-card__stepper-btn--plus {
  background: var(--color-accent-mint);
}

.product-sidebar__note {
  margin: 0;
  font-size: 12px;
  font-weight: 500;
  text-align: center;
  color: var(--color-text-dark);
}

/* Описание */
.product-description {
  margin-top: 67px;
  padding: 41px 0 66px;
  background: var(--color-bg-light);
}

.product-description__list {
  margin-top: 32px;
  max-width: 1053px;
  font-size: 16px;
  line-height: 24px;
  gap: 16px;
}

/* Секция страницы товара, в которой размещён компонент Specifications. */
.product-specs {
  padding: 41px 0 66px;
  background: #ffffff;
}

/* ===== Specifications (глобальный компонент) =====
 *
 * Одна постоянная DOM-структура на оба состояния:
 *
 *   .specifications
 *     └ .specifications__surface        внешний контур: фон, radius, clipping
 *         └ .specifications__stack      контур стопки строк: radius + overflow
 *             ├ .specifications__row--head
 *             ├ .specifications__primary        основные строки (dl)
 *             └ .specifications__reveal         единственный раскрываемый блок
 *                 └ .specifications__reveal-inner
 *                     └ .specifications__additional  дополнительные строки (dl)
 *
 * Раскрытие — grid-техника 0fr → 1fr: анимируется единственное свойство
 * grid-template-rows на .specifications__reveal, высоту никто не считает.
 * Свёрнутое состояние объявлено в CSS (0fr — значение по умолчанию), поэтому
 * первый же кадр страницы отрисовывается свёрнутым, до выполнения JS.
 *
 * Геометрия — из Figma (708:1130 / 502:654). В макете строки нарисованы
 * прямоугольниками 70px с шагом 48px, то есть нижние 22px каждой строки всегда
 * закрыты следующей: видимая полоса строки — 48px, и подписи отцентрированы
 * именно по ней (502:670 y=2278 h=19 при строке 2264…2312). Поэтому строка
 * здесь имеет высоту видимой полосы и не требует ни отрицательных отступов, ни
 * перекрытия — раскладка совпадает с макетом пиксель в пиксель и при этом не
 * выносит содержимое за верхнюю границу reveal-контейнера.
 */
.specifications {
  /* Шаг строк из Figma: 2264 → 2312 → 2361 … (среднее 48px). */
  --spec-row-height: 48px;
  /*
   * Замыкающая полоса. В Figma последняя строка (502:667) — 60px и скруглена со
   * всех сторон. Здесь эти 12px принадлежат не строке, а стопке: они всегда
   * ниже последней видимой строки, поэтому замыкание одинаково работает и на
   * последней основной строке (свёрнуто), и на последней дополнительной
   * (раскрыто). Ни одна строка не меняет ни высоту, ни скругление.
   */
  --spec-stack-tail: 12px;
  /*
   * Вылет шапки под первую строку. В Figma шапка (502:657) — прямоугольник
   * 70px, а первая строка начинается на 48px ниже, то есть нижние 22px шапки
   * всегда перекрыты. Перекрытие видно не полосой, а в скруглённых верхних
   * углах первой строки: через них проглядывает серая подложка шапки, и
   * получаются те самые уголки по бокам стыка. 70 − 48 = 22.
   */
  --spec-head-bleed: 22px;
  /* Подпись: x=165 при строке x=98 (502:670 / 502:658). */
  --spec-row-padding: 67px;
  --spec-reveal-duration: 0.5s;
  --spec-reveal-easing: cubic-bezier(0.4, 0, 0.2, 1);

  max-width: 954px;
  margin-top: 39px;
}

/*
 * Внешний контур компонента. Именно surface владеет общим border-radius и
 * отсечением, поэтому внешняя форма постоянна и не зависит от состояния.
 * Строки отступают от края на 18px, тень строки уходит на 17px (blur/2 +
 * spread − offset), поэтому clipping её не срезает.
 */
.specifications__surface {
  padding: 30px 18px 46px;
  background: var(--color-bg-light);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}

/*
 * Контур стопки строк. Радиус и отсечение живут здесь, а не на строках,
 * поэтому скругление верхних углов шапки и нижних углов последней видимой
 * строки получается автоматически в обоих состояниях — без временных классов,
 * без переключения радиусов и без участия JS.
 */
.specifications__stack {
  padding-bottom: var(--spec-stack-tail);
  background: #ffffff;
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}

.specifications__list {
  margin: 0;
  padding: 0;
}

/*
 * Строка. Две колонки 309 : 475 внутри поля 784px (918 − 2 × 67) дают центр
 * колонки значений на 613.5px от левого края строки — как в макете (502:683
 * и соседние центрируются по 711.5px при строке x=98).
 */
.specifications__row {
  display: grid;
  grid-template-columns: minmax(0, 309fr) minmax(0, 475fr);
  align-items: center;
  min-height: var(--spec-row-height);
  padding: 6px var(--spec-row-padding);
  background: #ffffff;
  border-radius: var(--radius-card) var(--radius-card) 0 0;
  /*
   * Шов между строками. Тень нарисована внутри строки, поэтому её никогда не
   * срезает overflow reveal-контейнера: у всех стыков, включая стык основных и
   * дополнительных строк, вид одинаковый в любом состоянии.
   */
  box-shadow: inset 0 11px 13px -7px rgba(31, 77, 94, 0.38);
}

/*
 * Верхняя строка стопки. Шва над ней нет, а её фон уходит на --spec-head-bleed
 * ниже — под первую строку списка. В потоке шапка занимает обычные 48px
 * (вылет снимается отрицательным margin), поэтому геометрия стопки не меняется.
 * Первая строка непрозрачная и перекрывает вылет целиком, кроме собственных
 * скруглённых верхних углов: там остаётся серый — уголки со стыка из макета.
 * Нижний паддинг увеличен на ту же величину, чтобы подпись осталась по центру
 * видимой полосы 48px, а не поехала вниз вместе с фоном.
 */
.specifications__row--head {
  min-height: calc(var(--spec-row-height) + var(--spec-head-bleed));
  padding-bottom: calc(6px + var(--spec-head-bleed));
  margin-bottom: calc(-1 * var(--spec-head-bleed));
  background: var(--color-table-highlight);
  box-shadow: none;
}

.specifications__label {
  margin: 0;
  font-size: 16px;
  color: var(--color-text-dark);
  transition: color 0.2s ease;
}

.specifications__value {
  margin: 0;
  font-size: 16px;
  text-align: center;
  color: var(--color-text-dark);
}

.specifications__row--head .specifications__label,
.specifications__row--head .specifications__value {
  font-size: 20px;
  letter-spacing: -0.1px;
}

.specifications__row:not(.specifications__row--head):hover .specifications__label {
  color: var(--color-orange);
}

/*
 * Единственный раскрываемый контейнер. Анимируется ровно одно свойство —
 * grid-template-rows; высота трека сама берётся из содержимого, поэтому
 * количество дополнительных строк может быть любым и JS ничего не измеряет.
 */
.specifications__reveal {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--spec-reveal-duration) var(--spec-reveal-easing);
}

.specifications.is-expanded .specifications__reveal {
  grid-template-rows: 1fr;
}

.specifications__reveal-inner {
  min-height: 0;
  overflow: hidden;
}

@media (prefers-reduced-motion: reduce) {
  .specifications__reveal {
    transition: none;
  }
}

.specifications__export {
  display: flex;
  flex-wrap: wrap;
  justify-content: flex-end;
  gap: 22px;
  margin-top: 32px;
}

.specifications__actions {
  margin-top: 22px;
}

.specifications__toggle {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 0;
  border: none;
  background: none;
  font-family: inherit;
  font-size: 16px;
  color: var(--color-icon-account);
  cursor: pointer;
  transition: color 0.2s ease;
}

.specifications__toggle:hover,
.specifications__toggle:focus-visible {
  color: var(--color-orange-active);
}

.specifications__toggle-icon {
  flex: 0 0 auto;
  transform: rotate(90deg);
  transition: transform 0.2s ease;
}

.specifications__toggle[aria-expanded="true"] .specifications__toggle-icon {
  transform: rotate(-90deg);
}

@media (max-width: 1199px) {
  .specifications {
    --spec-row-padding: 40px;
  }
}

@media (max-width: 767px) {
  .specifications {
    --spec-row-padding: 16px;
  }

  .specifications__surface {
    padding: 18px 10px 28px;
  }

  .specifications__row {
    gap: 0 12px;
  }

  .specifications__label,
  .specifications__value {
    font-size: 14px;
  }

  .specifications__row--head .specifications__label,
  .specifications__row--head .specifications__value {
    font-size: 16px;
  }

  .specifications__export {
    justify-content: stretch;
    gap: 12px;
  }
}

/*
 * Печать — локально для компонента: полный список без экранной анимации,
 * без органов управления и без теней, которые на печати дают серую заливку.
 */
@media print {
  .specifications__reveal {
    grid-template-rows: 1fr;
    transition: none;
  }

  .specifications__reveal-inner {
    overflow: visible;
  }

  .specifications__actions,
  .specifications__export {
    display: none;
  }

  .specifications__surface,
  .specifications__stack {
    box-shadow: none;
  }

  .specifications__row {
    box-shadow: none;
    border-bottom: 1px solid var(--color-border-muted);
  }
}

.btn--amber,
.btn--mint {
  padding: 0 32px;
  font-size: 16px;
}

.btn--amber {
  background-color: var(--color-accent-amber);
}

.btn--mint {
  background-color: var(--color-accent-mint);
}

.btn--amber:hover,
.btn--mint:hover {
  filter: brightness(0.94);
}

.btn--amber:active,
.btn--mint:active {
  filter: brightness(0.88);
}

.btn--amber:focus-visible,
.btn--mint:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

/* Аксессуары */
.product-accessories {
  margin-top: 36px;
  padding: 41px 0 66px;
  background: var(--color-bg-light);
}

.product-accessories .product-grid {
  grid-template-columns: repeat(3, 302px);
  justify-content: flex-start;
  margin-top: 42px;
}

.product-accessories__cta {
  max-width: 954px;
  margin-top: 41px;
  display: flex;
  justify-content: center;
}

/* Области применения */
.product-applications {
  margin-top: 41px;
  padding: 41px 0 66px;
  background: var(--color-bg-light);
}

.product-applications__list {
  margin-top: 32px;
  max-width: 1036px;
  font-size: 16px;
  line-height: 24px;
  gap: 12px;
}

/* ===== Tablet (<=1199px): collapse nav into offcanvas menu ===== */
@media (max-width: 1199px) {
  .header__burger {
    display: flex;
  }

  .header__nav {
    position: fixed;
    top: 0;
    right: 0;
    height: 100vh;
    width: min(360px, 85vw);
    background: #ffffff;
    flex-direction: column;
    align-items: stretch;
    gap: 32px;
    padding: 96px 24px 24px;
    margin-left: 0;
    transform: translateX(100%);
    transition: transform 0.3s ease;
    z-index: 25;
    overflow-y: auto;
  }

  .header__nav.is-open {
    transform: translateX(0);
  }

  .header__nav-list {
    flex-direction: column;
    align-items: flex-start;
    gap: 20px;
  }

  .header__search {
    flex: 0 0 auto;
    width: 100%;
    max-width: none;
    margin-left: 0;
  }

  .footer__inner {
    grid-template-columns: 1fr 1fr;
  }

  .header__actions {
    flex-direction: column;
    align-items: stretch;
    gap: 16px;
  }

  .header__actions .btn {
    width: 100%;
  }

  .header__backdrop:not([hidden]) {
    display: block;
  }

  .header__backdrop[hidden] {
    display: none;
  }

  .cart-empty__image {
    width: 220px;
  }

  .cart-empty__title {
    font-size: 28px;
  }

  .cart-empty__subtitle {
    font-size: 20px;
    line-height: 32px;
  }
}

@media (min-width: 1200px) {
  .header__backdrop {
    display: none !important;
  }

  .header__nav-item.is-open > .header__dropdown {
    display: block;
  }

  /* Вниз — свёрнуто, вверх — раскрыто (конвенция проекта: .dropdown__chevron) */
  .header__nav-item.is-open .header__nav-chevron {
    transform: rotate(-90deg);
  }
}

/* ===== Mobile (<=767px) ===== */
@media (max-width: 767px) {
  .header__inner {
    padding: 12px 16px;
  }

  .header__logo {
    width: 96px;
    height: 54.5px;
  }

  /* Полоса заголовка и её кегль заданы в разделе «Адаптив» ниже: там высота
     перестаёт быть фиксированной, иначе длинный H1 из данных в неё не
     помещается. Боковые поля полоса берёт из --container-padding-content. */

  .cart-empty {
    margin-top: 24px;
    padding: 32px 16px;
  }

  .cart-empty__image {
    width: 180px;
    margin-top: 16px;
  }

  .cart-empty__title {
    font-size: 22px;
  }

  .cart-empty__subtitle {
    font-size: 16px;
    line-height: 26px;
    margin-top: 12px;
  }

  .cart-empty__inner .btn--catalog {
    width: 100%;
    max-width: 280px;
  }

  .footer {
    margin-top: 48px;
    padding: 32px 0;
  }

  .footer__inner {
    grid-template-columns: 1fr;
    gap: 28px;
    padding: 0 16px;
  }

  .footer__col--about {
    max-width: none;
  }

  .footer__heading {
    margin-bottom: 12px;
  }

  .footer__text,
  .footer__contact-text,
  .footer__link {
    line-height: 26px;
  }

  .footer__social {
    margin-top: 16px;
  }

  .header__nav {
    width: 100%;
  }
}

/* ===== Print (Product page) ===== */
@media print {
  .header,
  .header__backdrop,
  .product-dealer,
  .product-sidebar__rail,
  .product-accessories,
  .product-accessories__cta,
  .footer {
    display: none !important;
  }
}

/* ===== Compare page (страница сравнения товаров) ===== */

/*
 * Одна универсальная страница на все состояния списка сравнения.
 *
 * Два фрейма Figma — «Сравнение товаров (2 позиции)» (502:1264) и
 * «(3 позиции)» (502:1419) — отличаются друг от друга ровно пятью величинами:
 * шириной блока, числом колонок, высотой фото карточки, высотой карточки и
 * раскладкой колонок таблицы. Все пять вынесены в переменные и переключаются
 * единственным атрибутом data-compare-count на .compare-page. Ни одно правило
 * ниже не дублируется под состояние, и ни один класс при смене состояния не
 * меняется.
 *
 * Состояния 4+ (окно из трёх товаров), 1 (карточка + пустой слот) и 0
 * (очищенный список) в Figma не нарисованы — они используют ту же геометрию,
 * что состояния 3 и 2 соответственно, и не вводят новой визуальной системы.
 */
.compare-page {
  /* 2 позиции (и вырожденные 1 / 0): 1063px = 2 × 519 + 25 (502:1306). */
  --compare-block: 1063px;
  --compare-cols: 2;
  --compare-media-h: 336px;
  --compare-card-h: 645px;
  /*
   * Колонки таблицы выведены из центров значений в макете: при строке 1027px и
   * левом отступе подписи центры товарных колонок стоят на расстоянии 328px
   * друг от друга, на колонку подписи остаётся 240px.
   */
  --compare-table-cols: minmax(0, 240fr) minmax(0, 328fr) minmax(0, 328fr);
}

/* Один товар: таблица вырождается в две колонки — те же пропорции, что на PDP. */
.compare-page[data-compare-count="1"] {
  --compare-table-cols: minmax(0, 309fr) minmax(0, 475fr);
}

.compare-page[data-compare-count="3"] {
  /* 3 позиции: 1281px = 3 × 410.33 + 2 × 25 (502:1542). */
  --compare-block: 1281px;
  --compare-cols: 3;
  --compare-media-h: 282px;
  --compare-card-h: 623px;
  /* Шаг центров товарных колонок 326px, на подпись остаётся 169px (502:1554…502:1557). */
  --compare-table-cols: minmax(0, 169fr) minmax(0, 326fr) minmax(0, 326fr) minmax(0, 326fr);
}

/*
 * Общий контур контента: сетка карточек, навигация и таблица имеют одну и ту же
 * ширину, поэтому колонки таблицы стоят ровно под карточками, а названия в
 * серой полосе — ровно над ними.
 */
.compare__block {
  max-width: var(--compare-block);
  width: 100%;
}

/* --- Верхний серый блок --- */

/*
 * Это существующий .page-title: фон, высота 70px и типографика 32px/500 не
 * меняются. Модификатор заменяет одну строку заголовка сеткой из N названий,
 * повторяющей сетку карточек. Структура блока постоянна во всех состояниях,
 * меняются только тексты внутри (в состоянии «0 товаров» полоса остаётся
 * пустой).
 */
.page-title--compare > .section-container {
  width: 100%;
}

.page-title__names {
  display: grid;
  grid-template-columns: repeat(var(--compare-cols), minmax(0, 1fr));
  gap: 25px;
}

/*
 * Название внутри полосы использует ту же типографику .page-title__text, но не
 * его раскладку: контейнер и внешние отступы здесь принадлежат сетке.
 */
.page-title--compare .page-title__text {
  max-width: none;
  width: auto;
  margin: 0;
  padding: 0;
  text-align: center;
}

/* --- Сетка карточек --- */

.compare {
  padding-bottom: 41px;
}

.compare__grid {
  display: grid;
  grid-template-columns: repeat(var(--compare-cols), minmax(0, 1fr));
  gap: 25px;
  /* 228 − 192 (низ серой полосы) = 36px. */
  padding-top: 36px;
}

/*
 * Previous / Next. В Figma состояние 4+ товаров не нарисовано, поэтому взят уже
 * утверждённый в проекте элемент .carousel__arrow (включая его :hover,
 * :focus-visible и :disabled) — новых стрелок и новых состояний не заводится.
 */
.compare__nav {
  display: flex;
  align-items: center;
  justify-content: flex-end;
  gap: 24px;
  margin-top: 24px;
}

.compare__nav[hidden] {
  display: none;
}

/* --- Comparison Card --- */

/*
 * Карточка сравнения — отдельный компонент макета (COMPONENTS.md §9), а не
 * увеличенный .product-card: другой размер, другая тень (0.49α против 0.7α),
 * другая типографика и вместо круглых иконок — степпер и кнопка «В корзину».
 * Собрана из уже существующих частей проекта: .marker-list, крупный вариант
 * .product-card__stepper--large, .btn с существующими модификаторами и общие
 * токены. Новых токенов компонент не вводит.
 */
.compare-card {
  display: flex;
  flex-direction: column;
  min-height: var(--compare-card-h);
  background: var(--color-bg-light);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
}

/*
 * Фото несёт собственную тень и скругление верхних углов (502:1367). Отсечение
 * здесь безопасно: кнопка «Удалить из сравнения» лежит внутри границ фото.
 */
.compare-card__media {
  position: relative;
  flex-shrink: 0;
  height: var(--compare-media-h);
  border-radius: var(--radius-card) var(--radius-card) 0 0;
  box-shadow: var(--shadow-soft);
  overflow: hidden;
}

.compare-card__image {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: cover;
}

/*
 * «Удалить из сравнения» — существующий .btn--amber (#ffbe00), у которого здесь
 * переопределены только размер и кегль по макету: 156×48, 12px Medium.
 */
.compare-card__remove {
  position: absolute;
  top: 16px;
  right: 12px;
  width: 156px;
  padding: 0;
  font-size: 12px;
  font-weight: 500;
  cursor: pointer;
}

.compare-card__body {
  /* 600 − (228 + 336) = 36px от низа фото; боковой отступ 18px. */
  padding: 36px 18px 0;
}

.compare-card__article {
  margin: 0;
  font-size: 16px;
  line-height: 31px;
  color: var(--color-text-dark);
}

.compare-card__title {
  margin: 12px 0 0;
  font-size: 20px;
  font-weight: 500;
  line-height: 23px;
  color: var(--color-text-dark);
}

.compare-card__specs {
  margin-top: 12px;
}

/*
 * Плотный вариант списка с маркерами: в карточке сравнения строки идут с шагом
 * 32px без дополнительного зазора между пунктами (502:1368 — межстрочный 32px,
 * шевроны на 683 / 716 / 748). Иконка центрируется по строке: (32 − 20) / 2.
 */
.marker-list--tight {
  gap: 0;
}

.marker-list--tight .marker-list__item {
  font-size: 16px;
  line-height: 32px;
}

.marker-list--tight .marker-list__icon {
  margin-top: 6px;
}

/*
 * Нижняя строка карточки. Цена прижата влево, степпер и «В корзину» — вправо.
 * Перенос по ширине даёт обе раскладки макета одной разметкой: при 519px всё
 * умещается в одну строку (502:1371…502:1387), при 411px цена уходит на строку
 * выше (502:1474…502:1487). Отдельного правила под состояние не требуется.
 */
.compare-card__footer {
  margin-top: auto;
  padding: 24px 18px 25px;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px 17px;
}

.compare-card__price {
  margin: 0;
  font-size: 20px;
  font-weight: 600;
  color: var(--color-icon-account);
  white-space: nowrap;
}

.compare-card__buy {
  display: flex;
  align-items: center;
  gap: 17px;
  margin-left: auto;
}

/* Крупный степпер 40 / 60 / 40 — макетные 139.77px. */
.compare-card__stepper {
  width: 140px;
  flex: 0 0 auto;
}

.compare-card__cart {
  width: 150px;
  flex: 0 0 auto;
  cursor: pointer;
}

.compare-card__cart .btn__icon {
  width: 16px;
  height: 16px;
}

/*
 * Пустой слот — в Figma не нарисован. Используется, когда в сравнении остался
 * один товар и рядом освободилось место, и когда список очищен целиком.
 * Повторяет поверхность карточки, поэтому новой визуальной сущности в сетке не
 * появляется; внутри — существующая оранжевая кнопка .btn--catalog.
 */
.compare-card--empty {
  align-items: center;
  justify-content: center;
}

/* --- Таблица сравнения --- */

/*
 * Тот же компонент Specifications, что на product.html. Модификатор меняет
 * только ширину, число колонок строки, кегль шапки и добавляет серый фон
 * строкам с различающимися значениями. Высоты строк, швы, скругления, отступы,
 * фон шапки, замыкающая полоса и тени наследуются как есть.
 */
.specifications--compare {
  max-width: none;
  /* 921 − 873 = 48px от низа карточек. */
  margin-top: 48px;
}

.specifications--compare[hidden] {
  display: none;
}

.specifications--compare .specifications__row {
  grid-template-columns: var(--compare-table-cols);
}

/*
 * Подкладка строк друг под друга.
 *
 * В макете каждая строка — прямоугольник 70px со скруглением 25px сверху, а шаг
 * строк 48px, поэтому нижние 22px каждой строки всегда закрыты следующей. Из-за
 * этого в скруглённых верхних уголках строки виден фон ПРЕДЫДУЩЕЙ строки, а не
 * подложка стопки. На PDP разницы нет — там все строки белые, как и подложка. В
 * таблице сравнения соседние строки бывают разного цвета, и без вылета в уголках
 * серых строк проглядывала белая подложка: серая полоса выглядела незакрашенной
 * по бокам.
 *
 * Вылет задан тем же приёмом и той же величиной, что уже используется у шапки
 * (--spec-head-bleed = 70 − 48): строка рисует на 22px ниже, но в потоке
 * занимает прежние 48px, поэтому геометрия стопки не меняется. Нижний паддинг
 * увеличен на ту же величину, чтобы содержимое осталось по центру видимой
 * полосы. Порядок отрисовки даёт нужный результат сам: строки не спозиционированы
 * и идут в DOM по порядку, поэтому каждая следующая закрашивает вылет предыдущей.
 *
 * Правило локально для таблицы сравнения. На PDP строки лежат внутри
 * анимируемого .specifications__reveal, и отрицательные отступы там выносят
 * содержимое за верхнюю границу контейнера — именно это вызывало «проскок»
 * раскрытия, см. COMPONENTS.md §13. Последняя строка не подкладывается: под ней
 * замыкающий хвост стопки.
 */
.specifications--compare .specifications__primary > .specifications__row:not(:last-child) {
  min-height: calc(var(--spec-row-height) + var(--spec-head-bleed));
  padding-bottom: calc(6px + var(--spec-head-bleed));
  margin-bottom: calc(-1 * var(--spec-head-bleed));
}

/*
 * В таблице сравнения шапка набрана тем же кеглем, что и строки (16px), в
 * отличие от PDP, где она 20px. Правило локально для страницы сравнения — на
 * product.html шапка не меняется.
 */
.specifications--compare .specifications__row--head .specifications__label,
.specifications--compare .specifications__row--head .specifications__value {
  font-size: 16px;
  letter-spacing: -0.08px;
}

/*
 * Строка с различающимися значениями. Класс проставляется только скриптом и
 * только по факту различия значений видимых товаров — вручную конкретным
 * строкам серый фон не назначается. Цвет — существующий --color-table-highlight,
 * тот же, что у шапки таблицы в макете.
 */
.specifications--compare .specifications__row--diff {
  background: var(--color-table-highlight);
}

/*
 * Кнопки под таблицей — 166.51 × 48 по макету, 16px Regular. Ширина и кегль
 * задаются здесь, потому что .btn--accent-strong в проекте растягивается на
 * всю ширину сайдбара PDP.
 */
.specifications--compare .specifications__export .btn {
  width: 167px;
  padding: 0 16px;
  font-size: 16px;
  font-weight: 400;
  cursor: pointer;
}

/*
 * Оранжевая кнопка (#ff9900) без фиксированной ширины — «Экспорт CSV» на
 * странице сравнения. Существующие .btn--compare / .btn--cart для этого не
 * подходят: у них жёсткая ширина 160px.
 */
.btn--accent {
  background-color: var(--color-orange);
}

.btn--accent:hover {
  background-color: #e88a00;
}

.btn--accent:active {
  background-color: #cc7a00;
}

.btn--accent:focus-visible {
  outline: 2px solid #003241;
  outline-offset: 2px;
}

/* ===== Form field (глобальный компонент)
   Капсула с обводкой 2px --color-border-muted — тот же приём, что у поля промокода
   и outline-кнопок. Подпись поля лежит внутри как placeholder (фрейм 506:2739).
   Оранжевая обводка = «поле требует внимания»: пустое обязательное поле (.is-error),
   плюс hover и фокус. Заполненное поле возвращается к обычной обводке и получает
   фон --color-bg-light, тем же фоном гасится автозаполнение браузера. ===== */
.field {
  min-width: 0;
}

/* Видимая подпись НАД полем. Нужна там, где так задано макетом (contacts.html,
   фрейм 544:788); на оформлении заказа подпись лежит внутри поля как placeholder
   и label остаётся `.visually-hidden`. Оба варианта — один и тот же компонент. */
.field__label {
  display: block;
  margin: 0 0 13px;
  font-size: 16px;
  font-weight: 400;
  line-height: 24px;
  color: var(--color-text-dark);
}

.field__input {
  width: 100%;
  height: 48px;
  padding: 0 17px;
  border: 2px solid var(--color-border-muted);
  border-radius: 999px;
  background: transparent;
  font-family: inherit;
  font-size: 16px;
  font-weight: 300;
  color: var(--color-text-dark);
  transition: border-color 0.2s ease;
}

/* Многострочный вариант того же поля: высота и радиус по макету (544:798),
   остальные состояния (hover / focus / filled / .is-error) наследуются. */
.field__input--textarea {
  display: block;
  height: 197px;
  padding: 14px 17px;
  border-radius: var(--radius-card);
  line-height: 24px;
  resize: vertical;
}

.field__input::placeholder {
  color: var(--color-text-dark);
  opacity: 1;
}

/* Обводка подсвечивается акцентным оранжевым при наведении и фокусе.
   Заполненное поле оранжевым НЕ подсвечивается: оранжевый в этом компоненте
   означает «поле требует внимания» — пустое обязательное поле (см. .is-error). */
.field__input:hover,
.field__input:focus {
  border-color: var(--color-orange);
}

/* Заполненное поле получает фон проекта — так введённое вручную значение
   выглядит так же, как подставленное автозаполнением браузера (см. ниже) */
.field__input:not(:placeholder-shown) {
  background: var(--color-bg-light);
}

/* Автозаполнение: Chrome рисует поверх поля собственный голубой фон.
   Перекрываем его внутренней тенью в цвет проекта — цвет текста и шрифт сохраняем.
   Два отдельных правила: браузер, не знающий один селектор, отбросил бы всё правило целиком. */
.field__input:-webkit-autofill,
.field__input:-webkit-autofill:hover,
.field__input:-webkit-autofill:focus,
.field__input:-webkit-autofill:active {
  box-shadow: 0 0 0 1000px var(--color-bg-light) inset;
  -webkit-box-shadow: 0 0 0 1000px var(--color-bg-light) inset;
  -webkit-text-fill-color: var(--color-text-dark);
  caret-color: var(--color-text-dark);
  font-family: inherit;
  font-size: 16px;
  font-weight: 300;
}

.field__input:autofill {
  box-shadow: 0 0 0 1000px var(--color-bg-light) inset;
  -webkit-text-fill-color: var(--color-text-dark);
  caret-color: var(--color-text-dark);
  font-family: inherit;
  font-size: 16px;
  font-weight: 300;
}

/* Индикатор фокуса — оранжевая обводка самого поля, без второй рамки поверх */
.field__input:focus,
.field__input:focus-visible {
  outline: none;
}

/* Error-state: меняется только цвет обводки, остальные параметры поля не трогаются.
   Ошибка возникает только у пустого поля, поэтому она отличима от заполненного:
   в покое пустое поле серое, а подсвеченное оранжевым — именно ошибочное. */
.field.is-error .field__input {
  border-color: var(--color-orange);
}

/* ===== Checkbox (глобальный компонент)
   Бокс 20×20, radius 3, галочка — экспорт из Figma (506:2815).
   Состояний в макете нет: hover добавлен по требованию — оранжевый #ff9900. ===== */
.checkbox__label {
  display: flex;
  width: fit-content;
  align-items: center;
  gap: 10px;
  cursor: pointer;
}

.checkbox__box {
  flex-shrink: 0;
  width: 20px;
  height: 20px;
  border: 1px solid var(--color-text-dark);
  border-radius: 3px;
  background-color: transparent;
  background-repeat: no-repeat;
  background-position: center;
  background-size: 20px 20px;
  transition: background-color 0.2s ease, border-color 0.2s ease;
}

.checkbox__text {
  font-size: 16px;
  font-weight: 300;
  line-height: 19px;
  color: var(--color-text-dark);
}

/* Мелкий вариант подписи — 14px/20 (contacts.html, узлы 739:937 и 739:943) */
.checkbox__text--sm {
  font-size: 14px;
  line-height: 20px;
}

/* Многострочная подпись: бокс выравнивается по первой строке, а не по центру блока */
.checkbox--top .checkbox__label {
  align-items: flex-start;
}

.checkbox__input:checked + .checkbox__label .checkbox__box {
  background-color: var(--color-text-dark);
  background-image: url("images/icon-check.svg");
}

.checkbox__label:hover .checkbox__box {
  border-color: var(--color-orange);
}

.checkbox__input:checked + .checkbox__label:hover .checkbox__box {
  border-color: var(--color-orange);
  background-color: var(--color-orange);
}

.checkbox__input:focus-visible + .checkbox__label .checkbox__box {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

/* ===== Оформление заказа — контакты (checkout-contact.html) ===== */
.checkout {
  padding-top: 41px;
}

/* 631 + 435 в контейнере 1280: 80 → 711 (форма), 925 → 1360 (обзор) по макету */
.checkout__inner {
  display: grid;
  grid-template-columns: 631px 435px;
  justify-content: space-between;
  align-items: start;
}

/* Верхний отступ выравнивает «Адрес доставки» с «Обзор» — оба заголовка на 260px */
.checkout__form {
  display: flex;
  flex-direction: column;
  padding-top: 27px;
}

.checkout__group {
  min-width: 0;
  margin: 0;
  padding: 0;
  border: none;
}

.checkout__group--extra {
  margin-top: 45px;
}

.checkout__legend {
  padding: 0;
  font-size: 24px;
  font-weight: 400;
  line-height: 28px;
  color: var(--color-text-dark);
}

.checkout__fields {
  margin-top: 31px;
  display: flex;
  flex-direction: column;
  gap: 30px;
}

.checkout__fields--extra {
  margin-top: 30px;
}

.field-row {
  display: grid;
  grid-template-columns: 302px 302px;
  column-gap: 24px;
}

.checkout__checkbox {
  margin-top: 30px;
}

.checkout__submit {
  width: 302px;
  margin: 45px auto 0;
}

/* ===== Обзор заказа — вариант блока итогов корзины ===== */
.cart-summary--checkout {
  width: 435px;
  padding: 27px 26px 32px 24px;
  background: var(--color-bg-light);
}

.cart-summary--checkout .cart-summary__rows {
  margin-top: 31px;
  gap: 15px;
}

/* Сообщение о промокоде занимает 31px-зазор макета — строки итогов не сдвигаются */
.cart-summary--checkout .cart-summary__promo-status:not([hidden]) + .cart-summary__rows {
  margin-top: 2px;
}

.cart-summary--checkout .cart-summary__divider {
  width: 344px;
  margin: 19px auto 0;
}

.cart-summary--checkout .cart-summary__row--total {
  margin-top: 29px;
}

/* Промокод — тот же компонент, что в корзине, отличаются только ширины строки */
.cart-summary__promo--checkout {
  width: 100%;
  margin: 45px 0 0;
  gap: 6px;
}

.cart-summary__promo-input--checkout {
  width: 212px;
  background: #ffffff;
}

.cart-summary__promo-submit--checkout {
  width: 167px;
}

/* ===== Мини-карточка товара в обзоре заказа ===== */
.order-mini-list {
  margin-top: 27px;
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.order-mini {
  display: grid;
  grid-template-columns: 109px minmax(0, 1fr) auto;
  column-gap: 12px;
  align-items: start;
}

.order-mini__media {
  width: 109px;
  height: 90px;
  border-radius: 20px;
  overflow: hidden;
  box-shadow: var(--shadow-soft);
}

.order-mini__image {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.order-mini__info {
  padding-top: 15px;
}

.order-mini__title {
  margin: 0;
  font-size: 14px;
  font-weight: 400;
  line-height: 16px;
  color: var(--color-text-dark);
}

.order-mini__price-row {
  margin-top: 17px;
  display: flex;
  align-items: center;
}

.order-mini__price {
  display: inline-flex;
  align-items: center;
  font-size: 16px;
  line-height: 28px;
  color: var(--color-text-dark);
}

.order-mini__currency {
  flex-shrink: 0;
}

.order-mini__badge {
  margin-left: 57px;
}

.order-mini__qty {
  padding-top: 9px;
  font-size: 16px;
  line-height: 19px;
  color: var(--color-text-dark);
  text-align: right;
}

/* ===== Order success (order-success.html, фрейм 502:1962) =====
 * Серая панель успешного оформления заказа. Фон --color-bg-light, отступ 36px
 * от плашки .page-title и центрирование по колонке — тот же приём, что у
 * .cart-empty, но размеры и начертания текста в макете другие (24/400 вместо
 * 32/400, 20/28 вместо 24/40), поэтому правила отдельные, а не переопределение.
 * Вертикальный ритм внутри панели по макету: 40 → 24 → 24 → 14 → 24 → 35. */
.order-success {
  background: var(--color-bg-light);
  margin-top: 36px;
  padding: 40px var(--container-padding) 35px;
}

.order-success__inner {
  max-width: var(--container-width);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
}

.order-success__lead {
  font-size: 24px;
  font-weight: 400;
  color: var(--color-text-black);
}

/* Утверждённый постоянный asset. 373x365 — натуральный размер файла и размер
   в макете одновременно, поэтому кадрирование и масштабирование не нужны. */
.order-success__image {
  width: 373px;
  height: 365px;
  margin-top: 24px;
}

.order-success__number {
  margin-top: 24px;
  font-size: 24px;
  font-weight: 400;
  color: var(--color-text-black);
}

.order-success__number-value {
  font-weight: 500;
}

.order-success__note {
  margin-top: 14px;
  max-width: 731px;
  font-size: 20px;
  font-weight: 400;
  line-height: 28px;
  color: var(--color-text-black);
}

/* Ширина кнопки из макета (166.51px) — тем же приёмом, что у .cart-empty. */
.order-success__inner .btn--orders {
  margin-top: 24px;
  min-width: 166.5px;
}

/* ===== Страница «Контакты» (contacts.html), фрейм 544:788 ===== */

/* --- Баннер: зеркальный вариант Hero/Secondary — фото справа, заголовок слева.
   Общая геометрия (1440×500, капсула 623px, контейнер 80px) — из базового
   компонента `.hero-banner`, здесь переопределяются только сторона и градиент. --- */
.hero-banner--contacts {
  background: var(--gradient-hero-secondary-reverse);
}

.hero-banner--contacts .hero-banner__media,
.hero-banner--validation .hero-banner__media,
.hero-banner--news .hero-banner__media {
  top: 62px;
  right: 0;
  left: auto;
  width: 623px;
  height: 384px;
  border-radius: 320.5px 0 0 320.5px;
}

/* Кроп фото повторяет трансформацию из макета (544:821): изображение увеличено
   сильнее, чем даёт object-fit: cover, поэтому размеры заданы в процентах.
   Тот же кадр и тот же файл — в баннере «Валидации» (525:1004), поэтому правило
   общее на два инстанса, а не продублировано. */
.hero-banner--contacts .hero-banner__image,
.hero-banner--validation .hero-banner__image {
  position: absolute;
  top: -4.93%;
  left: -28.92%;
  width: 130.25%;
  height: 118.93%;
  max-width: none;
  object-fit: cover;
}

.hero-banner--contacts .hero-banner__title {
  top: 250px;
  right: auto;
  left: var(--container-padding-content);
  line-height: 44px;
}

/* --- Двухколоночный блок: 628 + 543 в контейнере 1280
   (80 → 708 контакты, 817 → 1360 форма), зазор 109px --- */
.contacts {
  padding-top: 59px;
}

.contacts__inner {
  display: grid;
  grid-template-columns: 628px 543px;
  justify-content: space-between;
  align-items: start;
}

.contacts-card {
  background: var(--color-bg-light);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
}

/* --- Левая карточка: контактные данные ---
   Вся структура — данные, а не вёрстка: отдел = `[data-contact-department]`,
   строка = `[data-contact-row]`. Отделы и строки можно добавлять, удалять
   и заполнять, не трогая CSS. Пустое значение остаётся пустым `<dd>`
   (так в макете) — данные будут добавлены позже. */
.contacts-info {
  padding: 41px 15px;
}

.contacts-info__lead {
  max-width: 608px;
  font-size: 20px;
  font-weight: 400;
  line-height: 28px;
  color: var(--color-text-dark);
}

.contacts-info__title,
.contacts-info__department {
  margin: 0;
  font-size: 20px;
  font-weight: 500;
  line-height: 24px;
  color: var(--color-text-dark);
}

.contacts-info__title {
  margin-top: 24px;
}

.contacts-info__hours {
  margin-top: 24px;
  font-size: 16px;
  font-weight: 400;
  color: var(--color-text-dark);
}

.contacts-info__hours-lead {
  line-height: 28px;
}

.contacts-info__hours-row {
  margin-top: 11px;
  line-height: 24px;
}

.contacts-info__hours-day {
  font-weight: 500;
}

.contacts-info__group {
  margin-top: 22px;
}

/* Между отделами шаг больше, чем внутри списка строк */
.contacts-info__group + .contacts-info__group {
  margin-top: 24px;
}

.contacts-info__list {
  margin: 0;
}

.contacts-info__row {
  display: flex;
  gap: 8px;
  margin-top: 16px;
  font-size: 16px;
  line-height: 24px;
  color: var(--color-text-dark);
}

/* Первая строка отдела отстоит от его заголовка дальше, чем строки друг от друга */
.contacts-info__row:first-child {
  margin-top: 24px;
}

.contacts-info__label {
  font-weight: 500;
}

.contacts-info__value {
  margin: 0;
  font-weight: 400;
}

.contacts-info__value a {
  text-decoration: underline;
}

.contacts-info__value a:hover {
  color: var(--color-orange);
}

.contacts-info__value a:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

/* --- Правая карточка: форма обращения ---
   Ритм по макету: подпись (16/24) + 13px + поле 48px, шаг между группами 24px
   (в сумме шаг полей 109px). Поля 499px вместо 500: паддинг карточки 22px
   выравнивает поле и его подпись, которые в самом макете расходятся на 2px. */
.contacts-form {
  padding: 41px 22px 46px;
}

.contacts-form__title {
  margin: 0 0 20px;
  font-size: 20px;
  font-weight: 500;
  line-height: 24px;
  color: var(--color-text-dark);
}

.contacts-form__group {
  margin: 25px 0 0;
  padding: 0;
  border: none;
}

.contacts-form__legend {
  padding: 0;
  font-size: 20px;
  font-weight: 500;
  line-height: 24px;
  color: var(--color-text-dark);
}

.contacts-form__fields {
  display: flex;
  flex-direction: column;
  gap: 24px;
  margin-top: 24px;
}

/* Примечание про звёздочку — оно же пояснение к обязательным полям */
.contacts-form__note {
  margin-top: 38px;
  font-size: 16px;
  font-weight: 400;
  line-height: 24px;
  color: var(--color-text-dark);
}

.contacts-form__consent {
  margin-top: 16px;
}

.contacts-form__subscribe {
  margin-top: 33px;
}

.contacts-form__submit {
  display: flex;
  width: 190px;
  margin: 45px auto 0;
}

/* Поля лежат на серой карточке, поэтому заливка обратная к оформлению заказа:
   в макете (544:792–544:798) поле белое. Белым гасится и автозаполнение
   браузера — заполненное вручную и подставленное выглядят одинаково. */
.contacts-form .field__input,
.contacts-form .field__input:not(:placeholder-shown),
.contacts-form .dropdown--field .dropdown__trigger {
  background: #ffffff;
}

.contacts-form .field__input:-webkit-autofill,
.contacts-form .field__input:-webkit-autofill:hover,
.contacts-form .field__input:-webkit-autofill:focus,
.contacts-form .field__input:-webkit-autofill:active {
  box-shadow: 0 0 0 1000px #ffffff inset;
  -webkit-box-shadow: 0 0 0 1000px #ffffff inset;
}

.contacts-form .field__input:autofill {
  box-shadow: 0 0 0 1000px #ffffff inset;
}

/* ===== Text section / Accordion (глобальный компонент) =====
 *
 * Текстовая секция страницы. Два типа, различающиеся ТОЛЬКО наличием стрелки
 * справа от заголовка (признак берётся из макета, не из смысла текста):
 *
 *   1. Постоянно раскрытая — заголовка-кнопки нет, содержимое лежит прямо в
 *      .text-section__content. Ни JS, ни aria-expanded такой секции не нужны.
 *   2. Accordion — заголовок обёрнут в <button> с aria-expanded/aria-controls,
 *      содержимое лежит в .text-section__panel и по умолчанию свёрнуто.
 *
 * Структура Accordion:
 *
 *   .text-section[data-accordion]
 *     └ .section-container
 *         ├ .text-section__heading (h2)
 *         │   └ .text-section__toggle (button, кликабельна вся строка)
 *         │       ├ .text-section__title (inline — чтобы стрелка вставала
 *         │       │   сразу за последним словом даже при переносе заголовка)
 *         │       └ .text-section__icon
 *         └ .text-section__panel
 *             └ .text-section__panel-inner
 *                 └ .text-section__content
 *
 * Анимация — та же техника, что в компоненте Specifications: переходит одно
 * свойство grid-template-rows (0fr → 1fr), высоту никто не измеряет, поэтому
 * количество и объём секций могут меняться без правок CSS и JS.
 *
 * Секции независимы: состояние живёт на своём корне .text-section, общего
 * «активного» индекса нет — одновременно может быть раскрыто сколько угодно.
 */
.text-section {
  --text-section-pad: 41px;
  --text-section-pad-end: var(--text-section-pad);
  --text-section-reveal-duration: 0.5s;
  --text-section-reveal-easing: cubic-bezier(0.4, 0, 0.2, 1);
}

.text-section + .text-section {
  margin-top: 41px;
}

/* Полноширинная светлая полоса. Вертикальные паддинги в макете не
   унифицированы (43 / 39 / 59–60 / 41–48 / 41), поэтому заданы переменной и
   уточняются поблочно ниже — см. FRONTEND-SPEC, фрейм 518:727. */
.text-section--surface {
  background: var(--color-bg-light);
  padding-top: var(--text-section-pad);
  padding-bottom: var(--text-section-pad-end);
}

/* ── Заголовок ── */
.text-section__heading {
  margin: 0;
  font-size: 24px;
  font-weight: 400;
  line-height: 32px;
  color: var(--color-text-dark);
}

.text-section__toggle {
  display: block;
  width: 100%;
  margin: 0;
  padding: 0;
  border: 0;
  background: none;
  font: inherit;
  color: inherit;
  text-align: left;
  cursor: pointer;
  transition: color 0.2s ease;
}

.text-section__toggle:hover {
  color: var(--color-orange-active);
}

.text-section__toggle:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 4px;
}

/*
 * Стрелка. Исходный ассет — правый шеврон 10×20, поэтому бокс 13×26 с
 * поворотом на 90° даёт нужные в макете 26×13. Внешний span держит именно
 * итоговые 26×13, чтобы строка заголовка получила правильную ширину и высоту:
 * повёрнутая картинка сама по себе занимает в потоке доповоротный бокс.
 * Между текстом и стрелкой в макете нет зазора — видимый отступ даёт
 * собственный паддинг глифа внутри вьюбокса.
 */
.text-section__icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 26px;
  height: 13px;
  vertical-align: middle;
}

/* Вниз — свёрнуто, вверх — раскрыто (конвенция проекта: .dropdown__chevron,
   .specifications__toggle-icon). */
.text-section__icon img {
  flex: 0 0 auto;
  transform: rotate(90deg);
  transition: transform 0.2s ease;
}

.text-section.is-expanded .text-section__icon img {
  transform: rotate(-90deg);
}

/* ── Раскрываемая часть ── */
.text-section__panel {
  display: grid;
  grid-template-rows: 0fr;
  transition: grid-template-rows var(--text-section-reveal-duration) var(--text-section-reveal-easing);
}

.text-section.is-expanded .text-section__panel {
  grid-template-rows: 1fr;
}

.text-section__panel-inner {
  min-height: 0;
  overflow: hidden;
}

/* Отбивка от заголовка живёт ВНУТРИ обрезаемой области: вынеси её на .panel —
   и в свёрнутом состоянии под заголовком остался бы пустой зазор. */
.text-section__panel .text-section__content {
  padding-top: 24px;
}

.section-title + .text-section__content {
  margin-top: 24px;
}

@media (prefers-reduced-motion: reduce) {
  .text-section__panel {
    transition: none;
  }
}

/* ── Содержимое ── */
.text-section__content > * + * {
  margin-top: 24px;
}

/* Плотная группа строк (контакты сервисного центра, парные абзацы вводного
   блока) — шаг 16px вместо общих 24px. */
.text-section__group {
  display: flex;
  flex-direction: column;
  gap: 16px;
}

.text-section__group .text-section__text {
  line-height: 20px;
}

.text-section__text {
  font-size: 16px;
  font-weight: 400;
  line-height: 24px;
  color: var(--color-text-dark);
}

.text-section__text--sm {
  font-size: 14px;
  line-height: 20px;
}

.text-section__text--lg {
  font-size: 20px;
  line-height: 28px;
}

.text-section__text--xl {
  font-size: 24px;
  line-height: 32px;
}

.text-section__text--light {
  font-weight: 300;
}

.text-section__text--medium {
  font-weight: 500;
}

.text-section__text--semibold {
  font-weight: 600;
}

/* Подпись пары «подпись: значение» в контактных строках */
.text-section__label {
  font-weight: 500;
}

.text-section__inline-link {
  color: inherit;
  text-decoration: underline;
  transition: color 0.2s ease;
}

.text-section__inline-link:hover {
  color: var(--color-orange-active);
}

.text-section__inline-link:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

/* Ссылка во всю строку блока (ФГИС «АРШИН») */
.text-section__link {
  color: inherit;
  text-decoration: none;
  transition: color 0.2s ease;
}

.text-section__link:hover {
  color: var(--color-orange-active);
}

.text-section__link:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 4px;
}

/* ===== Страница «Поверка» (verification.html), фрейм 518:727 ===== */

/* --- Баннер: базовый Hero/Secondary (фото-капсула слева, текст справа,
   градиент со светлым краем слева). Переопределяются только собственные
   координаты и кегль этого инстанса, геометрия капсулы — из базы. --- */
.hero-banner--verification .hero-banner__media {
  top: 90px;
}

/* Кроп повторяет трансформацию узла 518:862: изображение шире капсулы
   (149.89%) и сдвинуто влево, object-fit такого кадра не даёт. */
.hero-banner--verification .hero-banner__image {
  position: absolute;
  top: 0.01%;
  left: -10.7%;
  width: 149.89%;
  height: 100%;
  max-width: none;
  object-fit: cover;
}

/* Заголовок в три строки, выключка вправо (в базовом компоненте он однострочный
   и nowrap, поэтому text-align там не задан). */
.hero-banner--verification .hero-banner__title {
  top: 153px;
  width: 717px;
  line-height: 44px;
  white-space: normal;
  text-align: right;
}

.hero-banner--verification .hero-banner__text {
  top: 314px;
  width: 543px;
  font-size: 20px;
}

/* --- Вводный блок: 59px от баннера, 64px до первой светлой полосы --- */
.hero-banner + .text-section {
  margin-top: 59px;
}

.text-section--intro + .text-section {
  margin-top: 64px;
}

/* --- Паддинги светлых полос по макету (см. комментарий у .text-section--surface) --- */
.text-section--importance {
  --text-section-pad: 43px;
}

.text-section--delivery {
  --text-section-pad: 39px;
}

.text-section--quantities {
  --text-section-pad-end: 48px;
}

/* --- Блок ФГИС «АРШИН» (518:854): текст по центру полосы --- */
.text-section--arshin {
  --text-section-pad: 59px;
  --text-section-pad-end: 60px;
}

.text-section--arshin .text-section__text {
  text-align: center;
}

/* ===== Страница «Валидация» (validation.html), фрейм 525:976 ===== */

/*
 * --- Баннер: зеркальная раскладка Hero/Secondary (капсула справа, текст слева),
 * но на ОРАНЖЕВОМ градиенте --gradient-hero-primary — подтверждено рендером
 * фрейма 525:1003. Ранее в документации этот инстанс числился бирюзовым
 * ("testo gradient 2"); запись оказалась неверной, макет — источник истины.
 * Геометрия капсулы и кроп фото — из правил `.hero-banner--contacts` выше,
 * здесь переопределяются только координаты и типографика этого инстанса.
 * ---
 */
.hero-banner--validation {
  background: var(--gradient-hero-primary);
}

.hero-banner--validation .hero-banner__media {
  top: 106px;
}

/* На оранжевом фоне текст тёмный, а не --color-footer-text, как в базе.
   Выключка влево: в базовом компоненте текст прижат к правому краю. */
.hero-banner--validation .hero-banner__eyebrow,
.hero-banner--validation .hero-banner__title,
.hero-banner--validation .hero-banner__text {
  right: auto;
  left: var(--container-padding-content);
  color: var(--color-text-dark);
  text-align: left;
}

/* Кегли эйбрау и подписи в этом инстансе «перевёрнуты» относительно базы
   (20/32 Light → 24/28 Regular и 24/28 → 16/24) — переопределяем поштучно. */
.hero-banner--validation .hero-banner__eyebrow {
  top: 140px;
  width: 475px;
  font-size: 24px;
  font-weight: 400;
  line-height: 28px;
}

.hero-banner--validation .hero-banner__title {
  top: 206px;
  width: 519px;
  line-height: 44px;
  white-space: normal;
}

.hero-banner--validation .hero-banner__text {
  top: 307px;
  width: 626px;
  font-size: 16px;
  line-height: 24px;
}

/* --- Отбивка заголовка постоянно раскрытой секции от содержимого.
   У Accordion за заголовком идёт .text-section__panel, поэтому правило
   их не затрагивает (там отбивку даёт padding-top внутри панели). --- */
.text-section__heading + .text-section__content {
  margin-top: 24px;
}

/* --- Группа абзацев основного кегля: шаг 16px, но интерлиньяж компонента
   (16/24) не понижается до 16/20, как в контактных строках. --- */
.text-section__group--body .text-section__text {
  line-height: 24px;
}

/* --- Серый блок: последний абзац идёт через 16px, а не через общие 24px --- */
.text-section--validation-order .text-section__group + .text-section__text {
  margin-top: 16px;
}

/* ===== Страница «Сервис и поддержка» (service-support.html), фрейм 528:1067 ===== */

/*
 * --- Баннер: базовая раскладка Hero/Secondary (капсула-фото слева, текст
 * справа), но на ОРАНЖЕВОМ градиенте — и зеркальном относительно «Валидации»:
 * жёлтый угол слева (подтверждено рендером узла 528:1122). Текст на оранжевом
 * тёмный, как на «Валидации». Геометрия капсулы, ширина контейнера и выключка
 * вправо — из базового `.hero-banner`, здесь только координаты, цвет и кегли
 * этого инстанса.
 * ---
 */
.hero-banner--service {
  background: var(--gradient-hero-primary-reverse);
}

.hero-banner--service .hero-banner__media {
  top: 68px;
}

/* Кадр в капсуле — обычный cover без собственной трансформации, но кроп по
   ширине снят с центра, а не от левого края, как в базовом правиле (сверено
   попиксельно с рендером узла 528:1126: центр даёт минимальное расхождение,
   левый край — в семь раз большее). */
.hero-banner--service .hero-banner__image {
  object-position: center;
}

.hero-banner--service .hero-banner__eyebrow,
.hero-banner--service .hero-banner__title,
.hero-banner--service .hero-banner__text {
  color: var(--color-text-dark);
}

/* Эйбрау и подпись «перевёрнуты» по кеглю относительно базы (20/32 Light →
   24/28 Light и 24/28 → 16/24). В макете правый край эйбрау стоит на 66px от
   края кадра против 80px у заголовка и подписи — по согласованию выровнен
   по контейнеру вместе с остальным текстом баннера. */
.hero-banner--service .hero-banner__eyebrow {
  top: 115px;
  width: max-content;
  font-size: 24px;
  line-height: 28px;
}

.hero-banner--service .hero-banner__title {
  top: 206px;
  line-height: 44px;
}

.hero-banner--service .hero-banner__text {
  top: 278px;
  width: 608px;
  font-size: 16px;
  line-height: 24px;
}

/* --- Серый блок «Сервисный центр» (528:1068) ---
   Заголовок этого блока (528:1128) — единственный на странице с авто-
   интерлиньяжем (28px против 32px у остальных), из-за чего весь блок садится
   на ровный шаг: 41px паддинги полосы, 16px между строками и 24px до
   заключительного абзаца. */
.text-section--service-center .text-section__heading {
  line-height: normal;
}

.text-section--service-center .text-section__heading + .text-section__content,
.text-section--service-center .text-section__content > * + * {
  margin-top: 16px;
}

/* Заключительный абзац блока (528:1079) — единственный, кто идёт через общие
   для компонента 24px. */
.text-section--service-center .text-section__group + .text-section__text--sm {
  margin-top: 24px;
}

/* --- Серый блок «Техническая поддержка» (528:1069) ---
   Тот же шаг 16px между строками, но контактные строки здесь идут с
   интерлиньяжем 28px (528:1091, 528:1087), а не 20px, принятых в
   `.text-section__group`. */
.text-section--support .text-section__content > * + * {
  margin-top: 16px;
}

.text-section--support .text-section__group .text-section__text {
  line-height: 28px;
}

/* Заключительный абзац блока (528:1108): 14px, но с интерлиньяжем базового
   кегля (24px), а не 20px модификатора --sm, и через общие 24px. */
.text-section--support .text-section__content > .text-section__text--sm {
  margin-top: 24px;
  line-height: 24px;
}

/* ===== Страница 404 (404.html, фрейм 508:2943) =====
 * Серая панель с роботом. Блок — .error-404, класс <body> — page-404.
 * Фон --color-bg-light, отступ 36px от плашки .page-title и центрирование по
 * колонке — тот же приём, что у .cart-empty и .order-success; собственные
 * здесь только вертикальные отступы, потому что панель фиксированной высоты
 * и шаги в макете другие.
 * Вертикальный ритм по макету: 46 → изображение 459 → 31 → кнопка 48 → 35,
 * в сумме 619px — высота прямоугольника 508:2954 (y 228 → 847). */
.error-404 {
  background: var(--color-bg-light);
  margin-top: 36px;
  padding: 46px var(--container-padding) 35px;
}

.error-404__inner {
  max-width: var(--container-width);
  margin: 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
}

/* Утверждённый постоянный asset с прозрачным фоном (заливка узла 508:2982,
   1536x1024). Рендер самого узла не годится: под картинкой у прямоугольника
   лежит белая заливка, и экспорт (1x и 2x) отдаёт непрозрачный белый фон,
   которого в макете нет — внутри бокса там #f4f3f1, проверено пиксельно.
   Бокс 583x459 и вложенная картинка 144.77% x 122.49% со сдвигом -18% / -14.59%
   повторяют режим Crop у заливки один в один: композиция, пропорции и кадр
   остаются ровно такими, как спроектировано. */
.error-404__media {
  position: relative;
  width: 583px;
  height: 459px;
  overflow: hidden;
}

.error-404__image {
  position: absolute;
  top: -14.59%;
  left: -18%;
  width: 144.77%;
  height: 122.49%;
  max-width: none;
}

/* Ширина кнопки из макета (190.297px) — тем же приёмом, что у .cart-empty
   и .order-success. */
.error-404__inner .btn--home {
  margin-top: 31px;
  min-width: 190.3px;
}

/* =====================================================================
   Страница «Новости» (news.html, фрейм 1:2370)
   ===================================================================== */

/*
 * --- Баннер: шестой инстанс Hero/Secondary. Раскладка «контактная»
 * (капсула справа, текст слева, текст тёмный), заливка — оранжевый
 * --gradient-hero-primary с жёлтым углом СПРАВА, то есть существующий токен
 * без зеркала. И заливка, и её направление проверены рендером фрейма:
 * по аналогии с соседними страницами они не выводятся.
 * Геометрия капсулы подключена дописыванием `--news` в общую группу
 * селекторов `--contacts / --validation` выше, правила не продублированы.
 * ---
 */
.hero-banner--news {
  background: var(--gradient-hero-primary);
}

.hero-banner--news .hero-banner__media {
  top: 58px;
}

/* Кроп фото у этого инстанса свой: в макете кадр сдвинут вправо
   (w 147.96% при left −35.33%), что для капсулы 623×384 и исходника 1942×809
   равнозначно object-position 73.7% — поэтому здесь достаточно сместить точку
   кадрирования, а не переопределять размеры картинки, как на контактах. */
.hero-banner--news .hero-banner__image {
  object-position: 73.7% center;
}

/* На оранжевом фоне текст тёмный и прижат влево — как на «Валидации». */
.hero-banner--news .hero-banner__eyebrow,
.hero-banner--news .hero-banner__title,
.hero-banner--news .hero-banner__text {
  right: auto;
  left: var(--container-padding-content);
  color: var(--color-text-dark);
  text-align: left;
}

.hero-banner--news .hero-banner__eyebrow {
  top: 120px;
  width: 651px;
  font-size: 24px;
  font-weight: 300;
  line-height: 28px;
}

/* Интерлиньяж 28px при кегле 36px — так задано в макете (высота текстового
   бокса 28px): строка одна, поэтому текст «перекрывает» бокс симметрично
   и садится ровно на позицию из Figma. */
.hero-banner--news .hero-banner__title {
  top: 197px;
  line-height: 28px;
}

.hero-banner--news .hero-banner__text {
  top: 288px;
  width: 535px;
  font-size: 16px;
  font-weight: 400;
  line-height: 24px;
}

/* --- Список новостей: 2 колонки по 628px в контейнере 1280 (зазор 24px),
   вертикальный шаг 35px. --- */
.news-list-section {
  padding-top: 47px;
}

.news-list {
  display: grid;
  grid-template-columns: repeat(2, 628px);
  gap: 35px 24px;
}

/*
 * --- News Card, горизонтальный вариант (628×298): тот же компонент, что
 * в сетке новостей на главной, другая раскладка — текстовая колонка слева,
 * фото справа во всю высоту. Колонки 377 + 251 повторяют макет: фото 250px
 * прижато к правому краю карточки (1px в макете — округление).
 * ---
 */
.news-card--wide {
  position: relative;
  display: grid;
  grid-template-columns: 377px 251px;
  width: 628px;
  /* min-height — по той же причине, что и у остальных карточек: более длинный
     анонс из админки должен помещаться, а не срезаться. */
  min-height: 298px;
  background: #ffffff;
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
}

.news-card--wide .news-card__media {
  height: 100%;
  border-radius: 0 var(--radius-card) var(--radius-card) 0;
  box-shadow: none;
}

.news-card__body {
  display: flex;
  flex-direction: column;
  min-width: 0;
  padding: 36px 39px 17px 31px;
}

.news-card--wide .news-card__title {
  margin: 0;
  font-size: 20px;
  font-weight: 400;
  line-height: 23px;
}

/* Анонс занимает всю свободную высоту колонки. Обрезки по строкам нет: более
   длинный текст из админки увеличивает высоту карточки, а не прячется. */
.news-card--wide .news-card__text {
  flex: 1;
  min-height: 0;
  margin: 10px 0 0;
}

/* Дата и CTA стоят по краям текстовой колонки — ровно так же, как в макете
   (дата от левого края колонки, «Читать далее» до правого). */
.news-card__meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  margin-top: 28px;
}

.news-card__date {
  position: relative;
  font-size: 16px;
  font-weight: 500;
  line-height: 24px;
  color: var(--color-icon-account);
}

.news-card--wide .news-card__link {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
  line-height: 24px;
  color: var(--color-text-dark);
  outline: none;
}

/* Вся карточка кликабельна: псевдоэлемент единственной ссылки накрывает
   карточку целиком. Второй ссылки в разметке нет, поэтому вложенных <a>
   не возникает, а с клавиатуры фокус один и ведёт на ту же новость. */
.news-card--wide .news-card__link::after {
  content: "";
  position: absolute;
  inset: 0;
  border-radius: var(--radius-card);
}

/* Hover CTA — #ff9900 (--color-orange). Вертикальная карточка на главной
   сохраняет свой прежний #ff8300: правило намеренно ограничено `--wide`. */
.news-card--wide .news-card__link:hover,
.news-card--wide .news-card__link:focus-visible {
  color: var(--color-orange);
}

/* Индикатор фокуса рисуется на перекрывающем псевдоэлементе, то есть
   обводится вся карточка, а не одна строка текста. */
.news-card--wide .news-card__link:focus-visible::after {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

/* --- Нижний ряд страницы: Testo Smart App (628×325) и подписка (628×239).
   Блоки выровнены по верху, а не растянуты: в макете у них разная высота,
   и блок подписки дополнительно растёт вниз при раскрытии формы. --- */
.news-extra {
  padding-top: 60px;
}

.news-extra__inner {
  display: grid;
  grid-template-columns: repeat(2, 628px);
  gap: 24px;
  align-items: start;
}

/* ===== Testo Smart App ===== */
.smart-app {
  position: relative;
  height: 325px;
  padding: 22px 31px 25px;
  overflow: hidden;
  background: var(--color-bg-light);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
}

/* Декоративная часть — оранжевая капсула-подложка и фото телефонов поверх неё.
   Обе картинки из макета, позиционируются абсолютно и в поток не вмешиваются. */
.smart-app__media {
  position: absolute;
  inset: 0;
  pointer-events: none;
}

.smart-app__capsule {
  position: absolute;
  top: 24px;
  left: 411px;
  width: 217px;
  height: 278px;
  border-radius: 140px 0 0 140px;
}

/* Бокс 118×123 с вложенной картинкой 138.14% × 132.52% и сдвигом −18.64% /
   −17.07% повторяет режим Crop заливки из макета: кадр крупнее, чем даёт
   object-fit: cover, поэтому размеры заданы в процентах (тот же приём,
   что у .hero-banner__image на контактах). */
.smart-app__phones {
  position: absolute;
  top: 101px;
  left: 467px;
  width: 118px;
  height: 123px;
  overflow: hidden;
}

.smart-app__phones-image {
  position: absolute;
  top: -17.07%;
  left: -18.64%;
  width: 138.14%;
  height: 132.52%;
  max-width: none;
}

.smart-app__logo {
  display: block;
  position: relative;
  width: 59px;
  height: 60px;
  overflow: hidden;
}

.smart-app__logo-image {
  position: absolute;
  top: -3.33%;
  left: 0;
  width: 108.47%;
  height: 106.67%;
  max-width: none;
}

.smart-app__eyebrow,
.smart-app__title,
.smart-app__text {
  position: relative;
  color: var(--color-text-dark);
}

.smart-app__eyebrow {
  margin: 14px 0 0;
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
}

.smart-app__title {
  margin: 8px 0 0;
  font-size: 20px;
  font-weight: 400;
  line-height: 28px;
}

.smart-app__text {
  width: 374px;
  margin: 12px 0 0;
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
}

.smart-app__stores {
  position: relative;
  display: flex;
  gap: 15px;
  margin-top: 18px;
}

/* --- Бейджи магазинов. В макете оба лежат ОДНИМ растровым спрайтом,
   обрезанным двумя разными кропами; файл сохранён без изменений, каждый бейдж
   вырезается тем же приёмом «бокс + процентная картинка», что и фото выше. --- */
.store-badge {
  display: block;
  position: relative;
  height: 38px;
  overflow: hidden;
}

.store-badge--google-play {
  width: 124px;
}

.store-badge--app-store {
  width: 118px;
}

.store-badge:focus-visible {
  outline: 2px solid var(--color-text-dark);
  outline-offset: 2px;
}

.store-badge__image {
  position: absolute;
  top: -76.81%;
  height: 261.51%;
  max-width: none;
}

.store-badge--google-play .store-badge__image {
  left: -5.65%;
  width: 213.71%;
}

.store-badge--app-store .store-badge__image {
  left: -118.64%;
  width: 224.58%;
}

/* ===== Подписка на рассылку =====
   Высота 239px — из макета, но задана как min-height: при раскрытии inline-формы
   блок растёт вниз, поэтому содержимое выложено потоком, а не абсолютно.
   Соседний блок при этом не перекрывается: оба лежат в grid-ряду. */
.news-subscribe {
  min-height: 239px;
  padding: 15px 31px 20px;
  background: var(--color-bg-light);
  border-radius: var(--radius-card);
  box-shadow: var(--shadow-soft);
}

.news-subscribe__icon {
  display: block;
  width: 24px;
  height: 24px;
}

.news-subscribe__title {
  margin: 25px 0 0;
  font-size: 20px;
  font-weight: 400;
  line-height: 28px;
  color: var(--color-text-dark);
}

.news-subscribe__text {
  width: 546px;
  margin: 22px 0 0;
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
  color: var(--color-text-dark);
}

/* Кнопка 302×48 по центру блока — Button/Large (.btn--catalog) без изменений,
   задаётся только ширина из макета. `display: flex` нужен, чтобы сработало
   центрирование через margin: auto (тот же приём, что у .news__more). */
.news-subscribe__button {
  display: flex;
  width: 302px;
  margin: 37px auto 0;
}

/*
 * --- Inline-форма подписки. В макете нарисовано только закрытое состояние,
 * поэтому здесь ровно то, что требует поведение: форма лежит в потоке НАД
 * кнопкой и скрыта атрибутом `hidden` (display не переопределяется — иначе
 * `hidden` перестал бы работать). Поле — общий .field/.field__input без
 * единого собственного правила: обводка, радиус, hover/focus, filled
 * и error-state (#ff9900) наследуются со страницы контактов.
 * ---
 */
.news-subscribe__form {
  margin-top: 37px;
}

.news-subscribe__form .field {
  width: 302px;
  margin: 0 auto;
}

/* Когда форма раскрыта, она забирает себе верхний отступ кнопки, и поле встаёт
   ровно на её место (y171 из макета), а сама кнопка отбивается меньшим шагом. */
.news-subscribe__form:not([hidden]) + .news-subscribe__button {
  margin-top: 24px;
}

/* ===== Breadcrumbs (хлебные крошки) =====
 *
 * Своего макета у компонента нет (docs/COMPONENTS.md §15), поэтому ничего
 * нового не рисуется — всё взято из уже принятых в проекте значений:
 * кегль 14/20 Regular (как у `.category-card__text`), фирменный тёмный
 * --color-text-dark, подчёркивание ссылки в hover/focus (как у `.legal-note a`),
 * обводка фокуса 2px с отступом 2px (общий приём проекта), выключка по левой
 * границе контейнера --container-padding-content — той же, что у `.page-title`
 * и `.section-container`. Разделитель — текстовый «›» в разметке.
 *
 * Этап desktop-only: отдельных правил для планшета и телефона здесь нет.
 */
.breadcrumbs {
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
}

/* Сброс у `ol` свой: общее правило в начале файла обнуляет только `ul`. */
.breadcrumbs__list {
  display: flex;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.breadcrumbs__item {
  display: flex;
  align-items: center;
  gap: 8px;
}

.breadcrumbs__link:hover,
.breadcrumbs__link:focus-visible {
  text-decoration: underline;
}

/* Цвет обводки берётся от текста звена, поэтому одно правило работает и на
   светлом фоне (там это --color-text-dark, как у остальных фокусов проекта),
   и на баннере, где текст светлый. */
.breadcrumbs__link:focus-visible {
  outline: 2px solid currentColor;
  outline-offset: 2px;
}

/* --- Вариант на обычном фоне страницы: сразу после шапки, перед серой полосой
   заголовка или перед содержимым. Отбивка 14.24px — та же, с которой серая
   полоса `.page-title` отбивалась от шапки, поэтому шаг страницы не меняется. --- */
.breadcrumbs--page {
  max-width: var(--container-width);
  margin: 14.24px auto 0;
  padding: 0 var(--container-padding-content);
  color: var(--color-text-dark);
}

/* --- Вариант внутри Hero/Banner: верхняя часть баннера, та же левая граница.
   Слои баннера позиционируются абсолютно, крошки — тоже, поэтому его геометрия
   не меняется. Отбивка от верхнего края — базовый шаг --container-padding;
   капсула фото начинается не выше 55px, пересечения нет. --- */
.breadcrumbs--banner {
  position: absolute;
  top: var(--container-padding);
  right: 0;
  left: 0;
  z-index: 2;
  max-width: var(--container-width);
  margin: 0 auto;
  padding: 0 var(--container-padding-content);
  color: var(--color-footer-text);
}

/* Баннеры на оранжевом градиенте: текст тёмный — ровно тот же цвет, что у
   заголовка и подписи этих баннеров (`--news`, `--validation`, `--service`). */
.page-news .breadcrumbs--banner,
.page-validation .breadcrumbs--banner,
.page-service-support .breadcrumbs--banner {
  color: var(--color-text-dark);
}

/* Обёртка крошек на страницах услуг: их баннер перенесён готовой разметкой
   строкой (`src/content/info-pages`), вставить React-узел внутрь неё нельзя.
   Обёртка стоит перед баннером, но места не занимает (height: 0), поэтому
   дополнительной полосы между шапкой и баннером не появляется, а крошки
   ложатся в верхнюю часть баннера — ровно как у остальных баннеров. */
.hero-banner-breadcrumbs {
  position: relative;
  z-index: 2;
  height: 0;
}

/* =====================================================================
   АДАПТИВ — планшет (768–1199px) и телефон (<768px)
   =====================================================================
 *
 * Desktop (>=1200px) — утверждённый эталон, и ни одно правило этого раздела
 * до него не доходит: все блоки ограничены `max-width: 1199px` либо
 * `max-width: 767px`. Два этих порога уже использовались в файле (офкэнвас
 * шапки, компонент Specifications) — новых breakpoints раздел не вводит.
 *
 * Принцип раздела: правится общий компонент, а не страница. Поэтому сетка
 * товаров, карточка товара, плитка категории, баннер, таблица характеристик и
 * контейнеры перестраиваются по одному разу и действуют на всех страницах,
 * где используются.
 *
 * Порядок блоков повторяет порядок компонентов в файле.
 */

/* ---------- Основание: боковые поля контейнеров ----------
 * Единственный системный источник ширины контента — два токена полей. Все
 * контейнеры проекта (`.container`, `.section-container`, `.page-title__text`,
 * `.breadcrumbs`, `.carousel-wide`, баннеры) считают отступы от них, поэтому
 * одно изменение здесь расширяет контентную полосу на всех страницах сразу.
 * 80px рассчитаны на окно 1440px; на планшете и телефоне они съедали до 43%
 * ширины, и сетки ломались намного раньше, чем этого требует содержимое. */
@media (max-width: 1199px) {
  :root {
    --container-padding-content: 40px;
  }
}

@media (max-width: 767px) {
  :root {
    --container-padding: 16px;
    --container-padding-content: 16px;
  }
}

/* ---------- Шапка: touch-навигация ниже 1200px ----------
 * Офкэнвас-панель собрана выше (блок «Tablet (<=1199px)»). Здесь добавляется
 * то, чего в ней не было: раскрытие разделов по тапу. До этой правки ниже
 * 1200px `.header__dropdown` оставался `display: none` — на планшете и
 * телефоне «Услуги», «Компания» и все подкатегории «Продуктов» были
 * недоступны вообще.
 *
 * Разметка остаётся одна на оба режима, данные меню — те же
 * (`productsMenu`, `SERVICES_MENU`, `COMPANY_MENU`): второй список категорий
 * не заводится. Отличие мобильного режима только в том, что раскрытием
 * управляет отдельная кнопка `.header__nav-toggle` /
 * `.header__dropdown-toggle`, а не наведение курсора.
 *
 * Имя раздела при этом остаётся ссылкой на сам раздел (задача §8): «Приборы
 * для измерения давления» ведёт на `/catalog/pressure`, а подкатегории
 * открывает кнопка рядом. Выбирать подкатегорию не обязательно. */

/* Органы раскрытия — только для touch-режима: на desktop раскрытием управляет
   наведение и фокус, и кнопки в разметке не участвуют (из a11y-дерева их
   убирает `display: none`). Правило стоит ДО медиа-запроса, который их
   включает: иначе оно перебивало бы его на всех ширинах. */
.header__nav-toggle,
.header__dropdown-toggle {
  display: none;
}

@media (max-width: 1199px) {
  /* Бёрджер лежит выше панели: иначе открытая панель накрывает его своим
     белым фоном и закрыть меню крестиком нельзя (панель — z-index 25). */
  .header__burger {
    position: relative;
    z-index: 26;
  }

  /* Три уровня подкатегорий с длинными названиями в 360px складываются в
     слишком узкую колонку. Панель шире, но по-прежнему не на весь экран —
     фон остаётся видимым, по нему меню закрывается. */
  .header__nav {
    width: min(420px, 90vw);
  }

  /* Строка раздела: имя занимает всю доступную ширину, кнопка раскрытия
     стоит справа, вложенный список переносится на следующую строку. */
  .header__nav-item,
  .header__dropdown-item {
    display: flex;
    flex-wrap: wrap;
    align-items: center;
    width: 100%;
  }

  .header__nav-link,
  .header__dropdown-link {
    flex: 1 1 auto;
    min-width: 0;
    /* Длинные названия категорий переносятся, а не растягивают панель. */
    white-space: normal;
    overflow-wrap: break-word;
  }

  /* Шеврон внутри ссылки — desktop-элемент: там раскрытием управляет сам
     пункт. На touch-ширинах у ссылок рядом стоит кнопка раскрытия, и второй
     шеврон в строке был бы лишним. Правило касается только ссылок: у «Услуг»
     и «Компании» пункт — кнопка, она же и есть орган раскрытия, поэтому свой
     шеврон сохраняет. */
  .header__nav-item > a.header__nav-link > .header__nav-chevron,
  .header__dropdown-link > .header__dropdown-chevron {
    display: none;
  }

  /* Пункт-кнопка («Услуги», «Компания») — тот же индикатор состояния, что у
     отдельных кнопок раскрытия. */
  .header__nav-link--trigger[aria-expanded="true"] .header__nav-chevron {
    transform: rotate(-90deg);
  }

  /* Отдельный орган раскрытия. 44x44 — комфортная touch-цель. */
  .header__nav-toggle,
  .header__dropdown-toggle {
    display: flex;
    align-items: center;
    justify-content: center;
    flex: 0 0 auto;
    width: 44px;
    height: 44px;
    margin: 0;
    padding: 0;
    border: none;
    background: none;
    color: inherit;
  }

  .header__nav-toggle:focus-visible,
  .header__dropdown-toggle:focus-visible {
    outline: 2px solid var(--color-icon-dark);
    outline-offset: -2px;
    border-radius: 8px;
  }

  /* Свёрнуто — шеврон вниз, раскрыто — вверх: та же конвенция, что у
     desktop-навигации и у `.dropdown__chevron`. */
  .header__nav-toggle .header__nav-chevron,
  .header__dropdown-toggle .header__dropdown-chevron {
    display: block;
    transform: rotate(90deg);
    transition: transform 0.2s ease;
  }

  .header__nav-toggle[aria-expanded="true"] .header__nav-chevron,
  .header__dropdown-toggle[aria-expanded="true"] .header__dropdown-chevron {
    transform: rotate(-90deg);
  }

  /* Панель раздела — не всплывающее окно, а вложенный список в потоке.
     `order` ставит её под строку раздела независимо от места кнопки. */
  .header__dropdown {
    position: static;
    top: auto;
    left: auto;
    flex: 1 0 100%;
    order: 10;
    padding-top: 4px;
  }

  .header__nav-item.is-expanded > .header__dropdown {
    display: block;
  }

  .header__dropdown > .header__dropdown-list {
    position: static;
  }

  /* Внутри офкэнваса это уже не всплывающая панель: ни своей ширины, ни
     белого фона, ни тени ей не нужно — фон и скругление даёт сама панель. */
  .header__dropdown-list {
    width: auto;
    padding: 0 0 0 12px;
    background: none;
    border-radius: 0;
    box-shadow: none;
  }

  .header__dropdown-link {
    padding: 10px 8px;
  }

  /* Вложенный список подкатегорий — тем же приёмом, ещё на уровень глубже. */
  .header__submenu {
    position: static;
    top: auto;
    right: auto;
    bottom: auto;
    left: auto;
    display: none;
    flex: 1 0 100%;
    order: 10;
    padding-left: 0;
    visibility: visible;
  }

  .header__dropdown-item--parent.is-expanded > .header__submenu {
    display: block;
  }

  .header__submenu > .header__dropdown-list {
    width: auto;
    min-height: 0;
  }

  /* Поиск и кнопки в офкэнвасе не должны выходить за панель. */
  .header__search-input {
    min-width: 0;
  }
}

/* ---------- Плашка заголовка ----------
 * Утверждённая полоса фиксированной высоты (70px) рассчитана на контентную
 * полосу 1280px. Самое длинное название товара в базе — 162 символа: на узком
 * экране оно не помещается в 70px ни при одном читаемом кегле, а обрезать его
 * нельзя (задача §17). Поэтому ниже 1200px высота становится минимальной, а не
 * фиксированной, и полоса растёт под заголовок.
 *
 * Auto-fit компонента `PageTitleBar` при этом сохраняется и продолжает
 * работать на desktop, где полоса фиксирована: там кегль по-прежнему
 * подбирается под 70px. Ниже 1200px кегль задан здесь обычным `font-size` —
 * переменную `--page-title-fs` эти правила не читают, поэтому серверная
 * разметка и клиентский пересчёт на мобильную верстку не влияют и скачка
 * кегля после гидратации нет. */
@media (max-width: 1199px) {
  .page-title {
    height: auto;
    min-height: 70px;
    padding: 12px 0;
  }

  .page-title__text {
    font-size: 28px;
  }
}

@media (max-width: 767px) {
  .page-title {
    min-height: 56px;
    padding: 10px 0;
  }

  .page-title__text {
    font-size: 24px;
  }
}

/* ---------- Крупные заголовки секций ----------
 * Утверждённые 32px рассчитаны на строку в 1280px. На 375px заголовок секции
 * занимал до четырёх строк и перебивал содержимое. Шаг один на весь проект —
 * `.section-title` и `.section-tagline` стоят на всех страницах, поэтому
 * страничных правил не нужно. 26px остаётся заметно крупнее основного текста
 * (16px) — читаемость не страдает. Начертание, цвет и выключка не меняются. */
@media (max-width: 767px) {
  .section-title,
  .section-tagline {
    font-size: 26px;
  }

  .section-subtitle {
    font-size: 18px;
  }
}

/* ---------- Хлебные крошки ----------
 * Логика крошек не меняется, промежуточные уровни не удаляются (задача §18) —
 * меняется только раскладка: строка переносится вместо выхода за viewport. */
@media (max-width: 1199px) {
  .breadcrumbs__list {
    flex-wrap: wrap;
    row-gap: 4px;
  }

  .breadcrumbs__item {
    /* Длинное название товара в последнем звене переносится внутри звена. */
    min-width: 0;
    flex-wrap: wrap;
  }

  .breadcrumbs__current,
  .breadcrumbs__link,
  .breadcrumbs__text {
    overflow-wrap: break-word;
    min-width: 0;
  }

  /* Баннер ниже 1200px выстроен в поток, и абсолютные крошки поверх него
     легли бы на фотографию. В потоке они встают над содержимым баннера —
     тем же левым полем контейнера. */
  .breadcrumbs--banner {
    position: static;
    top: auto;
    right: auto;
    left: auto;
    padding-top: var(--container-padding);
  }

  /* Обёртка крошек на страницах услуг: `height: 0` рассчитана на абсолютные
     крошки поверх баннера. В потоке обёртке нужна своя высота, а крошки
     оказываются над баннером на светлом фоне страницы — отсюда тёмный текст
     (на всех трёх баннерах услуг он иначе сливался бы с фоном страницы). */
  .hero-banner-breadcrumbs {
    height: auto;
  }

  .hero-banner-breadcrumbs .breadcrumbs--banner {
    color: var(--color-text-dark);
  }
}

/* ---------- Hero-слайдер главной ----------
 * Desktop-раскладка слайда целиком абсолютная: фото 623x389 прижато вправо,
 * текстовые слои спозиционированы поштучно от левого края (left: 80px) с
 * собственными `top` и `width` на каждый из четырёх вариантов слайда. Ниже
 * 1200px эта раскладка нерабочая по построению, поэтому слайд переводится в
 * поток: фото сверху, под ним текст и CTA — ровно в порядке DOM, то есть
 * порядок блоков слайда не меняется.
 *
 * Сбросы ширины заданы через `.hero-slide .hero-slide__*` (та же
 * специфичность 0-2-0, что у вариантных правил `.hero-slide--N ...`, но ниже
 * в файле): иначе `width: 652px` варианта продолжал бы растягивать страницу. */
@media (max-width: 1199px) {
  .hero-slider {
    height: auto;
  }

  .hero-slide {
    height: auto;
  }

  /* Капсула фото остаётся прижатой вправо, как в макете, и сохраняет свои
     пропорции и скругление. `position: relative`, а не `static`: кадрирование
     некоторых инстансов задано абсолютной картинкой внутри капсулы. */
  .hero-slide .hero-slide__media {
    position: relative;
    top: auto;
    right: auto;
    left: auto;
    width: 100%;
    max-width: 560px;
    height: auto;
    margin-left: auto;
    margin-right: 0;
    aspect-ratio: 623 / 389;
  }

  .hero-slide__inner {
    height: auto;
  }

  .hero-slide__content {
    display: flex;
    flex-direction: column;
    align-items: flex-start;
    gap: 16px;
    padding: 24px var(--container-padding-content) 40px;
  }

  .hero-slide .hero-slide__eyebrow,
  .hero-slide .hero-slide__title,
  .hero-slide .hero-slide__text,
  .hero-slide .hero-slide__models {
    position: static;
    top: auto;
    left: auto;
    width: auto;
    max-width: none;
    overflow-wrap: break-word;
  }

  .btn--hero {
    position: static;
    top: auto;
    left: auto;
    width: 100%;
    max-width: 283px;
  }

  /* Слой с дисклеймером и индикаторами перекрывал слайд целиком; в потоке он
     становится подвалом слайдера. */
  .hero-slider__inner {
    position: static;
    inset: auto;
    padding: 0 var(--container-padding-content) 24px;
    pointer-events: auto;
  }

  .hero-slider__disclaimer {
    position: static;
    top: auto;
    left: auto;
    width: auto;
  }

  .hero-slider__nav {
    position: static;
    left: auto;
    bottom: auto;
    width: 289px;
    max-width: 100%;
    height: auto;
    margin-top: 16px;
    padding: 18px 16px;
    align-items: center;
  }
}

@media (max-width: 767px) {
  .hero-slide .hero-slide__title {
    font-size: 28px;
  }

  .hero-slide .hero-slide__text,
  .hero-slide .hero-slide__models {
    font-size: 16px;
    line-height: 24px;
  }
}

/* ---------- Hero-баннер (каталог, услуги, контакты, новости) ----------
 * Та же природа, что у слайдера: фото-капсула и три текстовых слоя
 * спозиционированы абсолютно, у каждого инстанса свои `top` и `width`, а у
 * `.hero-banner__inner` стоял `min-width: 760px` — прямой источник
 * горизонтального переполнения на телефоне. Ниже 1200px баннер — поток.
 *
 * Сторона, с которой стоит капсула, сохраняется: она несёт композицию
 * инстанса и согласована со скруглением капсулы. Кадрирование и скругления
 * вариантов не переопределяются. */
@media (max-width: 1199px) {
  .hero-banner {
    height: auto;
  }

  .hero-banner__inner {
    min-width: 0;
    height: auto;
    padding-bottom: 40px;
  }

  .hero-banner .hero-banner__media {
    position: relative;
    top: auto;
    right: auto;
    left: auto;
    width: 100%;
    max-width: 560px;
    height: auto;
    aspect-ratio: 623 / 389;
  }

  /* Базовый инстанс и «Поверка» / «Сервис» — капсула слева. */
  .hero-banner .hero-banner__media {
    margin-right: auto;
    margin-left: 0;
  }

  /* Контакты, «Валидация», новости — капсула справа. */
  .hero-banner--contacts .hero-banner__media,
  .hero-banner--validation .hero-banner__media,
  .hero-banner--news .hero-banner__media {
    margin-left: auto;
    margin-right: 0;
  }

  .hero-banner .hero-banner__eyebrow,
  .hero-banner .hero-banner__title,
  .hero-banner .hero-banner__text {
    position: static;
    top: auto;
    right: auto;
    left: auto;
    width: auto;
    max-width: none;
    margin-top: 16px;
    padding: 0 var(--container-padding-content);
    /* Базовый заголовок однострочный (`nowrap`) — на узком экране он должен
       переноситься. */
    white-space: normal;
    text-align: left;
    overflow-wrap: break-word;
  }

  .hero-banner .hero-banner__eyebrow {
    margin-top: 24px;
  }
}

@media (max-width: 767px) {
  .hero-banner .hero-banner__title {
    font-size: 28px;
    line-height: 36px;
  }

  .hero-banner .hero-banner__eyebrow {
    font-size: 18px;
    line-height: 26px;
  }

  .hero-banner .hero-banner__text {
    font-size: 16px;
    line-height: 24px;
  }
}

/* ---------- Сетка товаров и карточка товара ----------
 * Утверждённая сетка — четыре колонки ровно по 302px (ширина карточки). Ниже
 * 1200px колонки считаются от фактической ширины карточки, а не от их числа:
 * `auto-fit` + `minmax` сам решает, сколько карточек встаёт в ряд, поэтому
 * отдельных правил на 375 / 768 / 1024 не нужно и промежуточные ширины не
 * ломаются. `min(302px, 100%)` — защита на случай окна уже самой карточки.
 *
 * Карточка в сетке перестаёт быть фиксированной 302px и занимает колонку
 * целиком: на телефоне она разворачивается на всю ширину контента, а не
 * сжимается до desktop-габарита (задача §14). Карточка в карусели остаётся
 * 302px — там ширина задаёт шаг прокрутки, и она помещается уже с 375px.
 *
 * Внутри карточки ничего не обрезается: ключевые характеристики и название
 * выводятся целиком, карточка растёт по высоте (это уже заложено в
 * `min-height` и отсутствии `line-clamp` в базовых правилах). */
@media (max-width: 1199px) {
  /* Нижняя граница колонки — 280px, а не утверждённые 302px: при 302px на
     1024px в ряд вставали только две колонки по 460px (на 10px не хватало до
     трёх), и карточка растягивалась вдвое против макета. С 280px на 1024px
     встают три колонки по ~298px — практически desktop-габарит карточки, а на
     375px по-прежнему одна во всю ширину контента. */
  .product-grid,
  .product-accessories .product-grid,
  .catalog-products .product-grid {
    grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
    justify-content: start;
  }

  .product-grid > .product-card {
    width: auto;
  }
}

/* ---------- Плитки категорий (витрина `/catalog`, «Рекомендуем посмотреть») ----------
 * Утверждённая сетка — три равные колонки. Ниже 1200px три колонки на телефоне
 * давали полосы по ~100px; колонки считаются от реальной ширины плитки
 * (задача §12). Состав плитки не меняется: фото, плашка с названием и
 * короткий текст `formatCategoryTileText` остаются как есть, без `line-clamp`,
 * скрывающего overflow и `nth-child`-правил. */
@media (max-width: 1199px) {
  .category-tile-grid {
    grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  }
}

@media (max-width: 767px) {
  /* Отбивка «Рекомендуем посмотреть» (76px) рассчитана на desktop-ритм. */
  .category-recommend .category-tile-grid {
    margin-top: 32px;
  }

  .category-tile__media {
    height: 240px;
  }
}

/* ---------- Карточки категорий главной ----------
 * Карточка — «текст слева + фото справа» с текстовой колонкой ровно 363px.
 * Ниже 1200px колонка становится гибкой, а фото занимает долю карточки;
 * на телефоне, где на две колонки ширины уже нет, карточка складывается
 * вертикально в порядке DOM: текст, затем фото. */
@media (max-width: 1199px) {
  .category-grid {
    grid-template-columns: repeat(auto-fit, minmax(min(420px, 100%), 1fr));
  }

  .category-card__content {
    flex: 1 1 auto;
    padding: 28px 24px;
  }

  .category-card__media {
    flex: 0 0 38%;
  }
}

@media (max-width: 767px) {
  .category-card {
    flex-direction: column;
    min-height: 0;
  }

  .category-card__content {
    flex: 1 1 auto;
    gap: 20px;
  }

  .category-card__title {
    margin-bottom: 0;
  }

  .category-card__cta {
    margin-top: 0;
  }

  .category-card__media {
    flex: 0 0 auto;
    height: 200px;
    order: 2;
  }
}

/* ---------- Сетки новостей и «Почему выбирают нас» на главной ---------- */
@media (max-width: 1199px) {
  .news-grid {
    grid-template-columns: repeat(auto-fit, minmax(min(300px, 100%), 1fr));
  }

  .trust-grid {
    grid-template-columns: repeat(auto-fit, minmax(min(280px, 100%), 1fr));
  }
}

/* ---------- Карусель «Лидеры продаж» ----------
 * Шаг прокрутки компонент считает по фактической ширине карточки и пересчитывает
 * на resize, поэтому адаптировать логику не нужно. Правится только то, что
 * мешает: на телефоне стрелки и полоса трека должны оставаться нажимаемыми. */
@media (max-width: 767px) {
  .carousel__viewport {
    padding: 30px 16px;
    margin: -30px -16px;
  }

  .carousel__nav {
    gap: 12px;
  }
}

/* ---------- Панель управления страницы категории ----------
 * Строка «Фильтры … Сортировка» на desktop раздвинута по краям. На узком
 * экране две капсулы по 190px в один ряд не встают — ряд переносится, а
 * органы управления растягиваются на всю ширину, оставаясь нажимаемыми. */
@media (max-width: 767px) {
  .catalog-products__row {
    flex-wrap: wrap;
    gap: 12px;
  }

  .catalog-products__row > * {
    flex: 1 1 100%;
  }

  .btn--outline {
    width: 100%;
    min-width: 0;
  }

  .dropdown__menu {
    width: 100%;
  }
}

/* ---------- Страница «Новости»: список и нижний ряд ----------
 * Карточка списка — жёсткие 628px с колонками 377 + 251. Ниже 1200px ширину
 * задаёт сетка, а колонки считаются в долях; на телефоне карточка
 * складывается вертикально в порядке DOM: текст, затем фото. */
@media (max-width: 1199px) {
  .news-list,
  .news-extra__inner {
    grid-template-columns: repeat(auto-fit, minmax(min(320px, 100%), 1fr));
  }

  .news-card--wide {
    width: auto;
    grid-template-columns: minmax(0, 1fr) 38%;
  }

  .news-card__body {
    padding: 28px 24px 17px;
  }
}

@media (max-width: 767px) {
  .news-card--wide {
    grid-template-columns: minmax(0, 1fr);
  }

  /* Фото из правой колонки во всю высоту становится нижней полосой карточки:
     скругление переносится на нижние углы. */
  .news-card--wide .news-card__media {
    height: 200px;
    order: 2;
    border-radius: 0 0 var(--radius-card) var(--radius-card);
  }

  .news-card__meta {
    gap: 12px;
  }
}

/* ---------- Блок Testo Smart App ----------
 * Декоративная капсула и фото телефонов спозиционированы абсолютно от левого
 * края и рассчитаны на блок ровно 628px: на более узком блоке они уходили за
 * его правый край (и обрезались `overflow: hidden`). Привязка переносится к
 * правому краю — композиция инстанса и кадрирование сохраняются при любой
 * ширине блока, потому что в макете капсула прижата к правому краю. */
@media (max-width: 1199px) {
  .smart-app {
    height: auto;
    min-height: 325px;
  }

  .smart-app__capsule {
    right: 0;
    left: auto;
  }

  .smart-app__phones {
    right: 43px;
    left: auto;
  }

  .smart-app__text {
    width: auto;
    max-width: 374px;
    padding-right: 232px;
  }
}

@media (max-width: 767px) {
  .smart-app {
    padding: 22px 16px 25px;
  }

  /* На телефоне капсула в натуральную величину заняла бы почти всю ширину
     блока. Та же композиция в масштабе 0.62: все пропорции, скругление и
     кадр фото (они заданы в процентах от своих боксов) сохраняются. */
  .smart-app__capsule {
    top: 20px;
    width: 134px;
    height: 172px;
    border-radius: 87px 0 0 87px;
  }

  .smart-app__phones {
    top: 68px;
    right: 27px;
    width: 73px;
    height: 76px;
  }

  .smart-app__text {
    padding-right: 146px;
  }
}

/* ---------- Блок подписки на рассылку ---------- */
@media (max-width: 1199px) {
  .news-subscribe__text {
    width: auto;
  }

  .news-subscribe__button,
  .news-subscribe__form .field {
    max-width: 100%;
  }
}

@media (max-width: 767px) {
  .news-subscribe {
    padding: 15px 16px 20px;
  }

  .news-subscribe__title {
    font-size: 18px;
    line-height: 26px;
  }
}

/* ---------- Страница товара ----------
 * Desktop-раскладка: блок товара ровно 1063px, а панель покупки вынесена из
 * потока абсолютным `.product-sidebar__rail` в правое поле контейнера 1440px.
 * Оба габарита рассчитаны на окно 1440px и ниже 1200px растягивали страницу.
 *
 * Ниже 1200px зона становится колонкой, а панель покупки встаёт в поток. Она
 * относится к первому экрану товара, поэтому ставится сразу под блоком
 * «галерея + информация», а не в конец страницы: единственное правило
 * `order: -1` у `.product-hero` поднимает блок товара выше панели, остальные
 * секции остаются в порядке DOM (описание → характеристики → аксессуары →
 * области применения). Состав и данные секций не меняются. */
@media (max-width: 1199px) {
  .product-sticky-zone {
    display: flex;
    flex-direction: column;
  }

  .product-hero {
    order: -1;
  }

  .product-sidebar__rail {
    position: static;
    top: auto;
    right: auto;
    bottom: auto;
    width: auto;
    margin-top: 24px;
    padding: 0 var(--container-padding-content);
  }

  .product-sidebar {
    position: static;
    top: auto;
    width: auto;
    max-width: 420px;
  }

  .product-hero__main {
    width: auto;
  }

  /* Галерея и информация — две гибкие колонки, которые сами складываются в
     одну, когда ширины на две не остаётся. Отдельных правил на 375 / 768 /
     1024 не требуется. */
  .product-hero__top {
    flex-wrap: wrap;
  }

  .product-gallery {
    flex: 1 1 340px;
  }

  .product-info {
    flex: 1 1 260px;
  }
}

/* ---------- Галерея товара ----------
 * Большая фотография занимает доступную ширину и сохраняет пропорции макета;
 * миниатюры остаются под ней и переносятся внутри её ширины (ряд ограничен
 * шириной галереи, поэтому через страницу они не уходят и `.product-info`
 * не перекрывают). Поведение клика по миниатюре не меняется. */
@media (max-width: 1199px) {
  .product-gallery__main {
    width: auto;
    height: auto;
    aspect-ratio: 610 / 336;
  }
}

@media (max-width: 1199px) {
  /*
   * У товара в базе до 16 изображений. В узкой колонке перенос давал восемь
   * рядов миниатюр: большая фотография и информация о товаре расходились почти
   * на экран. Поэтому ряд остаётся одной строкой с собственной горизонтальной
   * прокруткой — второй вариант, разрешённый задачей §16.
   *
   * Прокрутка локальная: ширину документа она не увеличивает (проверено
   * `scrollWidth` страницы), миниатюры остаются под большой фотографией и в
   * границах галереи, `.product-info` не перекрывают. Поведение клика по
   * миниатюре не меняется, фокус с клавиатуры подматывает ряд сам.
   *
   * Вертикальные поля — под тень миниатюр: контейнер с `overflow-x: auto`
   * отсекает и по вертикали, без них тень срезалась бы.
   */
  .product-gallery__thumbs {
    flex-wrap: nowrap;
    gap: 12px;
    margin-top: 14px;
    padding: 8px 0 12px;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    scroll-snap-type: x proximity;
  }

  .product-gallery__thumbs > li {
    flex: 0 0 auto;
    scroll-snap-align: start;
  }
}

/* ---------- Таблица характеристик ----------
 * На странице товара таблица двухколоночная и доли колонок тянутся — своей
 * ширины у неё нет, боковые поля строк уже уменьшены в блоках выше, поэтому
 * viewport она не ломает и горизонтальная прокрутка ей не нужна.
 *
 * Таблица сравнения — другое дело: у неё три-четыре товарные колонки, и ниже
 * 1200px они становятся нечитаемо узкими. Ей даётся локальная горизонтальная
 * прокрутка внутри своего контура (задача §26): колонки и данные сохраняются
 * целиком, а ширину документа прокрутка не увеличивает. */
@media (max-width: 1199px) {
  .specifications--compare .specifications__surface {
    overflow-x: auto;
    overflow-y: hidden;
  }

  .specifications--compare .specifications__stack {
    min-width: 640px;
  }
}

/* ---------- Корзина и обзор заказа ----------
 * В текущей реализации маршрут `/cart` отдаёт только пустое состояние, а
 * разметка строки товара и блока итогов перенесена из утверждённой вёрстки и
 * ждёт этапа корзины. Адаптируются оба: пустое состояние — то, что видно
 * сейчас, строка товара — чтобы блок не пришлось переверстывать позже.
 * Бизнес-логика и backend корзины не затрагиваются. */
@media (max-width: 1199px) {
  /* Товары и блок итогов — друг под другом: 411px на итоги рядом с товарами
     ниже 1200px не остаётся. */
  .cart__inner {
    grid-template-columns: minmax(0, 1fr);
  }

  .cart-summary {
    width: auto;
    max-width: 411px;
  }
}

@media (max-width: 767px) {
  /* Строка товара «фото 302 + описание + цена» складывается в две строки:
     уменьшенное фото и описание рядом, цена — под ними во всю ширину. */
  .cart-item {
    grid-template-columns: 120px minmax(0, 1fr);
    column-gap: 16px;
    row-gap: 16px;
  }

  .cart-item__media {
    width: auto;
    height: 120px;
  }

  .cart-item__info {
    min-height: 0;
    padding-top: 0;
  }

  .cart-item__note {
    margin-top: 20px;
    margin-left: 0;
  }

  .cart-item__pricing {
    grid-column: 1 / -1;
  }

  .cart-item__controls {
    flex-wrap: wrap;
    gap: 12px;
  }

  .cart-summary {
    max-width: none;
  }
}

/* ---------- Оформление заказа ---------- */
@media (max-width: 1199px) {
  .checkout__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: 40px;
  }

  .cart-summary--checkout {
    width: auto;
    max-width: 435px;
  }
}

@media (max-width: 767px) {
  /* Две колонки полей по 302px в одну строку не встают. */
  .field-row {
    grid-template-columns: minmax(0, 1fr);
    row-gap: 30px;
  }

  .cart-summary--checkout {
    max-width: none;
  }

  /* Разделитель итогов — жёсткие 344px из макета: на телефоне блок уже этого,
     и линия выходила за карточку (единственный остаток переполнения на
     `/checkout` после перестройки сеток). */
  .cart-summary--checkout .cart-summary__divider {
    width: auto;
  }

  /* Строка промокода в корзине — та же природа. */
  .cart-summary__promo {
    width: auto;
  }
}

/* ---------- Страница «Контакты» ---------- */
@media (max-width: 1199px) {
  .contacts__inner {
    grid-template-columns: minmax(0, 1fr);
    gap: 32px;
  }
}

@media (max-width: 767px) {
  .contacts-info {
    padding: 28px 16px;
  }

  .contacts-form {
    padding: 28px 16px 32px;
  }

  /* Подпись и значение в строке контакта переносятся друг под друга, когда
     в одну строку они не помещаются. */
  .contacts-info__row {
    flex-wrap: wrap;
  }

  .contacts-form__submit {
    width: 100%;
    max-width: 280px;
  }
}

/* ---------- Страница сравнения ----------
 * Число колонок карточек задаёт переменная `--compare-cols` (2 или 3 по
 * состоянию списка). Ниже 768px на такую сетку ширины нет, поэтому карточки и
 * названия в серой полосе над ними выстраиваются в одну колонку — обе сетки
 * переключаются вместе, чтобы названия остались ровно над карточками. */
@media (max-width: 1199px) {
  .compare__grid,
  .page-title__names {
    gap: 16px;
  }
}

@media (max-width: 767px) {
  .compare__grid,
  .page-title__names {
    grid-template-columns: minmax(0, 1fr);
  }

  .page-title--compare .page-title__text {
    text-align: left;
  }

  .compare__nav {
    justify-content: center;
  }
}

/* ---------- Страница 404 ---------- */
@media (max-width: 1199px) {
  .error-404__media {
    width: 100%;
    max-width: 583px;
    height: auto;
    aspect-ratio: 583 / 459;
  }
}

@media (max-width: 767px) {
  .error-404 {
    padding: 28px var(--container-padding) 28px;
  }
}

/* ---------- Пустые состояния и общие органы управления ---------- */
@media (max-width: 767px) {
  /* Кнопка в капсуле с длинной подписью не должна выходить за свой блок. */
  .btn {
    max-width: 100%;
  }

  .btn--hero,
  .btn--category {
    max-width: 100%;
  }

  /* Экспорт характеристик: две кнопки по 167px в строку не встают. Перенос у
     `.specifications__export` уже задан в базовых правилах — здесь только
     ширина кнопок. */
  .specifications--compare .specifications__export .btn {
    width: 100%;
  }
}

/* =====================================================================
   ПРОМЕЖУТОЧНЫЙ DESKTOP-ДИАПАЗОН (1200–1359px)
   =====================================================================
 *
 * Утверждённые desktop-сетки заданы в фиксированных пикселях и рассчитаны на
 * контентную полосу 1280px, то есть на окно ровно 1440px. Ниже 1440px полоса
 * сужается (окно − 2 × 80px), а сами сетки нет — и до какого-то момента они
 * выходят за правый край окна.
 *
 * Граница измерена на production, а не выведена из макета (замеры 1200 … 1440
 * с шагом до 1px):
 *
 *   .product-grid        4 × 302 + 3 × 24 = 1280 → правый край 80 + 1280 = 1360
 *   .news-extra__inner   2 × 628 + 24     = 1280 → правый край 1360
 *   .news-list           2 × 628 + 24     = 1280 → правый край 1360
 *   .contacts__inner     628 + 543        = 1171 → правый край 80 + 1171 = 1251
 *
 * Отсюда переполнение страницы: у трёх первых — при окне < 1360px (на 1359px
 * ровно +1px, на 1360px уже 0), у контактов — при окне < 1251px. Объединение
 * даёт диапазон 1200–1359px: снизу его замыкает уже работающий планшетный
 * блок (max-width: 1199px), сверху — первая чистая ширина 1360px.
 *
 * Поэтому запрос ограничен с обеих сторон и до 1366px и 1440px не доходит:
 * утверждённый desktop не затрагивается вообще.
 *
 * Решение системное, тем же приёмом, что уже используется в разделе выше:
 * число колонок перестаёт быть константой и считается от доступной ширины.
 * Габариты карточек при этом не трогаются — `auto-fill` с шагом ровно 302px
 * сохраняет утверждённый размер карточки, уменьшается только число колонок
 * в ряду (4 → 3), поэтому «сжатия карточек ради четырёх колонок» не возникает.
 */
@media (min-width: 1200px) and (max-width: 1359px) {
  /* 4 → 3 колонки. Шаг колонки и `justify-content: space-between` остаются
     базовыми: меняется только то, что число колонок больше не задано
     константой. Сетка аксессуаров PDP (`repeat(3, 302px)` = 1002px) в полосу
     помещается и своё правило сохраняет — её специфичность выше. */
  .product-grid {
    grid-template-columns: repeat(auto-fill, 302px);
  }

  /* Два блока в ряд — это и есть композиция макета, поэтому колонок
     по-прежнему две; фиксированные 628px заменяются долями, и пара
     занимает ровно доступную полосу. */
  .news-list,
  .news-extra__inner {
    grid-template-columns: repeat(2, minmax(0, 1fr));
  }

  /* Пропорция колонок макета (628 : 543) сохраняется, зазор между карточками —
     те же 109px, которые на 1440px давал `justify-content: space-between`
     (1280 − 628 − 543). */
  .contacts__inner {
    grid-template-columns: minmax(0, 628fr) minmax(0, 543fr);
    gap: 109px;
  }
}
