/* Дизайн-система MITLIS.
   Построена по разбору настоящих стилей g-energy.org (main.min.css, site.css
   из папки project1) и видеозаписи сайта. Ключевые приёмы оттуда:
   тёмная двухъярусная шапка, полноэкранный герой с фотофоном и вкладками-слайдами,
   оранжевые кнопки-пилюли капсом, центрированные заголовки секций,
   крупные оранжевые числа, карточки товара с оранжевым названием капсом. */

/* Неизменное в обеих темах ------------------------------------------------ */
:root {
  /* Бренд-оранжевый в роли идентичности: заливки, линии, акценты.
     Роли «текст» и «заливка кнопки» зависят от темы — они ниже. */
  --prime: #e35205;
  --prime-hover: #f46316;

  /* Чёрная хромировка. Шапка, подвал и мобильное меню чёрные при любой теме:
     на них стоит фирменный знак, а он рассчитан на тёмную подложку. Отдельные
     токены нужны именно потому, что --ink и --surface под темой переворачиваются,
     а эти поверхности — нет. */
  --chrome: #0d0c0c;
  --chrome-fg: #f4f2f0;         /* 17.49 */
  --chrome-muted: #a29e9b;      /* 7.35 */
  --chrome-prime: #ff8c4d;      /* 8.47 — оранжевый текст и контур фокуса */
  --chrome-line: #302c29;       /* декоративная линия */
  --chrome-ctl: #6f6b68;        /* граница органа управления, 3.70 */
  /* Высота шапки в обычном и прижатом состоянии. На эти числа опираются
     прилипшая корзина и scroll-padding — держать их врозь нельзя. */
  --header-h: 139px;            /* 62 служебный ярус + 76 ярус навигации + линия */
  --header-h-stuck: 60px;       /* служебный ярус свёрнут, остался ярус навигации */

  --chrome-btn: #f46316;        /* заливка кнопки на чёрном */
  --chrome-btn-hover: #ff7a33;
  --chrome-on-btn: #14120f;     /* 5.91 на заливке */

  /* Типографика бренда: те же гарнитуры, что на g-energy.org. GPN DIN держит
     текст, DINPro — заголовки, кнопки и подписи капсом. Раскладка ролей
     повторяет сайт бренда: текст спокойный, акценты узнаваемые. Обе гарнитуры
     родом от промышленного DIN, кириллица у обеих родная. */
  --font: "GPN DIN", "Segoe UI", Arial, sans-serif;
  --font-ui: "dinpro", "GPN DIN", "Segoe UI", Arial, sans-serif;

  /* Метрика */
  --container: 1280px;
  --gutter: 20px;
  --radius: 18px;      /* карточки и панели */
  --radius-ctl: 10px;  /* поля форм: на 18px инпут выглядит пилюлей, не полем */
  --radius-pill: 40px;
  --glow: 0 5px 18px rgba(224, 82, 6, .45);   /* фирменное свечение кнопки */

  /* Движение. --ease остаётся линейным: он навешен на цвет, а цвету
     разгон и торможение не нужны. Всё, что двигается или меняет размер,
     идёт по --out — затухающей кривой без отскока: механика, а не игрушка.
     Уход быстрее прихода, поэтому длительностей три, а не одна. */
  --ease: .2s linear;
  --out: cubic-bezier(.16, 1, .3, 1);
  --t-fast: .16s;      /* отклик под пальцем: нажатие, подсветка */
  --t-mid: .26s;       /* смена состояния: раскрытие, ховер картинки */
  --t-slow: .44s;      /* приход блока в кадр, панель на весь экран */
  --t-header: .5s;     /* ужатие шапки: восемьдесят пикселей высоты за раз */
  --t-hero: .62s;      /* смена слайда: кадр во весь экран идёт дольше */
  --t-theme: .55s;     /* круг темы: проходит экран целиком, спешить некуда */
  --out-soft: cubic-bezier(.4, 0, .2, 1);   /* разгон и торможение поровну */
}

/* Чёрная тема — состояние по умолчанию ------------------------------------ */
/* Значения продублированы в [data-theme="dark"]: без этого возврат со светлой
   на тёмную пришлось бы делать снятием атрибута, а переключателю нужно уметь
   ставить оба состояния явно. */
:root,
:root[data-theme="dark"] {
  --prime-dark: #ff9a63;
  --prime-pale: #3a2318;

  /* Оранжевый в ролях, где важен контраст текста. Минимум по теме 6.47:1. */
  --prime-text: #ff8c4d;        /* 8.47 на фоне страницы */
  --prime-text-hover: #ffa571;
  --btn-fill: #f46316;
  --btn-fill-hover: #ff7a33;
  --on-prime: #14120f;          /* 5.91 на заливке кнопки */
  --btn-off-bg: #2f2c2a;
  --btn-off-text: #a8a5a2;

  /* Лестница чёрных поверхностей. Страница и шапка — одна глубина,
     иначе шапка отслаивается; различает их волосяная линия. Карточка
     на ступень выше, чтобы сетка товаров не расплывалась в фон. */
  --page: #0d0c0c;
  --dark: #0d0c0c;
  --dark-2: #151413;
  --light: #151413;             /* утопленные секции, плашки под текстом */
  --surface: #1c1b1a;           /* карточки, панели, поля */
  --surface-rail: #151413;
  --white: #1c1b1a;             /* историческое имя поверхности карточки */

  --line: #302c29;              /* декоративная волосяная линия */
  --grey: #6f6b68;              /* граница элементов управления, 3.70 на фоне */
  --ink: #cfccc9;               /* 12.22 */
  --ink-strong: #f4f2f0;        /* 17.49 */
  --grey-text: #a29e9b;         /* 7.35 на фоне, 6.47 на карточке */
  --on-dark: #f4f2f0;           /* текст поверх фотографии героя */

  /* Плитка под фотографией товара остаётся светлой: съёмка сделана
     на белом, на чёрном её край обрубается. */
  --photo-tile: #e9e6e2;

  --ok-text: #4cbb72;           /* «в наличии»: 8.05 на фоне, 7.09 на карточке */
  --focus: #f46316;             /* 6.18 на фоне страницы */
  --shadow-lift: 0 10px 28px rgba(0, 0, 0, .6);
  --picker-icon-shadow: drop-shadow(0 10px 18px rgba(8, 8, 9, .32));   /* объёмные значки подбора по авто */
}

/* Светлая тема ------------------------------------------------------------ */
/* Переключается только контентная область: шапка и подвал остаются чёрными.
   Оранжевый в текстовой роли здесь темнее собственной идентичности — #e35205
   на белом даёт 3.84 при норме 4.5, одним цветом обе роли не закрыть. */
:root[data-theme="light"] {
  --prime-dark: #b83f05;
  --prime-pale: #fceee6;

  --prime-text: #bd430a;        /* 5.29 на белом, 4.71 на утопленном */
  --prime-text-hover: #a83a04;  /* 6.42 / 5.72 */
  --btn-fill: #c4460a;          /* белый текст поверх: 4.97 */
  --btn-fill-hover: #b83f05;
  --on-prime: #fff;
  --btn-off-bg: #f1f2f2;
  --btn-off-text: #656867;      /* 5.02 на своей подложке */

  /* Лестница светлых поверхностей: без неё страница из одного белого
     читается плоской. Значения из палитры референса. */
  --page: #fff;
  --dark: #2c2a29;              /* тёмные врезки внутри контента */
  --dark-2: #232120;
  --light: #f1f2f2;             /* утопленные секции */
  --surface: #fff;              /* карточки, панели, поля */
  --surface-rail: #f7f7f7;
  --white: #fff;

  --line: #e3e3e3;              /* декоративная волосяная линия */
  --grey: #8a8a8a;              /* граница элементов управления, 3.45 / 3.08 */
  --ink: #2a2a2a;               /* 14.35 */
  --ink-strong: #1e1e1e;        /* 16.67 */
  --grey-text: #666968;         /* 5.55 на белом, 4.95 на утопленном */
  --on-dark: #fff;              /* текст поверх фотографии героя */

  --photo-tile: #f1f2f2;

  --ok-text: #1f7a3d;           /* «в наличии»: 5.37 на белом, 4.79 на утопленном */
  --focus: #e35205;             /* 3.84 на белом, 3.42 на утопленном */
  --shadow-lift: 0 10px 28px rgba(30, 30, 30, .13);
  --picker-icon-shadow: drop-shadow(0 8px 16px rgba(30, 30, 30, .13));
}

/* Смена темы не должна выглядеть как перезагрузка страницы. Переход навешивается
   классом только на время переключения: постоянный transition на всех поверхностях
   дорог и сбивает ховеры, у которых свои длительности. */
.theme-fade, .theme-fade *, .theme-fade *::before, .theme-fade *::after {
  transition: background-color .22s linear, border-color .22s linear,
              color .22s linear, fill .22s linear !important;
}

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

/* Классы с собственным display (кнопки, флексы) перебивают браузерное правило
   для атрибута hidden — возвращаем ему приоритет, иначе скрытое видно. */
[hidden] { display: none !important; }
/* Отступ под липкую шапку: иначе цель якорной ссылки встаёт под неё. */
html {
  -webkit-text-size-adjust: 100%;
  scroll-behavior: smooth;
  scroll-padding-top: calc(var(--header-h-stuck) + 16px);
}

body {
  margin: 0;
  font-family: var(--font);
  font-size: 16px;
  line-height: 1.6;
  color: var(--ink);
  background: var(--page);
}

/* То, что рисует браузер, а не мы: выделение текста, каретка в поле, полоса
   прокрутки. По умолчанию все три приходят из системной темы и на чёрной
   странице выглядят чужими — уводим их в свою палитру. */
::selection { background: var(--prime); color: #fff; }
:root[data-theme="light"] ::selection { background: var(--prime-pale); color: var(--prime-dark); }
input, textarea, select { caret-color: var(--prime); }

* { scrollbar-color: var(--grey) transparent; scrollbar-width: thin; }
::-webkit-scrollbar { width: 10px; height: 10px; }
::-webkit-scrollbar-track { background: transparent; }
::-webkit-scrollbar-thumb { background: var(--grey); border-radius: 6px; border: 2px solid var(--page); }
::-webkit-scrollbar-thumb:hover { background: var(--prime); }

/* Числа в наличии, счётчиках и итогах выстраиваются в колонку только
   моноширинными цифрами — иначе «1 964» и «1 111» разной длины. */
.stock, .stat b, .cat-count, .cart__total b, .stepper__value,
.cart__row-sum, .cart__row-calc, .spec__value, .pack__price {
  font-variant-numeric: tabular-nums;
}

/* Заголовки набраны акцентной гарнитурой — как на сайте бренда. DIN на
   крупном кегле просит отрицательного трекинга: у него широкие прописные
   и просторные межбуквенные, без сжатия заголовок распадается на буквы. */
h1, h2, h3, h4 {
  font-family: var(--font-ui); font-weight: 700; line-height: 1.12;
  letter-spacing: -.02em; color: var(--ink-strong); margin: 0 0 .5em;
}
h1 { font-size: 2.4rem; }
h2 { font-size: 1.9rem; }
h3 { font-size: 1.2rem; letter-spacing: -.01em; }

p { margin: 0 0 1em; }
a { color: var(--prime-text); text-decoration: none; transition: color var(--ease); }
a:hover { color: var(--prime-text-hover); }
img { max-width: 100%; height: auto; display: block; }
ul { margin: 0 0 1em; padding-left: 1.2em; }

.container { width: 100%; max-width: var(--container); margin: 0 auto; padding: 0 var(--gutter); }

.visually-hidden {
  position: absolute; width: 1px; height: 1px; margin: -1px;
  padding: 0; overflow: hidden; clip: rect(0 0 0 0); white-space: nowrap; border: 0;
}


/* Фокус с клавиатуры. У полей ранее стоял outline:none без замены —
   для тех, кто ходит по сайту табом, индикатор пропадал совсем. */
:focus-visible {
  outline: 3px solid var(--focus);
  outline-offset: 2px;
  border-radius: 4px;
}
/* Чёрные поверхности не переключаются темой — контур на них тоже фиксирован. */
.header :focus-visible, .footer :focus-visible,
.mobile-nav :focus-visible { outline-color: var(--chrome-prime); }
.btn:focus-visible, .stepper button:focus-visible { outline-offset: 3px; }
.field input:focus-visible, .field textarea:focus-visible { outline-offset: 0; }
/* Панель всегда белая, темой не управляется */
.submenu :focus-visible { outline-color: #b83f05; }

/* ---------- Кнопки: пилюли капсом, как на g-energy ---------- */

.btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  gap: 8px;
  min-height: 52px;
  padding: 0 34px;
  border: 1px solid transparent;
  border-radius: var(--radius-pill);
  font-family: var(--font-ui);
  font-size: .82rem;
  font-weight: 700;
  letter-spacing: .09em;
  text-transform: uppercase;
  cursor: pointer;
  background: none;
  transition: background-color var(--ease), border-color var(--ease), color var(--ease), box-shadow var(--ease);
}

.btn--prime { background: var(--btn-fill); border-color: var(--btn-fill); color: var(--on-prime); }
/* Шапка и мобильное меню чёрные при любой теме, поэтому кнопка в них берёт
   светлый оранжевый, а не тематический: тёмный #c4460a на чёрном глохнет. */
.header .btn--prime, .mobile-nav .btn--prime {
  background: var(--chrome-btn); border-color: var(--chrome-btn); color: var(--chrome-on-btn);
}
.header .btn--prime:hover, .mobile-nav .btn--prime:hover {
  background: var(--chrome-btn-hover); border-color: var(--chrome-btn-hover); color: var(--chrome-on-btn);
}
.btn--prime:hover { background: var(--btn-fill-hover); border-color: var(--btn-fill-hover); color: var(--on-prime); box-shadow: var(--glow); }
.btn--border { border-color: var(--prime); color: var(--prime-text); }
.btn--border:hover { background: var(--btn-fill); border-color: var(--btn-fill); color: var(--on-prime); }
.btn--ghost { border-color: var(--grey); color: var(--ink); }
.btn--ghost:hover { border-color: var(--ink); }
.btn--light { background: #fff; color: #1e1e1e; border-color: #fff; }
.btn--light:hover { background: #f1ece8; border-color: #f1ece8; color: #1e1e1e; box-shadow: 0 6px 20px rgba(0, 0, 0, .22); }
/* Прозрачная на фото: белый контур поверх затемнения */
.btn--outline {
  border-color: rgba(255, 255, 255, .7); color: #fff;
  background: rgba(10, 10, 11, .32);
}
.btn--outline:hover { background: #fff; border-color: #fff; color: #1e1e1e; }
.btn--sm { min-height: 42px; padding: 0 22px; font-size: .74rem; }
.btn--wide { width: 100%; }
.btn[aria-disabled="true"] { background: var(--btn-off-bg); border-color: var(--btn-off-bg); color: var(--btn-off-text); box-shadow: none; }
.btn[aria-disabled="true"]:hover { background: var(--btn-off-bg); border-color: var(--grey); color: var(--btn-off-text); box-shadow: none; }

/* Отклик на нажатие. Кнопка без него ощущается как картинка: палец уже
   на экране, а подтверждения нет до самой перерисовки страницы. */
.btn:active:not([aria-disabled="true"]),
.cat-tab:active,
.theme-toggle:active, .header__burger:active, .mobile-nav__close:active { transform: translateY(1px); }
.btn, .cat-tab, .theme-toggle, .header__burger, .mobile-nav__close {
  transition: background-color var(--ease), border-color var(--ease), color var(--ease),
              box-shadow var(--t-fast) var(--out), transform var(--t-fast) var(--out);
}

/* Текстовая ссылка со стрелкой — «УЗНАТЬ БОЛЬШЕ →» из референса */
.link-more {
  display: inline-flex; align-items: center; min-height: 24px; gap: 12px;
  font-family: var(--font-ui); font-size: .78rem; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--ink-strong);
}
/* Черта растёт масштабом, а не шириной: ширина пересчитывает раскладку
   всей строки на каждый кадр, масштаб живёт в композиторе. */
.link-more::after {
  content: ""; width: 48px; height: 1px; background: var(--prime);
  transform: scaleX(.7); transform-origin: left center;
  transition: transform var(--t-mid) var(--out);
}
.link-more:hover { color: var(--prime-text-hover); }
.link-more:hover::after { transform: scaleX(1); }

/* ---------- Шапка: два яруса на чёрном ---------- */
/* Заказчик просил оставить её чёрной ради читаемости знака: малиновая
   надпись логотипа набирает на ней 4.49, выворотка монограммы — 17.49. */

/* Шапка едет вместе с экраном: кнопка подбора и навигация должны быть под рукой
   на любой глубине страницы.

   position: fixed, а не sticky. Липкая шапка остаётся в потоке, и когда при
   прокрутке служебный ярус сворачивается, страница разом подпрыгивает на его
   высоту — 81px рывка на пороге в 24px. Фиксированная не двигает ничего:
   меняется только её собственная коробка. Цена — компенсирующий отступ
   у body, он завязан на тот же токен --header-h. */
.header {
  background: var(--chrome);
  position: fixed; top: 0; left: 0; right: 0; z-index: 30;
  border-bottom: 1px solid var(--chrome-line);
  transition: box-shadow var(--ease), background-color var(--t-mid) var(--out),
              border-color var(--t-mid) var(--out), min-height var(--t-mid) var(--out);
}
body { padding-top: var(--header-h); }
.header__top, .header__bar { transition: min-height var(--t-mid) var(--out), height var(--t-mid) var(--out), opacity var(--t-fast) var(--out); }
.logo img { transition: height var(--t-mid) var(--out); }
.header__item > a { transition: padding var(--t-mid) var(--out), color var(--ease); }

/* Прижатое состояние. Тень нужна, чтобы шапка читалась как слой над контентом,
   а не как его продолжение: фон у неё тот же чёрный, что и у страницы.
   Класс вешает nav.js за порогом в 24px — за тень он и отвечает. */
.header.is-stuck { box-shadow: 0 8px 26px rgba(0, 0, 0, .55); }

/* Второй знак — тот, что выходит в ярус навигации, когда служебный ярус
   свёрнут. Скрыт по умолчанию; показывают его правила ниже, каждое своим
   способом. Селектор с .header: у соседнего .logo стоит display: block. */
.header .logo--compact { display: none; margin-left: 0; }
.logo--compact img { height: 26px; }

/* Затемнение под прозрачной шапкой. Живёт всегда, а гасится по прокрутке:
   так его исчезновение идёт тем же ходом, что и появление фона. */
.has-hero .header::before {
  content: ""; position: absolute; inset: 0; z-index: -1;
  background: linear-gradient(180deg, rgba(8, 8, 9, .72) 0%, rgba(8, 8, 9, .34) 55%, transparent 100%);
}

/* ---- основной путь: высота привязана к самой прокрутке ---- */
/* Шапка ужимается ровно настолько, насколько человек прокрутил. Движение идёт
   под пальцем и в обе стороны, без щелчка на 24-м пикселе — за это отвечает
   прокруточный таймлайн, а не класс.

   Диапазон 0…130px один на все элементы: разъедься они по фазе, ярус, знак
   и отбивка навигации поехали бы вразнобой. */
@supports (animation-timeline: scroll()) {
  .header, .header::before, .header__top, .header__bar, .header__top .logo img,
  .header__nav > .header__item > a, .header .logo--compact img {
    animation: linear both;
    animation-timeline: scroll(root block);
    animation-range: 0 130px;
  }

  .header__top { animation-name: hdrTopCollapse; }
  .header__bar { animation-name: hdrBarShrink; }
  .header__nav > .header__item > a { animation-name: hdrNavPad; }
  .has-hero .header { animation-name: hdrBackdrop; }
  .has-hero .header::before { animation-name: hdrScrim; }
  .has-hero .header__top { animation-name: hdrTopCollapse, hdrTopLine; }

  /* min-height анимируется вместе с height: иначе он держит ярус
     раскрытым, сколько бы высоту ни уменьшали. */
  @keyframes hdrTopCollapse {
    from { height: 62px; min-height: 62px; opacity: 1; }
    40%  { opacity: 0; }
    to   { height: 0; min-height: 0; opacity: 0; border-bottom-width: 0; }
  }
  @keyframes hdrBarShrink { from { min-height: 76px; } to { min-height: 58px; } }
  @keyframes hdrLogoShrink { from { height: 40px; } to { height: 30px; } }
  @keyframes hdrNavPad { from { padding: 26px 0; } to { padding: 18px 0; } }
  @keyframes hdrBackdrop {
    from { background-color: transparent; border-bottom-color: transparent; }
    to { background-color: var(--chrome); border-bottom-color: var(--chrome-line); }
  }
  @keyframes hdrScrim { from { opacity: 1; } 65% { opacity: 0; } to { opacity: 0; } }
  @keyframes hdrTopLine {
    from { border-bottom-color: transparent; }
    to { border-bottom-color: var(--chrome-line); }
  }

  /* Знак проявляется тем же ходом, а не выскакивает на пороге. Ширина идёт
     вместе с прозрачностью: невидимый, но занимающий место знак отодвигал бы
     кнопку вправо на пустом месте. */
  @media (min-width: 993px) {
    .header__top .logo img { animation-name: hdrLogoShrink; }
    .header .logo--compact { display: block; }
    .header .logo--compact img { animation-name: hdrCompactIn; }
    /* Растёт высота картинки, ширина идёт за ней по пропорции — знак нигде
       не обрезается. Отрицательный отступ гасит зазор ряда, пока знака нет:
       иначе кнопки в правом краю стояли бы в тридцати пикселях от края. */
    @keyframes hdrCompactIn {
      from { height: 0; opacity: 0; margin-left: -30px; }
      45%  { opacity: 0; }
      to   { height: 26px; opacity: 1; margin-left: 0; }
    }
  }

  /* На телефоне ярус один и ужимать нечего, кроме самой шапки. */
  @media (max-width: 992px) {
    .header { animation-name: hdrMobileShrink; }
    .has-hero .header { animation-name: hdrBackdrop, hdrMobileShrink; }
    @keyframes hdrMobileShrink { from { min-height: 64px; } to { min-height: 56px; } }
  }
}

/* ---- запасной путь: браузер без прокруточных таймлайнов ---- */
/* Здесь ужатие идёт разом, по классу. Время своё: вдвое длиннее обычного
   перехода и кривая мягче — у --out резкий старт, и на восьмидесяти пикселях
   высоты он читается щелчком, а не движением. */
@supports not (animation-timeline: scroll()) {
  .header, .header__top, .header__bar, .logo img, .header__item > a {
    transition-duration: var(--t-header);
    transition-timing-function: var(--out-soft);
  }
  .header.is-stuck .header__bar { min-height: 58px; }
  .header.is-stuck .header__top { min-height: 0; height: 0; opacity: 0; border-bottom-width: 0; }
  .header.is-stuck .logo img { height: 30px; }
  .header.is-stuck .header__item > a { padding: 18px 0; }

  .has-hero .header:not(.is-stuck) { background: transparent; border-bottom-color: transparent; }
  .has-hero .header:not(.is-stuck) .header__top { border-bottom-color: transparent; }
  .has-hero .header.is-stuck::before { opacity: 0; }

  @media (min-width: 993px) {
    .header.is-stuck .logo--compact { display: block; }
  }
}

/* Отступ под шапку не нужен: герой и есть то, что под ней лежит. */
.has-hero { padding-top: 0; }
/* Первый экран занимает высоту окна целиком. svh, а не vh: на телефоне
   динамическая панель браузера иначе прибавляет к экрану свою высоту,
   и низ героя вместе с вкладками уезжает под неё. */
.has-hero .hero { min-height: var(--hero-min); padding-top: var(--header-h); }

/* Высота задана числом, а не только min-height: из auto в ноль браузер
   не анимирует, и ярус схлопывался бы рывком. overflow прячет содержимое
   по мере сворачивания. */
.header__top {
  display: flex; align-items: center; gap: 26px;
  height: 62px; min-height: 62px; overflow: hidden;
  border-bottom: 1px solid var(--chrome-line);
}

.header__util { display: flex; align-items: center; gap: 24px; font-family: var(--font-ui); font-size: .8rem; letter-spacing: .04em; color: var(--chrome-muted); }
.header__util span { display: inline-flex; align-items: center; gap: 7px; }
.header__util a { display: inline-flex; align-items: center; min-height: 24px; color: var(--chrome-muted); }
.header__phone-icon { display: none; width: 19px; height: 19px; }
.header__util a:hover { color: var(--chrome-prime); }

/* Оригинальный знак со старого сайта в фирменных цветах: малиновый
   #ED174A сохранён как есть, чернильная монограмма вывернута под чёрную
   подложку. Высота задана, ширина по пропорции. */
.logo { display: block; margin-left: auto; line-height: 0; }
.logo img { height: 40px; width: auto; }

.header__bar { display: flex; align-items: center; gap: 30px; min-height: 76px; }
.header__nav { display: flex; gap: 34px; margin-left: auto; align-self: stretch; }
/* Только сами пункты меню, без ссылок внутри выпадающей панели: иначе капс
   и разрядка протекают в подменю и в промо-текст. */
.header__nav > .header__item > a {
  font-family: var(--font-ui); font-size: .82rem; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--chrome-fg);
}
.header__nav > .header__item > a:hover,
.header__nav > .header__item > a[aria-current] { color: var(--chrome-prime); }


/* Выпадающее меню шапки. Раскрытие по :hover и :focus-within — как
   .prime-nav__ell:hover .prime-nav__inner на g-energy, но с промо-блоком. */
.header__item { display: flex; align-items: center; }
/* Якорь выпадашки — вся навигация, а не пункт: панель шириной 680px,
   прижатая к правому краю пункта «Каталог», на десктопе 993–1140px
   уходила бы за левый край экрана. Правый край навигации совпадает
   с краем контейнера — оттуда панель никогда не вылезает. */
.header__nav { position: relative; }
.header__item > a {
  font-family: var(--font-ui); font-size: .82rem; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--chrome-fg);
  padding: 26px 0;
}
.header__item > a:hover { color: var(--chrome-prime); }

.submenu {
  position: absolute; right: 0; left: auto; top: 100%;
  width: min(680px, calc(100vw - 48px)); padding: 26px;
  display: grid; grid-template-columns: 1fr 240px; gap: 26px;
  background: #fff; border-radius: var(--radius);
  /* Капс и разрядка наследуются от навигации — внутри панели они не нужны. */
  text-transform: none; letter-spacing: normal;
  box-shadow: 0 5px 27px 3px rgba(40, 39, 38, .38);
  z-index: 40;

  /* Раскрытие вместо мгновенной подмены display. Панель всегда в разметке,
     закрытая — прозрачная, приподнятая и невидимая для мыши и скринридера.
     visibility в переходе участвует наравне с непрозрачностью, поэтому
     закрытая панель не перехватывает нажатия по тому, что под ней. */
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateY(-8px);
  transition: opacity var(--t-mid) var(--out), transform var(--t-mid) var(--out), visibility var(--t-mid);
}
.header__item:hover .submenu, .header__item:focus-within .submenu {
  opacity: 1; visibility: visible; pointer-events: auto; transform: none;
}

.submenu__links { list-style: none; margin: 0; padding: 0; }
.submenu__links li { margin-bottom: 2px; }
.submenu__links a {
  display: block; padding: 9px 12px; border-radius: 6px;
  font-size: .92rem; color: #1e1e1e;
  transition: background-color var(--ease), color var(--ease);
}
.submenu__links a:hover { background: #f1f2f2; color: #c4460a; }

.submenu__promo { display: block; color: #1e1e1e; }
.submenu__promo img { width: 100%; height: auto; border-radius: 6px; margin-bottom: 12px; }
.submenu__promo-title { display: block; font-family: var(--font-ui); font-weight: 700; font-size: .95rem; color: #1e1e1e; margin-bottom: 6px; }
.submenu__promo-text { display: block; font-size: .8rem; line-height: 1.45; color: #3c3c3c; margin-bottom: 12px; }
.submenu__promo .link-more { font-size: .7rem; color: #1e1e1e; }
.submenu__promo:hover .submenu__promo-title { color: #c4460a; }


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

/* Правая группа шапки: переключатель темы и бургер. Отступ auto держит
   именно она — в служебной строке кнопка выталкивала логотип за край экрана. */
.header__tools { display: flex; align-items: center; gap: 14px; margin-left: auto; }

.theme-toggle {
  display: inline-flex; align-items: center; justify-content: center;
  width: 34px; height: 34px; padding: 0;
  background: none; border: 1px solid var(--chrome-ctl); border-radius: 50%;
  color: var(--chrome-muted); cursor: pointer;
  transition: color var(--ease), border-color var(--ease);
}
.theme-toggle:hover { color: var(--chrome-prime); border-color: var(--chrome-prime); }
/* display здесь не задаётся намеренно: правило по типу (0,1,1) перебивало бы
   скрытие иконки по классу (0,1,0), и обе иконки показывались разом. */
.theme-toggle svg { width: 17px; height: 17px; }

/* Показываем иконку той темы, в которую переключит: на тёмной — солнце. */
.theme-toggle__sun { display: block; }
.theme-toggle__moon { display: none; }
:root[data-theme="light"] .theme-toggle__sun { display: none; }
:root[data-theme="light"] .theme-toggle__moon { display: block; }
.theme-toggle__label--light { display: none; }
:root[data-theme="light"] .theme-toggle__label--light { display: inline; }
:root[data-theme="light"] .theme-toggle__label--dark { display: none; }

/* ---------- Мобильное меню ---------- */

.header__burger {
  display: none;
  width: 46px; height: 46px; padding: 0;
  background: none; border: 1px solid var(--chrome-ctl);
  border-radius: 50%; cursor: pointer;
  flex-direction: column; align-items: center; justify-content: center; gap: 5px;
}
.header__burger span { display: block; width: 18px; height: 2px; background: var(--chrome-fg); }

.mobile-nav {
  position: fixed; inset: 0; z-index: 60;
  background: var(--chrome); color: var(--chrome-fg);
  padding: 20px; overflow-y: auto;
  display: flex; flex-direction: column; gap: 26px;
  transition: opacity var(--t-mid) var(--out), transform var(--t-mid) var(--out), visibility var(--t-mid);
}

/* Панель открывается и закрывается атрибутом hidden — его ставит nav.js.
   display: none обрывает любой переход, поэтому закрытому состоянию
   возвращаем display и гасим его непрозрачностью и видимостью: скрипт
   не меняется, а панель приходит и уходит плавно.
   Правило перекрывает общее [hidden] { display: none !important } — отсюда
   и !important, и вес селектора. */
.mobile-nav[hidden] {
  display: flex !important;
  opacity: 0; visibility: hidden; pointer-events: none;
  transform: translateY(-10px);
}
.mobile-nav__head { order: -2; display: flex; align-items: center; justify-content: space-between; gap: 10px; }
.mobile-nav__actions { display: flex; align-items: center; gap: 4px; }
.mobile-nav__head .logo { align-items: flex-start; margin-left: 0; }
.mobile-nav__close {
  width: 44px; height: 44px; padding: 0;
  border: 1px solid var(--chrome-ctl); border-radius: 50%; background: none;
  color: var(--chrome-fg); font-size: 1.5rem; line-height: 1; cursor: pointer;
}
.mobile-nav__close:hover { color: var(--chrome-prime); border-color: var(--chrome-prime); }
.mobile-nav__list { display: flex; flex-direction: column; gap: 22px; }
.mobile-nav__group ul { list-style: none; margin: 10px 0 0; padding: 0 0 0 2px; }
.mobile-nav__group li { margin-bottom: 8px; }
.mobile-nav__group li a { color: var(--chrome-muted); font-size: .95rem; }
.mobile-nav__group li a:hover { color: var(--chrome-prime); }
.mobile-nav__title {
  font-family: var(--font-ui); font-size: 1.05rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--chrome-fg);
}
/* Кнопка и телефон стоят сразу под знаком, а не в самом низу: список разделов
   длиннее экрана (1109px против 844), и в подвале панели их не видел никто,
   кто не долистал. order вместо перестановки в разметке — порядок чтения
   с клавиатуры и в разметке остаётся прежним. */
.mobile-nav__foot {
  order: -1;
  padding-bottom: 20px;
  border-bottom: 1px solid var(--chrome-line);
  display: flex; flex-direction: column; gap: 10px;
  font-size: .85rem; color: var(--chrome-muted);
}
.mobile-nav__phone { font-family: var(--font-ui); font-size: 1.2rem; font-weight: 700; color: var(--chrome-fg); }

/* Шапка на сенсорных ширинах — один ярус вместо двух.

   Два яруса это черта референса, но на телефоне они разворачивались в 139px
   (шестая часть экрана) ради четырёх элементов, причём знак уезжал в правый
   верхний угол, а слева, на месте, где его ищут, стояла оранжевая кнопка.
   Читалось как перевёрнутая шапка.

   Ярусы схлопываются без правки разметки: оба контейнера распускаются через
   display: contents, и флексом становится сама .header. Порядок задаёт order,
   горизонтальный отступ переезжает с контейнеров на шапку.

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

@media (max-width: 992px) {
  :root { --header-h: 64px; --header-h-stuck: 56px; }

  .header {
    display: flex; align-items: center; gap: 12px;
    padding: 0 var(--gutter);
    min-height: var(--header-h);
  }
  .header__top, .header__bar { display: contents; }

  .header__top .logo { order: 1; margin-left: 0; }
  .header__top .logo img { height: 30px; }

  .header__util { order: 2; margin-left: auto; gap: 0; }
  /* Город и часы работы: в один ярус со знаком они не помещаются, а дублируются
     в меню и на странице контактов. Телефон остаётся — на телефоне это
     единственный элемент конверсии в шапке. */
  .header__util span:not(.header__phone-text) { display: none; }
  .header__util a { color: var(--chrome-fg); }

  .header__bar > .btn { display: none; }
  .header__tools { order: 3; margin-left: 0; }
  .header__tools .theme-toggle { display: none; }
  /* Кабинет уезжает в меню отдельной строкой: пятый кружок в ярус не влезает,
     а форма входа на 44-пиксельной панели неудобна — в меню она ведёт на
     страницу заявки, где поля нормального размера. */
  .header__tools .account { display: none; }
  .header__burger { display: flex; width: 44px; height: 44px; }

  /* Прижатое состояние: ужимать по ярусам больше нечего, ярус один.
     Знак теряет 4px — движение при прокрутке остаётся заметным. */
  .header.is-stuck { min-height: var(--header-h-stuck); }
  .header.is-stuck .header__top .logo img { height: 26px; }
}

/* Ниже 340px номер текстом рядом со знаком уже не стоит: остаётся трубка
   в такой же кнопке-кружке, что и бургер. */
@media (max-width: 340px) {
  /* Селектор с .header__util, а не голый класс: у соседнего
     .header__util span уже стоит display: inline-flex, и по весу он старше. */
  .header__util .header__phone-text { display: none; }
  .header__phone-icon { display: block; }
  .header__phone {
    justify-content: center;
    width: 44px; padding: 0;
    border: 1px solid var(--chrome-ctl); border-radius: 50%;
    color: var(--chrome-fg);
  }
  .header { gap: 8px; }
}

/* ---------- Крошки ---------- */

/* Только вертикальные отступы: у блока классы container breadcrumbs, и шорткат
   padding обнулял горизонтальный отступ контейнера — крошки прижимало к краю. */
.breadcrumbs { padding-top: 26px; padding-bottom: 6px; }
.breadcrumbs ol { display: flex; flex-wrap: wrap; gap: 10px; list-style: none; margin: 0; padding: 0; }
.breadcrumbs li { display: flex; align-items: center; min-height: 24px; font-family: var(--font-ui); font-size: .72rem; letter-spacing: .09em; text-transform: uppercase; color: var(--grey-text); }
.breadcrumbs li::after { content: "•"; margin-left: 10px; color: var(--grey); }
.breadcrumbs li:last-child::after { content: none; }
.breadcrumbs a { display: flex; align-items: center; align-self: stretch; color: var(--grey-text); }
.breadcrumbs a:hover { color: var(--prime-text); }

/* ---------- Герой: фотофон, крупный заголовок, вкладки слайдов ---------- */

@supports (height: 100svh) { .hero { --hero-min: 100svh; } }
.hero { --hero-interval: 7s; --hero-min: 100vh; position: relative; min-height: var(--hero-min); display: flex; flex-direction: column; justify-content: flex-start; overflow: hidden; background: var(--dark); }

/* Обёртка фонов. Слои вынесены с самих слайдов, потому что на .hero__slide
   уже сидит translateX смены кадра, а на его ::before — бесконечный наезд
   heroScale. Второй transform на том же элементе затёр бы первый.

   Запас только сверху, и это важно: слой едет вниз, снизу ему запас не
   нужен вовсе. Симметричный inset растил бы слой вдвое сильнее, а вместе
   с ним — и масштаб, в котором cover разворачивает кадр: картинка сильнее
   растягивается и сильнее режется по бокам. 25% сверху под ход в 22%. */
.hero__layers { position: absolute; inset: -25% 0 0 0; }

/* Смена слайда — движение справа налево: новый кадр въезжает от правого края,
   прежний уходит за левый. Не растворение: у героя шесть сюжетов, и лента
   читается как лента, а направление подсказывает, что дальше есть ещё.

   Сделано анимациями, а не переходами. У перехода состояние «ушедшего» пришлось
   бы держать классом, и при возврате слайда он въезжал бы не с той стороны;
   анимация же отыгрывает и оставляет элемент в исходном положении — за правым
   краем, готовым к следующему выходу. */
.hero__slide {
  position: absolute; inset: 0;
  background-position: center center; background-size: cover; background-repeat: no-repeat;
  opacity: 0;
}
.hero__slide.is-active { opacity: 1; }
.hero__slide.is-entering { animation: heroSlideIn var(--t-hero) var(--out); }
.hero__slide.is-leaving { animation: heroSlideOut var(--t-hero) var(--out); }

@keyframes heroSlideIn { from { transform: translateX(100%); } to { transform: none; } }
@keyframes heroSlideOut {
  from { transform: none; opacity: 1; }
  to { transform: translateX(-100%); opacity: 0; }
}
/* Медленный наезд — приём из .section-prime__bg--image (14s, бесконечно) */
.hero__slide.is-active::before {
  content: ""; position: absolute; inset: 0;
  background: inherit; background-size: cover; background-position: center;
  animation: heroScale 16s ease-in-out infinite alternate;
}
.hero::after {
  content: ""; position: absolute; inset: 0;
  background: linear-gradient(90deg, rgba(24, 22, 21, .82) 0%, rgba(24, 22, 21, .55) 45%, rgba(24, 22, 21, .25) 100%);
  z-index: 1;
}

@keyframes heroScale { from { transform: scale(1); } to { transform: scale(1.08); } }

/* Контент занимает всё поле над таймлайном и центрируется по вертикали —
   раньше он был прижат к низу. Текст и блок подбора — слева, узкой колонкой;
   горизонтальные отступы приходят от .container. */
.hero__inner {
  position: relative; z-index: 2;
  flex: 1 1 auto; display: flex; flex-direction: column; justify-content: center;
  padding-top: 40px; padding-bottom: 24px;
}
.hero__stage { max-width: 640px; }
.hero__eyebrow {
  display: inline-block; font-family: var(--font-ui); font-size: .78rem; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--prime-hover); margin-bottom: 16px;
}
.hero h1 { font-size: 3.25rem; font-weight: 700; line-height: 1.12; color: #fff; margin-bottom: 20px; }
.hero__desc { font-size: 1.125rem; color: rgba(255, 255, 255, .85); margin-bottom: 28px; max-width: 620px; }
.hero__actions { display: flex; flex-wrap: wrap; gap: 14px; }

/* Поле подбора вынесено отдельной полосой над «Брендами» (в герое
   перегружало первый экран). Сам чат открывается drawer'ом — стили ниже. */
.ai-card { max-width: 720px; margin: 0 auto; text-align: center; }
.ai-card__ttl { font-size: 1.6rem; font-weight: 700; line-height: 1.2; color: var(--ink-strong); margin: 0 0 8px; }
.ai-card__sub { font-size: 1rem; line-height: 1.5; color: var(--grey-text); margin: 0 auto 22px; max-width: 560px; }
.ai-card__form { display: flex; gap: 10px; max-width: 620px; margin: 0 auto; }
.ai-card__input {
  flex: 1; min-width: 0; padding: 14px 20px; font: inherit; font-size: 1rem;
  color: var(--ink); background: var(--surface); border: 1px solid var(--grey);
  border-radius: var(--radius-pill); transition: border-color var(--ease);
}
.ai-card__input::placeholder { color: var(--grey-text); }
.ai-card__input:focus { outline: none; border-color: var(--prime); }
.ai-card__form .btn { flex: 0 0 auto; }
.ai-card__chips { display: flex; justify-content: center; flex-wrap: wrap; gap: 8px; margin-top: 16px; }
.ai-card__chip {
  padding: 7px 14px; font: inherit; font-size: .84rem; cursor: pointer;
  color: var(--ink); background: var(--surface); border: 1px solid var(--line);
  border-radius: var(--radius-pill); transition: border-color var(--ease), color var(--ease);
}
.ai-card__chip:hover { border-color: var(--prime); color: var(--prime-text); }
@media (max-width: 560px) {
  .ai-card__form { flex-direction: column; }
  .ai-card__chips { flex-wrap: nowrap; overflow-x: auto; justify-content: flex-start; scrollbar-width: none; }
  .ai-card__chips::-webkit-scrollbar { display: none; }
  .ai-card__chip { flex: 0 0 auto; }
}

/* Выдвижная панель чата справа — по образцу «борфи новый сайт-v2». */
.ai-overlay { position: fixed; inset: 0; background: rgba(8, 8, 9, .5); z-index: 200; opacity: 0; pointer-events: none; transition: opacity var(--t-mid) var(--out); }
.ai-overlay.is-open { opacity: 1; pointer-events: auto; }
.ai-drawer {
  position: fixed; top: 0; right: 0; bottom: 0; width: min(460px, 100vw); z-index: 201;
  display: flex; flex-direction: column; background: var(--surface); color: var(--ink);
  transform: translateX(100%); visibility: hidden;
  transition: transform var(--t-mid) var(--out), visibility 0s linear var(--t-mid);
  box-shadow: -24px 0 60px rgba(8, 8, 9, .32);
}
.ai-drawer.is-open { transform: none; visibility: visible; transition: transform var(--t-mid) var(--out), visibility 0s; }
.ai-drawer__head { display: flex; align-items: flex-start; gap: 12px; padding: 20px 22px 16px; border-bottom: 1px solid var(--line); }
.ai-drawer__who { flex: 1; min-width: 0; }
.ai-drawer__nm { display: flex; align-items: center; gap: 8px; font-family: var(--font-ui); font-weight: 700; font-size: 1.1rem; color: var(--ink-strong); }
.ai-drawer__dot { width: 8px; height: 8px; border-radius: 50%; background: var(--prime); box-shadow: 0 0 0 3px color-mix(in srgb, var(--prime) 32%, transparent); flex: 0 0 auto; }
.ai-drawer__dsc { font-size: .85rem; color: var(--grey-text); margin-top: 4px; }
.ai-drawer__close { width: 40px; height: 40px; border-radius: 50%; border: 1px solid var(--line); background: var(--surface); color: var(--ink); display: inline-flex; align-items: center; justify-content: center; cursor: pointer; flex: 0 0 auto; }
.ai-drawer__close svg { width: 18px; height: 18px; }
.ai-drawer__close:hover { border-color: var(--prime); color: var(--prime-text); }
.ai-drawer__log { flex: 1; overflow-y: auto; padding: 20px 22px; display: flex; flex-direction: column; gap: 14px; overscroll-behavior: contain; }
.ai-msg { max-width: 92%; font-size: .98rem; line-height: 1.4; }
.ai-msg.user { align-self: flex-end; background: var(--prime); color: #fff; border-radius: 16px 16px 4px 16px; padding: 11px 15px; white-space: pre-wrap; }
.ai-msg.bot { align-self: flex-start; background: var(--light); color: var(--ink); border-radius: 16px 16px 16px 4px; padding: 13px 16px; }
.ai-msg.bot p { margin: 0 0 10px; }
.ai-msg.bot p:last-child { margin-bottom: 0; }
.ai-acts { display: flex; flex-wrap: wrap; gap: 8px; }
.ai-act {
  font: inherit; font-size: .85rem; cursor: pointer; color: var(--ink); text-decoration: none;
  padding: 7px 13px; background: var(--surface); border: 1px solid var(--grey); border-radius: var(--radius-pill);
  transition: border-color var(--ease), color var(--ease);
}
.ai-act:hover { border-color: var(--prime); color: var(--prime-text); }
.ai-msg.wait { padding: 4px 2px; }
.ai-dots { display: inline-flex; gap: 5px; }
.ai-dots i { width: 7px; height: 7px; border-radius: 50%; background: var(--grey-text); animation: aiDot 1.2s ease-in-out infinite; }
.ai-dots i:nth-child(2) { animation-delay: .15s; }
.ai-dots i:nth-child(3) { animation-delay: .3s; }
/* Ответ помощника: списки, ссылки, карточки найденных позиций, ошибка. */
.ai-msg.bot ul { margin: 0 0 10px; padding-left: 18px; }
.ai-msg.bot li { margin: 3px 0; }
.ai-msg.bot p a, .ai-msg.bot li a { color: var(--prime-text); text-decoration: underline; text-underline-offset: 2px; }
.ai-msg.bot p a:hover, .ai-msg.bot li a:hover { color: var(--prime-text-hover); }
.ai-msg.bot a.ai-act { text-decoration: none; }
.ai-msg.bot.is-error { border: 1px solid var(--prime); }
.ai-cards { display: grid; gap: 8px; margin-top: 10px; }
.ai-card-mini { display: flex; flex-direction: column; gap: 2px; padding: 10px 12px; border: 1px solid var(--line); border-radius: 12px; background: var(--surface); color: var(--ink); text-decoration: none; transition: border-color var(--ease); }
.ai-card-mini:hover { border-color: var(--prime); }
.ai-card-mini b { font-size: .92rem; line-height: 1.3; color: var(--ink-strong); }
.ai-card-mini span { font-size: .78rem; color: var(--grey-text); }
.ai-msg.bot .ai-acts { margin-top: 10px; }
.ai-drawer__note { margin: 0; padding: 0 18px 12px; font-size: .74rem; line-height: 1.4; color: var(--grey-text); }
@keyframes aiDot { 0%, 60%, 100% { opacity: .35; transform: translateY(0); } 30% { opacity: 1; transform: translateY(-4px); } }
.ai-drawer__input { display: flex; gap: 10px; padding: 14px 18px; border-top: 1px solid var(--line); }
.ai-drawer__input input {
  flex: 1; min-width: 0; padding: 11px 15px; font: inherit; font-size: 1rem;
  color: var(--ink); background: var(--surface); border: 1px solid var(--grey); border-radius: var(--radius-pill);
}
.ai-drawer__input input:focus { outline: none; border-color: var(--prime); }
.ai-drawer__send { width: 44px; height: 44px; border-radius: 50%; border: 0; background: var(--prime); color: #fff; display: inline-flex; align-items: center; justify-content: center; cursor: pointer; flex: 0 0 auto; }
.ai-drawer__send svg { width: 18px; height: 18px; }
body.ai-locked { overflow: hidden; }
@media (prefers-reduced-motion: reduce) {
  .ai-overlay, .ai-drawer { transition: none; }
  .ai-dots i { animation: none; opacity: .7; }
}

/* ---- Параллакс первого экрана ----

   Фон отстаёт от прокрутки, текст уходит чуть быстрее. Разница хода и есть
   ощущение глубины: одинаковая скорость читалась бы как плоская картинка.

   Считает браузер, прокруточным таймлайном — той же идиомой, что ужимает
   шапку выше. В обработчике прокрутки не висит ничего, движение идёт
   в композиторе.

   Ход задан долей от высоты героя, а не процентом от самого слоя: слой на
   выше героя, и процент от него дал бы число, которое ничего не значит
   при чтении. 13% высоты героя — это 13% высоты героя.

   Диапазон тоже привязан к герою, а не к 100vh: у героя своя min-height,
   и на высоком экране движение кончалось бы раньше, чем он уедет.

   Без поддержки таймлайнов эффекта нет, фон стоит. Это украшение, а не
   навигация: держать ради него слушатель прокрутки и считать позиции в JS
   дороже, чем потерять эффект в старом браузере. При сокращённом движении
   выключается по той же причине, по какой выключено всё остальное. */
@supports (animation-timeline: scroll()) {
  @media (prefers-reduced-motion: no-preference) {
    .hero__layers,
    .hero__inner {
      animation-timing-function: linear;
      animation-fill-mode: both;
      animation-timeline: scroll(root block);
      animation-range: 0 100vh;
    }
    .hero__layers { animation-name: heroParallaxBack; }
    .hero__inner { animation-name: heroParallaxFront; }
  }
}

@keyframes heroParallaxBack {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(0, 22vh, 0); }
}
@keyframes heroParallaxFront {
  from { transform: translate3d(0, 0, 0); }
  to { transform: translate3d(0, -8vh, 0); }
}

/* Вкладки слайдов внизу героя — узнаваемый элемент g-energy */
.hero__tabs { position: relative; z-index: 2; display: grid; grid-auto-flow: column; grid-auto-columns: 1fr; gap: 26px; padding-bottom: 34px; }
/* Колонка с прижатием к верху. Браузер центрирует содержимое button
   по вертикали, поэтому у вкладок с короткой подписью полоса опускалась
   ниже, чем у соседней с более длинной. */
.hero__tab {
  display: flex; flex-direction: column; justify-content: flex-start;
  text-align: left; background: none; border: 0; padding: 0; cursor: pointer;
  color: rgba(255, 255, 255, .68);
  font-family: var(--font-ui); font-size: .92rem; font-weight: 600;
  letter-spacing: 0; line-height: 1.3;
  transition: color var(--ease);
}
.hero__tab:hover { color: #fff; }
.hero__tab.is-active { color: var(--prime-hover); }

/* Дорожка и индикатор: у g-energy это .section-prime__progress (белая полоса
   3px) и .section-prime__bar (оранжевая заливка, растущая от width: 0). */
.hero__tab-track {
  display: block; height: 3px; border-radius: 2px; overflow: hidden;
  background: rgba(255, 255, 255, .28); margin-bottom: 14px;
}
.hero__tab-bar { display: block; height: 100%; width: 0; background: var(--prime); }
.hero__tab.is-active .hero__tab-track { background: rgba(255, 255, 255, .4); }
.hero__tab.is-active .hero__tab-bar {
  animation: heroProgress var(--hero-interval, 7s) linear forwards;
}
.hero__tab-label { display: -webkit-box; -webkit-line-clamp: 2; -webkit-box-orient: vertical; overflow: hidden; }

@keyframes heroProgress { from { width: 0; } to { width: 100%; } }

/* Наведение останавливает таймер — индикатор замирает вместе с ним. */
.hero.is-paused .hero__tab-bar { animation-play-state: paused; }

/* Текст слайда проявляется с лёгким подъёмом: смена не должна читаться
   как мгновенная подмена. */
.hero__stage { min-height: 268px; }
.hero__content { animation: heroContent var(--t-hero) var(--out) both; }

@keyframes heroContent {
  from { opacity: 0; transform: translateX(52px); }
  to { opacity: 1; transform: none; }
}

/* ---------- Секции ---------- */

.section { padding: 76px 0; }
/* Страница с полосой-шапкой: крошки уже дали отступ сверху, второй лишний. */
.section--page { padding-top: 6px; }

/* Текстовая страница держит одну меру на всё: полосу-шапку, плашки фактов
   и прозу. Разная ширина у соседних блоков даёт ступеньку по правому краю,
   а колонка шире 70 знаков теряет начало следующей строки.
   Колонка прижата влево — по той же вертикали, что крошки, знак и навигация. */
.section--text { --measure: 68ch; padding-top: 6px; }
.section--text > .page-head--cover { margin-top: 14px; }
.section--text .page-head:not(.page-head--cover),
.section--text .prose,
.section--text .facts { max-width: var(--measure); }
.section--light { background: var(--light); }
.section--dark { background: var(--light); color: var(--ink); }
.section--dark h2, .section--dark h3 { color: var(--ink-strong); }

.section__head { display: flex; align-items: center; justify-content: space-between; gap: 24px; margin-bottom: 40px; }
.section__head h2 { margin: 0; }
.section__head--center { flex-direction: column; text-align: center; gap: 14px; }

/* ---------- Крупные числа ---------- */

/* Числа стоят на общем рельсе и разделены волосяной линией: без неё четыре
   разновысоких столбика читались как четыре отдельных блока, а не как одна
   строка показателей. Линия рисуется слева у каждого, кроме первого. */
.stats { display: grid; grid-template-columns: repeat(4, 1fr); gap: 0; border-top: 1px solid var(--line); padding-top: 26px; }
.stat { padding: 0 30px; border-left: 1px solid var(--line); }
.stat:first-child { padding-left: 0; border-left: 0; }
/* Иконка над числом: монохромный 3D-рендер с оранжевыми акцентами (Polza),
   парит прямо на фоне блока — без плашки, фон прозрачный. */
.stat__icon {
  display: block; width: 84px; height: 84px; margin-bottom: 14px; object-fit: contain;
  filter: drop-shadow(0 8px 16px rgba(8, 8, 9, .32));
}
.stat b { display: block; font-family: var(--font); font-size: 2.9rem; font-weight: 600; line-height: 1; color: var(--prime-text); margin-bottom: 8px; letter-spacing: -.02em; }
.section--dark .stat b { color: var(--prime-text); }
.stat span { font-size: .92rem; color: var(--grey-text); }
.section--dark .stat span { color: var(--grey-text); }

/* ---------- Сетки и карточки ---------- */

.grid { display: grid; gap: 22px; }
.grid--2 { grid-template-columns: repeat(2, 1fr); }
.grid--3 { grid-template-columns: repeat(3, 1fr); }
.grid--4 { grid-template-columns: repeat(4, 1fr); }

/* ---------- Бренды на главной: список-оглавление ---------- */
/* Марки — строками во всю ширину, как оглавление каталога, а не плитками:
   у семи марок вес от трёхсот позиций до одной, и одинаковые карточки врали
   бы про равенство. Снимок товара всплывает под курсором (brands.js): чужие
   товарные знаки не рисуем, настоящая банка узнаётся лучше и не устаревает. */
.brands__lead { max-width: 60ch; margin: -22px 0 34px; color: var(--grey-text); }
.brands__list { position: relative; list-style: none; margin: 0; padding: 0; border-top: 1px solid var(--line); }
.brands__item { border-bottom: 1px solid var(--line); }
/* Ширины двух правых колонок заданы числом: у каждой строки своя сетка, и
   колонки с «auto» гуляли бы между строками на ширину числа позиций. */
.brands__row { position: relative; display: grid; grid-template-columns: minmax(0, 1.1fr) minmax(0, 1fr) 128px 46px; align-items: center; gap: 32px; padding: 26px 0; color: var(--ink); text-decoration: none; }
/* Оранжевая линия вырастает слева под строкой, что под курсором. */
.brands__row::after { content: ""; position: absolute; left: 0; right: 0; bottom: -1px; height: 1px; background: var(--prime); transform: scaleX(0); transform-origin: left; transition: transform .55s var(--out); }
.brands__row:hover::after, .brands__row:focus-visible::after { transform: scaleX(1); }
.brands__name { font-family: var(--font-ui); font-size: clamp(1.45rem, 2.6vw, 2.25rem); font-weight: 700; line-height: 1; letter-spacing: .01em; text-transform: uppercase; color: var(--ink-strong); transition: color var(--ease), transform var(--t-mid) var(--out); }
.brands__row:hover .brands__name, .brands__row:focus-visible .brands__name { color: var(--prime-text); transform: translateX(12px); }
.brands__desc { font-size: .95rem; line-height: 1.5; color: var(--grey-text); }
.brands__count { font-family: var(--font-ui); font-size: .76rem; font-weight: 700; letter-spacing: .09em; text-transform: uppercase; white-space: nowrap; text-align: right; color: var(--prime-text); }
.brands__go { display: inline-flex; align-items: center; justify-content: center; width: 46px; height: 46px; border: 1px solid var(--line); border-radius: 50%; color: var(--ink-strong); transition: background-color var(--t-mid) var(--out), border-color var(--t-mid) var(--out), color var(--t-mid) var(--out), transform var(--t-mid) var(--out); }
.brands__go svg { width: 18px; height: 18px; }
.brands__row:hover .brands__go, .brands__row:focus-visible .brands__go { background: var(--btn-fill); border-color: var(--btn-fill); color: var(--on-prime); transform: rotate(-45deg); }
.brands__row:focus-visible { outline: none; }
.brands__row:focus-visible .brands__name { text-decoration: underline; text-underline-offset: 6px; }
/* Снимок: карточка над списком. Без скрипта встаёт справа от строки по
   наведению; со скриптом едет за курсором (transform ставит brands.js). */
.brands__shot { position: absolute; z-index: 2; top: 50%; right: 150px; width: 220px; height: 220px; display: flex; align-items: center; justify-content: center; border-radius: var(--radius); background: var(--photo-tile); box-shadow: var(--shadow-lift); overflow: hidden; opacity: 0; transform: translateY(-50%) rotate(-5deg) scale(.9); transition: opacity var(--t-mid) linear, transform .5s var(--out); pointer-events: none; }
.brands__shot img { max-width: 78%; max-height: 78%; width: auto; height: auto; mix-blend-mode: multiply; }
/* Плашка марки без снимка — та же светлая карточка, что и у снимков: имя
   тёмным, за ним крупный инициал оранжевым вполнакала; на телефоне остаётся
   один инициал. Логотип МИТЛИС — цветной, на той же карточке. */
.brands__shot--type b { position: relative; padding: 18px; font-family: var(--font-ui); font-size: 1.35rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; text-align: center; color: #1e1e1e; }
.brands__shot--type i { position: absolute; left: 50%; top: 50%; transform: translate(-50%, -54%); font-family: var(--font-ui); font-style: normal; font-weight: 700; font-size: 11rem; line-height: 1; color: rgba(227, 82, 5, .14); pointer-events: none; }
.brands__shot--type img { position: relative; max-width: 62%; mix-blend-mode: normal; }
.brands__row:hover .brands__shot, .brands__row:focus-visible .brands__shot, .brands__shot.is-on { opacity: 1; transform: translateY(-50%) rotate(0) scale(1); }
/* Со скриптом положение и наклон считает brands.js от курсора; переход
   остаётся только у прозрачности, иначе снимок отставал бы от руки. */
.brands--fx .brands__shot, .brands--fx .brands__row:hover .brands__shot, .brands--fx .brands__shot.is-on { top: 0; right: auto; left: 0; transform: none; transition: opacity var(--t-mid) linear; will-change: transform; }
/* С клавиатуры снимок встаёт на место без скрипта — справа от строки
   (brands.js на фокусе снимает свой transform). */
.brands--fx .brands__row:focus-visible .brands__shot { left: auto; right: 150px; top: 50%; transform: translateY(-50%); }
/* Строки входят в кадр ступенькой (brands.js ставит brands-fx и is-in). */
.brands-fx .brands__item { opacity: 0; transform: translateY(18px); transition: opacity .6s var(--out), transform .6s var(--out); transition-delay: calc(var(--i, 0) * 55ms); }
.brands-fx .brands__list.is-in .brands__item { opacity: 1; transform: none; }
@media (max-width: 992px) {
  .brands__row { grid-template-columns: 72px minmax(0, 1fr) auto; grid-template-areas: "shot name go" "shot desc go" "shot count go"; gap: 4px 18px; padding: 18px 0; }
  .brands__name { grid-area: name; font-size: clamp(1.3rem, 4.6vw, 1.8rem); }
  .brands__desc { grid-area: desc; font-size: .9rem; }
  .brands__count { grid-area: count; margin-top: 4px; }
  .brands__go { grid-area: go; width: 40px; height: 40px; }
  .brands__row:hover .brands__name { transform: none; }
  .brands__shot, .brands--fx .brands__shot { grid-area: shot; position: static; width: 72px; height: 72px; border-radius: 14px; opacity: 1; box-shadow: none; transform: none !important; transition: none; }
  .brands__shot--type b, .brands__shot--type img { display: none; }
  .brands__shot--type i { position: static; transform: none; font-size: 1.7rem; color: #c4460a; }
}

/* Карточка товара — как в каталоге g-energy */
.product-card {
  display: flex; flex-direction: column; background: var(--white);
  border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden;
  transition: border-color var(--ease), box-shadow var(--t-mid) var(--out), transform var(--t-mid) var(--out);
}
.product-card:hover { border-color: var(--prime); box-shadow: var(--shadow-lift); transform: translateY(-3px); }
.product-card__media { height: 230px; display: flex; align-items: center; justify-content: center; padding: 22px; background: var(--photo-tile); overflow: hidden; }
.product-card__media img {
  max-height: 100%; max-width: 100%; width: auto; object-fit: contain; mix-blend-mode: multiply;
  transition: transform var(--t-slow) var(--out);
}
.product-card:hover .product-card__media img { transform: scale(1.05); }
.product-card__body { padding: 22px; display: flex; flex-direction: column; flex: 1; }
.product-card__brand { font-family: var(--font-ui); font-size: .68rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--grey-text); margin-bottom: 8px; }
.product-card__name { font-family: var(--font-ui); font-size: 1.05rem; font-weight: 700; letter-spacing: .02em; text-transform: uppercase; color: var(--prime-text); margin-bottom: 10px; }
.product-card__packs { font-size: .82rem; color: var(--grey-text); margin-bottom: 16px; }
.product-card__price { margin-top: auto; font-family: var(--font); font-size: 1.15rem; font-weight: 600; color: var(--ink-strong); }
.product-card__price small { display: block; font-size: .74rem; font-weight: 400; color: var(--grey-text); margin-top: 4px; }
.product-card__price small .stock { font-size: .74rem; }

/* Лежит на светлой плитке, поэтому цвет свой, а не токен тёмного текста. */
/* ---------- Наличие и артикул ---------- */
/* Состояние передаётся словами, цвет только помогает: «В наличии 322 шт»
   читается и в монохроме, и дальтоником. */

.stock { font-family: var(--font-ui); font-weight: 700; letter-spacing: .02em; }
.stock--in { color: var(--ok-text); }
.stock--order { color: var(--prime-text); }
.stock--ask { color: var(--grey-text); }

.pack__sku {
  font-family: var(--font-ui); font-size: .72rem; letter-spacing: .06em;
  color: var(--grey-text); margin-bottom: 14px;
}

/* Фотографии нет у 157 товаров из 710 — это пятая часть сетки. Голая надпись
   читалась как незагрузившаяся картинка, поэтому рисуем силуэт канистры.
   Цвета свои, а не токены: плитка под снимком светлая в обеих темах. */
.media-empty {
  display: flex; flex-direction: column; align-items: center; justify-content: center; gap: 10px;
  font-family: var(--font-ui); font-size: .72rem; letter-spacing: .08em;
  text-transform: uppercase; color: #66615b; text-align: center; padding: 0 14px;
}
.media-empty svg { width: 44px; height: 44px; stroke: #847d75; fill: none; stroke-width: 1.5; }

/* ---------- Плоский каталог ---------- */
/* Каталог показывает все 710 позиций сразу, а срез задают фильтры — так
   устроен каталог new.borfi.ru, сайта той же компании. Пошаговое хождение
   «марка → раздел → товар» заменено на один список: покупатель, знающий
   артикул или марку, доходит за один шаг вместо трёх. */

.cat-tabs { display: flex; flex-wrap: wrap; gap: 10px; margin: 26px 0 22px; }
.cat-tab {
  display: inline-flex; align-items: baseline; gap: 8px;
  padding: 11px 20px; cursor: pointer;
  background: var(--white); border: 1px solid var(--grey);
  border-radius: var(--radius-pill);
  font-family: var(--font-ui); font-size: .82rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink);
  transition: background-color var(--ease), border-color var(--ease), color var(--ease);
}
.cat-tab span { font-size: .74rem; font-weight: 400; letter-spacing: 0; color: var(--grey-text); }
.cat-tab:hover { border-color: var(--prime); }
.cat-tab.is-active { background: var(--btn-fill); border-color: var(--btn-fill); color: var(--on-prime); }
.cat-tab.is-active span { color: var(--on-prime); opacity: .75; }

.cat-layout { display: grid; grid-template-columns: 268px 1fr; gap: 28px; align-items: start; }

/* Боковая панель разделов выбранной марки. */
.cat-side__toggle { display: none; }
.cat-side__panels { position: sticky; top: calc(var(--header-h-stuck) + 20px); }
.side-brand ul { list-style: none; margin: 0 0 14px; padding: 0; }
.side-brand li { margin-bottom: 2px; }
.side-brand button {
  display: flex; align-items: baseline; justify-content: space-between; gap: 10px;
  width: 100%; padding: 9px 12px; cursor: pointer; text-align: left;
  background: none; border: 0; border-radius: 6px;
  font: inherit; font-size: .92rem; color: var(--ink);
  transition: background-color var(--ease), color var(--ease);
}
.side-brand button span { font-size: .78rem; color: var(--grey-text); }
.side-brand button:hover { background: var(--light); color: var(--prime-text); }
.side-brand button[aria-pressed="true"] {
  background: var(--light); color: var(--prime-text); font-weight: 700;
}
.side-link {
  display: inline-flex; align-items: center; min-height: 24px; font-family: var(--font-ui); font-size: .76rem;
  letter-spacing: .06em; text-transform: uppercase;
}

/* Строка над сеткой: счётчик, наличие, поиск. */
.cat-tools {
  display: flex; align-items: center; gap: 16px; flex-wrap: wrap;
  margin-bottom: 18px;
}
.cat-count {
  font-family: var(--font-ui); font-size: .82rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink-strong);
}
.cat-stock {
  display: inline-flex; align-items: center; min-height: 24px; gap: 8px;
  font-size: .88rem; color: var(--ink); cursor: pointer;
}
.cat-stock input { width: 17px; height: 17px; accent-color: var(--prime); cursor: pointer; }
.cat-search { margin: 0 0 0 auto; min-width: 260px; }
.cat-search input { min-height: 44px; }

.cat-empty { padding: 40px 0; color: var(--grey-text); }

@media (max-width: 992px) {
  .cat-layout { grid-template-columns: 1fr; gap: 0; }
  /* Список разделов длиннее первого экрана и иначе отодвигает сам каталог. */
  .cat-side__toggle {
    display: inline-flex; align-items: center; gap: 10px;
    min-height: 44px; padding: 0 18px; margin-bottom: 14px;
    background: var(--white); border: 1px solid var(--grey);
    border-radius: var(--radius-pill); cursor: pointer;
    font-family: var(--font-ui); font-size: .8rem; font-weight: 700;
    letter-spacing: .06em; text-transform: uppercase; color: var(--ink);
  }
  .cat-side__toggle svg { width: 18px; height: 18px; }
  .cat-side__panels { display: none; position: static; margin-bottom: 22px; }
  .cat-side.is-open .cat-side__panels { display: block; }
  .cat-search { margin-left: 0; width: 100%; }
}

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

.section-cards {
  display: grid; grid-template-columns: repeat(auto-fill, minmax(236px, 1fr));
  gap: 14px; margin: 26px 0 40px;
}

.section-card {
  display: flex; align-items: stretch; gap: 0; min-height: 92px;
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius); overflow: hidden; color: var(--ink);
  transition: border-color var(--ease), box-shadow var(--t-mid) var(--out), transform var(--t-mid) var(--out);
}
.section-card:hover { border-color: var(--prime); box-shadow: var(--shadow-lift); transform: translateY(-3px); }

.section-card__media {
  flex: none; width: 88px;
  display: flex; align-items: center; justify-content: center;
  background: var(--photo-tile); overflow: hidden;
}
/* Снимки сняты на белом — multiply убирает границу подложки.
   Размеры в пикселях, а не в процентах: процент от блока с авто-высотой
   не ограничивает картинку, и она растягивала строку сетки втрое. */
.section-card__media img {
  max-width: 66px; max-height: 66px; width: auto; height: auto;
  mix-blend-mode: multiply; transition: transform var(--t-slow) var(--out);
}
.section-card:hover .section-card__media img { transform: scale(1.07); }

/* Раздел без единой фотографии: вместо пустой плашки — знак из фирменной
   линии, чтобы карточка не читалась как незагрузившаяся картинка. */
.section-card--bare .section-card__media { background: var(--light); }
.section-card__mark {
  width: 22px; height: 22px; border: 2px solid var(--prime);
  border-radius: 3px 12px 3px 12px;
}

.section-card__body {
  display: flex; flex-direction: column; justify-content: center; gap: 4px;
  padding: 14px 16px; min-width: 0;
}
.section-card__name {
  font-family: var(--font-ui); font-weight: 700; font-size: .95rem;
  line-height: 1.25; color: var(--ink-strong);
}
.section-card__count { font-size: .8rem; color: var(--grey-text); }

/* Плитки разделов */
.section-list { display: flex; flex-wrap: wrap; gap: 10px; margin-bottom: 36px; padding: 0; list-style: none; }
.section-list a {
  display: inline-flex; align-items: center; padding: 11px 20px;
  border: 1px solid var(--grey); border-radius: var(--radius-pill);
  font-family: var(--font-ui); font-size: .8rem; letter-spacing: .04em;
  color: var(--ink); background: var(--white);
  transition: border-color var(--ease), color var(--ease);
}
.section-list a:hover { border-color: var(--prime); color: var(--prime-text); }
.section-list b { font-weight: 700; margin-left: 8px; color: var(--grey-text); }

/* ---------- Широкие баннеры-полосы ---------- */

.banner {
  display: grid; grid-template-columns: 1fr auto; align-items: center; gap: 30px;
  padding: 34px 40px; border-radius: var(--radius); margin-bottom: 22px;
  background: var(--surface);
}
.banner--prime { background: linear-gradient(100deg, #c4460a 0%, #e35205 55%, #f46316 100%); color: #fff; }

/* Два предложения рядом, снимок склада полосой под ними. Текст и кнопка
   в узкой колонке встают друг под друга — в две колонки по 40 знаков
   заголовок ломался на четыре строки. */
/* Нижний отступ несёт сам ряд: у баннеров внутри грида margin-bottom
   съедается ячейкой (height: 100%), и ряд прилипал к полосе со снимком. */
.banner-row { display: grid; grid-template-columns: 1fr 1fr; gap: 22px; margin-bottom: 22px; }
.banner-row .banner { margin-bottom: 0; }
.banner--stack { grid-template-columns: 1fr; align-content: space-between; gap: 22px; height: 100%; }
@media (max-width: 860px) { .banner-row { grid-template-columns: 1fr; } }
.banner--dark { background: var(--surface); color: var(--grey-text); border: 1px solid var(--line); }

/* Полоса с фотографией склада. Единственный блок на главной, который делает
   утверждение о наличии, — ему и нужна опора на снимок, а не ещё один текст.
   Картинка вставлена тегом, а не фоном: так у неё есть width/height, страница
   не дёргается при загрузке и работает loading="lazy". */
.banner--photo {
  position: relative; overflow: hidden; border: 0;
  min-height: 216px; align-items: end; color: #f4f2f0;
}
.banner__bg {
  position: absolute; inset: 0; width: 100%; height: 100%;
  object-fit: cover; z-index: 0;
}
/* Затемнение слева направо — тот же приём, что у героя. Текст лежит на
   плотной части: белый по rgba(8,8,9,.88) даёт больше 15:1. */
.banner--photo::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(90deg, rgba(8, 8, 9, .88) 0%, rgba(8, 8, 9, .74) 44%, rgba(8, 8, 9, .3) 100%);
}
.banner--photo > div { position: relative; z-index: 2; }
.banner--photo .banner__title { color: #fff; }
.banner--photo .banner__text { color: rgba(255, 255, 255, .86); margin: 0; }

@media (max-width: 640px) {
  /* На узком экране колонки складываются, и затемнение должно накрывать всё
     полотно, иначе подпись ложится на светлую часть снимка. */
  .banner--photo::after {
    background: linear-gradient(180deg, rgba(8, 8, 9, .82) 0%, rgba(8, 8, 9, .9) 100%);
  }
}
.banner__title { font-size: 1.45rem; font-weight: 600; line-height: 1.25; margin: 0 0 6px; color: var(--ink-strong); }
.banner--prime .banner__title { color: #fff; }
.banner--dark .banner__title { color: var(--ink-strong); }
.banner__text { margin: 0; font-size: .95rem; color: var(--grey-text); }
.banner--prime .banner__text { color: rgba(255, 255, 255, .85); }
.banner--dark .banner__text { color: var(--grey-text); }
.banner__actions { display: flex; gap: 12px; flex-wrap: wrap; }

/* ---------- Страница товара ---------- */

.product-head { display: grid; grid-template-columns: 460px 1fr; gap: 46px; padding-top: 16px; padding-bottom: 52px; }
.product-head__media { background: var(--photo-tile); border-radius: var(--radius); padding: 36px; display: flex; align-items: center; justify-content: center; min-height: 420px; }
.product-head__media img { max-height: 400px; width: auto; mix-blend-mode: multiply; }
.product-head__brand { font-family: var(--font-ui); font-size: .72rem; font-weight: 700; letter-spacing: .16em; text-transform: uppercase; color: var(--grey-text); margin-bottom: 10px; }
.product-head h1 { font-size: 2.3rem; font-weight: 700; margin-bottom: 16px; }
.product-head__lead { font-size: 1.02rem; color: var(--grey-text); }
.product-head__meta { display: flex; flex-wrap: wrap; gap: 10px; margin: 24px 0; }
.tag { display: inline-flex; padding: 8px 16px; border-radius: var(--radius-pill); background: var(--light); color: var(--ink); font-family: var(--font-ui); font-size: .74rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.tag--prime { background: var(--prime-pale); color: var(--prime-dark); }
.product-head__actions { display: flex; flex-wrap: wrap; gap: 14px; }

/* Вертикальные отступы задаём отдельно: у блока классы container product-detail,
   и шорткат padding обнулял бы горизонтальный отступ контейнера. */
/* Мера описания: на 1240px строка уходила за 120 знаков, а в таблице
   показатель и значение расходились по разным краям экрана. */
.product-detail { padding-top: 8px; padding-bottom: 64px; max-width: 1000px; }
.product-detail h3 { font-family: var(--font-ui); font-size: 1.05rem; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-strong); margin-top: 32px; }
.product-detail li { margin-bottom: 7px; }

/* ---------- Блок «Цены и фасовки» ---------- */

.order { padding: 60px 0 72px; background: var(--light); }
.order__terms { display: grid; grid-template-columns: repeat(4, 1fr); gap: 16px; margin-bottom: 34px; }
/* Четыре условия отгрузки. Цветная планка слева здесь была костылём: она
   утяжеляла ряд и повторяла оранжевый по четыре раза подряд. Тонкая линия
   сверху держит ряд не хуже, а вес отдаёт тексту. */
.order__term {
  background: var(--white); border-radius: var(--radius); padding: 18px 22px 20px;
  font-size: .88rem; color: var(--ink);
  border-top: 2px solid var(--prime);
  border-radius: 0 0 var(--radius) var(--radius);
}
.order__term-icon { display: block; width: 26px; height: 26px; color: var(--prime); margin-bottom: 10px; }
.order__layout { display: grid; grid-template-columns: 1fr 380px; gap: 28px; align-items: start; }
.order__packs { display: grid; grid-template-columns: repeat(auto-fill, minmax(172px, 1fr)); gap: 16px; align-content: start; }

.pack {
  display: flex; flex-direction: column; background: var(--white);
  border: 1px solid var(--line); border-radius: var(--radius); padding: 18px;
  transition: border-color var(--ease), box-shadow var(--ease);
}
.pack.is-active { border-color: var(--prime); box-shadow: 0 0 0 1px var(--prime) inset; }
.pack__media { aspect-ratio: 1 / 1; display: flex; align-items: center; justify-content: center; margin-bottom: 14px; background: var(--photo-tile); border-radius: var(--radius); }
.pack__media img { max-height: 120px; width: auto; mix-blend-mode: multiply; }
.pack__media img.is-placeholder { opacity: .45; }
/* Без капса: единицы измерения «1 л», «18 кг» капсом читаются как ошибка. */
.pack__name { font-family: var(--font-ui); font-weight: 700; font-size: 1.05rem; color: var(--ink-strong); }
.pack__price { font-family: var(--font); font-size: 1.24rem; font-weight: 600; color: var(--ink-strong); margin-top: 6px; }
.pack__unit { font-size: .78rem; margin-bottom: 4px; }
.pack__action { margin-top: auto; }

/* Пилюля со счётчиком. Кнопки тянутся во всю высоту: подсветка при наведении
   иначе не доходит до края и внутри скруглённой пилюли появляется прямоугольник.
   Отбивка у числа своя — без неё «100» упирается в плюс. */
.stepper {
  display: flex; align-items: stretch; justify-content: space-between;
  width: 100%; min-height: 46px;
  border: 1px solid var(--prime); border-radius: var(--radius-pill);
  overflow: hidden; background: var(--white);
}
.stepper button {
  flex: none; width: 46px; align-self: stretch; padding: 0;
  /* Центрируем сами: у растянутой кнопки браузер уже не выравнивает подпись
     по середине, и минус с плюсом сидят выше центра. */
  display: flex; align-items: center; justify-content: center;
  border: 0; background: none;
  color: var(--prime-text); font-size: 1.2rem; line-height: 1; cursor: pointer;
  transition: background-color var(--ease), color var(--ease);
}
.stepper button:hover:not([disabled]) { background: var(--btn-fill); color: var(--on-prime); }
.stepper button[disabled] { color: var(--grey); cursor: default; }
/* Число занимает всю середину и центрируется в ней: иначе при росте
   разрядности оно съезжает и «прыгает» относительно кнопок. */
.stepper__value {
  flex: 1; display: flex; align-items: center; justify-content: center;
  padding: 0 4px;
  font-family: var(--font-ui); font-weight: 700; font-size: 1.05rem;
  color: var(--ink-strong); font-variant-numeric: tabular-nums;
}

/* Компактный вид — в корзине страницы товара и в строке заявки.
   Класс ставился обоими скриптами, а правил под него не было вовсе:
   и там, и там пилюля оставалась полноразмерной. */
.stepper--compact { min-height: 38px; }
.stepper--compact button { width: 38px; font-size: 1.05rem; }
.stepper--compact .stepper__value { font-size: .98rem; }

.cart { position: sticky; top: calc(var(--header-h-stuck) + 20px); background: var(--white); border: 1px solid var(--line); border-radius: var(--radius); padding: 26px; }
.cart h3 { font-family: var(--font-ui); font-size: 1.15rem; letter-spacing: .04em; text-transform: uppercase; margin-bottom: 4px; }
.cart__counter { font-size: .84rem; color: var(--grey-text); margin-bottom: 18px; }
.cart__list { display: flex; flex-direction: column; gap: 15px; margin-bottom: 18px; }
.cart__row { display: grid; grid-template-columns: 1fr auto; gap: 7px 12px; padding-bottom: 15px; border-bottom: 1px solid var(--line); }
.cart__row-name { font-family: var(--font-ui); font-weight: 700; color: var(--ink-strong); }
.cart__row-sum { font-weight: 600; text-align: right; white-space: nowrap; }
.cart__row-calc { font-size: .76rem; color: var(--grey-text); text-align: right; }
/* Размеры компактной пилюли теперь общие (.stepper--compact), здесь остаётся
   только ширина колонки в строке корзины. */
.cart__row .stepper { width: 132px; }
.cart__empty { font-size: .88rem; color: var(--grey-text); background: var(--light); border-radius: var(--radius); padding: 16px; margin-bottom: 18px; }
.cart__ship { display: flex; justify-content: space-between; font-size: .84rem; color: var(--grey-text); margin-bottom: 12px; }
.cart__total { display: flex; align-items: baseline; justify-content: space-between; padding: 14px 0 18px; border-top: 2px solid var(--ink-strong); }
.cart__total span { font-family: var(--font-ui); font-size: .95rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; }
.cart__total b { font-size: 1.55rem; font-weight: 600; }
.cart__hint { margin-top: 12px; font-size: .84rem; color: var(--prime-dark); background: var(--prime-pale); border-radius: var(--radius); padding: 12px 14px; }
/* Две вторые кнопки стояли встык: у обеих ширина во всю панель, а зазора
   между ними не было — пара читалась как одна разрезанная кнопка. */
.cart__secondary { margin-top: 12px; display: flex; flex-direction: column; gap: 10px; }
.cart__note { margin-top: 16px; font-size: .74rem; color: var(--grey-text); line-height: 1.45; }


/* ---------- Модальная форма ---------- */

.modal[hidden] { display: none; }
/* Поверх панели помощника (201): форму заявки открывают из неё. */
.modal { position: fixed; inset: 0; z-index: 300; display: flex; align-items: center; justify-content: center; padding: 20px; background: rgba(0, 0, 0, .74); }
/* Форма приходит из-под руки: затемнение проявляется, окно поднимается
   и доезжает до полного размера. display: none → flex перезапускает
   анимацию сам, скрипту помогать не нужно. */
.modal { animation: modalBack var(--t-mid) var(--out); }
.modal__box { animation: modalBox var(--t-mid) var(--out); }
@keyframes modalBack { from { opacity: 0; } to { opacity: 1; } }
@keyframes modalBox { from { opacity: 0; transform: translateY(12px) scale(.98); } to { opacity: 1; transform: none; } }

.modal__box { width: 100%; max-width: 500px; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 32px; position: relative; }
.modal__box h3 { font-family: var(--font-ui); letter-spacing: .04em; text-transform: uppercase; }
.modal__close { position: absolute; top: 14px; right: 14px; width: 36px; height: 36px; border: 0; background: none; font-size: 1.3rem; color: var(--grey-text); cursor: pointer; }
.modal__close:hover { color: var(--prime-text); }

.field { margin-bottom: 16px; }
.field label { display: block; font-family: var(--font-ui); font-size: .78rem; font-weight: 700; letter-spacing: .06em; text-transform: uppercase; margin-bottom: 6px; }
/* Граница поля — элемент управления: берёт --grey (3.70 на фоне), а не
   декоративную --line. Цвет и фон заданы явно: иначе браузер подставит
   свой белый и поле выпадет из чёрной страницы. */
.field input, .field textarea, .field select {
  width: 100%; padding: 13px 16px; border: 1px solid var(--grey);
  border-radius: var(--radius-ctl); font: inherit; font-size: .94rem;
  background: var(--surface); color: var(--ink);
  transition: border-color var(--ease);
}
.field select { cursor: pointer; }
.field select:disabled { opacity: .55; cursor: default; }
.field input::placeholder, .field textarea::placeholder { color: var(--grey-text); }
.field input:focus, .field textarea:focus, .field select:focus { outline: none; border-color: var(--prime); }

.field textarea { min-height: 104px; resize: vertical; }
.field--check { display: flex; gap: 10px; align-items: flex-start; font-size: .78rem; color: var(--grey-text); text-transform: none; letter-spacing: 0; }
.field--check input { width: auto; margin-top: 3px; }
.field--check label { text-transform: none; letter-spacing: 0; font-weight: 400; font-family: var(--font); font-size: .82rem; }

/* ---------- Подвал ---------- */

.footer { background: var(--chrome); color: var(--chrome-muted); padding: 62px 0 30px; border-top: 1px solid var(--chrome-line); }
.footer a { color: var(--chrome-muted); }
.footer a:hover { color: var(--chrome-prime); }
.footer__grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1.2fr; gap: 34px; }
.footer__title { font-family: var(--font-ui); font-size: .78rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--chrome-fg); margin-bottom: 16px; }
.footer ul { list-style: none; margin: 0; padding: 0; }
.footer li { margin-bottom: 10px; font-size: .9rem; }
.footer .logo { margin-left: 0; margin-bottom: 18px; }
.footer .logo img { height: 34px; }
.footer__bottom { margin-top: 40px; padding-top: 22px; border-top: 1px solid var(--chrome-line); font-size: .78rem; display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; }

/* ---------- Появление при прокрутке ---------- */
/* Каталог длинный: 710 карточек подряд. Лёгкий подъём при входе в кадр даёт
   ритм и показывает, что список живой. Работает только если reveal.js
   поставил на <html> класс — без JS и при выключенном движении контент
   виден сразу, никакого мигания. */

.reveal-on .reveal { opacity: 0; transform: translateY(16px); }
.reveal-on .reveal.is-in {
  opacity: 1; transform: none;
  transition: opacity var(--t-slow) var(--out), transform var(--t-slow) var(--out);
}

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

.spec-scroll { overflow-x: auto; margin-bottom: 26px; }
.spec { width: 100%; border-collapse: collapse; font-size: .94rem; }
.spec th, .spec td { text-align: left; padding: 12px 16px 12px 0; border-bottom: 1px solid var(--line); vertical-align: baseline; }
.spec thead th {
  font-family: var(--font-ui); font-size: .72rem; font-weight: 700;
  letter-spacing: .09em; text-transform: uppercase; color: var(--grey-text);
  border-bottom-color: var(--grey); padding-bottom: 10px; white-space: nowrap;
}
.spec tbody th { font-weight: 400; color: var(--ink); padding-right: 28px; }
.spec tbody tr { transition: background-color var(--t-fast) var(--out); }
.spec tbody tr:hover { background: var(--light); }
.spec__value { font-weight: 600; color: var(--ink-strong); }
.spec__unit, .spec__std { color: var(--grey-text); font-size: .84rem; white-space: nowrap; }
.spec__std { font-family: var(--font-ui); letter-spacing: .03em; }
.spec__dash { color: var(--grey); }

/* Перечень свойств. Маркер рисуем сами: браузерная точка сидит на базовой
   линии текста, а не на строке, и в длинном списке ряд маркеров плывёт. */
.spec-points { list-style: none; margin: 0 0 22px; padding: 0; }
.spec-points li { position: relative; padding-left: 22px; margin-bottom: 9px; }
.spec-points li::before {
  content: ""; position: absolute; left: 2px; top: .62em;
  width: 6px; height: 6px; border-radius: 50%; background: var(--prime);
}

/* Допуски и спецификации — короткие однородные обозначения вроде «API SM/CF».
   Столбиком с точками они занимают полэкрана, плашками читаются одним взглядом
   и сразу видно, сколько их. */
.spec-tags { list-style: none; display: flex; flex-wrap: wrap; gap: 8px; margin: 0 0 24px; padding: 0; }
.spec-tags li {
  padding: 7px 14px; border: 1px solid var(--line); border-radius: var(--radius-pill);
  background: var(--light); color: var(--ink);
  font-family: var(--font-ui); font-size: .8rem; font-weight: 700; letter-spacing: .03em;
}

/* Разбору не поддалось — выводим как есть, но без лестницы заголовков. */
.spec-raw { list-style: none; margin: 0 0 22px; padding: 0; columns: 2; column-gap: 40px; font-size: .9rem; color: var(--ink); }
.spec-raw li { break-inside: avoid; padding: 5px 0; border-bottom: 1px solid var(--line); }

/* ---------- Шапка страницы и текстовые полосы ---------- */
/* Страницы «О компании», «Оплата и доставка», «Контакты» и разделы каталога
   начинались одинаково: h1 в общем потоке и сразу содержимое. Полоса-шапка
   даёт им начало, а тексту — читаемую ширину строки. */

.page-head { padding: 34px 0 30px; border-bottom: 1px solid var(--line); margin-bottom: 40px; }
.page-head h1 { margin: 0; max-width: 20ch; }
.page-head__lead { margin: 16px 0 0; max-width: 62ch; font-size: 1.08rem; color: var(--grey-text); }
.page-head__meta { display: flex; flex-wrap: wrap; gap: 10px; margin-top: 22px; }

/* Полоса со снимком: та же механика, что у баннера склада на главной —
   фотография тегом, затемнение поверх, текст на плотной части. */
/* Полоса во всю ширину окна: контейнер ей не нужен, он внутри — на заголовке.
   Так левый край заголовка совпадает с крошками, прозой и знаком в шапке. */
.page-head--cover { position: relative; overflow: hidden; border: 0; padding: 0; margin-bottom: 46px; }
.page-head--cover .page-head__inner { position: relative; z-index: 2; padding-top: 58px; padding-bottom: 62px; max-width: var(--container); }
.page-head--cover .page-head__inner > * { max-width: var(--measure, 62ch); }
.page-head--cover img { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; z-index: 0; }
.page-head--cover::after {
  content: ""; position: absolute; inset: 0; z-index: 1;
  background: linear-gradient(90deg, rgba(8, 8, 9, .9) 0%, rgba(8, 8, 9, .74) 46%, rgba(8, 8, 9, .34) 100%);
}
.page-head--cover h1 { color: #fff; }
.page-head--cover .page-head__lead { color: rgba(255, 255, 255, .86); }

/* Текстовая страница. Мера строки 62–68 знаков: на 880px без ограничения
   в строке помещалось под 110, и глаз терял начало следующей. */
.prose { max-width: var(--measure, 68ch); }
.prose > h2, .prose > h3 {
  font-family: var(--font-ui); letter-spacing: .04em; text-transform: uppercase;
  margin: 44px 0 14px; padding-top: 18px; border-top: 1px solid var(--line);
}
.prose > h3:first-child, .prose > h2:first-child { margin-top: 0; padding-top: 0; border-top: 0; }
.prose p { margin: 0 0 14px; }
.prose a { text-decoration: underline; text-underline-offset: .18em; text-decoration-thickness: 1px; text-decoration-color: color-mix(in srgb, currentColor 45%, transparent); }
.prose a:hover { text-decoration-color: currentColor; }
.prose ul { list-style: none; margin: 0 0 20px; padding: 0; }
.prose li { position: relative; padding-left: 22px; margin-bottom: 10px; }
.prose li::before {
  content: ""; position: absolute; left: 1px; top: .66em;
  width: 10px; height: 2px; background: var(--prime);
}
.prose strong { color: var(--ink-strong); font-weight: 600; }
.prose .btn { margin-top: 10px; }
.prose img { max-width: 100%; height: auto; border-radius: var(--radius-ctl); }
.prose table { border-collapse: collapse; margin: 0 0 20px; font-size: .92rem; }
.prose td, .prose th { border: 1px solid var(--line); padding: 8px 12px; text-align: left; }
/* Видео из текстов прежнего сайта: без коробки iframe приходит 300×150. */
.prose-video { aspect-ratio: 16 / 9; margin: 0 0 14px; }
.prose-video iframe { width: 100%; height: 100%; border: 0; border-radius: var(--radius-ctl); }

/* ---------- Продукция (карусель G-Family / Газпромнефть) ---------- */

/* Карусель двух блоков продукции: лента едет по 100% ширины, переключение
   стрелками и точками-табами с названиями брендов. */
.prodcar__viewport { overflow: hidden; }
.prodcar__track { display: flex; transition: transform var(--t-mid) var(--out); }
.prodcar__slide { flex: 0 0 100%; min-width: 0; }
.prodcar__nav { display: flex; align-items: center; justify-content: center; gap: 16px; margin-top: 32px; }
.prodcar__arrow {
  width: 44px; height: 44px; border-radius: 50%; flex: 0 0 auto;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  display: inline-flex; align-items: center; justify-content: center; cursor: pointer;
  transition: border-color var(--ease), color var(--ease);
}
.prodcar__arrow svg { width: 20px; height: 20px; }
.prodcar__arrow:hover { border-color: var(--prime); color: var(--prime-text); }
.prodcar__dots { display: flex; gap: 8px; flex-wrap: wrap; justify-content: center; }
.prodcar__dot {
  padding: 9px 18px; border-radius: var(--radius-pill); cursor: pointer;
  border: 1px solid var(--line); background: var(--surface); color: var(--ink);
  font-family: var(--font-ui); font-weight: 700; font-size: .78rem; letter-spacing: .04em; text-transform: uppercase;
  transition: border-color var(--ease), color var(--ease), background-color var(--ease);
}
.prodcar__dot:hover { border-color: var(--prime); color: var(--prime-text); }
.prodcar__dot.is-active { background: var(--prime); border-color: var(--prime); color: #fff; }

/* Появление панели при переключении линейки — fade со сдвигом (как tab-pane
   fade у g-energy). */
.gfam__panel.is-anim { animation: gfamPanelIn var(--t-mid) var(--out); }
@keyframes gfamPanelIn { from { opacity: 0; transform: translateX(26px); } to { opacity: 1; transform: none; } }

/* Слева заголовок и список линеек в две колонки, справа оранжевая панель
   выбранной линейки — приём с главной сайта-референса. */
.gfam { display: grid; grid-template-columns: minmax(280px, 5fr) 7fr; gap: 44px; align-items: start; }
.gfam__list { display: grid; grid-template-columns: 1fr 1fr; gap: 6px 18px; }
.gfam__tab {
  justify-self: start; padding: 10px 18px; border: 0; background: none;
  font: inherit; font-weight: 600; text-align: left; color: var(--ink);
  border-radius: var(--radius-pill); cursor: pointer;
  transition: background-color var(--ease), color var(--ease);
}
.gfam__tab:hover { color: var(--prime-text); }
.gfam__tab.is-active { background: var(--prime); color: #fff; }

.gfam__panel {
  display: grid; grid-template-columns: 1fr 230px; gap: 34px; align-items: center;
  background: linear-gradient(100deg, #c4460a 0%, #e35205 55%, #f46316 100%);
  border-radius: var(--radius); padding: 40px 44px; color: #fff;
}
/* Газпромнефть — фирменный синий вместо оранжевого: панель, активная
   пилюля линейки и подсветка при наведении. */
.gfam--blue .gfam__panel { background: linear-gradient(100deg, #06376b 0%, #0a58a6 55%, #1277d6 100%); }
.gfam--blue .gfam__tab.is-active { background: #0a58a6; }
.gfam--blue .gfam__tab:hover { color: #1277d6; }
.gfam__eyebrow { font-family: var(--font-ui); font-weight: 700; font-size: .82rem; letter-spacing: .09em; text-transform: uppercase; margin-bottom: 16px; }
.gfam__text { margin: 0 0 28px; max-width: 36ch; color: rgba(255, 255, 255, .92); }
.gfam__foot { display: flex; align-items: center; gap: 24px; flex-wrap: wrap; }
.gfam__count { display: flex; align-items: center; gap: 12px; font-size: .8rem; line-height: 1.35; }
.gfam__count b {
  display: inline-flex; align-items: center; justify-content: center;
  width: 46px; height: 46px; border: 1.6px solid rgba(255, 255, 255, .8);
  border-radius: 50%; font-size: 1.1rem; font-weight: 700;
}
/* Снимки товара приходят на белом фоне — на оранжевом им нужна своя плитка. */
.gfam__media { align-self: stretch; display: flex; align-items: center; justify-content: center; background: #fff; border-radius: var(--radius-ctl); padding: 18px; min-height: 230px; }
.gfam__media img { max-width: 100%; max-height: 230px; width: auto; height: auto; }
@media (max-width: 992px) {
  .gfam { grid-template-columns: 1fr; gap: 26px; }
  .gfam__list { grid-template-columns: repeat(auto-fill, minmax(190px, 1fr)); }
  .gfam__panel { grid-template-columns: 1fr; padding: 28px 24px; }
  .gfam__media { min-height: 200px; }
}

/* ---------- Новости и статьи ---------- */

.post-tabs { display: flex; gap: 10px; margin-bottom: 28px; }
.post-tabs a {
  padding: 10px 24px; border: 1px solid var(--line); border-radius: var(--radius-pill);
  font-family: var(--font-ui); font-weight: 700; font-size: .82rem;
  letter-spacing: .06em; text-transform: uppercase; color: var(--ink);
  transition: border-color var(--ease), color var(--ease);
}
.post-tabs a:hover { border-color: var(--prime); color: var(--prime-text); }
.post-tabs a[aria-current] { background: var(--prime); border-color: var(--prime); color: #fff; }

.posts { display: grid; grid-template-columns: repeat(auto-fill, minmax(280px, 1fr)); gap: 22px; }
.post-card {
  display: flex; flex-direction: column; background: var(--white);
  border: 1px solid var(--line); border-radius: var(--radius); overflow: hidden; color: var(--ink);
  transition: border-color var(--ease), box-shadow var(--t-mid) var(--out), transform var(--t-mid) var(--out);
}
.post-card:hover { border-color: var(--prime); box-shadow: var(--shadow-lift); transform: translateY(-3px); }
.post-card__media { display: block; aspect-ratio: 16 / 9; background: var(--photo-tile); }
.post-card__media img { width: 100%; height: 100%; object-fit: cover; }
.post-card__body { display: flex; flex-direction: column; gap: 8px; padding: 16px 20px 18px; }
.post-card__date { font-size: .78rem; color: var(--grey-text); }
.post-card__title { font-weight: 600; line-height: 1.35; }
.post-card__text { font-size: .86rem; line-height: 1.5; color: var(--grey-text); }
.post-date { margin-top: 10px; }
.post-back { margin-top: 38px; }

.pager { display: flex; flex-wrap: wrap; gap: 8px; margin-top: 36px; }
.pager a, .pager span {
  min-width: 40px; padding: 9px 13px; text-align: center;
  border: 1px solid var(--line); border-radius: var(--radius-ctl);
  font-size: .9rem; color: var(--ink); transition: border-color var(--ease), color var(--ease);
}
.pager a:hover { border-color: var(--prime); color: var(--prime-text); }
.pager [aria-current] { background: var(--prime); border-color: var(--prime); color: #fff; }
.pager .pager__gap { border: 0; color: var(--grey-text); }

/* Карточки фактов на странице контактов: телефон, почта, адрес, часы.
   Списком из четырёх строк они читались как продолжение текста. */
.facts { display: grid; grid-template-columns: repeat(auto-fit, minmax(190px, 1fr)); gap: 14px; margin: 0 0 38px; }
/* Примечание прижато к низу: иначе в ряду с разной длиной адреса плашки
   заканчиваются на разной высоте и низ ряда выглядит обрывом. */
.fact { display: flex; flex-direction: column; background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px 22px; }
.fact__label { font-family: var(--font-ui); font-size: .7rem; font-weight: 700; letter-spacing: .12em; text-transform: uppercase; color: var(--grey-text); margin-bottom: 8px; }
.fact__value { font-size: 1.06rem; color: var(--ink-strong); line-height: 1.4; }
.fact__value a { color: var(--ink-strong); }
.fact__value a:hover { color: var(--prime-text); }
.fact__note { font-size: .84rem; color: var(--grey-text); margin-top: auto; padding-top: 10px; }

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

   Шапка и подвал выведены в собственные группы: они одинаковы на всех
   страницах, и растворять их вместе с контентом значит моргать знаком
   на каждом переходе. Так они стоят на месте, а меняется только середина.

   Браузеры без поддержки просто переходят по ссылке, как раньше. */
@view-transition { navigation: auto; }

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

   Круг задаёт theme-switch.js готовыми пикселями. Ключевыми кадрами в CSS
   его не описать: кадры перехода живут в отдельном дереве псевдоэлементов,
   и пользовательские свойства в него не наследуются — круг расходился бы
   из середины экрана, а не от кнопки.

   Здесь остаётся то, чего из скрипта не задать: снять у кадров сложение
   по яркости (plus-lighter даёт пересвет там, где кадры перекрываются),
   убрать переходы по умолчанию и положить новый кадр поверх старого. */
:root.theme-turn::view-transition-old(root),
:root.theme-turn::view-transition-new(root) {
  animation: none;
  mix-blend-mode: normal;
}
:root.theme-turn::view-transition-old(root) { z-index: 0; }
:root.theme-turn::view-transition-new(root) { z-index: 1; }

/* Шапка и подвал на время хода отдают свои имена перехода: со своими
   группами они переключились бы мгновенно, пока круг ползёт по странице. */
:root.theme-turn .header,
:root.theme-turn .footer { view-transition-name: none; }

.header { view-transition-name: chrome-top; }
.footer { view-transition-name: chrome-bottom; }

::view-transition-group(root) { animation-duration: var(--t-mid); }
::view-transition-old(root) { animation: vtOut var(--t-mid) var(--out) both; }
::view-transition-new(root) { animation: vtIn var(--t-mid) var(--out) both; }

@keyframes vtOut { to { opacity: 0; transform: translateY(-6px); } }
@keyframes vtIn { from { opacity: 0; transform: translateY(10px); } }

/* ---------- Счётчик заявки в шапке ---------- */
/* Появляется только когда в заявке что-то есть: пустая корзина в шапке —
   ссылка в никуда, а на телефоне она отнимает ширину у знака и телефона. */

.basket {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px;
  border: 1px solid var(--chrome-ctl); border-radius: 50%;
  color: var(--chrome-fg);
  transition: color var(--ease), border-color var(--ease), transform var(--t-fast) var(--out);
}
.basket:hover { color: var(--chrome-prime); border-color: var(--chrome-prime); }
.basket:active { transform: translateY(1px); }
.basket svg { width: 19px; height: 19px; }
.basket__count {
  position: absolute; top: -3px; right: -3px;
  min-width: 20px; height: 20px; padding: 0 5px;
  display: inline-flex; align-items: center; justify-content: center;
  background: var(--chrome-btn); color: var(--chrome-on-btn);
  border-radius: 10px;
  font-family: var(--font-ui); font-size: .72rem; font-weight: 700;
  font-variant-numeric: tabular-nums;
}

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

.account { position: relative; }
.account__btn {
  position: relative;
  display: inline-flex; align-items: center; justify-content: center;
  width: 44px; height: 44px; padding: 0; cursor: pointer;
  background: none; border: 1px solid var(--chrome-ctl); border-radius: 50%;
  color: var(--chrome-fg);
  transition: color var(--ease), border-color var(--ease), transform var(--t-fast) var(--out);
}
.account__btn:hover { color: var(--chrome-prime); border-color: var(--chrome-prime); }
.account__btn:active { transform: translateY(1px); }
.account__btn svg { width: 19px; height: 19px; }
/* Вошёл — кружок подсвечен и снизу справа стоит точка. Цветом одним
   обойтись нельзя: точка видна и в монохроме, и дальтонику. */
.account__btn.is-in { color: var(--chrome-prime); border-color: var(--chrome-prime); }
.account__dot {
  position: absolute; right: 0; bottom: 1px;
  width: 10px; height: 10px; border-radius: 50%;
  background: var(--ok-text); border: 2px solid var(--chrome);
  opacity: 0; transform: scale(.4);
  transition: opacity var(--t-mid) var(--out), transform var(--t-mid) var(--out);
}
.account__btn.is-in .account__dot { opacity: 1; transform: none; }

.account__panel {
  position: absolute; top: calc(100% + 14px); right: 0; z-index: 45;
  width: 320px; padding: 20px;
  background: var(--chrome); color: var(--chrome-fg);
  border: 1px solid var(--chrome-line); border-radius: var(--radius);
  box-shadow: 0 18px 44px rgba(0, 0, 0, .5);
  text-transform: none; letter-spacing: normal;
  transform-origin: 100% 0;
  animation: accountIn var(--t-mid) var(--out);
}
/* Уход быстрее прихода, как и везде на сайте. Атрибут hidden скрипт ставит
   после ухода — иначе анимация обрывалась бы на первом кадре. */
.account__panel.is-closing { pointer-events: none; animation: accountOut var(--t-fast) var(--out-soft) forwards; }
@keyframes accountIn { from { opacity: 0; transform: translateY(-10px) scale(.96); } }
@keyframes accountOut { to { opacity: 0; transform: translateY(-6px) scale(.98); } }

.account__title {
  font-family: var(--font-ui); font-size: .8rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--chrome-fg);
  margin-bottom: 6px;
}
.account__hint { font-size: .82rem; line-height: 1.45; color: var(--chrome-muted); margin-bottom: 14px; }
.account__note { margin-top: 14px; font-size: .78rem; line-height: 1.45; color: var(--chrome-muted); }
.account__note a { color: var(--chrome-prime); }
.account__note a:hover { text-decoration: underline; }
.account__who { font-size: .98rem; font-weight: 700; color: var(--chrome-fg); margin-bottom: 12px; word-break: break-word; }

.account__link {
  display: block; margin: 0 -12px; padding: 10px 12px; border-radius: 6px;
  font-size: .92rem; color: var(--chrome-fg);
  transition: background-color var(--ease), color var(--ease);
}
.account__link:hover { background: rgba(255, 255, 255, .07); color: var(--chrome-prime); }
.account__signout {
  margin-top: 14px; padding: 0; min-height: 24px; cursor: pointer;
  background: none; border: 0;
  font-family: var(--font-ui); font-size: .74rem; letter-spacing: .06em;
  text-transform: uppercase; color: var(--chrome-muted);
  transition: color var(--ease);
}
.account__signout:hover { color: var(--chrome-prime); }

.account__panel .field { margin-bottom: 12px; }
.account__panel .field label { font-size: .72rem; color: var(--chrome-muted); }
.account__panel .field input {
  padding: 11px 14px; background: rgba(255, 255, 255, .06);
  border-color: var(--chrome-ctl); color: var(--chrome-fg);
}
.account__panel .field input:focus { border-color: var(--chrome-prime); }
.account__panel .btn { min-height: 46px; }
.account__panel :focus-visible { outline-color: var(--chrome-prime); }

.account__status { margin-top: 12px; font-size: .82rem; line-height: 1.45; color: var(--chrome-muted); animation: accountSay var(--t-mid) var(--out); }
.account__status.is-error { color: var(--chrome-prime); }
@keyframes accountSay { from { opacity: 0; transform: translateY(-4px); } }

/* Вход принят: панель не перерисовывается заново, поэтому смену состояния
   отмечает само содержимое — иначе переход из формы в имя проходит незаметно. */
.account__panel.is-welcome [data-account-in] { animation: accountWelcome var(--t-slow) var(--out); }
@keyframes accountWelcome { from { opacity: 0; transform: translateY(8px); } }

/* Строка входа в мобильном меню: в шапке телефона уже стоят знак, трубка,
   заявка и бургер — пятый кружок туда не помещается. */
.mobile-nav__account {
  display: inline-flex; align-items: center; gap: 8px;
  font-family: var(--font-ui); font-size: .86rem; font-weight: 700;
  letter-spacing: .04em; color: var(--chrome-fg);
}
.mobile-nav__account::before {
  content: ""; width: 8px; height: 8px; border-radius: 50%;
  background: var(--chrome-prime);
}

/* ---------- Страница заявки ---------- */

.section--order .page-head { margin-bottom: 30px; }
.order-note { font-size: .9rem; color: var(--grey-text); }

.order-empty {
  max-width: var(--measure);
  padding: 34px 0 10px;
}
.order-empty p { margin-bottom: 10px; }
.order-empty .btn { margin-top: 16px; }

.order-page { display: grid; grid-template-columns: 1fr 380px; gap: 28px; align-items: start; max-width: none; }
.order-page__list { display: flex; flex-direction: column; gap: 16px; }

.order-group { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 20px 22px; }
.order-group__head { display: flex; align-items: baseline; justify-content: space-between; gap: 16px; margin-bottom: 8px; }
.order-group__title { font-family: var(--font-ui); font-size: 1.05rem; font-weight: 700; letter-spacing: .02em; text-transform: uppercase; color: var(--prime-text); }
a.order-group__title:hover { color: var(--prime-text-hover); }
.order-group__clear {
  background: none; border: 0; padding: 0; cursor: pointer;
  font-family: var(--font-ui); font-size: .74rem; letter-spacing: .06em;
  text-transform: uppercase; color: var(--grey-text);
  min-height: 24px;
}
.order-group__clear:hover { color: var(--prime-text); }

/* Строка фасовки: подпись слева, счётчик и «убрать» справа. Артикул под
   названием — по нему менеджер и клиент находят позицию в 1С. */
.order-line {
  display: grid; grid-template-columns: 1fr 132px auto; gap: 14px;
  align-items: center; padding: 14px 0; border-top: 1px solid var(--line);
}
.order-line__name { font-family: var(--font-ui); font-weight: 700; color: var(--ink-strong); }
.order-line__meta { font-family: var(--font-ui); font-size: .74rem; letter-spacing: .04em; color: var(--grey-text); margin-top: 2px; }
.order-line__drop {
  background: none; border: 0; padding: 0 2px; cursor: pointer; min-height: 24px;
  font-family: var(--font-ui); font-size: .74rem; letter-spacing: .06em;
  text-transform: uppercase; color: var(--grey-text);
}
.order-line__drop:hover { color: var(--prime-text); }
/* Фасовки, которой нет в кабинете, в заказ не отправить: помечаем строку,
   а не выбрасываем её — количество человек набирал осознанно. */
.order-line--offline .order-line__name { color: var(--ink); }
.order-line--offline .order-line__meta { color: var(--prime-text); }

.order-side {
  position: sticky; top: calc(var(--header-h-stuck) + 20px);
  background: var(--white); border: 1px solid var(--line);
  border-radius: var(--radius); padding: 26px;
}
.order-side h2 { font-family: var(--font-ui); font-size: 1.15rem; letter-spacing: .04em; text-transform: uppercase; margin-bottom: 4px; }
.order-side__counter { font-size: .84rem; color: var(--grey-text); margin-bottom: 18px; }
.order-side__hint { font-size: .84rem; color: var(--grey-text); margin-bottom: 12px; }
.order-side__who { font-size: .88rem; color: var(--ink); margin-bottom: 14px; display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.order-side__who b { color: var(--ink-strong); }
.order-side__out {
  background: none; border: 0; padding: 0; cursor: pointer; min-height: 24px;
  font-family: var(--font-ui); font-size: .74rem; letter-spacing: .06em;
  text-transform: uppercase; color: var(--grey-text);
}
.order-side__out:hover { color: var(--prime-text); }
.order-side__second { margin-top: 22px; padding-top: 18px; border-top: 1px solid var(--line); }

/* Ответ портала. Три состояния и три цвета: ход дела серым, отказ оранжевым
   на подложке, предупреждение о непроходных позициях — тоже оранжевым,
   но без подложки: это не ошибка, а уточнение. */
.order-side__status { margin-top: 14px; font-size: .86rem; color: var(--grey-text); }
.order-side__status.is-error { color: var(--prime-dark); background: var(--prime-pale); border-radius: var(--radius); padding: 12px 14px; }
.order-side__status.is-warn { color: var(--prime-text); }

.order-auth .field { margin-bottom: 14px; }
/* Вход принят — на месте формы появляется кнопка отправки. Смена блоков
   идёт через hidden (display), а он перезапускает анимацию сам. */
.order-auth, .order-empty { animation: panelIn var(--t-mid) var(--out); }

.order-done { max-width: var(--measure); padding: 20px 0 30px; }
.order-done h2 { margin-bottom: 10px; }
.order-done__actions { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 20px; }

/* ---------- Движение вокруг заказа ---------- */
/* Одно событие — одно движение, все по общей кривой --out. Правило простое:
   двигается то, что изменилось, и ровно настолько, чтобы глаз это заметил.
   Ничего не крутится «для красоты»: каждая анимация здесь отвечает на действие
   человека и сообщает результат.

   Под prefers-reduced-motion общее правило сводит длительности к нулю —
   смысл остаётся (число меняется, галочка стоит), движение уходит. */

/* Число в счётчике: растёт — приходит снизу, убавляется — сверху. Направление
   и есть сообщение: видно не только что число изменилось, но и куда. */
@keyframes stepUp { from { opacity: 0; transform: translateY(5px); } to { opacity: 1; transform: none; } }
@keyframes stepDown { from { opacity: 0; transform: translateY(-5px); } to { opacity: 1; transform: none; } }
.stepper__value.is-up { animation: stepUp var(--t-fast) var(--out); }
.stepper__value.is-down { animation: stepDown var(--t-fast) var(--out); }

/* Фасовку положили в заявку: от карточки расходится одно кольцо. Не мигание
   и не подпрыгивание — короткий отклик там, где человек нажал. */
@keyframes packTake {
  from { box-shadow: 0 0 0 0 rgba(227, 82, 5, .5); }
  to { box-shadow: 0 0 0 16px rgba(227, 82, 5, 0); }
}
.pack.is-taken { animation: packTake var(--t-slow) var(--out); }

/* Счётчик в шапке — вторая половина того же сообщения: положил здесь,
   выросло там. Значок и число отзываются вместе, но по-разному. */
@keyframes badgePop { 0% { transform: scale(1); } 35% { transform: scale(1.32); } 100% { transform: scale(1); } }
@keyframes basketNudge { 0%, 100% { transform: none; } 40% { transform: translateY(-2px); } }
@keyframes badgeArrive { from { opacity: 0; transform: scale(.5); } to { opacity: 1; transform: none; } }
.basket__count.is-bump { animation: badgePop var(--t-slow) var(--out); }
.basket.is-bump svg { animation: basketNudge var(--t-slow) var(--out); }
.basket__count.is-arrive { animation: badgeArrive var(--t-mid) var(--out); }

/* Кнопка ждёт ответа портала. Кольцо — единственная бесконечная анимация
   на сайте, и живёт она ровно столько, сколько идёт запрос. */
@keyframes spin { to { transform: rotate(1turn); } }
.btn.is-working { pointer-events: none; opacity: .8; }
.btn.is-working::after {
  content: ""; width: 15px; height: 15px; flex: none;
  border: 2px solid currentColor; border-right-color: transparent;
  border-radius: 50%; animation: spin .7s linear infinite;
}

/* Заказ принят. Кольцо обводится, галочка дорисовывается следом — момент,
   ради которого человек сюда пришёл. Один раз, полсекунды, без повторов. */
.order-done__mark { color: var(--ok-text); width: 52px; height: 52px; margin-bottom: 18px; }
.order-done__mark svg { width: 100%; height: 100%; }
.order-done__ring {
  stroke-dasharray: 145; stroke-dashoffset: 145;
  animation: drawRing var(--t-slow) var(--out) forwards;
}
.order-done__tick {
  stroke-dasharray: 34; stroke-dashoffset: 34;
  animation: drawTick var(--t-mid) var(--out) .34s forwards;
}
@keyframes drawRing { to { stroke-dashoffset: 0; } }
@keyframes drawTick { to { stroke-dashoffset: 0; } }

/* Приход блоков: панель вкладки, экран «отправлено», состав заказа.
   display: none → block перезапускает анимацию сам, скрипту помогать не нужно. */
@keyframes panelIn { from { opacity: 0; transform: translateY(8px); } to { opacity: 1; transform: none; } }
[data-order-panel], .order-done, .order-card__items { animation: panelIn var(--t-mid) var(--out); }

/* Панель вкладки приезжает с той стороны, где стоит её вкладка: заявка
   слева, заказы справа. Направление и есть подсказка, куда переключились. */
@keyframes panelFromRight { from { opacity: 0; transform: translateX(24px); } }
@keyframes panelFromLeft { from { opacity: 0; transform: translateX(-24px); } }
[data-order-panel].from-right { animation: panelFromRight var(--t-mid) var(--out); }
[data-order-panel].from-left { animation: panelFromLeft var(--t-mid) var(--out); }

/* Карточки заказов приходят лесенкой — так видно, что это список, а не
   одна плита. Задержка ступеньки ставится из order.js и ограничена. */
@keyframes cardIn { from { opacity: 0; transform: translateY(10px); } to { opacity: 1; transform: none; } }
.order-card { animation: cardIn var(--t-slow) var(--out) both; }

/* ---------- Магазин: цены, вход, итог ---------- */
/* Цена договорная, и портал отдаёт её только вошедшему клиенту. Поэтому
   у витрины два состояния, и оба честные: гостю — «цена по запросу» плюс
   приглашение войти, клиенту — его цена. Переключает состояния один класс
   is-signed на документе, его ставит account.js. */

[data-guest-only] { display: block; }
:root.is-signed [data-guest-only] { display: none; }

/* Приглашение войти. Не баннер и не модалка: строка там, где человек
   ищет цену, — под корзиной и в панели оформления. */
.cart__signin {
  margin-top: 14px; padding: 12px 14px;
  background: var(--light); border-radius: var(--radius);
  font-size: .82rem; line-height: 1.45; color: var(--grey-text);
}
.account__switch {
  padding: 0; border: 0; background: none; cursor: pointer;
  font: inherit; color: var(--prime-text); text-decoration: underline;
  text-underline-offset: 2px;
}
.account__switch:hover { color: var(--prime-text-hover); }
.account__panel .account__switch { color: var(--chrome-prime); }

/* Своя цена в карточке фасовки. Появляется на месте «по запросу», поэтому
   у строки заранее задана высота — иначе приход цены дёргал бы карточку. */
.pack__price { min-height: 1.5em; transition: color var(--ease); }
.pack__price.is-own { color: var(--ink-strong); font-weight: 700; }

/* Строка заказа: сумма справа от подписи, расчёт под ней мелким.
   Цифры моноширинные — иначе столбец сумм пляшет на каждой правке. */
.order-line__price {
  margin-top: 6px; display: flex; align-items: baseline; gap: 10px;
  font-variant-numeric: tabular-nums;
}
.order-line__price b { font-size: 1rem; font-weight: 700; color: var(--ink-strong); }
.order-line__price span { font-size: .8rem; color: var(--grey-text); }

/* Итог в панели оформления. Тот же вид, что у итога корзины на странице
   товара: человек видит одну и ту же сумму в двух местах и должен узнать её. */
.order-total {
  display: flex; align-items: baseline; justify-content: space-between;
  gap: 12px; margin-bottom: 6px; padding: 14px 0;
  border-top: 2px solid var(--ink-strong);
}
.order-total span {
  font-family: var(--font-ui); font-size: .95rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase;
}
.order-total b { font-size: 1.55rem; font-weight: 700; font-variant-numeric: tabular-nums; }
.order-side__vat { margin-bottom: 16px; font-size: .78rem; color: var(--grey-text); }

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

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

/* Доезд до нового места. Сдвиг ставит order.js разово, отсюда — только
   кривая и темп; без правила элемент прыгал бы мгновенно. */
.order-group, .order-line { transition: transform var(--t-mid) var(--out); }

/* Приход строки и карточки товара. Ступеньку ставит order.js. */
@keyframes lineFresh { from { opacity: 0; transform: translateY(10px); } }
.order-group.is-fresh, .order-line.is-fresh { animation: lineFresh var(--t-slow) var(--out) both; }

/* Слепок ушедшей строки: сама строка исчезает вместе с перерисовкой,
   тает её копия — поверх страницы, на том же месте. */
.is-ghost {
  /* Ниже шапки (30): слепок строки не должен перекрыть её, если заявку
     правят на прокрученной странице. */
  pointer-events: none; z-index: 20; margin: 0;
  background: var(--surface); overflow: hidden;
  animation: ghostOut var(--t-mid) var(--out-soft) forwards;
}
.order-group.is-ghost { border: 1px solid var(--line); border-radius: var(--radius); }
@keyframes ghostOut { to { opacity: 0; transform: translateX(16px) scale(.98); } }

/* Счётчик набранного: строка меняется на каждое нажатие, и смену видно. */
@keyframes counterSwap { from { opacity: .25; transform: translateY(-3px); } }
.order-side__counter.is-changed { animation: counterSwap var(--t-mid) var(--out); }

/* Ответ портала приезжает, а не подменяется на месте. */
@keyframes statusSay { from { opacity: 0; transform: translateY(-4px); } }
.order-side__status.is-said { animation: statusSay var(--t-mid) var(--out); }

/* Ожидание портала. Заявка притухает и перестаёт принимать нажатия — менять
   состав отправляемого заказа уже поздно, — а по верху панели идёт полоса:
   кольцо на кнопке отвечает за кнопку, полоса за всю отправку. */
.order-page__list { transition: opacity var(--t-mid) var(--out), filter var(--t-mid) var(--out); }
.order-page.is-sending .order-page__list { opacity: .45; filter: grayscale(.4); pointer-events: none; }
.order-side { overflow: hidden; }
.order-side::after {
  content: ""; position: absolute; left: 0; top: 0; height: 2px; width: 38%;
  background: linear-gradient(90deg, transparent, var(--prime), transparent);
  opacity: 0; transition: opacity var(--t-fast) linear;
}
.order-page.is-sending .order-side::after { opacity: 1; animation: sendSweep 1.15s linear infinite; }
@keyframes sendSweep { from { transform: translateX(-100%); } to { transform: translateX(365%); } }

/* Экран «отправлено» приходит по частям: галочка, заголовок, объяснение,
   кнопки. Это конец пути, и он единственный на сайте разложен по шагам. */
@keyframes doneRise { from { opacity: 0; transform: translateY(10px); } }
.order-done h2 { animation: doneRise var(--t-slow) var(--out) .06s both; }
.order-done > p { animation: doneRise var(--t-slow) var(--out) .14s both; }
.order-done__actions { animation: doneRise var(--t-slow) var(--out) .22s both; }

/* Мелочи, из которых складывается ощущение опрятности: карточка товара
   отзывается на наведение, «убрать» не мозолит глаза, пока курсор не рядом. */
.order-group { transition: border-color var(--ease), transform var(--t-mid) var(--out); }
.order-group:hover { border-color: var(--grey); }
@media (hover: hover) {
  .order-line__drop { opacity: .55; transition: opacity var(--ease), color var(--ease); }
  .order-line:hover .order-line__drop, .order-line__drop:focus-visible { opacity: 1; }
}

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

.order-tabs { position: relative; display: flex; gap: 8px; margin-bottom: 26px; border-bottom: 1px solid var(--line); }

/* Черта переезжает между вкладками; ширину и сдвиг ставит order.js. Пока
   она не поставлена (скрипт ещё не отработал), нижнюю границу держит сама
   вкладка — иначе активная вкладка на миг оставалась бы без подчёркивания. */
.order-tabs__ink {
  position: absolute; left: 0; bottom: -1px; width: 0; height: 2px;
  background: var(--prime); border-radius: 2px; opacity: 0;
  transition: transform var(--t-mid) var(--out), width var(--t-mid) var(--out), opacity var(--t-fast) linear;
}
.order-tabs__ink.is-set { opacity: 1; }
.order-tabs:has(.order-tabs__ink.is-set) .order-tab.is-active { border-bottom-color: transparent; }
.order-tab {
  position: relative; bottom: -1px;
  padding: 12px 20px; cursor: pointer;
  background: none; border: 0; border-bottom: 2px solid transparent;
  font-family: var(--font-ui); font-size: .84rem; font-weight: 700;
  letter-spacing: .06em; text-transform: uppercase; color: var(--grey-text);
  transition: color var(--ease), border-color var(--ease);
}
.order-tab:hover { color: var(--ink); }
.order-tab.is-active { color: var(--ink-strong); border-bottom-color: var(--prime); }
/* Счётчик набранного прямо на вкладке: пустой span схлопывается сам. */
.order-tab [data-tab-count]:not(:empty) {
  display: inline-flex; align-items: center; justify-content: center;
  min-width: 20px; height: 20px; margin-left: 8px; padding: 0 5px;
  background: var(--btn-fill); color: var(--on-prime);
  border-radius: 10px; font-size: .72rem; font-variant-numeric: tabular-nums;
}

.order-history { max-width: 880px; }
.order-history__signin { margin-top: 18px; max-width: 380px; }
.order-history__who { font-size: .88rem; color: var(--ink); margin-bottom: 18px; display: flex; align-items: baseline; gap: 10px; flex-wrap: wrap; }
.order-history__who b { color: var(--ink-strong); }
.order-history__list { display: flex; flex-direction: column; gap: 12px; }

.order-card { background: var(--surface); border: 1px solid var(--line); border-radius: var(--radius); padding: 18px 20px; }
.order-card__head { display: flex; align-items: baseline; justify-content: space-between; gap: 14px; }
.order-card__number { font-family: var(--font-ui); font-size: 1.02rem; font-weight: 700; letter-spacing: .04em; color: var(--ink-strong); }
/* Состояние словом, а не цветом: «Отгружен» читается и в монохроме. Цвет
   только подсказывает, и лишь у двух крайних состояний. */
.order-card__status {
  font-family: var(--font-ui); font-size: .72rem; font-weight: 700;
  letter-spacing: .08em; text-transform: uppercase; color: var(--grey-text);
  white-space: nowrap;
}
.order-card__status.is-shipped, .order-card__status.is-paid { color: var(--ok-text); }
.order-card__status.is-cancelled, .order-card__status.is-canceled, .order-card__status.is-rejected { color: var(--prime-text); }
.order-card__meta { font-size: .86rem; color: var(--grey-text); margin-top: 6px; font-variant-numeric: tabular-nums; }
.order-card__toggle {
  margin-top: 12px; padding: 0; min-height: 24px; cursor: pointer;
  background: none; border: 0;
  font-family: var(--font-ui); font-size: .74rem; letter-spacing: .06em;
  text-transform: uppercase; color: var(--prime-text);
}
.order-card__toggle:hover { color: var(--prime-text-hover); }
.order-card__items { margin-top: 12px; padding-top: 12px; border-top: 1px solid var(--line); font-size: .88rem; }
.order-card__item { display: flex; justify-content: space-between; gap: 16px; padding: 6px 0; }
.order-card__item-name { color: var(--ink-strong); }
.order-card__item-meta { color: var(--grey-text); white-space: nowrap; font-variant-numeric: tabular-nums; }
.order-card__comment { margin-top: 10px; font-size: .84rem; color: var(--grey-text); }

/* ---------- Сенсорные ширины: новые блоки ---------- */

@media (max-width: 992px) {
  /* Заявка: боковая панель уходит под список, липкость на телефоне только
     мешает — она перекрывает половину экрана при вводе логина. */
  .order-page { grid-template-columns: 1fr; }
  .order-side { position: static; }

  /* Счётчик заявки встаёт в ряд со знаком, телефоном и бургером. Ширины
     на четыре элемента не хватает, поэтому номер сворачивается в трубку:
     ровно тот же приём, что ниже 340px, но по другому поводу. */
  .header.has-basket .header__util .header__phone-text { display: none; }
  .header.has-basket .header__phone {
    justify-content: center; width: 44px; padding: 0;
    border: 1px solid var(--chrome-ctl); border-radius: 50%;
  }
  .header.has-basket .header__phone-icon { display: block; }
  .header.has-basket { gap: 8px; }

  /* Вкладки героя: шесть подписей столбиком занимали треть первого экрана,
     а сам сюжет и так назван заголовком слайда. Оставляем индикатор —
     шесть дорожек в ряд. Подпись уходит в скрытый текст, поэтому кнопка
     по-прежнему называет себя скринридеру, а палец получает свои 44px. */
  .hero__tabs { grid-auto-flow: column; grid-auto-columns: 1fr; gap: 10px; padding-bottom: 26px; }
  .hero__tab { min-height: 44px; justify-content: center; }
  .hero__tab-label { display: none; }
  .hero__tab-track { margin-bottom: 0; }

  .page-head--cover .page-head__inner { padding: 36px 24px; }
  .page-head { padding: 24px 0 22px; margin-bottom: 30px; }
  .page-head h1 { max-width: none; }
  .page-head__lead { font-size: 1rem; }
}

@media (max-width: 640px) {
  /* Вкладки во всю ширину: две штуки, каждая под палец. */
  .order-tabs { gap: 0; }
  .order-tab { flex: 1; padding: 12px 8px; text-align: center; min-height: 44px; }
  /* Состав заказа: название и хвост в столбик, иначе «арт. … × 12 · 5 699 ₽»
     ломает строку посреди артикула. */
  .order-card__item { flex-direction: column; gap: 2px; }
  .order-card__item-meta { white-space: normal; }

  /* Строка заявки: счётчик и «убрать» под подписью — в три колонки
     на 350px подпись фасовки ломается по слогам. */
  .order-line { grid-template-columns: 1fr auto; gap: 10px 12px; }
  .order-line__main { grid-column: 1 / -1; }

  /* Числа: в две колонки рельс слева достаётся и первому в ряду —
     линия повисает у края экрана. Оставляем её только правому столбцу. */
  .stats { grid-template-columns: 1fr 1fr; gap: 26px 0; }
  .stat { padding: 0 16px; }
  .stat:nth-child(odd) { padding-left: 0; border-left: 0; }
  .stat b { font-size: 2.2rem; }

  /* Таблица характеристик: четыре колонки в 350px не встанут ни при какой
     отбивке — «Пластичная смазка» ломается на две строки, а «Стандарт»
     уезжает за край. Строка разворачивается в две: показатель сверху,
     под ним значение с единицей и методом. Прочерки пустых ячеек убираем —
     на узкой строке они читаются как оборванный текст. */
  .spec, .spec tbody, .spec tr, .spec th, .spec td { display: block; }
  .spec thead { display: none; }
  .spec-scroll { overflow: visible; }
  .spec tr { padding: 12px 0; border-bottom: 1px solid var(--line); }
  .spec tr:last-child { border-bottom: 0; }
  .spec tbody th { padding: 0 0 3px; border: 0; font-size: .86rem; color: var(--grey-text); }
  .spec td { display: inline; padding: 0; border: 0; }
  .spec__value { font-size: 1rem; }
  .spec__dash { display: none; }
  /* Разделители ставятся только у заполненных ячеек: у пустой в разметке
     лежит прочерк, и :has ловит именно её. */
  .spec__unit:not(:has(.spec__dash))::before { content: " "; }
  .spec__std:not(:has(.spec__dash))::before { content: " · "; }
  .spec-raw { columns: 1; }

  .banner { padding: 26px 22px; }
  .banner__title { font-size: 1.2rem; }
}

/* ---------- Адаптив ---------- */

@media (max-width: 1100px) {
  .order__layout { grid-template-columns: 1fr; }
  .cart { position: static; }
  .product-head { grid-template-columns: 380px 1fr; gap: 32px; }
}

@media (max-width: 992px) {
  .grid--4 { grid-template-columns: repeat(2, 1fr); }
  .grid--3 { grid-template-columns: repeat(2, 1fr); }
  .stats { grid-template-columns: repeat(2, 1fr); }
  .order__terms { grid-template-columns: repeat(2, 1fr); }
  .product-head { grid-template-columns: 1fr; }
  .product-head__media { min-height: 320px; }
  .product-head__media img { max-height: 300px; }
  .footer__grid { grid-template-columns: repeat(2, 1fr); }
  .header__nav { display: none; }
  .hero h1 { font-size: 2.4rem; }
  .banner { grid-template-columns: 1fr; }
}

/* ---------- Цели нажатия на сенсорных ширинах ---------- */
/* Замер показал ссылки высотой 14–20px: крошки 14, подвал 17, мобильное меню 18,
   телефон в шапке 20. Порог WCAG 2.5.8 (AA) — 24px, рекомендация платформ — 44.
   Ссылки внутри предложения (почта и телефон в тексте контактов) под исключение
   для inline-целей подпадают и намеренно не трогаются: наращивать им отбивку
   значит рвать строку. Ширина брейкпоинта та же, где появляется бургер, — здесь
   макет заведомо сенсорный. */

@media (max-width: 992px) {
  /* Телефон в шапке: на телефоне это единственный элемент конверсии в верхнем
     ярусе, а был 20px. Ярус и так 62px высотой, места хватает. */
  .header__util a { display: inline-flex; align-items: center; min-height: 44px; }

  .theme-toggle { width: 44px; height: 44px; }
  .theme-toggle svg { width: 19px; height: 19px; }

  /* Крошки: 14px. Отбивка снизу у списка убрана в пользу отбивки у самих
     ссылок — иначе блок вырастает вдвое. */
  .breadcrumbs { padding-top: 18px; padding-bottom: 2px; }
  .breadcrumbs ol { gap: 2px 10px; }
  .breadcrumbs li { min-height: 28px; }

  /* Мобильное меню — главная навигация на телефоне, здесь было хуже всего: 18px.
     Список станет длиннее, но он и так с собственной прокруткой. */
  .mobile-nav__title { display: flex; align-items: center; min-height: 44px; }
  .mobile-nav__group ul { margin-top: 2px; }
  .mobile-nav__group li { margin-bottom: 0; }
  .mobile-nav__group li a { display: flex; align-items: center; min-height: 40px; }
  .mobile-nav__list { gap: 14px; }

  /* Подвал: 17px. Отбивку строки уменьшаем ровно на столько, сколько добавили
     внутрь ссылки, — ритм колонки не меняется. */
  .footer li { margin-bottom: 2px; }
  .footer li a { display: inline-flex; align-items: center; min-height: 28px; }

  /* «Узнать больше», «Весь каталог» — самостоятельные ссылки-призывы, были 20px. */
  .link-more { min-height: 44px; }

  /* Флажок «только в наличии» сам по себе 17px. Нажимается вся подпись,
     но целью считается видимая область — растим её до 44px целиком. */
  .cat-stock { min-height: 44px; }
  .cat-stock input { width: 20px; height: 20px; }

  /* Телефон и почта внутри предложения формально под исключение для inline-целей
     подпадают, но на странице контактов это элементы конверсии. Вертикальная
     отбивка у inline-элемента растит область попадания до 30px, не меняя высоту
     строки и не сдвигая макет. */
  main a[href^="tel:"], main a[href^="mailto:"] { padding: 5px 2px; }
}

@media (max-width: 640px) {
  h1 { font-size: 1.7rem; }
  /* и здесь тоже во весь экран, высоту задаёт правило выше */
  .hero__inner { padding-top: 90px; padding-bottom: 30px; }
  .hero h1 { font-size: 1.85rem; }
  .hero__desc { font-size: 1rem; }
  .section { padding: 52px 0; }
  .grid--2, .grid--3, .grid--4 { grid-template-columns: 1fr; }
  .stats { grid-template-columns: 1fr 1fr; }
  .order__packs { grid-template-columns: 1fr 1fr; }
  .order__terms { grid-template-columns: 1fr; }
  .footer__grid { grid-template-columns: 1fr; }
  .btn { padding: 0 24px; }
}

/* Узкие телефоны (320–360): два места, где строка не сходится.
   Замер на 320px: заголовок секции со ссылкой «Все масла G-Family» уезжал
   на 5px, сетка фасовок в две колонки — на 14px. */
@media (max-width: 360px) {
  .section__head { flex-wrap: wrap; gap: 12px; }
  .order__packs { grid-template-columns: 1fr; }
}

/* ---------- Подбор по автомобилю (picker) ---------- */
/* Здесь только то, что делят страница подбора и полоса на главной: плитки
   категорий. Всё остальное оформление /select/auto/ живёт в picker.css —
   его качает одна эта страница, и бюджет у него свой. Плитки — те же классы
   на обеих страницах (на главной это ссылки). */
.picker__cats { display: grid; grid-template-columns: repeat(5, minmax(0, 1fr)); gap: 14px; margin-top: 30px; }
.picker__cat { position: relative; display: flex; flex-direction: column; justify-content: flex-end; aspect-ratio: 16 / 10; padding: 0; border: 1px solid var(--line); border-radius: var(--radius); background: var(--surface); color: var(--ink); font: inherit; text-align: left; cursor: pointer; overflow: hidden; transition: border-color var(--ease), box-shadow var(--ease), transform var(--t-fast) var(--out); }
.picker__cat:hover, .picker__cat.is-hot { border-color: var(--prime); }
.picker__cat:active { transform: translateY(1px); }
.picker__cat.is-active { border-color: var(--prime); box-shadow: 0 0 0 2px var(--prime); }
.picker__cat-media { position: absolute; inset: 0; }
.picker__cat-media img { width: 100%; height: 100%; object-fit: cover; transition: transform var(--t-slow) var(--out); }
.picker__cat--photo .picker__cat-media::after { content: ""; position: absolute; inset: 0; background: linear-gradient(180deg, transparent 38%, rgba(8, 8, 9, .86)); }
.picker__cat:hover .picker__cat-media img { transform: scale(1.06); }
/* У плитки с роликом снимок не наезжает: ролик ложится поверх без
   увеличения, и увеличенный постер под ним давал скачок картинки. */
.picker__cat[data-video]:hover .picker__cat-media img, .picker__cat[data-video].is-hot .picker__cat-media img { transform: none; }
.picker__cat-name, .picker__cat-meta { position: relative; z-index: 1; padding: 0 16px; }
.picker__cat-name { font-family: var(--font-ui); font-size: 1.05rem; font-weight: 700; letter-spacing: .04em; text-transform: uppercase; color: var(--ink-strong); }
.picker__cat-meta { margin-top: 4px; padding-bottom: 16px; font-size: .8rem; color: var(--grey-text); }
/* Подложка идёт за подписью, не за плиткой: в две строки подпись вылезала
   на светлую крышу выше градиента (1.1–2.9 вместо 4.5); .86 даёт ≥ 14 везде. */
.picker__cat--photo .picker__cat-name { padding-top: 28px; background: linear-gradient(180deg, transparent, rgba(8, 8, 9, .86) 28px); color: #fff; }
.picker__cat--photo .picker__cat-meta { margin-top: 0; padding-top: 4px; background: rgba(8, 8, 9, .86); color: rgba(255, 255, 255, .78); }
/* Узкие плитки пяти колонок (177–230px): имя в две строки плюс счётчик не влезали по высоте. */
@media (min-width: 993px) and (max-width: 1300px) { .picker__cat-name { padding-bottom: 14px; font-size: .95rem; } .picker__cat-meta { display: none; } }
.picker__cat-check { position: absolute; z-index: 2; top: 12px; right: 12px; display: inline-flex; align-items: center; justify-content: center; width: 28px; height: 28px; border-radius: 50%; background: var(--btn-fill); color: var(--on-prime); transform: scale(0); transition: transform var(--t-mid) var(--out); }
.picker__cat-check svg { width: 14px; height: 14px; }
.picker__cat.is-active .picker__cat-check { transform: scale(1); }
.picker__cat-check.is-pop { animation: pickerPop var(--t-mid) var(--out); }
@keyframes pickerPop { from { transform: scale(.6); } }
.picker-band .picker__cats { grid-template-columns: repeat(4, minmax(0, 1fr)); margin-top: 26px; }
.picker-band__lead { max-width: 62ch; margin: -8px 0 0; color: var(--grey-text); }
.picker-band__actions { margin-top: 26px; }
/* Ролик плитки (picker-tiles.js) ложится поверх снимка и, однажды появившись,
   остаётся: на уходе курсора замирает на своём кадре. Появляется стоя на
   первом кадре, поэтому проявление короткое. */
.picker__cat-video { position: absolute; inset: 0; width: 100%; height: 100%; object-fit: cover; opacity: 0; transition: opacity .12s linear; }
.picker__cat-video.is-live { opacity: 1; }
/* На главной плитки — та же лента-гармошка, что на странице подбора
   (picker.css, лента на странице подбора): плитка под курсором раздвигается, остальные
   поджимаются и прячут счётчики. Только мышь и широкий экран. */
@media (hover: hover) and (min-width: 993px) {
  .picker-band .picker__cats { display: flex; gap: 12px; }
  .picker-band .picker__cat { flex: 1 1 0; min-width: 0; height: clamp(210px, 20vw, 300px); aspect-ratio: auto; transition: flex-grow .6s var(--out), border-color var(--ease), box-shadow var(--t-mid) var(--out); }
  .picker-band .picker__cat-name { font-size: clamp(.85rem, 1vw, 1.05rem); white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: font-size .3s var(--out); }
  .picker-band .picker__cat.is-hot .picker__cat-name { font-size: 1.12rem; }
  .picker-band .picker__cat-meta { white-space: nowrap; overflow: hidden; text-overflow: ellipsis; transition: opacity var(--t-mid) linear; }
  /* Горячая плитка — класс is-hot от picker-tiles.js, не :hover: тот терялся
     в зазоре между плитками, и лента дёргалась при каждом переходе. */
  /* Снимок и ролик — окно: слой шириной с раскрытую плитку стоит по центру и
     не меняет размер, плитка лишь открывает его больше или меньше (см. picker.css). */
  .picker-band .picker__cat-media { inset: 0 auto; left: 50%; width: 620px; margin-left: -310px; }
  .picker-band .picker__cats.has-hot .picker__cat { flex-grow: .84; }
  .picker-band .picker__cats.has-hot .picker__cat:not(.is-hot) .picker__cat-meta { opacity: 0; }
  .picker-band .picker__cats.has-hot .picker__cat.is-hot { flex-grow: 2.1; box-shadow: 0 24px 60px rgba(8, 8, 9, .35); }
}
/* Заголовок полосы длинный, в три строки на телефоне; ссылка «Открыть подборщик»
   с декоративной чертой рядом с ним уже не помещалась и раздвигала страницу
   вширь. Ниже стоит та же кнопка — на узком экране ссылка лишняя. */
@media (max-width: 640px) { .picker-band .section__head .link-more { display: none; } }
@media (max-width: 992px) { .picker__cats, .picker-band .picker__cats { grid-template-columns: repeat(2, minmax(0, 1fr)); } }
@media (max-width: 640px) { .picker__cats, .picker-band .picker__cats { grid-template-columns: 1fr; } .picker__cat { aspect-ratio: 16 / 9; } }

@media (prefers-reduced-motion: reduce) {
  .hero__tab.is-active .hero__tab-bar { width: 100%; }

  /* Сокращённое движение — это меньше перемещений, а не выключенный
     интерфейс: смена цвета и подсветка состояний остаются, ездить по экрану
     перестаёт всё. Переход между страницами сводится к простому растворению. */
  .reveal-on .reveal { opacity: 1; transform: none; }
  .mobile-nav[hidden], .submenu { transform: none; }
  ::view-transition-old(root) { animation: vtFadeOut var(--t-fast) linear both; }
  ::view-transition-new(root) { animation: vtFadeIn var(--t-fast) linear both; }
  @keyframes vtFadeOut { to { opacity: 0; } }
  @keyframes vtFadeIn { from { opacity: 0; } }

  /* Бренды на главной: снимок и строки стоят на месте. */
  .brands__shot, .brands__name, .brands__go, .brands__row::after { transition: none; }
  .brands__row:hover .brands__name { transform: none; }
  .brands-fx .brands__item { opacity: 1; transform: none; transition: none; }
  /* Плитки категорий (главная и подбор): без наезда снимка, без прыжка галочки,
     без роликов и без гармошки. */
  .picker__cat-media img, .picker__cat-check { transition: none; }
  .picker__cat:hover .picker__cat-media img { transform: none; }
  .picker__cat-video { display: none; }
  .picker-band .picker__cats.has-hot .picker__cat, .picker-band .picker__cat.is-hot { flex-grow: 1; }
  .picker-band .picker__cat-name { transition: none; }

  *, *::before, *::after {
    animation-duration: .01ms !important;
    animation-iteration-count: 1 !important;
    transition-duration: .01ms !important;
    scroll-behavior: auto !important;
  }
}
