/* ═══ ШРИФТ ═══════════════════════════════════════════════════════
   Одно семейство на весь сайт вместо двух. Подробное обоснование — в
   шапке index.html, там же про лицензию Nexa и почему именно Montserrat.
   Коротко: Oswald узкий, Manrope широкий, на одной странице они читались
   как две разные вёрстки. Иерархию держит вес, а не смена гарнитуры. */
@font-face{font-family:'Montserrat';src:url(/fonts/montserrat-cyrillic.woff2) format('woff2');font-weight:400 800;font-style:normal;font-display:optional;unicode-range:U+0301,U+0400-045F,U+0490-0491,U+04B0-04B1,U+2116}
@font-face{font-family:'Montserrat';src:url(/fonts/montserrat-cyrillic-ext.woff2) format('woff2');font-weight:400 800;font-style:normal;font-display:optional;unicode-range:U+0460-052F,U+1C80-1C8A,U+20B4,U+2DE0-2DFF,U+A640-A69F,U+FE2E-FE2F}
@font-face{font-family:'Montserrat';src:url(/fonts/montserrat-latin.woff2) format('woff2');font-weight:400 800;font-style:normal;font-display:optional;unicode-range:U+0000-00FF,U+0131,U+0152-0153,U+02BB-02BC,U+02C6,U+02DA,U+02DC,U+0304,U+0308,U+0329,U+2000-206F,U+20AC,U+2122,U+2191,U+2193,U+2212,U+2215,U+FEFF,U+FFFD}
@font-face{font-family:'Montserrat';src:url(/fonts/montserrat-latin-ext.woff2) format('woff2');font-weight:400 800;font-style:normal;font-display:optional;unicode-range:U+0100-02BA,U+02BD-02C5,U+02C7-02CC,U+02CE-02D7,U+02DD-02FF,U+0304,U+0308,U+0329,U+1D00-1DBF,U+1E00-1E9F,U+1EF2-1EFF,U+2020,U+20A0-20AB,U+20AD-20C0,U+2113,U+2C60-2C7F,U+A720-A7FF}
@font-face{font-family:'Montserrat Fallback';src:local('Arial'),local('Helvetica'),local('Liberation Sans');size-adjust:113.0%;ascent-override:85.8%;descent-override:22.2%;line-gap-override:0%}

/* ============================================================
   ИЗКО — Каталог оборудования
   catalog.css — все стили каталога
   ============================================================ */

/* ── Токены ────────────────────────────────────────────────── */
:root {
  --bg:           #13161D;
  --bg2:          #191C26;
  --card:         #1D2130;
  --card-h:       #242A3C;
  --gold:         #C9A435;
  --gold-lt:      #E8C45A;
  --gold-dp:      #8F7520;
  /* Золото как ТЕКСТ. Заливка (--gold) остаётся прежней: её нельзя
     темнить, иначе тёмная подпись на кнопке потеряет контраст.
     На светлой теме #C9A435 давал 2,05:1 — ниже нормы вдвое. */
  --gold-ink:     #C9A435;
  --gold-dim:     rgba(201, 164, 53, 0.12);
  --gold-glow:    rgba(201, 164, 53, 0.18);
  --ember:        #D97B3C;
  --steel:        #6080A8;
  /* «Чернильные» варианты семантических цветов — только для текста.
     Заливка бейджа остаётся полупрозрачной, темнить её незачем. */
  /* Подпись на золотой заливке. Была var(--bg), а он на светлой теме
     почти белый — «Запросить КП» давало 2,18:1 прямо на кнопке.
     Золото одинаково в обеих темах, значит и подпись фиксированная. */
  --on-gold:      #12140E;
  --steel-ink:    #7C9BC4;
  --ember-ink:    #E08A50;
  --text:         #ECF0FF;
  --muted:        #7C90B2;   /* было #6A7A9A — 3,71:1 на карточке */
  --muted-lt:     #9AAAC8;
  --border:       rgba(255, 255, 255, 0.07);
  --border-g:     rgba(201, 164, 53, 0.22);
  --atm-warm:     rgba(201, 164, 53, 0.17);
  --atm-cool:     rgba(96, 128, 168, 0.15);
  --atm-line:     rgba(201, 164, 53, 0.07);
  --atm-band:     rgba(255, 255, 255, 0.025);
  --font-display: 'Montserrat', 'Montserrat Fallback', sans-serif;
  --font-body:    'Montserrat', 'Montserrat Fallback', sans-serif;
  --nav-h:        60px;

  /* Шкала заголовков — одна на весь каталог. До этого H1 гулял по
     страницам (53,2 / 60,8 / 45,6px), а один и тот же уровень H2 имел
     пять разных значений. */
  --h1:           clamp(2rem, 5vw, 3.2rem);
  --h2:           clamp(1.5rem, 2.4vw, 2.1rem);

  --r:            6px;
  --r-lg:         12px;
  --trans:        0.22s ease;

  /* Шкала движения (CLAUDE-design.md §7). До этого кривые Безье были
     вписаны в правила по месту — одна и та же анимация имела три
     разных тайминга в разных частях листа. */
  --ease-out:     cubic-bezier(0.16, 1, 0.3, 1);   /* появление, оседает */
  --ease-smooth:  cubic-bezier(0.4, 0, 0.2, 1);    /* нейтральные переходы */
  --dur-fast:     .15s;   /* ховер кнопки, кольцо фокуса */
  --dur-base:     .25s;   /* обычные переходы UI */
  --dur-slow:     .5s;    /* крупные блоки, раскрытие секции */

  /* Минимальная зона нажатия (§2.5 / §6, Apple HIG) */
  --tap:          44px;
}

/* ── Reset ─────────────────────────────────────────────────── */
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
/* root font-size base mirrors landing-A (18.5 / 19px ≥1280) so every
   rem-based size — logo, nav links, headings — renders identically to
   the landing topbar instead of ~3% smaller */
html { font-size: 18.5px; scroll-behavior: smooth; }
@media (min-width: 1280px) { html { font-size: 19px; } }
body {
  background: var(--bg);
  color: var(--text);
  font-family: var(--font-body);
  font-weight: 400;
  line-height: 1.6;
  -webkit-font-smoothing: antialiased;
}
/* ═══ АТМОСФЕРА ФОНА ══════════════════════════════════════════
   Фон был плоской заливкой на всю высоту страницы. На ноутбуке это
   тысячи пикселей ровно одного цвета: глазу не за что зацепиться, и
   сайт читается мёртвым, хотя на нём всё двигается. Зерно поверх
   стоит на 2,2% непрозрачности и этой задачи не решает.

   Слои фиксированные, содержимое едет по ним как по подложке, и
   параллакс выходит бесплатно, без единого кадра скрипта.

   Нижний слой, неподвижный: сетка чертежа и дымка. Завод продаёт
   спроектированные блоки, на карточках изделий крутится настоящий
   чертёж — клетка держит ту же мысль, а не украшает. Дымка цветом
   фона гасит клетку к краям экрана, иначе выходят обои в клетку.
   В background первый слой лежит сверху, поэтому дымка идёт раньше
   сетки. */
html::before {
  content: '';
  position: fixed; inset: 0;
  z-index: -2; pointer-events: none;
  background:
    radial-gradient(76% 60% at 50% 42%, transparent 20%, var(--bg) 86%),
    repeating-linear-gradient(0deg,  var(--atm-line) 0 1px, transparent 1px 92px),
    repeating-linear-gradient(90deg, var(--atm-line) 0 1px, transparent 1px 92px),
    var(--bg);
}

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

   Свет медленно дышит. Сорок секунд на цикл — между двумя соседними
   кадрами не видно ничего, но за то время, пока читают экран, свет
   успевает сместиться, и страница перестаёт быть картинкой. Двигаем
   transform и opacity, то есть работу отдаём композитору: ни одного
   перерисованного пикселя. Отдельным слоем именно ради этого — сетку
   шевелить нельзя, она сразу читается как рябь. */
body::after {
  content: '';
  position: fixed; inset: -10%;
  z-index: -1; pointer-events: none;
  background:
    radial-gradient(120% 85% at 84% -6%, var(--atm-warm), transparent 58%),
    radial-gradient(95% 72% at 6% 104%, var(--atm-cool), transparent 60%);
  animation: atm-breathe 40s ease-in-out infinite;
}
@keyframes atm-breathe {
  0%, 100% { transform: scale(1)    translate3d(0, 0, 0);        opacity: 0.8; }
  50%      { transform: scale(1.08) translate3d(-1.5%, 1%, 0);   opacity: 1;   }
}

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

/* Слабое железо и просьба убрать движение: слой света гасим совсем,
   нижний оставляем — он ничего не стоит. */
.perf-lite body::after { display: none; }
@media (prefers-reduced-motion: reduce) { body::after { animation: none; } }

img { display: block; max-width: 100%; }
a { color: inherit; text-decoration: none; }
ul, ol { list-style: none; }
button { cursor: pointer; border: none; background: none; font: inherit; }
input, select { font: inherit; }

/* ── Утилиты ───────────────────────────────────────────────── */
.container {
  width: 100%;
  max-width: 1240px;
  margin-inline: auto;
  padding-inline: 20px;
}
.sr-only {
  position: absolute;
  width: 1px; height: 1px;
  padding: 0; margin: -1px;
  overflow: hidden; clip: rect(0,0,0,0);
  white-space: nowrap; border: 0;
}

/* ── Навигация ─────────────────────────────────────────────── */
.site-nav {
  position: fixed;
  top: 0; left: 0; right: 0;
  z-index: 900;
  height: var(--nav-h);
  background: rgba(16, 19, 28, 0.97);
  backdrop-filter: blur(24px) saturate(1.4);
  -webkit-backdrop-filter: blur(24px) saturate(1.4);
  border-bottom: 1px solid rgba(201, 164, 53, 0.18);
  box-shadow: 0 2px 20px rgba(0,0,0,0.4);
  transition: border-color 0.5s ease, background 0.5s ease, box-shadow 0.5s;
}
.site-nav__inner {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: clamp(1rem, 1.8vw, 2.4rem);
  height: 100%;
  /* full-bleed, edge-pinned — matches landing-A nav (padding: 0 3.4rem,
     no max-width container). Was max-width:1240px + margin auto, which
     floated the bar centered while the landing bar sat left. */
  padding: 0 clamp(1.75rem, 3vw, 3.4rem);
}
/* responsive nav padding scale — mirrors landing-A breakpoints exactly */
@media (max-width: 1060px) { .site-nav__inner { padding: 0 1.75rem; } }
@media (max-width: 768px)  { .site-nav__inner { padding: 0 1.25rem; } }
@media (max-width: 480px)  { .site-nav__inner { padding: 0 0.9rem; } }

/* Логотип */
.logo {
  display: flex;
  align-items: center;
  gap: 0.7rem;
  flex-shrink: 0;
  text-decoration: none;
}
.logo-ico {
  width: auto; height: 2.55rem;
  transition: transform 0.35s ease;
}
.logo:hover .logo-ico { transform: rotate(18deg); }
.logo-mark {
  font-family: var(--font-display);
  font-size: 2.05rem;
  letter-spacing: 0.12em;
  color: var(--text);
  line-height: 1;
  border-bottom: 4px solid var(--gold);
  padding-bottom: 0.2rem;
  margin-right: -0.12em;
}
.logo-mark em {
  font-style: normal;
  color: var(--gold-ink);
}

/* Nav links */
.nav-links {
  display: flex;
  align-items: center;
  gap: clamp(0.95rem, 1.7vw, 2.4rem);
}
.nav-links a {
  position: relative;
  font-family: var(--font-body);
  font-size: 0.67rem;
  font-weight: 600;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--muted-lt);
  padding: 0.5rem 0;
  transition: color 0.3s;
}
.nav-links a::before {
  content: ''; position: absolute;
  bottom: 0; left: 0; right: 0; height: 1px;
  background: var(--gold);
  transform: scaleX(0);
  transform-origin: right center;
  transition: transform 0.42s cubic-bezier(0.16, 1, 0.3, 1);
}
.nav-links a:hover { color: var(--text); }
.nav-links a:hover::before,
.nav-links a.is-active::before {
  transform: scaleX(1);
  transform-origin: left center;
}
.nav-links a.is-active { color: var(--text); }

/* Телефон в навигации — жирный, как на главной (.nav-ph) */
.nav-phone {
  font-family: var(--font-body);
  font-size: 0.92rem;
  font-weight: 700;
  color: var(--text);
  letter-spacing: 0.03em;
  white-space: nowrap;
  transition: color var(--trans);
}
.nav-phone:hover { color: var(--gold-ink); }

/* Бургер */
.nav-toggle {
  display: none;
  flex-direction: column;
  justify-content: center;
  gap: 5px;
  width: 36px; height: 36px;
  padding: 6px;
}
.nav-toggle span {
  display: block;
  width: 100%; height: 2px;
  background: var(--text);
  border-radius: 2px;
  transition: transform var(--trans), opacity var(--trans);
}
.nav-toggle[aria-expanded="true"] span:nth-child(1) { transform: translateY(7px) rotate(45deg); }
.nav-toggle[aria-expanded="true"] span:nth-child(2) { opacity: 0; }
.nav-toggle[aria-expanded="true"] span:nth-child(3) { transform: translateY(-7px) rotate(-45deg); }

/* Переключатель темы */
.theme-toggle {
  display: flex; align-items: center; gap: 0.4rem;
  background: var(--gold-dim);
  border: 1px solid var(--border-g);
  border-radius: 30px;
  padding: 0.28rem 0.7rem;
  cursor: pointer;
  font-size: 0.75rem; font-family: var(--font-body);
  color: var(--muted-lt); letter-spacing: 0.04em;
  transition: all 0.3s ease;
  white-space: nowrap; flex-shrink: 0;
}
.theme-toggle:hover { border-color: var(--gold-ink); color: var(--text); }
/* Иконка темы — inline-SVG вместо эмодзи ☀️/🌙: эмодзи рисуются
   шрифтом ОС, поэтому на Windows, macOS и Android кнопка выглядела
   по-разному и не подчинялась цвету текста. Обе лежат в разметке,
   нужную показывает тема — JS ничего не подменяет. */
.theme-toggle-icon { display: inline-flex; line-height: 0; color: currentColor; }
.theme-toggle-icon .ti { width: 16px; height: 16px; display: block; }
.theme-toggle-icon .ti--moon { display: none; }
[data-theme="light"] .theme-toggle-icon .ti--sun  { display: none; }
[data-theme="light"] .theme-toggle-icon .ti--moon { display: block; }
.theme-toggle-lbl { display: none; }
@media (min-width: 520px) { .theme-toggle-lbl { display: inline; } }

/* Nav right group */
.nav-r {
  display: flex;
  align-items: center;
  gap: clamp(0.8rem, 1.3vw, 1.75rem);
}

/* Кнопка «Заказать звонок» — копия .cta с главной, значение в значение:
   шапка обязана выглядеть одинаково на всех страницах сайта. */
.nav-cta {
  display: inline-flex; align-items: center; gap: 0.5rem;
  font-family: var(--font-body);
  font-size: 0.70rem; font-weight: 700;
  letter-spacing: 0.09em; text-transform: uppercase;
  padding: 0.55rem 1.6rem;
  background: var(--gold); color: #0B0D12;
  border: none; border-radius: 40px;
  cursor: pointer; transition: all 0.3s ease;
  white-space: nowrap;
}
.nav-cta:hover {
  background: var(--gold-lt);
  transform: translateY(-1px);
  box-shadow: 0 6px 28px rgba(201, 164, 53, 0.35);
}

/* ── Мега-меню «Каталог» ────────────────────────────────────
   Порт из index.html: пункт «Каталог» раскрывается одинаково на
   главной и в каталоге. Десктоп-только — ≤1060px список скрыт,
   работает выпадающее мобильное меню. */
.mm-host { position: relative; }
.mm-caret {
  display: inline-block; font-size: .7em; margin-left: 2px;
  transition: transform .25s ease; vertical-align: 1px;
}
.mm-host:focus-within .mm-caret { transform: rotate(180deg); }
.mm-panel {
  position: absolute; top: calc(100% + 16px); left: -24px; z-index: 999;
  display: flex; gap: 36px;
  padding: 24px 28px;
  background: var(--card);
  border: 1px solid var(--border-g);
  border-radius: 14px;
  box-shadow: 0 24px 60px rgba(0, 0, 0, .55);
  opacity: 0; visibility: hidden;
  transform: translateY(10px) scale(.985);
  transform-origin: top left;
  transition: opacity .24s ease, transform .24s cubic-bezier(.22,.61,.36,1),
              visibility 0s linear .24s;
}
.mm-panel::before { content: ''; position: absolute; top: -16px; left: 0; right: 0; height: 16px; }
.mm-panel::after {
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  border-radius: 14px 14px 0 0;
  background: linear-gradient(90deg, var(--gold), rgba(201,164,53,0) 70%);
}
@media (hover: hover) {
  .mm-host:hover .mm-panel { opacity: 1; visibility: visible; transform: none; transition-delay: 0s; }
  .mm-host:hover .mm-caret { transform: rotate(180deg); }
}
.mm-host:focus-within .mm-panel {
  opacity: 1; visibility: visible; transform: none; transition-delay: 0s;
}
.mm-col { display: flex; flex-direction: column; gap: 2px; min-width: 175px; }
.mm-hd {
  font-family: var(--font-display);
  font-size: .61rem; font-weight: 700;
  letter-spacing: .18em; text-transform: uppercase;
  color: var(--gold-ink);
  margin-bottom: 8px; white-space: nowrap;
}
.mm-panel .mm-col a {
  font-size: .79rem; color: var(--muted-lt); white-space: nowrap;
  padding: 5px 0; border-left: 2px solid transparent;
  transition: color .2s, padding-left .25s, border-color .25s;
}
.mm-panel .mm-col a:hover {
  color: var(--gold-ink); padding-left: 10px; border-left-color: var(--gold-ink);
}
.mm-col--cta { border-left: 1px solid var(--border); padding-left: 30px; }
.mm-tel {
  font-family: var(--font-display); font-weight: 800;
  font-size: 1.05rem !important; color: var(--text) !important;
  margin-top: 4px;
}
.mm-panel .mm-col a.mm-tel:hover { padding-left: 0; border-left-color: transparent; color: var(--gold-ink) !important; }
.mm-note { font-size: .63rem; color: var(--muted); margin-top: 2px; }

/* ── Мобильное меню ─────────────────────────────────────────
   Выпадающая панель под шапкой — как на главной (был полноэкранный
   оверлей, из-за чего меню открывалось по-разному на разных
   страницах). Порог 1060px = порог, на котором прячется список. */
.nav-mobile-menu {
  display: none; position: fixed;
  top: var(--nav-h); left: 0; right: 0; z-index: 899;
  background: rgb(11,13,18);
  border-bottom: 1px solid var(--border-g);
  padding: 0.4rem 1.5rem 1.25rem;
  flex-direction: column;
}
.nav-mobile-menu.open { display: flex; }
.nav-mobile-menu a {
  font-family: var(--font-body);
  font-size: 0.92rem; letter-spacing: 0.08em;
  text-transform: uppercase; color: var(--muted);
  padding: 0.8rem 0;
  border-bottom: 1px solid var(--border);
  transition: color 0.2s;
}
.nav-mobile-menu a:last-child { border-bottom: none; }
.nav-mobile-menu a:hover,
.nav-mobile-menu a:active { color: var(--text); }
.nav-mobile-menu .mob-cta {
  margin-top: 0.75rem; text-align: center;
  color: #0B0D12; border: none;
  background: var(--gold);
  padding: 0.75rem 1.6rem;
  border-radius: 40px;
  font-weight: 700;
}
[data-theme="light"] .nav-mobile-menu { background: rgba(237,238,246,0.97); }
[data-theme="light"] .nav-mobile-menu a { color: var(--muted); border-color: rgba(0,0,0,0.08); }
[data-theme="light"] .nav-mobile-menu .mob-cta { color: #0B0D12; }

@media (max-width: 1060px) {
  .nav-links { display: none; }
  .mm-panel, .mm-caret { display: none; }
  .nav-toggle { display: flex; }
}
/* Шапка не сжимается: логотип + три пункта + телефон + тема + кнопка
   складываются в 1227px, а список появляется уже с 1061px. На
   1061–1246px «Заказать звонок» уезжала за правый край — и молча, без
   скролла, потому что шапка position:fixed. Ниже 1250px кнопку прячем:
   телефон рядом остаётся, а на ≤1060 её дублирует мобильное меню. */
@media (max-width: 1330px) { .nav-cta { display: none; } }
@media (max-width: 768px) {
  .nav-phone { display: none; }
  .nav-r { gap: 0.75rem; }
  .theme-toggle-lbl { display: none !important; }
}
@media (prefers-reduced-motion: reduce) {
  .mm-panel, .mm-caret, .mm-panel .mm-col a, .nav-cta { transition: none; }
}

/* ── Хлебные крошки ────────────────────────────────────────── */
.breadcrumb {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  align-items: center;
  font-size: 0.8rem;
  color: var(--muted);
  margin-bottom: 20px;
}
.breadcrumb a {
  color: var(--muted-lt);
  transition: color var(--trans);
}
.breadcrumb a:hover { color: var(--gold-ink); }
.breadcrumb__sep { color: var(--muted); opacity: 0.5; }
.breadcrumb__current { color: var(--muted-lt); }

/* ── Шапка страницы каталога ───────────────────────────────── */
.cat-head {
  /* Отступ считался в одно число на все ширины: 116px сверху и 56px
     снизу что на 1440, что на 360. На телефоне это пустой блок высотой
     почти в треть экрана; на десктопе, наоборот, тесно относительно
     остального ритма страницы (88 to 112px, норма для .sec ниже).
     Разводим по брейкпоинту вместо одного фиксированного числа. */
  padding-top: calc(var(--nav-h) + 40px);
  padding-bottom: 96px;
  background: linear-gradient(180deg, var(--bg2) 0%, var(--bg) 100%);
  border-bottom: 1px solid var(--border);
}
@media (max-width: 768px) {
  .cat-head { padding-top: calc(var(--nav-h) + 4px); padding-bottom: 60px; }
}
.cat-head h1 {
  font-family: var(--font-display);
  font-size: var(--h1);
  font-weight: 800;
  letter-spacing: -0.015em;
  line-height: 1.15;
  margin-bottom: 14px;
}
.cat-head h1 em {
  font-style: normal;
  color: var(--gold-ink);
}
.cat-head__lede {
  font-size: 1rem;
  color: var(--muted-lt);
  max-width: 620px;
  line-height: 1.7;
}
.cat-head__meta {
  font-size: 0.82rem;
  color: var(--muted);
  margin-top: 10px;
}

/* ── Карточки категорий (хаб) ──────────────────────────────── */
.cat-hub {
  padding-block: 64px;
}
.cat-hub__grid {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 24px;
}
.cat-hub__card {
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  padding: 40px 36px;
  transition: border-color var(--trans), background var(--trans), transform var(--trans);
  text-decoration: none;
}
.cat-hub__card:hover {
  background: var(--card-h);
  border-color: var(--border-g);
  transform: translateY(-3px);
}
.cat-hub__card h2 {
  font-family: var(--font-display);
  font-size: 1.6rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  margin-bottom: 10px;
}
.cat-hub__card p {
  color: var(--muted-lt);
  font-size: 1.05rem;
  line-height: 1.6;
  flex: 1;
  margin-bottom: 28px;
}
.cat-hub__card-cta {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  color: var(--gold-ink);
  transition: gap var(--trans);
}
.cat-hub__card:hover .cat-hub__card-cta { gap: 14px; }
.cat-hub__card-cta::after { content: '→'; }

@media (max-width: 768px) {
  .cat-hub__grid { grid-template-columns: 1fr; }
  .cat-hub__card { padding: 28px 24px; }
}

/* ═══ ЕДИНАЯ ВИТРИНА (/catalog/ одностраничный) ═══════════ */
/* Шапка витрины единственная не отступала от фиксированной панели:
   хлебные крошки лежали на 18px ПОД ней и были не видны вообще.
   Отступ сверху теперь такой же, как у .cat-head. */
/* Тот же разбор по брейкпоинту, что и у .cat-head: 116px сверху и
   16px снизу были одним числом на 1440 и 360 разом. */
.shop-head { padding: calc(var(--nav-h) + 40px) 0 96px; }
@media (max-width: 768px) { .shop-head { padding: calc(var(--nav-h) + 4px) 0 60px; } }
.shop-head h1 { font-family: var(--font-display); font-size: var(--h1);
  font-weight: 800; letter-spacing: -0.015em; line-height: 1.15; }
.shop-head h1 em { font-style: normal; color: var(--gold-ink); }
.shop-head .lede { color: var(--muted-lt); margin-top: .5rem; max-width: 680px; }
/* Ссылка внутри абзаца различалась только цветом (link-in-text-block):
   на монохромном скриншоте или при слабом зрении её было не найти.
   Подчёркивание тоньше и с отступом, чтобы не биться о хвостики букв. */
.shop-head .lede a,
.cat-head__lede a,
.sec__lede a {
  color: var(--gold-ink);
  text-decoration: underline;
  text-decoration-thickness: 1px;
  text-underline-offset: 3px;
}
/* Телефон в лиде переносился между «+7» и «(800)» на 360px. */
.shop-head .lede a[href^="tel:"],
.cat-head__lede a[href^="tel:"],
.sec__lede a[href^="tel:"] {
  white-space: nowrap;
}

.pick-q { font-family: var(--font-display); font-size: 1rem; letter-spacing: .06em;
  color: var(--muted-lt); margin: 1.2rem 0 .8rem; text-transform: uppercase; }
.pick-tiles { display: grid; grid-template-columns: repeat(5, 1fr); gap: 14px; }
@media (max-width: 1024px) { .pick-tiles { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 620px)  { .pick-tiles { grid-template-columns: 1fr 1fr; } }
.tile { display: flex; flex-direction: column; align-items: center; gap: .5rem;
  background: var(--card); border: 1px solid var(--border); border-radius: var(--r-lg);
  padding: 1.2rem .8rem 1rem; cursor: pointer; text-align: center;
  transition: border-color .22s, transform .22s, background .22s; font-family: inherit; color: var(--text); }
.tile:hover { border-color: var(--border-g); transform: translateY(-3px); background: var(--card-h); }
.tile.on { border-color: var(--gold-ink); background: var(--card-h); box-shadow: 0 0 24px rgba(201,164,53,.14); }
.tile .t-ico { font-size: 1.6rem; line-height: 1; }
.tile .t-name { font-family: var(--font-display); font-weight: 700; font-size: .95rem; line-height: 1.25; }
.tile .t-n { font-size: .72rem; color: var(--muted); }

.shop-filters { position: sticky; top: 64px; z-index: 40; background: var(--bg);
  border-bottom: 1px solid var(--border); padding: .7rem 0; margin-top: 1.2rem; }
.chip-row { display: flex; flex-wrap: wrap; gap: .5rem; align-items: center; }
.chip-row[hidden] { display: none; } /* [hidden] (UA) loses to .chip-row display:flex — restore it */
.chip-row .row-lbl { font-size: .78rem; color: var(--muted); letter-spacing: .08em;
  text-transform: uppercase; margin-right: .2rem; }
.chip { border: 1px solid var(--border); background: transparent; color: var(--muted-lt);
  border-radius: 40px; padding: .42rem 1rem; font-size: .88rem; cursor: pointer;
  transition: all .2s ease; font-family: inherit; }
.chip:hover { border-color: var(--border-g); color: var(--text); }
.chip.on { background: var(--gold); border-color: var(--gold-ink); color: #0B0D12; font-weight: 700; }
.shop-count { font-size: .82rem; color: var(--muted); margin-left: auto; }

.shop-grid { display: grid; grid-template-columns: repeat(3, 1fr); gap: 22px; padding: 1.6rem 0 3rem; }
@media (max-width: 1024px) { .shop-grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px)  { .shop-grid { grid-template-columns: 1fr 1fr; gap: 12px; } }

.p-card { display: flex; flex-direction: column; background: var(--card);
  border: 1px solid var(--border); border-radius: var(--r-lg); overflow: hidden;
  transition: border-color .25s, transform .25s, background .25s; }
.p-card:hover { border-color: var(--border-g); transform: translateY(-3px); background: var(--card-h); }
.p-card.hide { display: none; }
.p-media { aspect-ratio: 16/10; overflow: hidden; position: relative; background: var(--bg2); }
.p-media img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s ease; }
.p-card:hover .p-media img { transform: scale(1.05); }
.p-tile { width: 100%; height: 100%; display: flex; flex-direction: column; align-items: center;
  justify-content: center; gap: .3rem;
  background: radial-gradient(120% 120% at 30% 20%, #1d212b 0%, #12151c 60%, #0e1117 100%); }
/* Артикул (07.01 и т.п.) с плитки-заглушки снят вместе с остальными
   кодами — подпись осталась одна, поэтому выросла до заголовка.
   clamp + перенос: на двухколоночной мобильной сетке плитка ~165px,
   и «ПРОМЫШЛЕННЫЕ КОТЛЫ» одной строкой вылезало за её края. */
.p-tile .tile-sub { font-family: var(--font-display);
  font-size: clamp(.72rem, 3.2vw, 1.05rem); font-weight: 700;
  letter-spacing: .12em; color: var(--muted-lt); text-transform: uppercase;
  text-align: center; line-height: 1.35; padding: 0 .9rem;
  max-width: 100%; overflow-wrap: anywhere; }
[data-theme="light"] .p-tile { background: radial-gradient(120% 120% at 30% 20%, #edeae2 0%, #e2ded4 60%, #d8d3c8 100%); }
.p-brand { position: absolute; top: 10px; left: 10px; font-size: .66rem; letter-spacing: .12em;
  text-transform: uppercase; background: rgba(11,13,18,.72); color: var(--gold-lt);
  /* подложка тёмная в ОБЕИХ темах — здесь нужно светлое золото, не чернильное */
  border: 1px solid rgba(201,164,53,.35); border-radius: 20px; padding: .18rem .6rem; }
.p-body { display: flex; flex-direction: column; flex: 1; padding: 14px 16px 16px; }
.p-name { font-family: var(--font-display); font-size: 1.05rem; font-weight: 700; line-height: 1.25; }
.p-name-link { color: inherit; text-decoration: none; }
.p-name-link:hover { color: var(--gold-ink); }
.p-sub { font-size: .82rem; color: var(--muted-lt); margin-top: .2rem; }
.p-meta { display: flex; flex-wrap: wrap; gap: .4rem; margin-top: .6rem; }
.p-meta span { font-size: .72rem; border: 1px solid var(--border); border-radius: 20px;
  padding: .14rem .55rem; color: var(--muted-lt); white-space: nowrap; }
.p-meta span.pow { color: var(--gold-ink); border-color: rgba(201,164,53,.4); }
/* flex-wrap — страховка: с левой рейкой карточка в трёхколоннике ужалась
   до ~280px, и пара кнопок вплотную подходит к её ширине. Если не влезут,
   «Подробнее» уходит на вторую строку, а не обрезается краем карточки. */
.p-cta { display: flex; gap: .5rem; align-items: center; flex-wrap: wrap; margin-top: auto; padding-top: .9rem; }
/* CTA-иерархия (2026-07-29): «Запросить цену» на каждой карточке заливкой
   превращала сетку в стену золотых пилюль. Кнопка остаётся, но контурной —
   сплошное золото теперь только у страничных CTA (.call-strip, .cta-band,
   .btn-primary). Паддинг минус 1px компенсирует рамку. */
.p-call { flex: 1; text-align: center; background: transparent; color: var(--gold-ink);
  border: 1px solid var(--border-g); font-weight: 600;
  font-size: .8rem; letter-spacing: .02em; border-radius: 30px; padding: calc(.5rem - 1px) .5rem;
  text-decoration: none; white-space: nowrap; transition: background .2s, border-color .2s, color .2s; }
.p-call:hover { background: var(--gold-dim); border-color: var(--gold-ink); color: var(--gold-ink); }
[data-theme="light"] .p-call, [data-theme="light"] .p-call:hover { color: var(--gold-ink); }
.p-more { font-size: .8rem; color: var(--muted-lt); text-decoration: none; white-space: nowrap; }
.p-more:hover { color: var(--gold-ink); }
@media (max-width: 560px) {
  .p-body { padding: 10px 11px 12px; }
  .p-name { font-size: .9rem; }
  .p-sub, .p-more { display: none; }
  /* «Запросить цену» на двухколоночной сетке ломалось на две строки —
     трекинг и кегль ужимаем ровно настолько, чтобы легло в одну */
  .p-call { font-size: .74rem; letter-spacing: .02em; padding: calc(.45rem - 1px) .4rem; }
}

/* мобильная полоса звонка — только на телефонах */
.call-strip { display: none; }
@media (max-width: 768px) {
  .call-strip { position: fixed; left: 0; right: 0; bottom: 0; z-index: 60;
    background: rgba(16,19,28,.97); border-top: 1px solid var(--border);
    padding: .6rem 1rem; display: flex; gap: 1rem; align-items: center; justify-content: center; }
  [data-theme="light"] .call-strip { background: rgba(245,243,238,.97); }
  .call-strip .cs-txt { color: var(--muted-lt); font-size: .82rem; }
  .call-strip a { display: inline-flex; align-items: center; gap: .45rem;
    min-height: var(--tap);
    background: var(--gold); color: #0B0D12; font-weight: 700; font-size: .85rem;
    border-radius: 30px; padding: .5rem 1.3rem; text-decoration: none; white-space: nowrap; }
  .call-strip .cs-ico { width: 17px; height: 17px; flex: 0 0 auto; }
/* Полоса «Позвонить» приколота к низу и на телефоне занимает 96px, а
   отведено под неё было 58 — последние 38px каждой страницы каталога
   оставались под ней навсегда. Меряем по факту, с запасом на строку
   подписи слева. */
  body:has(.call-strip) { padding-bottom: 104px; }
}
/* На самых узких телефонах подпись слева от кнопки переносилась на
   4 строки и полоса съедала 145px экрана. Ниже 400px подпись прячем
   и оставляем одну кнопку по центру, она и так называет действие. */
@media (max-width: 400px) {
  .call-strip .cs-txt { display: none; }
  body:has(.call-strip) { padding-bottom: 76px; }
}

/* ── Сетка продуктов ───────────────────────────────────────── */
/* padding-top меньше, чем у .related-section/.pdp-body: рейка
   фильтров (.shop-filters) и колонка карточек (.shop-col) несут
   собственные margin-top/padding-top (~30px на 1440), и оба зазора
   складываются с этим. Меньшее число здесь даёт тот же итоговый
   видимый отступ, что и полные 100px у соседних секций. */
.prod-section {
  padding-top: 70px;
  padding-bottom: 100px;
}
.prod-section__header {
  display: flex;
  align-items: baseline;
  gap: 14px;
  margin-bottom: 36px;
}
.prod-section__title {
  font-family: var(--font-display);
  font-size: var(--h2);
  font-weight: 700;
  letter-spacing: -0.015em;
}
.prod-grid {
  display: grid;
  grid-template-columns: repeat(3, 1fr);
  gap: 20px;
}

/* Карточка продукта */
.prod-card {
  display: flex;
  flex-direction: column;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  overflow: hidden;
  transition: border-color var(--trans), background var(--trans), transform var(--trans), box-shadow var(--trans);
}
.prod-card:hover {
  background: var(--card-h);
  border-color: var(--border-g);
  transform: translateY(-4px);
  box-shadow: 0 12px 40px rgba(0, 0, 0, 0.35);
}
.prod-card.is-hidden { display: none; }

.prod-card__img {
  width: 100%;
  height: 180px;
  background: var(--bg2);
  display: flex;
  align-items: center;
  justify-content: center;
  border-bottom: 1px solid var(--border);
  overflow: hidden;
}
/* карточки, где вместо схематичной иконки стоит настоящий снимок */
/* `<picture>` — инлайновая обёртка без собственной высоты, поэтому
   `height: 100%` на вложенном `<img>` разрешался в auto: в карточках
   «другие серии» фото занимало 63px из 176 и читалось как пустая
   плашка. Размер задаём обёртке — тот же корень, что у CLS на главной. */
.prod-card__img picture { display: block; width: 100%; height: 100%; }
.prod-card__img img { width: 100%; height: 100%; object-fit: cover; transition: transform .5s ease; }
.prod-card:hover .prod-card__img img { transform: scale(1.05); }

/* Кликабельна вся карточка — тот же stretched-link, что у .srow/.scard.
   Условие :not([href="#"]) намеренное: пока ссылка-заглушка, растягивать
   её нельзя, иначе клик по карточке прыгал бы в начало страницы. */
.prod-card { position: relative; }
.prod-card:has(.prod-card__link:not([href="#"]):not([href=""])) { cursor: pointer; }
.prod-card__link:not([href="#"]):not([href=""])::after {
  content: ''; position: absolute; inset: 0; z-index: 1;
}
.compare-check { position: relative; z-index: 2; }
.prod-card:has(.prod-card__link:focus-visible) { outline: 2px solid var(--gold); outline-offset: 4px; }
.prod-card__img img { width: 100%; height: 100%; object-fit: cover; }
.prod-card__img-placeholder {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
}
.prod-card__img-placeholder svg {
  width: 48px; height: 48px;
  opacity: 0.18;
}
.prod-card__body {
  padding: 20px 22px 16px;
  flex: 1;
  display: flex;
  flex-direction: column;
}
.prod-card__badges {
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
  margin-bottom: 14px;
}
.prod-card__badge {
  display: inline-flex;
  align-items: center;
  height: 22px;
  padding-inline: 10px;
  border-radius: 100px;
  font-size: 0.72rem;
  font-weight: 600;
  letter-spacing: 0.04em;
}
.prod-card__badge--power {
  background: var(--gold-dim);
  border: 1px solid var(--border-g);
  color: var(--gold-ink);
}
.prod-card__badge--fuel {
  background: rgba(96, 128, 168, 0.12);
  border: 1px solid rgba(96, 128, 168, 0.25);
  color: var(--steel-ink);
}
.prod-card__badge--loading {
  background: rgba(217, 123, 60, 0.1);
  border: 1px solid rgba(217, 123, 60, 0.22);
  color: var(--ember-ink);
}

.prod-card__name {
  font-family: var(--font-display);
  font-size: 1.15rem;
  font-weight: 700;
  letter-spacing: 0.03em;
  margin-bottom: 6px;
  line-height: 1.2;
}
.prod-card__subtitle {
  font-size: 0.82rem;
  color: var(--muted-lt);
  margin-bottom: 14px;
  line-height: 1.4;
}
.prod-card__desc {
  font-size: 0.83rem;
  color: var(--muted);
  line-height: 1.6;
  flex: 1;
  display: -webkit-box;
  -webkit-line-clamp: 3;
  -webkit-box-orient: vertical;
  overflow: hidden;
  margin-bottom: 20px;
}

.prod-card__footer {
  display: flex;
  align-items: center;
  justify-content: space-between;
  /* wrap + gap: на двухколоночной мобильной сетке карточка ~161px, и
     пара «Подробнее» + «Сравнить» вылезала за её правый край */
  flex-wrap: wrap;
  gap: 8px 12px;
  border-top: 1px solid var(--border);
  padding-top: 14px;
  margin-top: auto;
}
.prod-card__link {
  font-family: var(--font-display);
  font-size: 0.85rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--gold-ink);
  display: inline-flex;
  align-items: center;
  gap: 6px;
  transition: gap var(--trans);
}
.prod-card:hover .prod-card__link { gap: 10px; }
.prod-card__link::after { content: '→'; }

/* Сравнение — чекбокс */
.compare-check {
  display: flex;
  align-items: center;
  gap: 6px;
  font-size: 0.75rem;
  color: var(--muted);
  cursor: pointer;
  user-select: none;
}
.compare-check input[type="checkbox"] {
  appearance: none;
  -webkit-appearance: none;
  width: 16px; height: 16px;
  border: 1px solid var(--border);
  border-radius: 3px;
  background: transparent;
  cursor: pointer;
  position: relative;
  transition: border-color var(--trans), background var(--trans);
  flex-shrink: 0;
}
.compare-check input[type="checkbox"]:checked {
  background: var(--gold);
  border-color: var(--gold-ink);
}
.compare-check input[type="checkbox"]:checked::after {
  content: '';
  position: absolute;
  left: 4px; top: 1px;
  width: 5px; height: 9px;
  border: 2px solid var(--bg);
  border-top: none; border-left: none;
  transform: rotate(45deg);
}

/* ── Панель сравнения ──────────────────────────────────────── */
.compare-bar {
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 800;
  background: var(--card);
  border-top: 2px solid var(--gold);
  padding: 16px 20px;
  transform: translateY(100%);
  transition: transform 0.3s ease;
}
.compare-bar.is-visible { transform: translateY(0); }
.compare-bar__inner {
  display: flex;
  align-items: center;
  gap: 20px;
  max-width: 1240px;
  margin-inline: auto;
  flex-wrap: wrap;
}
.compare-bar__label {
  font-size: 0.82rem;
  color: var(--muted-lt);
  white-space: nowrap;
}
.compare-bar__items {
  display: flex;
  gap: 12px;
  flex: 1;
  flex-wrap: wrap;
}
.compare-bar__item {
  font-size: 0.85rem;
  color: var(--text);
  background: var(--bg2);
  border: 1px solid var(--border-g);
  border-radius: var(--r);
  padding: 4px 12px;
}
.compare-bar__btn {
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  color: var(--on-gold);
  background: var(--gold);
  border-radius: var(--r);
  padding: 8px 22px;
  transition: background var(--trans);
}
.compare-bar__btn:hover { background: var(--gold-lt); }
.compare-bar__reset {
  font-size: 0.8rem;
  color: var(--muted);
  text-decoration: underline;
  cursor: pointer;
}

/* ── Сетка продуктов — адаптив ─────────────────────────────── */
@media (max-width: 1200px) {
  .prod-grid { grid-template-columns: repeat(2, 1fr); }
}
@media (max-width: 768px) {
  /* Две колонки, как в витрине: одна и та же карточка не должна быть
     728px шириной на хабе и 353px на /catalog/ при том же вьюпорте. */
  .prod-grid { grid-template-columns: repeat(2, 1fr); }
  .prod-section { padding-top: 40px; padding-bottom: 60px; }
}

/* ── PDP — Hero ────────────────────────────────────────────── */
.pdp-head {
  /* Тот же разбор по брейкпоинту, что у .cat-head/.shop-head. Нижний
     паддинг раньше был 0, весь низ держал .pdp-hero, а его высоту
     трогать нельзя (от неё зависит блок с чертежом), поэтому зазор
     добираем здесь, у самой секции, а не у .pdp-hero. */
  padding-top: calc(var(--nav-h) + 40px);
  padding-bottom: 56px;
  background: linear-gradient(180deg, var(--bg2) 0%, var(--bg) 100%);
}
@media (max-width: 768px) {
  .pdp-head { padding-top: calc(var(--nav-h) + 4px); padding-bottom: 28px; }
}
.pdp-hero {
  display: grid;
  /* minmax(0,1fr), не голый 1fr: колонка чертежа несёт aspect-ratio +
     SVG с внутренним min-content, и без minmax(0,…) трек не мог
     сжаться меньше этого содержимого — переезд «вылезал» из своей
     колонки и тянул за собой горизонтальный скролл всей страницы. */
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  /* Название теперь отдельным грид-элементом (см. .pdp-hero__title), а
     не первым потомком .pdp-hero__info, так его можно поднять НАД
     чертежом на телефоне, не трогая порядок в разметке для десктопа.
     Строки внутри одной колонки (title/info) идут вплотную:
     row-gap:0, а зазор title→info даёт их собственный внутренний
     margin, как раньше внутри одного блока. column-gap несёт зазор
     между чертежом и текстовой колонкой, тот же, что был у gap. */
  grid-template-areas: "visual title" "visual info";
  grid-template-rows: auto 1fr;
  column-gap: 48px;
  row-gap: 0;
  align-items: start;
  padding-bottom: 48px;
}
.pdp-hero__visual {
  grid-area: visual;
  background: radial-gradient(ellipse at center, var(--bg2) 0%, var(--bg) 70%);
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  aspect-ratio: 4/3;
  display: flex;
  align-items: center;
  justify-content: center;
  overflow: hidden;
}
.pdp-hero__svg-placeholder {
  width: 100%;
  height: 100%;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column;
  gap: 12px;
}
.pdp-hero__title { grid-area: title; padding-top: 8px; }
.pdp-hero__info { grid-area: info; }
/* Грид-элемент, свой контекст форматирования: на карточках товара
   (.pdp-lean) нижний margin подписи (16px) больше не схлопывается с
   верхним margin полосы характеристик (тоже 16px) через границу
   .pdp-hero__title/.pdp-hero__info, как схлопывался раньше внутри
   одного блока,, зазор задваивался (32px вместо 16px). Обнуляем
   здесь тем же селектором, что и остальные .pdp-lean-переопределения:
   зазор несёт margin-top полосы характеристик. */
.pdp-lean .pdp-hero__title .pdp-hero__subtitle { margin-bottom: 0; }
.pdp-hero__code {
  font-family: var(--font-display);
  font-size: 0.8rem;
  font-weight: 400;
  letter-spacing: 0.14em;
  color: var(--gold-ink);
  margin-bottom: 10px;
  display: block;
}
.pdp-hero__name {
  font-family: var(--font-display);
  font-size: var(--h1);
  font-weight: 800;
  letter-spacing: -0.015em;
  line-height: 1.1;
  margin-bottom: 8px;
}
.pdp-hero__subtitle {
  font-size: 0.95rem;
  font-weight: 400;
  letter-spacing: normal;
  color: var(--muted-lt);
  margin-bottom: 28px;
  line-height: 1.7;
}

/* Полоса характеристик */
.spec-strip {
  display: flex;
  flex-wrap: wrap;
  gap: 0;
  border: 1px solid var(--border);
  border-radius: var(--r);
  overflow: hidden;
  margin-bottom: 28px;
}
.spec-strip__item {
  flex: 1;
  min-width: 120px;
  padding: 14px 18px;
  border-right: 1px solid var(--border);
  background: var(--card);
}
.spec-strip__item:last-child { border-right: none; }
.spec-strip__label {
  font-size: 0.72rem;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 4px;
}
.spec-strip__value {
  font-family: var(--font-display);
  font-size: 1rem;
  font-weight: 700;
  color: var(--gold-ink);
}

/* CTA кнопки */
.pdp-cta {
  display: flex;
  gap: 12px;
  flex-wrap: wrap;
}
.btn-primary {
  display: inline-flex;
  align-items: center;
  height: 48px;
  padding-inline: 28px;
  border-radius: var(--r);
  background: var(--gold);
  color: var(--on-gold);
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 800;
  letter-spacing: 0.06em;
  transition: background var(--trans), transform var(--trans);
}
.btn-primary:hover { background: var(--gold-lt); transform: translateY(-1px); }
.btn-secondary {
  display: inline-flex;
  align-items: center;
  height: 48px;
  padding-inline: 24px;
  border-radius: var(--r);
  border: 1px solid var(--border-g);
  color: var(--gold-ink);
  font-family: var(--font-display);
  font-size: 0.9rem;
  font-weight: 700;
  letter-spacing: 0.06em;
  background: transparent;
  transition: background var(--trans), border-color var(--trans);
}
.btn-secondary:hover {
  background: var(--gold-dim);
  border-color: var(--gold-ink);
}

/* ── PDP — Вкладки ─────────────────────────────────────────── */
.tab-nav {
  display: flex;
  gap: 0;
  border-bottom: 2px solid var(--border);
  margin-bottom: 36px;
  /* четыре вкладки на 375px давали 401px и растягивали ВСЮ страницу
     (шапка уезжала следом). Скроллим сам ряд вкладок, не документ. */
  overflow-x: auto;
  overscroll-behavior-x: contain;
  scrollbar-width: none;
}
.tab-nav::-webkit-scrollbar { display: none; }
.tab-nav a { flex: 0 0 auto; }
.tab-nav a {
  display: inline-block;
  padding: 14px 24px;
  font-size: 0.9rem;
  font-weight: 500;
  color: var(--muted-lt);
  border-bottom: 2px solid transparent;
  margin-bottom: -2px;
  transition: color var(--trans), border-color var(--trans);
}
.tab-nav a:hover { color: var(--text); }
.tab-nav a.is-active {
  color: var(--gold-ink);
  border-bottom-color: var(--gold-ink);
}

.tab-panel { display: none; }
.tab-panel.is-active { display: block; }
/* Ссылки вкладок вели на #desc / #specs / #apply, которых на странице не
   существовало — работал только JS-перехват клика. Панелям выданы эти id;
   открытие нужной по хэшу разбирает initTabs (правило :target здесь
   показало бы ДВЕ панели сразу — активную по разметке и целевую). */

.pdp-body { padding-block: 56px; }
.pdp-desc {
  font-size: 1.1rem;
  line-height: 1.8;
  color: var(--muted-lt);
  max-width: 720px;
  margin-bottom: 32px;
}
.feature-list {
  display: flex;
  flex-direction: column;
  gap: 12px;
  max-width: 640px;
}
.feature-list li {
  display: flex;
  gap: 12px;
  align-items: flex-start;
  font-size: 1.05rem;
  line-height: 1.5;
  color: var(--text);
}
.feature-list li::before {
  content: '';
  display: block;
  width: 18px; height: 18px;
  border-radius: 50%;
  background: var(--gold-dim);
  border: 1.5px solid var(--gold);
  flex-shrink: 0;
  margin-top: 2px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='10' height='8' viewBox='0 0 10 8'%3E%3Cpath d='M1 4l3 3 5-6' stroke='%23C9A435' stroke-width='1.5' fill='none' stroke-linecap='round' stroke-linejoin='round'/%3E%3C/svg%3E");
  background-repeat: no-repeat;
  background-position: center;
}

/* Таблица характеристик */
.spec-table {
  width: 100%;
  max-width: 640px;
  border-collapse: collapse;
  font-size: 1.07rem;
}
.spec-table tr {
  border-bottom: 1px solid var(--border);
}
.spec-table tr:last-child { border-bottom: none; }
.spec-table td {
  padding: 13px 16px;
  line-height: 1.4;
}
.spec-table td:first-child {
  color: var(--muted);
  width: 40%;
  font-weight: 500;
}
.spec-table td:last-child {
  color: var(--text);
  font-weight: 500;
}
.spec-table tr:hover td { background: var(--card); }

/* Применение */
.application-list {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 12px;
  max-width: 640px;
  margin-bottom: 28px;
}
.application-list li {
  display: flex;
  align-items: center;
  gap: 10px;
  background: var(--card);
  border: 1px solid var(--border);
  border-radius: var(--r);
  padding: 12px 16px;
  font-size: 1.0rem;
  color: var(--muted-lt);
}
.application-list li::before {
  content: '◆';
  color: var(--gold-ink);
  font-size: 0.6em;
  flex-shrink: 0;
}
.application-note {
  font-size: 0.88rem;
  color: var(--muted);
  line-height: 1.7;
  max-width: 600px;
}

/* ── Похожие продукты ──────────────────────────────────────── */
.related-section {
  padding-block: 100px;
  border-top: 1px solid var(--border);
  background: var(--bg2);
}
@media (max-width: 768px) { .related-section { padding-block: 60px; } }
.related-section h2 {
  font-family: var(--font-display);
  font-size: 1.4rem;
  font-weight: 700;
  letter-spacing: -0.015em;
  margin-bottom: 22px;
}
.related-row {
  display: grid;
  grid-template-columns: repeat(2, 1fr);
  gap: 20px;
}

/* ── Мобильная sticky CTA (PDP) ────────────────────────────── */
.pdp-mobile-cta {
  display: none;
  position: fixed;
  bottom: 0; left: 0; right: 0;
  z-index: 700;
  background: var(--card);
  border-top: 1px solid var(--border-g);
  padding: 12px 20px;
  gap: 10px;
}

@media (max-width: 768px) {
  .pdp-mobile-cta { display: flex; }
  .pdp-mobile-cta .btn-primary,
  .pdp-mobile-cta .btn-secondary {
    /* min-width:0 обязателен: без него flex-элемент не сжимается уже
       своего содержимого, и пара кнопок выносила полосу за 375px */
    flex: 1 1 0; min-width: 0;
    justify-content: center;
    padding-inline: 10px;
    font-size: 0.78rem;
    white-space: nowrap;
    overflow: hidden; text-overflow: ellipsis;
  }
  /* Заголовок первым: узнаваемость товара важнее чертежа на первом
     экране телефона, до этой правки h1 стартовал ниже 647px viewport. */
  .pdp-hero { grid-template-columns: minmax(0, 1fr); grid-template-areas: "title" "visual" "info"; grid-template-rows: auto auto auto; gap: 28px; }
  .pdp-hero__visual { aspect-ratio: 16/9; }
  .related-row { grid-template-columns: 1fr; }
  .application-list { grid-template-columns: 1fr; }
  .spec-strip { flex-direction: column; }
  .spec-strip__item { border-right: none; border-bottom: 1px solid var(--border); }
  .spec-strip__item:last-child { border-bottom: none; }
  .tab-nav a { padding: 12px 16px; font-size: 0.82rem; }
}

/* ── Доверие / Статистика ──────────────────────────────────── */

/* ── CTA-полоса ────────────────────────────────────────────── */
.cta-band {
  padding-block: 64px;
  text-align: center;
  background: linear-gradient(135deg, var(--bg2) 0%, var(--bg) 100%);
}
.cta-band h2 {
  font-family: var(--font-display);
  font-size: var(--h2);
  font-weight: 700;
  margin-bottom: 12px;
}
.cta-band p {
  font-size: 0.92rem;
  color: var(--muted-lt);
  margin-bottom: 22px;
  max-width: 480px;
  margin-inline: auto;
  line-height: 1.6;
}
.cta-band__actions {
  display: flex;
  justify-content: center;
  gap: 14px;
  flex-wrap: wrap;
}
/* Второй путь связи — строкой ниже и обычной ссылкой, не кнопкой.
   Две одинаковые по весу кнопки делили внимание пополам, и человек
   выбирал между ними вместо того, чтобы просто связаться. Кнопка одна,
   альтернатива рядом и не спорит. Скрыта до отработки JS: без него в
   ней нет смысла, а пустая строка занимала бы место. */
.cta-band__alt {
  margin: 12px 0 0;
  font-size: .84rem;
  color: var(--muted);
}
.cta-band__alt a {
  color: var(--gold-ink);
  border-bottom: 1px solid transparent;
  transition: border-color var(--dur-fast, .18s) var(--ease-out, ease);
}
.cta-band__alt a:hover { border-bottom-color: var(--gold-ink); }
.cta-band__alt[hidden] { display: none; }

/* ── Финал страницы: CTA-полоса + логотип «наверх» ───────────
   Большой подвал (три колонки ссылок, адрес, копирайт) снят
   2026-07-29 — на каталожных страницах это был экран текста,
   который никто не дочитывает. Осталась CTA-полоса; логотип
   слева возвращает к началу. #top — якорь документа по
   умолчанию (спец-случай в HTML), поэтому JS не нужен. */
/* Было 64/76px — 140px пустоты над «Нужна консультация?» на каждой
   странице. Полоса и так последняя, воздух ей нужен, но не столько. */
.cta-band { position: relative; padding-block: 40px 46px; border-top: 1px solid var(--border); }
.cta-band > .container { position: relative; }
/* Логотип + явная кнопка «наверх». Сетка 2×2: сверху шестерёнка и
   ИЗКО, снизу стрелка ровно под шестерёнкой и подпись под словом.
   Подпись видна всегда, а не по наведению: на телефоне наведения нет,
   а понять назначение нужно с первого взгляда. */
.cta-band__home {
  position: absolute; left: 0; top: 50%; transform: translateY(-50%);
  display: grid;
  grid-template-columns: auto auto;
  grid-template-areas: "ico mark" "up lbl";
  align-items: center; justify-content: start;
  gap: .4rem .55rem;
  text-decoration: none; opacity: .85;
  transition: opacity .3s ease;
}
.cta-band__home img       { grid-area: ico; }
.cta-band__home .logo-mark { grid-area: mark; }
.cta-band__up  { grid-area: up; justify-self: center; }
.cta-band__up-lbl { grid-area: lbl; }

.cta-band__up {
  display: inline-flex; align-items: center; justify-content: center;
  width: 30px; height: 30px;
  border: 1px solid var(--border-g); border-radius: 50%;
  color: var(--gold-ink); background: transparent;
  transition: background .25s ease, border-color .25s ease, transform .25s ease;
}
.cta-band__up svg { width: 15px; height: 15px; display: block; }
.cta-band__up-lbl {
  font-size: .68rem; font-weight: 700;
  letter-spacing: .16em; text-transform: uppercase;
  color: var(--muted); white-space: nowrap;
  transition: color .25s ease;
}
/* реакция на всю ссылку целиком — и на наведение, и на клавиатуру */
.cta-band__home:hover .cta-band__up,
.cta-band__home:focus-visible .cta-band__up {
  background: var(--gold-dim); border-color: var(--gold-ink);
  transform: translateY(-3px);
}
.cta-band__home:hover .cta-band__up-lbl,
.cta-band__home:focus-visible .cta-band__up-lbl { color: var(--gold-ink); }
[data-theme="light"] .cta-band__up { color: var(--gold-ink); }
[data-theme="light"] .cta-band__home:hover .cta-band__up-lbl { color: var(--gold-ink); }
.cta-band__home:hover { opacity: 1; }
.cta-band__home img { display: block; width: 44px; height: auto; transition: transform .35s ease; }
.cta-band__home:hover img { transform: rotate(18deg); }
.cta-band__home .logo-mark { font-size: 1.3rem; border-bottom-width: 3px; padding-bottom: .12rem; }
.cta-band__home:focus-visible { outline: 2px solid var(--gold); outline-offset: 6px; border-radius: 6px; }

/* Сплит-вариант (одностраничник ИЗКО) выровнен по левому краю —
   абсолютный логотип лёг бы прямо на заголовок. Ставим над ним. */
.cta-band--split .cta-band__home {
  position: static; transform: none; margin-bottom: 26px;
}

/* ≤1024: заголовок дорастает до логотипа — уводим логотип в поток
   над текстом (по центру, как и вся полоса). */
@media (max-width: 1024px) {
  .cta-band__home {
    position: static; transform: none;
    justify-content: center;      /* сетка та же, просто по центру полосы */
    margin-bottom: 26px;
  }
  .cta-band--split .cta-band__home { justify-content: start; }
}
@media (prefers-reduced-motion: reduce) {
  .cta-band__home, .cta-band__home img,
  .cta-band__up, .cta-band__up-lbl { transition: none; }
  .cta-band__home:hover img { transform: none; }
  .cta-band__home:hover .cta-band__up,
  .cta-band__home:focus-visible .cta-band__up { transform: none; }
}

/* Правовая полоса — один в один с подвалом главной (её Daniel
   утвердил как есть), чтобы низ страницы совпадал на всём сайте.
   Логотипа здесь нет: он стоит выше, в CTA-полосе, и ведёт наверх. */

/* ── Подвал (используется только демо-страницами /catalog/demo-*) ── */
.site-footer {
  background: var(--bg2);
  border-top: 1px solid var(--border);
  padding-block: 48px 28px;
}
.site-footer__grid {
  display: grid;
  grid-template-columns: 2fr 1fr 1fr;
  gap: 48px;
  margin-bottom: 40px;
}
.site-footer__brand .logo-mark {
  font-size: 1.1rem;
  border-bottom-width: 2.5px;
  margin-right: -0.12em;
  display: inline-block;
  margin-bottom: 12px;
}
.site-footer__tagline {
  font-size: 0.82rem;
  color: var(--muted);
  line-height: 1.6;
  max-width: 240px;
}
.site-footer__heading {
  font-family: var(--font-display);
  font-size: 0.78rem;
  letter-spacing: 0.1em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 16px;
}
.site-footer__links {
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.site-footer__links a {
  font-size: 0.875rem;
  color: var(--muted-lt);
  transition: color var(--trans);
}
.site-footer__links a:hover { color: var(--gold-ink); }
.site-footer__contact p {
  font-size: 0.875rem;
  color: var(--muted-lt);
  line-height: 1.7;
  margin-bottom: 8px;
}
.site-footer__contact a { color: var(--gold-ink); }
.site-footer__bottom {
  border-top: 1px solid var(--border);
  padding-top: 20px;
  display: flex;
  justify-content: space-between;
  align-items: center;
  flex-wrap: wrap;
  gap: 8px;
}
.site-footer__copy {
  font-size: 0.78rem;
  color: var(--muted);
}

@media (max-width: 768px) {
  .site-footer__grid { grid-template-columns: 1fr; gap: 32px; }
  .site-footer__bottom { flex-direction: column; align-items: flex-start; }
}

/* ── Блок цены (PDP only) ──────────────────────────────────── */
.pdp-price {
  margin-bottom: 24px;
}
.pdp-price__eyebrow {
  font-family: var(--font-body);
  font-size: 0.74rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
}
.pdp-price__amount {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-style: italic;
  font-size: 2.4rem;
  font-weight: 400;
  line-height: 1.15;
  color: var(--text);
}
.pdp-price__amount--query {
  font-size: 1.8rem;
  color: var(--muted-lt);
}

/* ── Светлая тема ──────────────────────────────────────────── */
[data-theme="light"] {
  --atm-warm:  rgba(201, 164, 53, 0.20);
  --atm-cool:  rgba(96, 128, 168, 0.16);
  --atm-line:  rgba(32, 52, 84, 0.06);
  --atm-band:  rgba(28, 44, 74, 0.035);
  --gold-ink:  #7A6318;   /* 5,3:1 на bg, 5,8:1 на card */
  --steel-ink: #4A6485;   /* 5,3:1 */
  --ember-ink: #A85520;   /* 4,8:1 */   /* 5,3:1 на bg, 5,8:1 на card */
  --bg:        #F4F5F8;
  --bg2:       #ECEEF4;
  --card:      #FFFFFF;
  --card-h:    #F0F2F8;
  --text:      #1A1D2A;
  --muted:     #5C6270;   /* было #6A7080 — 4,27:1 на bg2, ниже AA */
  --muted-lt:  #4A5068;
  --border:    rgba(0, 0, 0, 0.09);
  --border-g:  rgba(201, 164, 53, 0.35);
  --gold-dim:  rgba(201, 164, 53, 0.14);
  --gold-glow: rgba(201, 164, 53, 0.22);
}
[data-theme="light"] .site-nav {
  background: rgba(237, 238, 246, 0.92);
  border-bottom-color: rgba(0,0,0,0.09);
}
[data-theme="light"] .pdp-head,
[data-theme="light"] .cat-head {
  background: linear-gradient(180deg, var(--bg2) 0%, var(--bg) 100%);
}
[data-theme="light"] .pdp-hero__visual {
  background: radial-gradient(ellipse at center, var(--bg2) 0%, var(--bg) 70%);
}
[data-theme="light"] .related-section,
[data-theme="light"] .site-footer {
  background: var(--bg2);
}
[data-theme="light"] .spec-strip__item {
  background: var(--card);
}
[data-theme="light"] .application-list li {
  background: var(--card);
}

/* ═══ ANIMATIONS ══════════════════════════════════════════════════════════ */

/* ── Ember drift (CSS-only, approved Demo 2) ── */
@keyframes ember-rise {
  0%   { transform: translateY(0) translateX(0) scale(1);   opacity: 0; }
  15%  { opacity: 0.7; }
  85%  { opacity: 0.4; }
  100% { transform: translateY(-140px) translateX(var(--ember-x, 12px)) scale(0.6); opacity: 0; }
}

.ember-field {
  position: absolute;
  inset: 0;
  pointer-events: none;
  overflow: hidden;
  z-index: 0;
}

.ember {
  position: absolute;
  bottom: 0;
  width: 4px; height: 4px;
  border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 6px 2px rgba(201, 164, 53, 0.5);
  animation: ember-rise 3.6s ease-in infinite;
  opacity: 0;
}

/* Stagger 12 embers across cat-head sections */
.cat-head { position: relative; }
.cat-head .ember:nth-child(1)  { left: 8%;  animation-delay: 0s;    --ember-x: 8px; }
.cat-head .ember:nth-child(2)  { left: 18%; animation-delay: 0.5s;  --ember-x: -6px; }
.cat-head .ember:nth-child(3)  { left: 28%; animation-delay: 1.1s;  --ember-x: 12px; }
.cat-head .ember:nth-child(4)  { left: 38%; animation-delay: 0.3s;  --ember-x: -10px; }
.cat-head .ember:nth-child(5)  { left: 48%; animation-delay: 0.8s;  --ember-x: 6px; }
.cat-head .ember:nth-child(6)  { left: 58%; animation-delay: 1.4s;  --ember-x: -8px; }
.cat-head .ember:nth-child(7)  { left: 68%; animation-delay: 0.2s;  --ember-x: 14px; }
.cat-head .ember:nth-child(8)  { left: 78%; animation-delay: 0.9s;  --ember-x: -12px; }
.cat-head .ember:nth-child(9)  { left: 88%; animation-delay: 1.6s;  --ember-x: 4px; }
.cat-head .ember:nth-child(10) { left: 23%; animation-delay: 2.0s;  --ember-x: -4px; }
.cat-head .ember:nth-child(11) { left: 55%; animation-delay: 2.4s;  --ember-x: 10px; }
.cat-head .ember:nth-child(12) { left: 75%; animation-delay: 2.8s;  --ember-x: -6px; }

/* Disable on mobile/reduced-motion */
@media (max-width: 768px) { .ember-field { display: none; } }
@media (prefers-reduced-motion: reduce) { .ember-field { display: none; } }

/* ── Scroll reveals ── */
.reveal {
  opacity: 0;
  transform: translateY(24px);
  transition: opacity 0.6s ease, transform 0.6s ease;
}
/* transform: none, а не translateY(0). Любой transform, даже единичная
   матрица, делает элемент содержащим блоком для абсолютных потомков —
   и растянутая ссылка карточки (.srow__link::after{inset:0}) считалась
   от .srow__body вместо всего ряда, из-за чего клик по фотографии
   никуда не вёл. */
.reveal.in-view {
  opacity: 1;
  transform: none;
}

/* Раскрытие без сдвига — для элементов, которые являются предками
   растянутой ссылки. Правка выше чинила клик, но взамен давала скачок
   раскладки: на границе анимации ::after переезжал с размеров тела ряда
   на размеры всего ряда. 0,166 CLS на ряд, до 0,72 за прокрутку.
   Здесь transform не появляется вообще ни на одном кадре. */
.reveal.reveal--fade,
.reveal.reveal--fade.in-view { transform: none; }
.reveal.reveal--fade { transition: opacity .6s var(--ease-out); }

/* Stagger siblings via nth-child delay */
.cat-hub__grid .cat-hub__card.reveal:nth-child(1) { transition-delay: 0ms; }
.cat-hub__grid .cat-hub__card.reveal:nth-child(2) { transition-delay: 80ms; }
.cat-hub__grid .cat-hub__card.reveal:nth-child(3) { transition-delay: 160ms; }
.cat-hub__grid .cat-hub__card.reveal:nth-child(4) { transition-delay: 240ms; }
.cat-hub__grid .cat-hub__card.reveal:nth-child(5) { transition-delay: 320ms; }
.cat-hub__grid .cat-hub__card.reveal:nth-child(6) { transition-delay: 400ms; }

/* Disable reveals on reduced-motion */
@media (prefers-reduced-motion: reduce) {
  .reveal { opacity: 1; transform: none; transition: none; }
}

/* ═══ Модалки: контакт + лайтбокс товара ══════════════════════ */
.cmodal[hidden] { display: none; }
.cmodal {
  position: fixed; inset: 0;
  display: flex; align-items: center; justify-content: center; padding: 20px;
}.cmodal { z-index: 1300; }              /* контакт всегда поверх лайтбокса */
body.modal-open { overflow: hidden; }
.cmodal__backdrop {
  position: absolute; inset: 0; background: rgba(6,8,12,0.82);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
}
/* Крестик: 44px — минимальная зона касания. Раньше 34px и полупрозрачный
   белый фон поверх фотографии: на телефоне его было и не видно, и не
   попасть. Тёмный диск с золотой рамкой читается на любой картинке. */
.cmodal__x {
  position: absolute; top: 10px; right: 10px; z-index: 5;
  width: 44px; height: 44px; border-radius: 50%;
  background: rgba(11,13,18,0.82);
  border: 1px solid rgba(201,164,53,0.45);
  color: var(--gold-ink);
  font-size: 1.5rem; line-height: 1; display: flex; align-items: center; justify-content: center;
  cursor: pointer;
  backdrop-filter: blur(4px); -webkit-backdrop-filter: blur(4px);
  transition: background .2s, color .2s, border-color .2s;
}
.cmodal__x:hover {
  background: var(--gold); color: #0B0D12; border-color: var(--gold);
}
.cmodal__x:focus-visible {
  outline: 2px solid var(--gold); outline-offset: 2px;
}

/* Контакт */
.cmodal__panel {
  position: relative; z-index: 1; width: 100%; max-width: 420px;
  background: var(--card); border: 1px solid var(--border-g);
  border-radius: var(--r-lg); padding: 28px 26px 24px;
  box-shadow: 0 24px 70px rgba(0,0,0,0.55);
}
.cmodal__panel h3 {
  font-family: var(--font-display); font-size: 1.5rem; font-weight: 800;
  letter-spacing: .03em; margin-bottom: .4rem;
}
.cmodal__lede { font-size: .9rem; color: var(--muted-lt); line-height: 1.7; margin-bottom: 1.2rem; }
/* Заявка — главное действие окна: она одна работает одинаково у всех.
   Телефон и почта под ней остаются для тех, кто предпочитает свой канал. */
.cmodal__cta { display: block; text-align: center; width: 100%; margin-bottom: 1.1rem; }
.cmodal__row { display: flex; align-items: center; gap: .7rem; padding: .8rem 0; border-top: 1px solid var(--border); }
.cmodal__lbl { font-size: .7rem; letter-spacing: .1em; text-transform: uppercase; color: var(--muted); width: 60px; flex-shrink: 0; }
.cmodal__val { font-family: var(--font-display); font-size: 1.15rem; font-weight: 700; color: var(--text); flex: 1; transition: color .2s; }
.cmodal__val:hover { color: var(--gold-ink); }
.cmodal__copy {
  font-size: .74rem; letter-spacing: .03em; color: var(--gold-ink);
  border: 1px solid var(--border-g); border-radius: 30px; padding: .32rem .8rem;
  white-space: nowrap; transition: all .2s;
}
.cmodal__copy:hover { background: var(--gold-dim); border-color: var(--gold-ink); }
.cmodal__copy.done { color: #0B0D12; background: var(--gold); border-color: var(--gold-ink); }
.cmodal__addr { font-size: .8rem; color: var(--muted); line-height: 1.5; margin-top: 1rem; padding-top: .9rem; border-top: 1px solid var(--border); }@media (max-width: 700px) {}

/* Карточка кликабельна целиком + подсказка «смотреть» + заметная кнопка */
/* Карточка целиком ведёт на страницу изделия. Значок лупы в углу обещал
   увеличение фотографии, а открывалось промежуточное окно; окна больше
   нет, обещать нечего.

   Кликабельность даёт растянутый псевдоэлемент ссылки-заголовка, а не
   обработчик: браузер сам умеет Ctrl+клик, среднюю кнопку, Enter с
   клавиатуры и показ адреса в строке состояния. Ссылки внутри подписи
   поднимаем над ним, иначе «Подробнее» и «Запросить цену» перестали бы
   нажиматься. z-index 1 — ниже уголков карточки (у них 3). */
.p-card { position: relative; }
.p-name-link::after { content: ''; position: absolute; inset: 0; z-index: 1; }
.p-cta > a { position: relative; z-index: 2; }

/* Плашка дилерских позиций ИЗКО. Тон приглушённый: это пояснение к
   условиям поставки, а не второй ценник, и рядом с «от 1 200 000 ₽»
   она не должна перетягивать взгляд. */
.p-badge {
  font-size: .68rem; letter-spacing: .06em; text-transform: uppercase;
  color: var(--muted-lt); border: 1px solid var(--border);
  border-radius: 20px; padding: .16rem .55rem; white-space: nowrap;
}
/* Текст короче («под ключ» вместо «Поставка под ключ»), но на
   двухколоночной сетке (~165px) цена и плашка рядом всё ещё теснее,
   чем нужно, и раньше плашка растягивалась на всю ширину строки
   (flex:1 0 100%), из-за неё съезжала в сторону сама цена. Теперь
   плашка на самых узких карточках просто прячется: цена и так несёт
   главный смысл строки, а условие поставки не обязано быть видно
   именно здесь. */
@media (max-width: 560px) {
  .p-badge { display: none; }
}
/* парная кнопка к .p-call — нейтральная, чтобы пара читалась как
   «золотой контур = основное, серый контур = второстепенное» */
.p-more {
  border: 1px solid var(--border); color: var(--muted-lt);
  border-radius: 30px; padding: calc(.5rem - 1px) .72rem; font-size: .76rem; font-weight: 600;
  white-space: nowrap; background: transparent; transition: all .2s;
}
.p-more:hover { background: var(--gold-dim); border-color: var(--border-g); color: var(--gold-ink); }
[data-theme="light"] .p-more:hover { color: var(--gold-ink); }

/* ══ MOBILE FLUID PASS (2026-07-23) ═══════════════════════════
   The sticky filter bar wrapped its 8 category chips onto 8 rows,
   so on a 393×852 phone it occupied ~450px — filters + the fixed
   call-strip left barely 200px of visible grid. Turn each chip row
   into a single-line horizontal scroller.
   ═══════════════════════════════════════════════════════════ */
@media (max-width: 768px) {
  .shop-filters { padding: .55rem 0; margin-top: .8rem; }

  .chip-row {
    flex-wrap: nowrap;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    /* let the chips run to the container edge, then fade out */
    padding-bottom: .15rem;
    mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 24px), transparent 100%);
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 24px), transparent 100%);
  }
  .chip-row::-webkit-scrollbar { display: none; }
  .chip-row + .chip-row { margin-top: .4rem; }

  .chip { flex: 0 0 auto; white-space: nowrap; padding: .5rem .95rem; }
  .chip-row .row-lbl { flex: 0 0 auto; white-space: nowrap; }

  /* Строку «Показано: N» на телефоне раньше прятали ради высоты. Но на
     хабах «Буран» / «Котлы» другого счётчика нет, и после тапа по
     фильтру карточки просто исчезали без единого подтверждения.
     Возвращаем — одна строка дешевле немого интерфейса. */
  .shop-count {
    display: block; width: 100%;
    margin: .5rem 0 0; text-align: left;
    font-size: .78rem; color: var(--muted);
  }

  /* touch targets under the 44px minimum. Было 42×42 — двух пикселей
     не хватало до порога §2.5/§6 (QA). */
  .site-nav .nav-toggle,
  .nav-toggle { width: var(--tap); height: var(--tap); }
  .theme-toggle { min-height: 38px; }
  .breadcrumb a { display: inline-block; padding: .5rem 0; }
}

/* ═══════════════════════════════════════════════════════════════
   ХАБ ИЗКО — «заводской лукбук» (редизайн 2026-07)
   Бенто-сетка фото-плиток для /catalog/izko/. Аддитивно, скоуп:
     .cat-hub--photo · .trust-strip--rail · .cta-band--split
   ДОБАВЛЯТЬ В КОНЕЦ catalog.css — часть переопределений побеждает
   базу порядком каскада при равной специфичности.
   Плитки сохраняют .cat-hub__card: reveal/stagger из catalog.js
   работают без правок JS (stagger-delay из базы выше по
   специфичности и переживает нашу transition-шортку).
   ═══════════════════════════════════════════════════════════════ */

/* ── Секция и шапка индекса ── */

/* ── Сетка (mobile-first) ── */

/* ── Плитка: сброс базовой карточки хаба ── */

/* ── Кадр + светотень ── */
/* тональный унификатор: белые рендеры и живые фото — один ряд.
   Скримы намеренно тёмные в ОБЕИХ темах — текст на фото всегда светлый */

/* кадрирование под конкретные снимки */
.hub-media--vs img { object-position: 50% 45%; }  /* блочно-модульная станция */
.hub-media--vo img { object-position: 50% 55%; }  /* очистные сооружения      */
.hub-media--mk img { object-position: 50% 32%; }  /* каркас: балки + небо     */
.hub-media--bl img { object-position: 50% 60%; }  /* УЗП в нижней трети кадра */
/* ВРУ: у кадра белые поля — базовый зум выталкивает их за обрез */

/* ── Номер 01–06 — эхо золотого подчёрка логотипа ── */

/* ── Чип количества (рисунок как у .p-brand на витрине) ── */

/* ── Текст поверх кадра ── */
/* золотой подчёрк — та же кривая, что у ссылок в шапке сайта */

/* ── Hover: «Состав раздела» — панель с реальными названиями изделий.
   Только hover/клавиатура (прогрессивное улучшение): на тачах описание
   и так перечисляет изделия, информация не заперта за ховером. ── */

/* ── 06 · Доп. оборудование — плашка «по запросу» (фото нет).
   Пунктир + инженерная штриховка кодируют «состав определяется
   проектом». div, не ссылка: внутри три CTA. ── */

/* ── Планшет: 2 колонки, лид во всю ширину ── */

/* ── Десктоп: бенто 4+2 / 2+2+2 / полоса ── */

/* ── CTA-полоса: сплит, телефон набран как логотип ── */
.cta-band--split { text-align: left; }
.cta-band--split .cta-band__inner { display: grid; gap: 30px; }
.cta-band--split h2 {
  font-size: clamp(1.5rem, 2.4vw, 2.1rem);
  margin-bottom: 10px;
}
.cta-band--split .cta-band__txt p {
  margin: 0;
  margin-inline: 0;
  max-width: 46ch;
}
.cta-band__phone {
  display: inline-block;
  font-family: var(--font-display);
  font-weight: 800;
  font-size: clamp(1.7rem, 2vw + 1rem, 2.5rem);
  letter-spacing: .04em;
  line-height: 1.1;
  color: var(--text);
  border-bottom: 3px solid var(--gold);   /* эхо подчёрка логотипа */
  padding-bottom: 4px;
  white-space: nowrap;
  transition: color .25s ease;
}
.cta-band__phone:hover { color: var(--gold-ink); }
.cta-band__phone:focus-visible {
  color: var(--gold-ink);
  outline: 2px solid var(--gold);
  outline-offset: 4px;
}
.cta-band__note {
  display: block;
  font-size: .78rem;
  color: var(--muted);
  margin-top: 10px;
}
.cta-band--split .cta-band__actions {
  justify-content: flex-start;
  margin-top: 22px;
}
@media (min-width: 900px) {
  .cta-band--split .cta-band__inner {
    grid-template-columns: 1.05fr .95fr;
    align-items: center;
    gap: 48px;
  }
  .cta-band__contact { justify-self: end; }
}

/* ── Светлая тема ──
   Фото-плитки намеренно одинаковы в обеих темах (светлый текст на
   тёмном скриме — как .p-brand на витрине). Ниже — только золото
   на светлом фоне: контраст добирает --gold-dp. */
/* ── Reduced motion ── */
@media (prefers-reduced-motion: reduce) {
  .hub-media img,
  .hub-media::before,
  .cat-hub--photo .cat-hub__card h2::after,
  .cat-hub--photo .cat-hub__card p,
  .hub-list,
  .hub-cta,
  .hub-band__more,
  .cta-band__phone,
  /* ВРУ: базовый зум прячет белые поля кадра — держим его всегда */
  .hub-media--en img,
}

/* ══ СЕМЕЙНЫЙ ГЕРОЙ + анимация фильтра (2026-07-29) ═══════════
   /catalog/?family=izko|bogatyr — витрина семьи вместо хаб-страниц.
   Появление: подъём героя → рисуется золотой подчёрк → счётчик
   позиций → карточки всплывают каскадом. ═══════════════════════ */
.fam-hero {
  position: relative;
  margin-top: 26px;
  padding: 24px 28px 26px;
  background:
    radial-gradient(ellipse 420px 180px at 12% 0%, rgba(201,164,53,.10), transparent 70%),
    var(--card);
  border: 1px solid var(--border-g);
  border-radius: var(--r-lg);
  overflow: hidden;
  opacity: 0; transform: translateY(14px);
  transition: opacity .55s ease, transform .55s cubic-bezier(.22,.61,.36,1);
}
.fam-hero.on { opacity: 1; transform: none; }
.fam-hero.no-motion { transition: none; }
.fam-hero::after {              /* тонкая золотая кромка сверху */
  content: ''; position: absolute; top: 0; left: 0; right: 0; height: 2px;
  background: linear-gradient(90deg, var(--gold), rgba(201,164,53,0) 65%);
}
.fam-hero__kicker {
  display: block;
  font-family: var(--font-display);
  font-size: .64rem; font-weight: 700;
  letter-spacing: .26em; text-transform: uppercase;
  color: var(--muted);
  margin-bottom: 6px;
}
.fam-hero__row { display: flex; align-items: baseline; gap: 22px; flex-wrap: wrap; }
.fam-hero__name {
  position: relative;
  font-family: var(--font-display);
  font-size: clamp(2rem, 3.4vw, 2.9rem);
  font-weight: 800; line-height: 1;
  letter-spacing: -0.015em;
  color: var(--text);
  padding-bottom: 8px;
}
.fam-hero__name::after {        /* подчёрк — как у логотипа, рисуется */
  content: ''; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 3px;
  background: var(--gold);
  transform: scaleX(0); transform-origin: left center;
  transition: transform .6s cubic-bezier(.16,1,.3,1) .25s;
}
.fam-hero.on .fam-hero__name::after { transform: scaleX(1); }
.fam-hero.no-motion .fam-hero__name::after { transition: none; }
.fam-hero__meta {
  display: inline-flex; align-items: baseline; gap: 8px;
  font-size: .85rem; color: var(--muted-lt);
}
.fam-hero__all {
  margin-left: auto;
  display: inline-flex; align-items: center; gap: 9px;
  min-height: 44px; padding: .4rem 1.1rem;
  font-size: .8rem; letter-spacing: .06em;
  color: var(--muted-lt);
  border: 1px solid var(--border);
  border-radius: 30px;
  transition: color .25s, border-color .25s, gap .25s;
}
.fam-hero__all i { font-style: normal; font-size: 1rem; color: var(--gold-ink); }
.fam-hero__all:hover { color: var(--text); border-color: var(--gold-ink); gap: 13px; }
@media (max-width: 640px) {
  .fam-hero { padding: 18px 18px 20px; margin-top: 18px; }
  .fam-hero__row { gap: 12px; }
  .fam-hero__all { margin-left: 0; }
}

/* карточки всплывают каскадом при семейном фильтре / смене чипа */
@keyframes pcardPop {
  from { opacity: 0; transform: translateY(14px) scale(.98); }
  to   { opacity: 1; transform: none; }
}
.p-card.pop { animation: pcardPop .5s cubic-bezier(.22,.61,.36,1) both; }
@media (prefers-reduced-motion: reduce) {
  .p-card.pop { animation: none; }
  .fam-hero { opacity: 1; transform: none; transition: none; }
  .fam-hero__name::after { transform: scaleX(1); transition: none; }
}

/* ═══ ИЗКО ОДНОСТРАНИЧНЫЙ КАТАЛОГ (2026-07-29) ════════════════
   /catalog/izko/ — шесть разделов на одной странице вместо
   подсекций. Скоуп: .cat-head--tight, .sec-rail, .sec*, .srow*,
   .scard*, .sec-band*. Всё на существующих токенах.
   Правки из ревью спеки вшиты: reduced-motion на совпадающей
   специфичности, симметрия чётных рядов, рейка-скролл до 1100px,
   золото на светлой теме через --gold-dp, overflow-x clip против
   сдвиговых reveal'ов. ═══════════════════════════════════════ */

body { overflow-x: clip; } /* translateX(±24px) у нераскрытых reveal--l/r не должен рождать горизонтальный скролл */

.cat-head--tight { padding-bottom: 90px; }
@media (max-width: 768px) { .cat-head--tight { padding-bottom: 58px; } }

/* ── Секции ── */
/* overflow-x: clip именно здесь, а не только на body: body-клип не
   доезжал, и translateX(+24px) у нераскрытых reveal--r растягивал
   страницу до 379px при вьюпорте 375. clip (не hidden) не создаёт
   контейнер прокрутки, sticky-рейка и scroll-margin не задеты.
   Паддинг был фиксирован в 64px (десктоп) и 40px (телефон), оба
   числа ниже норм спейсинг-прохода (88 to 112 / 56 to 64): пусто
   между разделами читалось как обрыв вёрстки, а не как воздух. */
.sec { padding-block: 100px; scroll-margin-top: calc(var(--nav-h) + 64px); overflow-x: clip; }
.sec--alt { background: var(--atm-band); border-block: 1px solid var(--border); }
@media (max-width: 768px) { .sec { padding-block: 56px; } }

/* Нумерация разделов (01…06) и чип «N позиций» сняты 2026-07-29:
   номер ничего не значил для покупателя, а счётчик дублировал
   то, что и так видно по карточкам. Осталось имя + линейка. */
.sec__head { display: flex; align-items: baseline; gap: 16px; margin-bottom: 32px; }
.sec__head h2 {
  font-family: var(--font-display); font-weight: 700;
  font-size: var(--h2); letter-spacing: -0.015em;
  position: relative; padding-bottom: 8px; margin: 0;
}
.sec__head h2::after {           /* золотой подчёрк, рисуется при появлении */
  content: ''; position: absolute; left: 0; bottom: 0;
  width: 100%; height: 3px; background: var(--gold);
  transform: scaleX(0); transform-origin: left center;
  transition: transform .6s cubic-bezier(.16,1,.3,1) .25s;
}
.sec__head.in-view h2::after { transform: scaleX(1); }
.sec__rule { flex: 1; height: 1px; background: var(--border-g); align-self: center; min-width: 24px; }
.sec__lede { font-size: .9rem; color: var(--muted-lt); max-width: 62ch; margin: -16px 0 32px; }

/* ≤768: шапка секции — flex с переносом. Раньше её распирал nowrap-чип
   «под заказ» (515px при вьюпорте 375); чип убран, но перенос и
   min-width:0 оставлены — «Металлоконструкции» одно слово шире 375px. */
@media (max-width: 768px) {
  .sec__head { flex-wrap: wrap; gap: 10px 12px; margin-bottom: 22px; }
  .sec__head h2 { min-width: 0; overflow-wrap: anywhere; }
  .sec__rule { min-width: 0; }
}

/* ── Шаблон A: сплит-ряды ── */
.srow {
  display: grid; grid-template-columns: minmax(0,5fr) minmax(0,7fr);
  gap: clamp(24px, 4vw, 48px); align-items: center;
}
.srow + .srow { margin-top: 56px; }
/* чётный ряд: и порядок, и ширины зеркалятся — фото всегда 5fr */
.srow:nth-of-type(even) { grid-template-columns: minmax(0,7fr) minmax(0,5fr); }
.srow:nth-of-type(even) .srow__media { order: 2; }
.srow__media {
  position: relative; aspect-ratio: 4/3;
  border-radius: var(--r-lg); border: 1px solid var(--border);
  overflow: hidden; background: var(--bg2);
}
/* тональный унификатор — белые рендеры и полевые фото в один ряд;
   намеренно тёмный в ОБЕИХ темах */
.srow__media::after, .scard__media::after {
  content: ''; position: absolute; inset: 0;
  background: rgba(15,18,26,.14);
  transition: background .35s; pointer-events: none;
}
.srow__media img, .scard__media img {
  width: 100%; height: 100%; object-fit: cover;
  filter: saturate(.92) contrast(1.04);
  transition: transform .7s cubic-bezier(.22,.61,.36,1);
}
.srow:hover .srow__media img, .scard:hover .scard__media img { transform: scale(1.05); }
.srow:hover .srow__media::after, .scard:hover .scard__media::after { background: rgba(15,18,26,.28); }

/* ── Высокий узкий предмет: показывать целиком ────────────────────────
   `cover` вписывает квадратный кадр в рамку 4:3 по ширине и срезает верх
   и низ. Для водоразборной колонки это срезало ровно то, по чему её
   узнают: поворотную стрелу сверху и основание с приводом снизу —
   оставалась труба с манометрами, по которой не понять, что это.

   Фон рамки равен фону самого рендера (взят пипеткой из угла файла,
   #f0f1f3), поэтому поля по бокам не читаются как поля. */
.srow__media--tall img, .scard__media--tall img {
  object-fit: contain;
  transform: scale(.94);                 /* воздух по краям, иначе упирается */
}
.srow__media--tall, .scard__media--tall { background: #f0f1f3; }
.srow:hover .srow__media--tall img, .scard:hover .scard__media--tall img {
  transform: scale(.99);
}
.srow__body h3 { font-family: var(--font-display); font-size: 1.35rem; margin: 0 0 12px; }

/* ── Кликабелен весь ряд / вся карточка ──────────────────────
   Паттерн stretched-link, тот же, что у плиток семейств на главной:
   ссылка остаётся настоящей <a> (Tab, «открыть в новой вкладке»,
   правый клик), а её ::after растягивается на весь блок. Кнопки
   внутри поднимаем выше — «Запросить цену» обязана остаться
   телефоном, а не переходом на страницу товара. */
/* position: relative обязателен и не подменяется ничем: catalog.js вешает
   .reveal на .srow__body, а transform в .reveal создаёт содержащий блок —
   без явного relative на самом ряду ::after растягивался по .srow__body
   (672×249) вместо .srow (1200×360), и клик по фотографии не работал. */
.srow, .scard { position: relative; }
.srow:has(.srow__link), .scard:has(.srow__link) { cursor: pointer; }
.srow__link { color: inherit; text-decoration: none; transition: color .25s; }
.srow__link::after { content: ''; position: absolute; inset: 0; z-index: 1; }
.srow:hover .srow__link, .scard:hover .srow__link { color: var(--gold-ink); }
[data-theme="light"] .srow:hover .srow__link,
[data-theme="light"] .scard:hover .srow__link { color: var(--gold-ink); }
.srow__cta { position: relative; z-index: 2; }
.srow:has(.srow__link:focus-visible),
.scard:has(.srow__link:focus-visible) { outline: 2px solid var(--gold); outline-offset: 4px; border-radius: var(--r-lg); }
.srow__link:focus-visible { outline: none; }

/* Хвостовые ссылки раздела («Все серии →», «Сравнить модели →») */
.sec__more { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 34px; }
/* На телефоне .sec теперь несёт собственные 60px снизу (спейсинг-проход,
   мерка 9); своих 34px сверху у ссылки «Все серии» поверх них уже
   лишнее, вместе давали 94 to 118px, выше потолка в 84px. */
@media (max-width: 768px) { .sec__more { margin-top: 0; } }

/* Карточка без фотографии: плитка-заглушка не должна занимать столько
   же места, сколько настоящий снимок, иначе сетка превращается в стену
   пустых прямоугольников. Отдаём ей узкую полосу-шапку. */
.scard__media:has(.p-tile) { aspect-ratio: auto; height: 88px; }
.scard__media:has(.p-tile)::after { display: none; }   /* тональный слой не нужен без фото */
.scard__media .p-tile .tile-sub { font-size: .82rem; letter-spacing: .18em; }
.srow__body p { color: var(--muted-lt); font-size: .92rem; line-height: 1.65; max-width: 58ch; }
.srow__cta { display: flex; align-items: center; gap: 14px; margin-top: 18px; }
.srow__cta .p-call { flex: 0 0 auto; padding: .65rem 1.6rem; }
@media (max-width: 768px) {
  .srow, .srow:nth-of-type(even) { grid-template-columns: 1fr; gap: 18px; }
  .srow:nth-of-type(even) .srow__media { order: 0; }  /* фото всегда первым */
  .srow + .srow { margin-top: 36px; }
}

/* ── Направленные reveal-варианты ── */
.reveal--l.reveal { transform: translateX(-24px); transition: opacity .65s cubic-bezier(.22,.61,.36,1), transform .65s cubic-bezier(.22,.61,.36,1); }
.reveal--r.reveal { transform: translateX(24px);  transition: opacity .65s cubic-bezier(.22,.61,.36,1), transform .65s cubic-bezier(.22,.61,.36,1); }
.reveal--l.reveal.in-view, .reveal--r.reveal.in-view { transform: none; }
.srow__body.reveal { transition-delay: .12s; }  /* фото ведёт, текст догоняет */

/* ── Шаблон B: сетка 2×2 ── */
.sec-grid { display: grid; grid-template-columns: repeat(2,1fr); gap: 20px; }
@media (max-width: 700px) { .sec-grid { grid-template-columns: 1fr; } }
.scard {
  display: flex; flex-direction: column;
  background: var(--card); border: 1px solid var(--border);
  border-radius: var(--r-lg); overflow: hidden;
  /* hover-цвета отдельными транзишенами ПОСЛЕ reveal-пары — лесенка
     задержек ниже не тормозит смену рамки */
  transition: opacity .6s ease, transform .6s ease, border-color var(--trans), background-color var(--trans);
}
.scard:hover { border-color: var(--border-g); background: var(--card-h); }
.scard__media { position: relative; aspect-ratio: 16/10; overflow: hidden; }
.scard__body { padding: 20px 22px 22px; display: flex; flex-direction: column; flex: 1; }
.scard__body h3 { font-family: var(--font-display); font-size: 1.1rem; margin: 0 0 10px; }
.scard__body p { font-size: .88rem; color: var(--muted-lt); line-height: 1.6; }
.scard__body .srow__cta { margin-top: auto; padding-top: 16px; }
/* лесенка появления: только для reveal-пары, hover-цвета без задержки */
.sec-grid .scard.reveal:nth-child(1) { transition-delay: 0ms,   0ms,   0s, 0s; }
.sec-grid .scard.reveal:nth-child(2) { transition-delay: 80ms,  80ms,  0s, 0s; }
.sec-grid .scard.reveal:nth-child(3) { transition-delay: 160ms, 160ms, 0s, 0s; }
.sec-grid .scard.reveal:nth-child(4) { transition-delay: 240ms, 240ms, 0s, 0s; }

/* QA: /catalog/bogatyr/ — семь карточек в 2-колоночной сетке оставляли
   пустую ячейку в последнем ряду. Последняя карточка раздела «Котлы»
   занимает ряд целиком; ::media остаётся тем же 16/10, просто шире. */
#kotly .sec-grid .scard:last-child { grid-column: 1 / -1; }

/* ── Шаблон C: полосы ── */
.sec-band { position: relative; border-radius: var(--r-lg); border: 1px solid var(--border); overflow: hidden; }
.sec-band--mk { display: flex; flex-direction: column; background: var(--card); }
.sec-band__inner { padding: 30px clamp(24px,4vw,48px); max-width: 78ch; }
.sec-band--mk .sec-band__inner p { font-size: .92rem; line-height: 1.65; margin: 0 0 10px; color: var(--muted-lt); }
/* Полоса, а не портрет: исходник 886×665 во всю ширину дал бы почти
   метр высоты на десктопе. Соотношение задаём обёртке — <picture> сама
   по себе строчная и высоту не держит, из-за чего до загрузки не
   резервировалось место. */
.sec-band__pic {
  display: block; width: 100%;
  aspect-ratio: 13 / 3;        /* −40% высоты: полоса, а не панорама */
  overflow: hidden;
  border-top: 1px solid var(--border);
}
.sec-band__img {
  width: 100%; height: 100%; display: block;
  object-fit: cover; object-position: center 62%;
  filter: saturate(.92) contrast(1.04);
  transition: transform .7s cubic-bezier(.22,.61,.36,1);
}
.sec-band--mk:hover .sec-band__img { transform: scale(1.03); }
@media (max-width: 700px) {
  .sec-band__inner { padding: 22px 20px; }
  .sec-band__pic { aspect-ratio: 8 / 3; }
}
.sec-band--dop {
  background-color: var(--card);
  background-image: repeating-linear-gradient(135deg, var(--border) 0 1px, transparent 1px 13px);
  border: 1px dashed var(--border-g);
  padding: 26px 24px;
  display: flex; flex-wrap: wrap; align-items: center; justify-content: space-between;
  gap: 18px 32px;
}
.sec-band--dop p { font-size: .86rem; color: var(--muted-lt); max-width: 60ch; margin: 0; }
.sec-band__actions { display: flex; flex-wrap: wrap; align-items: center; gap: 10px 16px; }

/* Липкая рейка разделов («01 Водоснабжение · 02 …») снята 2026-07-29:
   на мобиле она обрезалась в горизонтальный скролл под шапкой и была
   основным источником визуального шума. Переходы к разделам остались
   в мега-меню «Каталог» (/catalog/izko/#vodosnabzhenie и т.д.). */

/* ── Reduced motion — специфичность СОВПАДАЕТ с базовыми правилами
   выше (одиночные классы в media проигрывали бы парным) ── */
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  .reveal--l.reveal, .reveal--r.reveal { transform: none; transition: none; }
  .srow__body.reveal { transition-delay: 0s; }
  .sec-grid .scard.reveal:nth-child(1),
  .sec-grid .scard.reveal:nth-child(2),
  .sec-grid .scard.reveal:nth-child(3),
  .sec-grid .scard.reveal:nth-child(4) { transition-delay: 0s; }
  .srow__media img, .scard__media img, .sec-band__img { transition: none; }
  .srow:hover .srow__media img, .scard:hover .scard__media img,
  .sec-band--mk:hover .sec-band__img { transform: none; }
  .sec__head h2::after { transform: scaleX(1); transition: none; }
}

/* ═══ ЛЕВАЯ РЕЙКА ФИЛЬТРОВ (2026-07-29) ══════════════════════
   Верхняя липкая полоса чипов уехала в боковое меню: она ехала
   за скроллом поверх контента и на телефоне съедала до 450px
   высоты. Взаимодействие — порт vertical-menu с 21st.dev
   (стрелка выезжает слева, подпись сдвигается и уходит в
   акцент) на голом CSS: React/Next/Tailwind в статику не тянем,
   поведение и тайминги (.3s ease-out) идентичны оригиналу.
   ≤1024px рейка снова разворачивается в горизонтальные чипы —
   на телефоне колонка слева съела бы пол-экрана. ═════════════ */

@media (min-width: 1025px) {
  .shop-layout {
    display: grid; grid-template-columns: 264px minmax(0, 1fr);
    gap: 0 44px; align-items: start;
  }

  .shop-filters {
    position: sticky; top: calc(var(--nav-h) + 20px); z-index: 30;
    background: none; border-bottom: 0;
    margin-top: 1.6rem; padding: 0 0 0 1.4rem;
    /* Рейка витрины — 710px. На 1366×768 её низ («Показано: N») уходил
       под край экрана навсегда: sticky-элемент выше вьюпорта не
       доскроллить. Ограничиваем и прокручиваем саму рейку. */
    max-height: calc(100vh - var(--nav-h) - 40px);
    overflow-y: auto;
    scrollbar-width: thin;
  }
  .shop-filters::-webkit-scrollbar { width: 4px; }
  .shop-filters::-webkit-scrollbar-thumb { background: var(--border-g); border-radius: 4px; }
  /* заголовки групп */
  .shop-filters .row-lbl {
    display: block; margin: 0 0 .85rem;
    font-size: .68rem; font-weight: 700; letter-spacing: .18em;
    text-transform: uppercase; color: var(--muted);
  }
  .shop-filters .chip-row {
    display: flex; flex-direction: column; align-items: stretch;
    flex-wrap: nowrap; gap: 0;
  }
  .shop-filters .chip-row + .chip-row {
    margin-top: 1.7rem; padding-top: 1.4rem; border-top: 1px solid var(--border);
  }

  /* пункт: стрелка стоит за левым краем и невидима, подпись
     сдвинута на её ширину — на hover/активном оба едут вправо */
  .shop-filters .chip {
    display: flex; align-items: center; width: 100%;
    padding: .5rem 0; border: 0; border-radius: 0; background: none;
    font-size: .9rem; line-height: 1.3; text-align: left; color: var(--muted-lt);
    transition: color .3s ease;
  }
  .shop-filters .chip::before {
    content: '→'; flex: 0 0 auto;
    width: 1.15em; margin-right: .3em; font-weight: 700; line-height: 1;
    opacity: 0; transform: translateX(-100%);
    transition: transform .3s ease-out, opacity .3s ease-out;
  }
  .shop-filters .chip > span {
    display: block; transform: translateX(-1.45em);
    transition: transform .3s ease-out;
  }
  .shop-filters .chip > small {
    margin-left: auto; padding-left: .5rem;
    font-size: .72rem; color: var(--muted); transition: color .3s ease;
  }
  .shop-filters .chip:hover,
  .shop-filters .chip.on            { color: var(--gold-ink); background: none; }
  .shop-filters .chip.on            { font-weight: 700; }
  .shop-filters .chip.on > small    { color: var(--gold-ink); }
  .shop-filters .chip:hover::before,
  .shop-filters .chip.on::before    { opacity: 1; transform: translateX(0); }
  .shop-filters .chip:hover > span,
  .shop-filters .chip.on > span     { transform: translateX(0); }
  .shop-filters .chip:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

  .shop-filters .shop-count {
    display: block; margin: 1.7rem 0 0; padding-top: 1.3rem;
    border-top: 1px solid var(--border); font-size: .78rem; color: var(--muted);
  }

  .shop-grid, .shop-col { padding-top: 1.6rem; }
  /* хабы «Буран» / «Котлы» — та же рейка, но сетка у них своя:
     три колонки в правой колонке шириной ~680px давали 212px на
     карточку, поэтому до 1280px их две */
  .shop-layout .prod-grid { grid-template-columns: repeat(2, 1fr); }
  @media (min-width: 1280px) { .shop-layout .prod-grid { grid-template-columns: repeat(3, 1fr); } }
  /* 264px рейки + 44px зазора: три колонки становятся уже 240px
     раньше 1280px — там переходим на две */
  @media (max-width: 1279px) { .shop-grid { grid-template-columns: repeat(2, 1fr); } }
}

/* JS гасит блок топлива через fuelRow.hidden. Правило .chip-row[hidden]
   выше по файлу имеет ту же специфичность, что и колоночный
   .shop-filters .chip-row, но идёт РАНЬШЕ — и проигрывало. Возвращаем.
   То же и для отдельных пунктов: при ?family=izko JS прячет чипы чужих
   групп через b.hidden, но авторское .shop-filters .chip{display:flex}
   било [hidden] и на десктопе оставляло кликабельные пункты, ведущие
   в пустую выдачу. */
.shop-filters .chip-row[hidden] { display: none; }
.shop-filters .chip[hidden] { display: none; }

/* золото как текст на светлой теме недотягивает по контрасту */
[data-theme="light"] .shop-filters .chip:hover,
[data-theme="light"] .shop-filters .chip.on,
[data-theme="light"] .shop-filters .chip.on > small { color: var(--gold-ink); }

/* Фирменное кольцо фокуса — вне блока ≥1025px: ниже него чипы получали
   только системную обводку браузера. */
.chip:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
/* Клавиатура на горизонтальной полосе: Chrome доскроллит ряд, только
   если элемент целиком за краем, — половинчатые чипы оставались
   обрезанными. Отступ прокрутки убирает это. */
.chip-row { scroll-padding-inline: 28px; }

/* Пустая выдача: раньше между рейкой и CTA просто оставалась дыра
   нулевой высоты — фильтр выглядел сломанным, а не строгим. */
.shop-empty {
  grid-column: 1 / -1;
  padding: 48px 24px; text-align: center;
  border: 1px dashed var(--border-g); border-radius: var(--r-lg);
  color: var(--muted-lt); font-size: .95rem; line-height: 1.7;
}
.shop-empty b { display: block; font-family: var(--font-display);
  font-size: 1.15rem; color: var(--text); margin-bottom: .5rem; }
.shop-empty button {
  margin-top: 1rem; background: transparent; color: var(--gold-ink);
  border: 1px solid var(--border-g); border-radius: 30px;
  padding: .5rem 1.2rem; font-size: .85rem; font-weight: 600; cursor: pointer;
  transition: background .2s, border-color .2s;
}
.shop-empty button:hover { background: var(--gold-dim); border-color: var(--gold-ink); }
[data-theme="light"] .shop-empty button { color: var(--gold-ink); }

/* ≤1024 — прежняя горизонтальная полоса; она теперь живёт внутри
   main.container, поэтому фон и нижнюю границу возвращаем в край
   отрицательным margin'ом */
@media (max-width: 1024px) {
  .shop-filters { margin-inline: -20px; padding-inline: 20px; }
  /* Подпись первой группы раньше жила отдельным <p class="fside__hd">
     СНАРУЖИ ряда и на узких экранах пряталась совсем: получался
     безымянный ряд чипов, а под ним подписанный «Загрузка:». Теперь
     обе подписи — .row-lbl внутри своего ряда. */
  .shop-filters .row-lbl::after { content: ':'; }
}
/* счётчик на планшете — своей строкой справа */
@media (min-width: 769px) and (max-width: 1024px) {
  .shop-filters .shop-count { display: block; margin-top: .4rem; text-align: right; }
}

/* ═══ ПРОХОД ПО CLAUDE-design.md (2026-07-29) ═══════════════════
   Аудит уже собранного каталога против глобального дизайн-справочника.
   Здесь только то, что реально нарушалось. ══════════════════════ */

/* §4 — переносы в заголовках. balance выравнивает строки заголовка,
   pretty не оставляет одинокое слово последней строкой в тексте.
   Самая дешёвая правка с заметным эффектом на длинных русских словах
   («Металлоконструкции», «Энергосбережение»). */
h1, h2, .sec__head h2, .cat-head h1, .shop-head h1, .pdp-hero__name,
.prod-section__title, .cta-band h2 { text-wrap: balance; }
/* QA: на 320px одно длинное слово («Пользовательское», «Твёрдотопливные»)
   не помещалось в узкую мобильную колонку и не переносилось — оно
   вылезало за рамку и тянуло за собой горизонтальный скролл всей
   страницы (/policy/, /catalog/kotly/07-04…). balance переносит по
   пробелам, но не спасает внутри самого длинного слова. */
h1, h2, .sec__head h2, .cat-head h1, .shop-head h1, .pdp-hero__name,
.prod-section__title, .cta-band h2 { overflow-wrap: break-word; }
h3, .p-name, .prod-card__name, .scard__body h3, .srow__body h3,
.cat-head__lede, .sec__lede, .shop-head .lede, .p-sub, .prod-card__desc,
.srow__body p, .scard__body p, .cta-band p { text-wrap: pretty; }

/* §2.5 / §6 — зона нажатия не меньше 44×44 на сенсорных экранах.
   Ограничено pointer:coarse намеренно: на мышке те же кнопки должны
   оставаться компактными, иначе левая рейка и карточки распухают. */
@media (pointer: coarse) {
  /* (а) элементы, у которых свой display уже задан и завязан на
     брейкпоинт — трогаем ТОЛЬКО размер. Раньше здесь стоял общий
     display:inline-flex, и он воскрешал бургер на 1061–1440px:
     кнопка снова появлялась и вылезала за правый край. */
  .compare-check, .nav-toggle, .theme-toggle, .cta-band__home,
  .shop-reset.on, .chip { min-height: var(--tap); }
  .nav-toggle, .theme-toggle { min-width: var(--tap); justify-content: center; }
  .chip { padding-block: .55rem; }
  .compare-check { gap: .5rem; }

  /* (б) строчные ссылки и кнопки — им display нужен, чтобы высота
     вообще применилась. Все они видны на любом брейкпоинте. */
  .p-call, .p-more, .prod-card__link,
  .compare-bar__reset, .compare-bar__btn,
  .fam-hero__all, .sec__more > * {
    min-height: var(--tap);
    display: inline-flex; align-items: center; justify-content: center;
  }
  /* .p-name-link и .srow__link намеренно не трогаем: они живут внутри
     <h3>, и inline-flex сломал бы перенос длинных названий. Порог
     нажатия там держит сама карточка — она кликабельна целиком. */

  /* (в) «или оставьте заявку» (catalog.js вставляет .cta-order текстом
     внутри предложения на PDP/хабах). Текст короткий и не переносится
     сам по себе, поэтому inline-flex безопасен — в отличие от (а),
     здесь риска сломать перенос длинного названия нет. */
  .cta-band__alt a {
    min-height: var(--tap);
    display: inline-flex; align-items: center;
  }
}

/* §7 — кнопка «наверх» была 30×30, ниже собственного порога. */
.cta-band__up { width: 38px; height: 38px; }
@media (pointer: coarse) { .cta-band__up { width: var(--tap); height: var(--tap); } }
.cta-band__up svg { width: 17px; height: 17px; }

/* §7 — переводим на общие токены движения то, что трогали в этом проходе */
.p-call, .p-more, .nav-cta, .chip, .cta-band__up, .cta-band__up-lbl,
.theme-toggle, .shop-empty button {
  transition-duration: var(--dur-base);
  transition-timing-function: var(--ease-out);
}

/* §16 — сброс фильтров прямо в рейке. Раньше снять выбор можно было
   только вернувшись к «Всё» или через пустую выдачу. */
.shop-reset {
  display: none; align-items: center; gap: .4rem;
  margin-top: 1rem; padding: .45rem 0;
  background: none; border: 0; cursor: pointer;
  font-family: var(--font-body); font-size: .78rem; font-weight: 600;
  letter-spacing: .04em; color: var(--muted-lt);
  transition: color var(--dur-base) var(--ease-out);
}
.shop-reset.on { display: inline-flex; }
.shop-reset:hover { color: var(--gold-ink); }
.shop-reset:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }
.shop-reset svg { width: 14px; height: 14px; flex: 0 0 auto; }
[data-theme="light"] .shop-reset:hover { color: var(--gold-ink); }
@media (max-width: 1024px) { .shop-reset { margin-top: .3rem; margin-left: auto; } }
@media (pointer: coarse) { .shop-reset.on { min-height: var(--tap); } }

/* §2.4 — третье семейство (Cormorant Garamond) грузилось на КАЖДОЙ
   странице каталога ради одной строки «Цена по запросу». Цена набрана
   тем же display-шрифтом, что и остальные числа сайта. */
.pdp-price__amount { font-family: var(--font-display); font-style: normal; }

/* ═══ ДВИЖЕНИЕ (2026-07-29) ═══════════════════════════════════
   Три приёма, каждый обязан нести смысл, а не украшать. Порты идей
   с 21st.dev на голый CSS/JS: React в статику не тянем.
   Всё на токенах --ease-* / --dur-* и глушится prefers-reduced-motion.
   ══════════════════════════════════════════════════════════════ */

/* 1. Штангенциркуль. Уголки-засечки сходятся на карточке при наведении —
      как губки инструмента на детали. Заодно дешевле, чем сейчас:
      трансформировать рамку в 14px вместо scale() картинки на 768px,
      что на слабых ноутбуках заметно. */
.p-card::before, .p-card::after,
.prod-card::before, .prod-card::after {
  content: ''; position: absolute; z-index: 3;
  width: 14px; height: 14px;
  border: 0 solid var(--gold);
  opacity: 0; pointer-events: none;
  transition: opacity var(--dur-fast) var(--ease-out),
              inset var(--dur-base) var(--ease-out);
}
.p-card::before, .prod-card::before {
  top: 10px; left: 10px; border-top-width: 2px; border-left-width: 2px;
}
.p-card::after, .prod-card::after {
  bottom: 10px; right: 10px; border-bottom-width: 2px; border-right-width: 2px;
}
.p-card:hover::before, .prod-card:hover::before { opacity: 1; top: 6px; left: 6px; }
.p-card:hover::after,  .prod-card:hover::after  { opacity: 1; bottom: 6px; right: 6px; }
.p-card:has(:focus-visible)::before, .prod-card:has(:focus-visible)::before { opacity: 1; top: 6px; left: 6px; }
.p-card:has(:focus-visible)::after,  .prod-card:has(:focus-visible)::after  { opacity: 1; bottom: 6px; right: 6px; }

/* 2. Чертёж прорисовывается. На страницах котлов лежат настоящие
      инженерные схемы — не иллюстрация, а часть описания товара.
      Линии затягиваются при появлении: страница как будто чертит их
      при тебе. Длину каждой линии считает JS, здесь только переход. */
.pdp-hero__visual svg [data-draw] {
  transition: stroke-dashoffset .75s var(--ease-smooth);
}

/* 3. Проводка взгляда по строке сравнения. Плотная таблица
      характеристик — рабочий инструмент снабженца; подсветка тянется
      слева направо и помогает не потерять строку между колонками. */
.compare-table tbody tr { position: relative; }
.compare-table tbody tr::after {
  content: ''; position: absolute; inset: 0; z-index: -1;
  background: var(--gold-dim);
  transform: scaleX(0); transform-origin: left center;
  transition: transform var(--dur-fast) var(--ease-out);
}
.compare-table tbody tr:hover::after,
.compare-table tbody tr:focus-within::after { transform: scaleX(1); }

@media (prefers-reduced-motion: reduce) {
  .p-card::before, .p-card::after,
  .prod-card::before, .prod-card::after,
  .compare-table tbody tr::after,
  .pdp-hero__visual svg [data-draw] { transition: none; }
}

/* ═══ Интерактивный чертёж оборудования ══════════════════════
   Покупатель может повернуть блок и ткнуть в узел. Цвета — те же
   три, что и на всех схемах сайта: золото — то, что делает завод,
   сталь — обвязка, «уголёк» — топливный узел, он и отличает
   модификации друг от друга.
   ═══════════════════════════════════════════════════════════ */
/* Родительская рамка держала жёсткое 4:3 и overflow: hidden — чертёж
   вместе с легендой в неё не влезал и обрезался. Там, где есть чертёж,
   рамка отдаёт высоту содержимому: сам холст сохраняет пропорцию, а
   легенда живёт под ним. */
.pdp-hero__visual:has([data-blueprint]) {
  /* min-width: 0 обязателен: элемент грид-колонки по умолчанию не уже
     своего содержимого, а лента узлов в одну строку имеет огромную
     минимальную ширину — без этого она растягивала всю колонку. */
  min-width: 0;
  aspect-ratio: auto;
  overflow: visible;
  background: none;
  border: none;
  border-radius: 0;
  display: block;
  padding: 0;
}
.pdp-hero__visual:has([data-blueprint]) .pdp-hero__svg-placeholder {
  height: auto;
  display: block;
  gap: 0;
}

.bp { display: flex; flex-direction: column; gap: 14px; width: 100%; min-width: 0; }
/* Скрипт вешает .bp на сам плейсхолдер и выбрасывает внутреннюю обёртку.
   Голого `.bp` для этого мало: правило с :has() выше по специфичности,
   и контейнер оставался display:block — четыре зазора по 14px исчезали
   в момент отработки скрипта. Блок ужимался на 42px, всё под ним
   прыгало вверх (CLS 0,05 на «Буране Г» при 1024px). Локально этого
   не видно: с диска скрипт успевает до первой отрисовки. */
.pdp-hero__visual:has([data-blueprint]) .pdp-hero__svg-placeholder.bp {
  display: flex;
  flex-direction: column;
  gap: 14px;
  /* align-items: center достаётся от базового правила плейсхолдера.
     В колоночном flex это ужимает детей до ширины содержимого: холст
     съезжал с 728px до 302px, а высота по aspect-ratio — с 516 до 214.
     Растягиваем явно, иначе лечение хуже болезни. */
  align-items: stretch;
  justify-content: flex-start;
}

.bp__stage {
  position: relative;
  border-radius: var(--r-lg);
  background:
    radial-gradient(120% 120% at 30% 15%, rgba(201,164,53,0.05) 0%, transparent 55%),
    var(--bg2);
  border: 1px solid var(--border);
  cursor: grab;
  touch-action: none;             /* иначе жест уводит страницу, а не блок */
  overflow: hidden;
  /* Держит высоту до того, как скрипт нарисует SVG — иначе появление
     чертежа сдвигало страницу (ловили CLS 0.44 на планшете). */
  aspect-ratio: 480 / 340;
}
.bp__stage.is-grabbing { cursor: grabbing; }
/* Над узлом курсор меняется на палец: единственный способ сказать «сюда
   можно ткнуть» на чертеже, где нет ни кнопок, ни рамок. */
.bp__stage.is-over:not(.is-grabbing) { cursor: pointer; }
.bp__stage:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

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

.bp__grid path {
  fill: none;
  stroke: var(--gold-ink);
  stroke-width: 0.5;
  opacity: 0.16;
}

.bp__part path {
  fill: none;
  stroke-linecap: round;
  stroke-linejoin: round;
  transition: opacity var(--dur-base, .25s) var(--ease-out, ease),
              stroke var(--dur-base, .25s) var(--ease-out, ease);
}
.bp__part--gold  path { stroke: var(--gold-ink); }
.bp__part--steel path { stroke: #9AAAC8; }
.bp__part--ember path { stroke: #D97B3C; }
.bp__part--dim   path { stroke: #6A7A9A; opacity: 0.7; }

/* ═══ Потоки: что и куда течёт ═══════════════════════════════════
   Бегущий пунктир по ниткам отвечает на вопрос «зачем это железо»
   без единого слова. Движение даёт CSS через stroke-dashoffset —
   в покое JS не считает ни кадра, а сама анимация уезжает
   на композитор.
   ═══════════════════════════════════════════════════════════════ */
.bp__flow-line {
  fill: none;
  stroke-width: 2;
  stroke-linecap: round;
  stroke-linejoin: round;
  stroke-dasharray: 7 13;
  opacity: 0;
  transition: opacity var(--dur-base, .25s) var(--ease-out, ease);
}
/* Пунктир бежит только когда чертёж на экране */
.bp__stage.is-live .bp__flow-line {
  opacity: .85;
  animation: bp-flow 2.4s linear infinite;
}
@keyframes bp-flow { to { stroke-dashoffset: -40; } }

.bp__flow-line--fuel  { stroke: #E08A45; }
.bp__flow-line--flue  { stroke: #8C93A6; }
.bp__flow-line--water { stroke: #5E93D6; }
.bp__flow-line--hot   { stroke: var(--gold); }

/* Выбран узел — потоки уходят на второй план: вопрос сменился с
   «как оно работает» на «что это за деталь», и спорить им незачем. */
.bp:has(.bp__part.is-on) .bp__flow-line { opacity: .18; }

.bp__key {
  position: absolute; right: 12px; bottom: 10px;
  display: flex; flex-wrap: wrap; justify-content: flex-end;
  gap: 8px 14px; max-width: 62%;
  pointer-events: none;
}
.bp__key-item {
  font-size: .62rem; line-height: 1.6; letter-spacing: .08em; text-transform: uppercase;
  color: var(--muted); white-space: nowrap;
}
.bp__key-item::before {
  content: ''; display: inline-block;
  width: 12px; height: 2px; border-radius: 2px;
  margin-right: 5px; vertical-align: 3px;
}
.bp__key-item--fuel::before  { background: #E08A45; }
.bp__key-item--flue::before  { background: #8C93A6; }
.bp__key-item--water::before { background: #5E93D6; }
.bp__key-item--hot::before   { background: var(--gold); }
.bp__stage.is-grabbing .bp__key { opacity: 0; }

@media (max-width: 700px) {
  /* На узком экране подсказка и ключ дерутся за один угол — ключ
     важнее, подсказку про поворот всё равно проверяют пальцем. */
  .bp__key { max-width: 100%; right: 10px; bottom: 8px; }
  .bp__key-item { font-size: .58rem; }
  .bp__stage .bp__hint { display: none; }
}

.bp__part.is-dim  path { opacity: 0.22; }
.bp__part.is-off  path { opacity: 0.16; }
.bp__part.is-hot  path,
.bp__part.is-on   path { opacity: 1; stroke: var(--gold); }
.bp__part.is-on   path { stroke-width: 2.4; }

.bp__hint {
  position: absolute; left: 14px; bottom: 12px;
  font-size: .7rem; line-height: 1.6; letter-spacing: .1em; text-transform: uppercase;
  color: var(--muted); pointer-events: none;
  transition: opacity var(--dur-base, .25s) var(--ease-out, ease);
}
.bp__stage.is-grabbing .bp__hint { opacity: 0; }

.bp__legend {
  display: flex; flex-wrap: wrap; gap: 10px;
  list-style: none; margin: 0; padding: 0;
}
.bp__chip {
  font-size: .74rem; line-height: 1.2;
  padding: calc(.42rem - 1px) .7rem;
  border-radius: 30px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--muted-lt);
  cursor: pointer;
  white-space: nowrap;
  transition: all var(--dur-fast, .18s) var(--ease-out, ease);
}
.bp__chip::before {
  content: ''; display: inline-block;
  width: 6px; height: 6px; border-radius: 50%;
  margin-right: 7px; vertical-align: 1px;
}
.bp__chip--gold::before  { background: var(--gold-ink); }
.bp__chip--steel::before { background: #9AAAC8; }
.bp__chip--ember::before { background: #D97B3C; }
.bp__chip--dim::before   { background: #6A7A9A; }
.bp__chip:hover { border-color: var(--border-g); color: var(--text); }
.bp__chip.is-on {
  border-color: var(--gold-ink); color: var(--gold-ink);
  background: var(--gold-dim);
}
/* Курсор на узле чертежа — загорается его фишка. Подсветка слабее, чем
   у выбранного: наведение это вопрос «что это такое», выбор — ответ,
   который остаётся на экране. Путать их нельзя. */
.bp__chip.is-hot:not(.is-on) {
  border-color: var(--border-g); color: var(--text);
  background: color-mix(in srgb, var(--gold-ink) 9%, transparent);
}
.bp__chip.is-hot::before { transform: scale(1.5); }
.bp__chip:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

.bp__readout {
  min-height: 2.6em; margin: 0;
  font-size: .84rem; line-height: 1.55; color: var(--muted-lt);
  opacity: 0; transform: translateY(-3px);
  transition: opacity var(--dur-base, .25s) var(--ease-out, ease),
              transform var(--dur-base, .25s) var(--ease-out, ease);
}
.bp__readout.is-on { opacity: 1; transform: none; }

@media (max-width: 700px) {
  .bp__chip { font-size: .72rem; padding: calc(.5rem - 1px) .65rem; }
  .bp__hint { font-size: .64rem; left: 10px; bottom: 8px; }
  /* Девять узлов в столбик занимали пять строк и выдавливали сам
     чертёж за экран. Ставим в одну прокручиваемую ленту — тот же
     приём, что у фильтров каталога. */
  .bp__legend {
    flex-wrap: nowrap;
    min-width: 0;
    max-width: 100%;
    overflow-x: auto;
    overscroll-behavior-x: contain;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    padding-bottom: 2px;
    mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 22px), transparent 100%);
    -webkit-mask-image: linear-gradient(90deg, #000 0, #000 calc(100% - 22px), transparent 100%);
  }
  .bp__legend::-webkit-scrollbar { display: none; }
  .bp__chip { flex: 0 0 auto; }
}

@media (prefers-reduced-motion: reduce) {
  .bp__part path, .bp__readout, .bp__hint { transition: none; }
  /* Пунктир замирает, но остаётся виден: трассы сред — это информация,
     а не украшение, и отнимать её у человека из-за настройки движения
     неправильно. Гасим движение, не смысл. */
  .bp__stage.is-live .bp__flow-line { animation: none; opacity: .75; }
}

/* ═══ Страница модели: плотная раскладка (пилот на «Буран К») ═══
   Вкладки убраны: они брали клик за то, что покупатель обязан видеть
   сразу, и при этом занимали высоту. Всё содержимое встало в две
   колонки, а объяснения заменены связью с чертежом.
   ═══════════════════════════════════════════════════════════════ */
.pdp-grid {
  display: grid;
  grid-template-columns: 1.15fr 1fr;
  gap: 46px;
  align-items: start;
}
.pdp-col { min-width: 0; }
/* Старые ссылки …#specs / #apply вели на вкладки. Вкладок нет, но ссылки
   живут — теперь якоря стоят на заголовках колонок, и отступ нужен,
   иначе цель уезжает под липкую шапку. */
.pdp-h2[id], .pdp-hero__subtitle[id] { scroll-margin-top: calc(var(--nav-h) + 28px); }

.pdp-h2 {
  font-family: var(--font-display);
  font-size: 1.15rem; font-weight: 700;
  letter-spacing: -0.015em;
  margin: 0 0 2px;
}
.pdp-h2--gap { margin-top: 34px; }
.pdp-h2__note {
  font-size: .76rem; color: var(--muted);
  margin: 0 0 12px;
}

/* Таблица, связанная с чертежом */
.spec-table--linked tr.is-linked { cursor: pointer; }
.spec-table--linked tr.is-linked td:first-child { position: relative; padding-left: 18px; }
.spec-table--linked tr.is-linked td:first-child::before {
  content: ''; position: absolute; left: 4px; top: 50%;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--gold-ink); opacity: .45;
  transition: opacity var(--dur-fast, .18s) var(--ease-out, ease),
              transform var(--dur-fast, .18s) var(--ease-out, ease);
}
.spec-table--linked tr.is-linked:hover td:first-child::before,
.spec-table--linked tr.is-linked:focus td:first-child::before { opacity: 1; transform: scale(1.5); }
.spec-table--linked tr.is-linked:hover td,
.spec-table--linked tr.is-linked:focus td { background: var(--gold-dim); color: var(--text); }
.spec-table--linked tr:focus { outline: none; }
.spec-table--linked tr:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }

/* Чипы комплектации и применения */
.pdp-chips {
  display: flex; flex-wrap: wrap; gap: 6px;
  list-style: none; margin: 0 0 10px; padding: 0;
}
.pdp-chip {
  display: inline-block;
  font-size: .78rem; line-height: 1.2;
  padding: calc(.46rem - 1px) .75rem;
  border-radius: 30px;
  border: 1px solid var(--border);
  background: transparent;
  color: var(--muted-lt);
  transition: all var(--dur-fast, .18s) var(--ease-out, ease);
}
button.pdp-chip { cursor: pointer; }
button.pdp-chip.is-linked::before {
  content: ''; display: inline-block;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--gold-ink); margin-right: 7px; vertical-align: 1px;
}
button.pdp-chip:hover { border-color: var(--gold-ink); color: var(--gold-ink); background: var(--gold-dim); }
button.pdp-chip:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }
.pdp-chips--plain .pdp-chip { color: var(--muted-lt); }

.pdp-note {
  font-size: .82rem; line-height: 1.7; color: var(--muted);
  margin: 0; max-width: 46ch;
}

/* Вертикальный ритм: между блоками было по 56px пустоты на каждом
   стыке — четыре стыка съедали четверть экрана ни за чем. */
/* +15% воздуха: первая версия вышла слишком тесной. */
/* Пересмотрено в спейсинг-проходе (мерка 9, 08.09): 30/38px у самой
   секции, это её СОБСТВЕННЫЙ отступ от .pdp-head сверху и от
   .related-section снизу, и по норме прохода (88 to 112px) это уже
   не «плотно», а мало. Ритм между блоками ВНУТРИ .pdp-body (grid-gap
   у .pdp-grid) эта правка не трогает, только внешний край секции. */
.pdp-body { padding-top: 100px; padding-bottom: 100px; }

@media (max-width: 860px) {
  .pdp-grid { grid-template-columns: 1fr; gap: 32px; }
  .pdp-h2--gap { margin-top: 28px; }
  .pdp-body { padding-top: 58px; padding-bottom: 62px; }
  /* На телефоне тап по строке — это выбор, а не наведение: подсветка
     должна залипать, иначе палец её тут же уносит. */
  .spec-table--linked tr.is-linked td { padding-top: 11px; padding-bottom: 11px; }
  .pdp-chip { font-size: .76rem; padding: calc(.52rem - 1px) .7rem; }
}

/* ── Плотный низ страницы модели (пилот на «Буран К») ─────────
   «Другие серии» занимали 1123px на телефоне — четверть страницы на
   два товара, которые покупатель и так найдёт в каталоге. Карточка
   становится строкой: превью слева, суть справа. Смысл сохранён,
   высота втрое меньше. */
/* padding-block пересмотрен в спейсинг-проходе (мерка 9, 08.09): было
   38px, ниже нормы прохода (88 to 112px на 1440). Компактный строчный
   формат карточек ниже (превью+текст в ряд) остаётся, экономилась
   высота самих карточек, а не воздух вокруг секции. */
.pdp-lean .related-section { padding-block: 100px; }
.pdp-lean .related-section h2 { font-size: 1.15rem; margin-bottom: 14px; }
.pdp-lean .related-row { gap: 12px; }

.pdp-lean .related-row .prod-card {
  display: grid;
  grid-template-columns: 132px 1fr;
  align-items: center;
}
/* Превью тянулось на всю высоту строки: снимок 754×566 попадал в рамку
   84×176 и `cover` оставлял от котла вертикальную полоску — узнать в ней
   котёл нельзя. 4:3 — это ровно пропорция самих снимков, поэтому кадр
   не режется вовсе. */
.pdp-lean .related-row .prod-card__img {
  aspect-ratio: 4 / 3; height: auto; min-height: 0;
  align-self: center; border-radius: 10px;
}
.pdp-lean .related-row .prod-card__body { padding: 12px 14px; }
.pdp-lean .related-row .prod-card__subtitle,
.pdp-lean .related-row .prod-card__desc { display: none; }
.pdp-lean .related-row .prod-card__badges { gap: 4px; margin-bottom: 6px; }
.pdp-lean .related-row .prod-card__badge { font-size: .66rem; padding: .1rem .45rem; }
.pdp-lean .related-row .prod-card__name { font-size: 1rem; margin-bottom: 4px; }
.pdp-lean .related-row .prod-card__footer { margin-top: 6px; padding-top: 0; border-top: none; }

.pdp-lean .cta-band { padding-block: 42px; }
.pdp-lean .cta-band h2 { font-size: 1.3rem; margin-bottom: 6px; }
.pdp-lean .cta-band p { margin-bottom: 16px; font-size: .86rem; }

/* Шапка страницы: между хлебными крошками, заголовком и полосой
   параметров стояли отступы, рассчитанные на пустую страницу. */
.pdp-lean .pdp-hero { padding-bottom: 22px; column-gap: 38px; row-gap: 0; }
.pdp-lean .pdp-hero__subtitle { margin-bottom: 16px; }
.pdp-lean .spec-strip { margin-block: 16px; }
.pdp-lean .pdp-price { margin-block: 14px; }

@media (max-width: 900px) {
  .pdp-lean .related-row { grid-template-columns: 1fr; }
  .pdp-lean .pdp-hero { column-gap: 24px; row-gap: 0; padding-bottom: 22px; }
  .pdp-lean .related-section { padding-block: 60px; }
  .pdp-lean .cta-band { padding-block: 32px; }
}
@media (max-width: 768px) {
  /* Ниже 768px .pdp-hero встаёт в один столбец (заголовок, чертёж,
     инфо друг под другом), здесь нужен обычный вертикальный зазор,
     а не row-gap:0 из планшетной колонки выше. */
  .pdp-lean .pdp-hero { row-gap: 24px; }
}

/* Широкий экран (Daniel: «слева пусто, справа тесно»): слева только
   4/3 фото занимало половину сетки, справа в столбик стояли код, имя,
   подзаголовок, полоса характеристик, цена, калькулятор и кнопки —
   пять блоков одной колонкой ниже фото. .pdp-hero__info сама не несёт
   ни паддинга, ни фона (проверено), поэтому display:contents безопасен:
   четыре её потомка становятся собственными элементами сетки со своим
   grid-area, полоса уходит под фото, цена под имя, калькулятор и кнопки
   встают справа рядом с полосой. Ниже 1200px раскладка не меняется.
   Селекторы здесь с .pdp-lean и стоят ПОСЛЕ .pdp-lean .pdp-hero /
   .pdp-lean .spec-strip выше по файлу (та же специфичность, 0,2,0):
   иначе column-gap и margin-top проигрывают им, тот самый gotcha про
   media query и базовое правило равной специфичности. */
@media (min-width: 1200px) {
  .pdp-lean .pdp-hero__info { display: contents; }
  .pdp-lean .pdp-hero {
    grid-template-columns: minmax(0, 1.15fr) minmax(0, 1fr);
    grid-template-areas: "visual title" "visual price" "visual ." "specs calc" "specs cta";
    /* Пустая третья строка забирает лишнюю высоту чертежа: без неё грид
       делил её между строками названия и цены, и цена уезжала вниз,
       оставляя пустоту под подзаголовком. */
    grid-template-rows: auto auto 1fr auto auto;
    column-gap: 56px;
    row-gap: 0;
    align-items: start;
  }
  .pdp-lean .pdp-hero__visual { grid-area: visual; }
  .pdp-lean .pdp-price { grid-area: price; }
  /* .spec-strip делит "specs" с калькулятором на две строки (рамка
     калькулятора обычно выше одной строки характеристик), и без
     align-self:stretch полоса обрывалась на своей высоте (86px), а
     калькулятор с кнопками тянулись заметно ниже — левая колонка
     заканчивалась на 300 до 400px выше правой. Растянутая рамка полосы
     держит тот же фон и паддинг у первой строки, просто ниже неё
     остаётся спокойное поле того же фона вместо резкого обрыва. */
  .pdp-lean .spec-strip { grid-area: specs; margin-top: 20px; align-self: stretch; }
  .pdp-lean .pcalc { grid-area: calc; }
  .pdp-lean .pdp-cta { grid-area: cta; }
}
/* Full HD и шире: 1240px-контейнер оставлял виджет в узком островке
   посреди экрана. 1600px — порог, где это заметно, не раньше. */
@media (min-width: 1600px) {
  .pdp-head .container { max-width: 1360px; }
}
@media (max-width: 480px) {
  .pdp-lean .related-row .prod-card { grid-template-columns: 84px 1fr; }
}

/* Таблица характеристик на телефоне шла кеглем 19,8px — значения не
   помещались в строку, переносились, и десять строк занимали 712px.
   Это не «крупно и читаемо», это просто много места ни за чем. */
@media (max-width: 900px) {
  .pdp-lean .spec-table { font-size: .92rem; }
  .pdp-lean .spec-table td { padding: 10px 10px 10px 8px; line-height: 1.35; }
  .pdp-lean .spec-table td:first-child { width: 44%; }
  .pdp-lean .spec-table--linked tr.is-linked td:first-child { padding-left: 16px; }
  .pdp-lean .pdp-note { font-size: .8rem; }
}

/* Полоса «Мощность / Топливо / Загрузка» на телефоне разворачивалась в
   столбик на 253px — и повторяла первые строки таблицы ниже. Три факта
   дважды на одной странице. Оставляем полосу как быстрый ответ, но в
   одну строку. */
@media (max-width: 1024px) {
  .pdp-lean .spec-strip {
    flex-direction: row;
    display: grid;
    /* minmax(0,1fr), а не 1fr: у `1fr` неявный минимум `auto`, и он
       пропускает вперёд min-width: 120px из базового правила. Три
       колонки требовали 360px там, где под содержимое отведено 353 —
       полоса вылезала вправо и вставала криво: слева отступ 20px,
       справа 11. Ровно тот перекос, который видно глазом. */
    grid-template-columns: repeat(3, minmax(0, 1fr));
  }
  .pdp-lean .spec-strip__item {
    border-bottom: none;
    border-right: 1px solid var(--border);
    padding: 10px 6px;
    min-width: 0;
    text-align: center;
  }
  .pdp-lean .spec-strip__item:last-child { border-right: none; }
  .pdp-lean .spec-strip__label { font-size: .64rem; margin-bottom: 2px; }
  /* Значение самое длинное у мощности («0,5 – 3,0 МВт»). В колонку 117px
     оно влезает впритык, а на 360px экране уже нет — поэтому размер
     привязан к ширине окна и на узких телефонах чуть уменьшается. */
  .pdp-lean .spec-strip__value { font-size: clamp(.72rem, 4vw, .86rem); line-height: 1.25; }
}

/* Характеристики как список пар, а не таблица: в две колонки на
   десктопе он вдвое ниже, и правая колонка страницы перестаёт
   заканчиваться на середине, оставляя пустое поле. Пара термин—
   значение семантически и есть <dl>, так что разметка стала честнее. */
/* auto-fill вместо фиксированных колонок: список сам решает, сколько
   их влезает, и никогда не сжимает пару уже 230px. С жёсткими двумя
   колонками на 768px пары ломались пополам. */
.spec-list {
  margin: 0;
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(270px, 1fr));
  column-gap: 30px;
}
/* Подпись над значением, а не рядом: в колонке ~330px пара
   «Теплоноситель — Вода (незамерзайка)» просто не расходилась по
   горизонтали и слипалась. Сверху вниз читается и уже, и быстрее. */
.spec-item {
  break-inside: avoid;
  padding: 8px 10px 9px 16px;
  border-bottom: 1px solid var(--border);
  position: relative;
}
.spec-item dt {
  color: var(--muted); margin: 0 0 1px;
  font-size: .68rem; font-weight: 600;
  letter-spacing: .09em; text-transform: uppercase;
}
.spec-item dd {
  color: var(--text); font-weight: 600; margin: 0;
  font-size: .95rem; line-height: 1.3;
}
.spec-item.is-linked { cursor: pointer; }
.spec-item.is-linked::before {
  content: ''; position: absolute; left: 4px; top: 17px;
  width: 5px; height: 5px; border-radius: 50%;
  background: var(--gold-ink); opacity: .45;
  transition: opacity var(--dur-fast, .18s) var(--ease-out, ease),
              transform var(--dur-fast, .18s) var(--ease-out, ease);
}
.spec-item.is-linked:hover::before,
.spec-item.is-linked:focus::before { opacity: 1; transform: scale(1.5); }
.spec-item.is-linked:hover, .spec-item.is-linked:focus { background: var(--gold-dim); }
.spec-item:focus { outline: none; }
.spec-item:focus-visible { outline: 2px solid var(--gold); outline-offset: -2px; }

/* ── Переключатель «Чертёж / Фото» ────────────────────────────
   Два ответа на два разных вопроса: как устроено и как выглядит.
   Раньше на странице модели был только первый. */
.bp__views { display: flex; gap: 4px; }
.bp__view {
  font-size: .74rem; font-weight: 600; letter-spacing: .06em; text-transform: uppercase;
  padding: calc(.48rem - 1px) .95rem;
  border: 1px solid var(--border); border-radius: 30px;
  background: transparent; color: var(--muted); cursor: pointer;
  transition: all var(--dur-fast, .18s) var(--ease-out, ease);
}
.bp__view:hover { color: var(--text); border-color: var(--border-g); }
.bp__view.is-on { color: var(--gold-ink); border-color: var(--gold-ink); background: var(--gold-dim); }
.bp__view:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

.bp__photo[hidden], .bp__stage[hidden], .bp__legend[hidden], .bp__readout[hidden] { display: none; }
.bp__photo-btn {
  display: block; width: 100%; padding: 0; border: 1px solid var(--border);
  border-radius: var(--r-lg); overflow: hidden; background: var(--bg2);
  cursor: zoom-in; aspect-ratio: 480 / 340;
}
.bp__photo-btn img { width: 100%; height: 100%; object-fit: cover; display: block; }
.bp__photo-btn:focus-visible { outline: 2px solid var(--gold); outline-offset: 3px; }

/* Лайтбокс снимка */
.bp__lb {
  position: fixed; inset: 0; z-index: 1400;
  display: flex; align-items: center; justify-content: center; padding: 28px 18px;
}
.bp__lb-bg {
  position: absolute; inset: 0; background: rgba(6,8,12,.9);
  backdrop-filter: blur(3px); -webkit-backdrop-filter: blur(3px);
}
.bp__lb img {
  position: relative; z-index: 1;
  max-width: min(94vw, 1100px); max-height: 86vh;
  object-fit: contain; border-radius: var(--r-lg);
  box-shadow: 0 24px 70px rgba(0,0,0,.6);
}
.bp__lb-x {
  position: absolute; top: 16px; right: 16px; z-index: 2;
  width: 44px; height: 44px; border-radius: 50%;
  background: rgba(11,13,18,.82); border: 1px solid rgba(201,164,53,.45);
  color: var(--gold-ink); font-size: 1.5rem; line-height: 1; cursor: pointer;
  display: flex; align-items: center; justify-content: center;
}
.bp__lb-x:hover { background: var(--gold); color: #0B0D12; border-color: var(--gold); }
.bp__lb-x:focus-visible { outline: 2px solid var(--gold); outline-offset: 2px; }

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

/* ═══ Чертежи в разделах ИЗКО ════════════════════════════════
   Здесь чертёж стоит не в шапке товара, а внутри раздела каталога,
   поэтому у него своя обёртка. Ширину держим меньше полной: схема
   принципа, а не главный герой страницы, и спорить с фотографиями
   изделий под ней ей незачем. */
.izko-bp {
  max-width: 720px;
  margin: 0 0 30px;
}
.izko-bp .bp__stage { aspect-ratio: 480 / 340; }
@media (max-width: 700px) {
  .izko-bp { margin-bottom: 22px; }
}

/* Описание раздела ПОД чертежом — для товара, у которого своей отдельной
   фотографии нет, потому что она уже стоит во вкладке «Фото» чертежа.
   Так было у металлоконструкций: снимок цеха показывался дважды подряд,
   первый раз во вкладке, второй — полосой ниже. */
.izko-lead > .izko-bp { margin-bottom: 0; }
.izko-brief { max-width: 78ch; margin-top: 26px; }
.izko-brief > h3 {
  font-family: var(--font-display); font-size: 1.14rem;
  margin: 0 0 10px; line-height: 1.25;
}
.izko-brief > p {
  font-size: .92rem; line-height: 1.65; margin: 0 0 12px; color: var(--muted-lt);
}
.izko-brief .p-meta + .p-meta { margin-top: 6px; }
.izko-brief .srow__cta { margin-top: 18px; }

/* ═══ ЕДИНИЦЫ ПРОКРУТКИ НА ОДНОСТРАНИЧНИКЕ ИЗКО (04.08.2026) ═══════════
   Разделы шли от 1,09 до 3,02 экрана. Любой ровный шаг резал их поперёк
   — та самая ошибка, из-за которой поблочную прокрутку с главной сняли:
   «приходится крутить ещё раз, чтобы прочитать две строки». Порядок
   правильный обратный: сначала блоки СДЕЛАНЫ ростом в экран, и только
   потом скрипт идёт по их границам.

   Разрез у каждого раздела один и тот же и читается как замысел:
   экран с чертежом (как узел устроен) и экран с товарами (что продаём).

   Всё под [data-blockscroll] — атрибут стоит только на этой странице,
   остальной каталог правила не видит. Порог слово в слово тот же, что
   в section-snap.js: ниже него единицы НЕ растянуты, и листать по ним
   значит снова резать содержимое.
   ═══════════════════════════════════════════════════════════════════ */
@media (min-width: 1025px) and (min-height: 800px) {
  [data-blockscroll] { --snap-nav: 60px; }

  /* Отступы раздела уезжают внутрь единиц. Иначе первый и последний
     экран раздела выше остальных ровно на 64px сверху и снизу. */
  [data-blockscroll] .sec { padding-block: 0; }

  [data-blockscroll] .snap-unit {
    min-height: calc(100vh - var(--snap-nav));
    box-sizing: border-box;
    display: flex; flex-direction: column; justify-content: center;
    padding-block: clamp(0.5rem, 1.6vh, 1.6rem);
  }

  /* Чертёж — самая крупная деталь экрана, он и решает, влезет ли
     единица. Пропорцию держит aspect-ratio, поэтому ограничиваем не
     высоту, а ШИРИНУ по бюджету высоты: схема не перерастает окно и
     при этом остаётся собой, без сплющивания. */
  [data-blockscroll] .izko-bp {
    --bp-h: clamp(290px, 48vh, 620px);
    max-width: 100%;
    margin-bottom: 0;
  }
  /* Ширину режем у ХОЛСТА, а не у всего блока. Когда ограничение стояло
     на обёртке, вместе с холстом сужалась и легенда: семь фишек на 384px
     складывались в пять строк, и блок терял на подписях ровно столько,
     сколько выигрывал на чертеже (замер: 519px против 531px при вдвое
     меньшем холсте — то есть лечение не работало вовсе). Теперь фишки
     идут во всю ширину раздела и укладываются в одну-две строки. */
  [data-blockscroll] .izko-bp .bp__stage,
  [data-blockscroll] .izko-bp .bp__views,
  [data-blockscroll] .izko-bp .bp__photo {
    width: min(100%, calc(var(--bp-h) * 480 / 340));
  }
  /* Два раздела, где чертёж делит экран с текстом, а не стоит на нём
     один: у «доп. оборудования» под ним полоса-призыв, у металла —
     описание с характеристиками (своей фотографии у металла нет, она
     во вкладке чертежа). Бюджет высоты у обоих меньше. */
  [data-blockscroll] #dop-oborudovanie .izko-bp {
    --bp-h: clamp(240px, 34vh, 420px);
    margin-bottom: clamp(0.8rem, 2.4vh, 2rem);
  }

  /* Вертикальный ритм — от высоты окна, а не в фиксированных пикселях:
     на ноутбуке 1366×768 и на мониторе 1440×1080 одни и те же 32px
     значат разное. */
  [data-blockscroll] .sec__head { margin-bottom: clamp(0.7rem, 2.2vh, 2rem); }
  [data-blockscroll] .sec__lede { margin-bottom: clamp(0.7rem, 2.2vh, 2rem); }

  /* ── экран товаров ── */
  [data-blockscroll] .srow + .srow { margin-top: clamp(16px, 3vh, 56px); }
  /* Высота фотографии тоже от окна. Пропорцию 4:3 отпускаем сознательно:
     кадр обрезается object-fit, а не сплющивается. */
  [data-blockscroll] .srow__media {
    aspect-ratio: auto; height: clamp(200px, 38vh, 460px);
  }
  /* Один товар на экране — ему можно и колонку пошире, и кадр покрупнее;
     двум нельзя, иначе пара не уложится. :only-of-type считает за нас.
     Колонка меняется вместе с высотой: если растить только высоту,
     из кадра 4:3 получается вертикальная щель, и у изделия срезает бока. */
  [data-blockscroll] .srow:only-of-type {
    grid-template-columns: minmax(0, 7fr) minmax(0, 5fr);
  }
  [data-blockscroll] .srow:only-of-type .srow__media {
    height: clamp(360px, 64vh, 720px);
  }
  /* Описание становится РЯДОМ с чертежом, а не под ним. Под ним оно
     добавляло ~218px, и раздел переставал влезать в экран; справа от
     чертежа оно не стоит ничего — там и так была пустота, потому что
     ширину холста держит бюджет высоты. Легенда при этом теряет часть
     ширины и переносится в две строки — это дешевле на полторы сотни
     пикселей, чем описание отдельной строкой. */
  [data-blockscroll] .izko-lead {
    display: grid;
    grid-template-columns: minmax(0, 1fr) minmax(0, clamp(240px, 26vw, 360px));
    gap: clamp(20px, 2.6vw, 44px);
    align-items: start;
  }
  [data-blockscroll] .izko-lead > .izko-brief { margin-top: 0; }
  [data-blockscroll] .izko-brief { margin-top: clamp(14px, 2.4vh, 26px); }
  [data-blockscroll] .izko-brief > p { margin-bottom: clamp(6px, 1.2vh, 12px); }
  [data-blockscroll] .izko-brief .srow__cta { margin-top: clamp(10px, 1.8vh, 18px); }

  /* Четыре карточки в ряд. В две строки они дают 1288px — полтора
     экрана, и нижняя пара всегда оставалась за краем. */
  /* auto-fit, а не фиксированные четыре: изделие, которое рисует чертёж,
     переехало наверх, и в сетке осталось три карточки. Четыре жёстких
     колонки оставляли бы четвёртую пустой дырой справа; auto-fit пустые
     дорожки схлопывает, и три карточки честно делят ширину. */
  [data-blockscroll] .sec-grid {
    grid-template-columns: repeat(auto-fit, minmax(min(200px, 100%), 1fr));
    gap: clamp(12px, 1.2vw, 20px);
  }
  [data-blockscroll] .sec-grid .scard__body { padding: clamp(12px, 2vh, 20px) 18px clamp(14px, 2.2vh, 22px); }
  [data-blockscroll] .sec-grid .scard__body h3 { font-size: clamp(.95rem, 2vh, 1.1rem); margin-bottom: clamp(6px, 1.1vh, 10px); }
  [data-blockscroll] .sec-grid .scard__body p { font-size: clamp(.79rem, 1.7vh, .88rem); }
  [data-blockscroll] .sec-grid .scard__body .srow__cta { padding-top: clamp(10px, 1.6vh, 16px); }

  /* ── полосы ── */
  [data-blockscroll] .sec-band__inner { padding-block: clamp(18px, 3vh, 30px); }
  [data-blockscroll] .sec-band--dop { padding: clamp(16px, 2.6vh, 26px) 24px; }

  /* Последний экран — призыв. Он короче прочих по содержанию, и это
     нормально: на выходе из страницы пустота вокруг одной фразы читается
     как точка, а не как недосмотр. */
  [data-blockscroll] .cta-band.snap-unit { padding-block: clamp(1.5rem, 7vh, 6rem); }
}

/* ═══ ОДИН ПРИЗЫВ ВМЕСТО ДВУХ (03.08.2026) ══════════════════════════════
   Было: у каждого товара «Уточнить цену» и «Заказать» рядом, одинакового
   веса. Обе вели к разговору с человеком, но обещали разное — первая цену,
   вторая заказ. Кто это замечал, переставал верить подписям.

   Считано на живом сайте, ширина телефона: витрина каталога — 43 призыва
   на страницу (20 «Уточнить цену», 20 «Подробнее» в двух написаниях),
   одностраничник ИЗКО — 23. Двадцать одинаковых золотых кнопок подряд это
   не двадцать шансов, а обои: по обоям не кликают.

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

/* Цена на карточке — не кнопка и не бейдж, просто заметная строка. */
.p-price {
  flex: 1;
  font-family: var(--font-display);
  font-size: .95rem; font-weight: 700;
  color: var(--gold-ink); letter-spacing: .01em;
  white-space: nowrap;
}
.srow__cta .p-price { flex: 0 0 auto; margin-right: auto; }

/* Пояснение под ценой: без него «от» выглядит уловкой. */
.pdp-price__note {
  margin-top: 10px; max-width: 46ch;
  font-size: .82rem; line-height: 1.7; color: var(--muted);
}

/* Телефон строкой. 44px по высоте — палец, а не мышь. */
.cta-phone {
  margin-top: 12px;
  font-size: .86rem; line-height: 1.7; color: var(--muted);
}
.cta-phone a {
  color: var(--gold-ink); font-weight: 600;
  text-decoration: none; border-bottom: 1px solid var(--border-g);
  padding: 4px 0; display: inline-block; min-height: 24px;
}
.cta-phone a:hover { border-bottom-color: var(--gold); }

/* Один призыв — значит колонка, а не два в ряд. */
.pdp-cta { flex-direction: column; align-items: flex-start; gap: 0; }
.pdp-cta .btn-primary { min-height: 48px; }

/* Липкая полоса на телефоне: кнопка и номер, а не две кнопки. */
.pdp-mobile-cta__tel {
  flex: 0 0 auto; display: inline-flex; align-items: center;
  min-height: 44px; padding: 0 .9rem;
  font-family: var(--font-display); font-size: .9rem; font-weight: 700;
  color: var(--gold-ink); text-decoration: none;
  border: 1px solid var(--border-g); border-radius: var(--r);
}
@media (max-width: 560px) {
  .p-cta { row-gap: .35rem; }
  .p-price { flex: 1 0 100%; white-space: normal; }
  .pdp-price__note { font-size: .78rem; }
}

/* Полоса уезжает вниз, пока основная кнопка на экране. */
.pdp-mobile-cta {
  transition: transform .28s var(--ease-out, ease), opacity .28s var(--ease-out, ease);
}
.pdp-mobile-cta.is-away {
  transform: translateY(115%); opacity: 0; pointer-events: none;
}
@media (prefers-reduced-motion: reduce) {
  .pdp-mobile-cta { transition: none; }
}

/* ── Правовая страница (Пользовательское соглашение) ─────────── */
.legal {
  max-width: 760px;
  margin: 0 auto;
  padding: 8px 0 64px;
}
.legal h2 {
  font-family: var(--font-display);
  font-size: 1.3rem;
  color: var(--text);
  margin: 2.2rem 0 .7rem;
}
.legal h2:first-child { margin-top: 0; }
.legal p {
  color: var(--muted-lt);
  line-height: 1.65;
  margin: 0 0 .85rem;
}
.legal p strong { color: var(--text); }
.legal .legal-updated {
  margin-top: 2.4rem;
  padding-top: 1.2rem;
  border-top: 1px solid var(--border);
  font-size: .85rem;
  color: var(--muted);
}

/* ── Согласие на обработку персональных данных ────────────────── */
.consent-row {
  display: flex;
  align-items: flex-start;
  gap: .55rem;
  margin: 4px 0 16px;
}
.consent-row input[type="checkbox"] {
  flex: 0 0 auto;
  width: 20px; height: 20px;
  margin-top: 1px;
  accent-color: var(--gold);
  cursor: pointer;
}
.consent-row label {
  font-size: .86rem;
  line-height: 1.5;
  color: var(--muted-lt);
  cursor: pointer;
}
.consent-row a { color: var(--gold-ink); text-decoration: underline; }
.submit-btn:disabled {
  opacity: .5;
  cursor: not-allowed;
}

/* ═══ Прикидка цены по мощности ═══════════════════════════════════
   Ползунок живёт под блоком цены на странице изделия. Логика и
   происхождение чисел — в `catalog/js/power-calc.js`.

   Воздуха намеренно много. Блок соседствует с ценой и кнопкой заказа,
   то есть стоит ровно в той точке, где посетитель решает, писать ему
   или закрывать вкладку. Плотная вёрстка здесь читается как мелкий
   шрифт в договоре. */
.pcalc {
  margin: 0 0 28px;
  padding: 22px 22px 20px;
  border: 1px solid var(--border);
  border-radius: var(--r-lg);
  background: var(--card);
}
.pcalc[hidden] { display: none; }

.pcalc__eyebrow {
  font-family: var(--font-body);
  font-size: 0.74rem;
  font-weight: 500;
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: var(--muted);
  margin: 0 0 14px;
}

.pcalc__readout {
  display: flex;
  align-items: baseline;
  gap: 8px;
  margin-bottom: 14px;
}
.pcalc__power {
  font-family: var(--font-display);
  font-size: 2.1rem;
  font-weight: 800;
  line-height: 1;
  color: var(--gold-ink);
  font-variant-numeric: tabular-nums;
}
.pcalc__unit {
  font-family: var(--font-body);
  font-size: 0.9rem;
  color: var(--muted-lt);
}

/* ── Сам ползунок ──────────────────────────────────────────────
   Заливка до ручки рисуется градиентом по --pc-fill, который ставит
   скрипт. Это дешевле лишнего элемента и переживает смену темы. */
.pcalc__range {
  -webkit-appearance: none;
  appearance: none;
  display: block;
  width: 100%;
  height: 22px;
  margin: 0;
  background: transparent;
  cursor: pointer;
}
.pcalc__range::-webkit-slider-runnable-track {
  height: 4px;
  border-radius: 2px;
  background: linear-gradient(to right,
              var(--gold) 0, var(--gold) var(--pc-fill, 35%),
              var(--border) var(--pc-fill, 35%), var(--border) 100%);
}
.pcalc__range::-moz-range-track {
  height: 4px;
  border-radius: 2px;
  background: var(--border);
}
.pcalc__range::-moz-range-progress {
  height: 4px;
  border-radius: 2px;
  background: var(--gold);
}
.pcalc__range::-webkit-slider-thumb {
  -webkit-appearance: none;
  appearance: none;
  width: 18px;
  height: 18px;
  margin-top: -7px;
  border: 0;
  border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 0 4px var(--gold-dim);
  transition: box-shadow var(--trans);
}
.pcalc__range::-moz-range-thumb {
  width: 18px;
  height: 18px;
  border: 0;
  border-radius: 50%;
  background: var(--gold);
  box-shadow: 0 0 0 4px var(--gold-dim);
  transition: box-shadow var(--trans);
}
.pcalc__range:hover::-webkit-slider-thumb,
.pcalc__range:focus-visible::-webkit-slider-thumb { box-shadow: 0 0 0 7px var(--gold-glow); }
.pcalc__range:hover::-moz-range-thumb,
.pcalc__range:focus-visible::-moz-range-thumb { box-shadow: 0 0 0 7px var(--gold-glow); }
.pcalc__range:focus { outline: none; }
.pcalc__range:focus-visible { outline: 2px solid var(--gold); outline-offset: 6px; border-radius: 4px; }

.pcalc__scale {
  display: flex;
  justify-content: space-between;
  font-family: var(--font-body);
  font-size: 0.78rem;
  color: var(--muted);
  margin: 2px 0 20px;
}

.pcalc__price {
  font-family: var(--font-display);
  font-style: normal;
  font-size: 2.1rem;
  font-weight: 400;
  line-height: 1.15;
  color: var(--text);
  margin: 0 0 6px;
  font-variant-numeric: tabular-nums;
}
.pcalc__fork {
  font-family: var(--font-body);
  font-size: 0.86rem;
  color: var(--muted-lt);
  margin: 0 0 14px;
}
.pcalc__note {
  font-family: var(--font-body);
  font-size: 0.8rem;
  line-height: 1.65;
  color: var(--muted);
  margin: 0;
  max-width: 46ch;
}

@media (max-width: 560px) {
  .pcalc { padding: 18px 16px 16px; }
  .pcalc__power { font-size: 1.8rem; }
  .pcalc__price { font-size: 1.75rem; }
}

/* Ручка ездит без анимации у тех, кто просил её отключить. */
@media (prefers-reduced-motion: reduce) {
  .pcalc__range::-webkit-slider-thumb,
  .pcalc__range::-moz-range-thumb { transition: none; }
}

/* ═══ НИЗ СТРАНИЦ КАТАЛОГА: контакты внутри полосы-призыва ═════════
   Та же ось, что у #contact на главной, только уже и без формы: заявку
   принимает главная, здесь ссылка на неё. Отдельной секции нет намеренно
   — второй блок с тем же номером под первым читается как ошибка вёрстки,
   а не как забота. */
.cta-band__contact { justify-self: start; }
.cta-band--split .cta-band__inner { grid-template-columns: .95fr 1.05fr; }
/* Колонки равняются по верху: знак и надпись-указатель должны начинаться
   с одной линии. По центру они разъезжались на 75px, и блок читался
   как две несвязанные половины. */
.cta-band--split .cta-band__inner { align-items: start; }
.cta-band--split .cta-band__note { display: block; }

.foot-contact__eyebrow {
  display: flex; align-items: center; gap: 0.9rem;
  margin: 0 0 1rem;
  font-family: var(--font-body);
  font-size: 0.7rem; letter-spacing: 0.22em; text-transform: uppercase;
  color: var(--muted);
}
.foot-contact__eyebrow::after {
  content: ''; flex: 1; height: 1px; background: var(--border-g);
}

/* Ширина живёт на обёртке <picture>, не на картинке: инлайновый бокс
   без width до загрузки резервирует 0 места и роняет всё под собой —
   это и был CLS 0.15 на главной, грабли задокументированы там же. */
.foot-contact__badge-wrap {
  display: block;
  width: clamp(96px, 8vw, 124px);
  margin: 0 0 1.1rem;
}
.foot-contact__badge {
  width: 100%; height: auto;
  aspect-ratio: 1 / 1;
  border-radius: 50%;
  display: block;
  border: 1px solid var(--border-g);
}

.foot-contact__meta {
  margin: 1.1rem 0 0;
  font-family: var(--font-body);
  font-size: 0.86rem;
  line-height: 1.7;
  color: var(--muted-lt);
}
.foot-contact__meta a { color: var(--muted-lt); text-decoration: none; transition: color 0.25s; }
.foot-contact__meta a:hover { color: var(--gold-ink); }

/* Номер не переносится: «+7 (800) 707-81-» и «14» на второй строке —
   это уже не номер, а два обрывка. */
.cta-band__phone { white-space: nowrap; }

@media (max-width: 860px) {
  .cta-band--split .cta-band__inner { grid-template-columns: 1fr; }
  .foot-contact__badge-wrap { width: 92px; }
  /* В одну колонку порядок разметки становится порядком чтения, а там
     контакты идут первыми — они стоят слева. Сначала должно читаться,
     о чём речь, поэтому на узком экране заголовок поднимается наверх. */
  .cta-band--split .cta-band__txt     { order: -1; }
  .cta-band--split .cta-band__contact { order: 0; }
}

/* ═══ ВЕС И РАЗРЯДКА ══════════════════════════════════════════════
   Иерархию держит только вес, поэтому ступень между текстом и
   заголовком должна быть заметной. Montserrat шире Oswald при том же
   кегле — крупным заголовкам нужна отрицательная разрядка, иначе
   строка набирает лишнюю ширину и переносится не там. */
h1, h2, h3, .pdp-hero__title, .cat-head__title, .sec__title,
.p-name, .pdp-price__amount, .pcalc__price, .scard__title {
  font-weight: 800;
  letter-spacing: -0.02em;
}
h4, h5, h6, .ci-lbl, .pdp-price__eyebrow, .pcalc__eyebrow { font-weight: 700; }
strong, b { font-weight: 700; }

/* ═══ ПРОВЕРКА НА МЕСТЕ ПО ОТЧЁТУ QA (04.09) ═════════════════════

   Отчёт описал находку M01 как «кнопка вылезает посреди заголовка в
   WebKit». Это артефакт съёмки: полоса объявлена position:fixed, а
   полностраничный снимок сшивается из экранов и оставляет такие
   элементы там, где их застала прокрутка. Но проверка самой полосы
   нашла две настоящие ошибки, которых в отчёте нет, и обе на всех
   десяти страницах изделий. Первая лечится в разметке (надпись стала
   короче), вторая здесь. ═══════════════════════════════════════ */

/* Под полосу не был отведён отступ. Она fixed высотой 73px, а у
   страницы padding-bottom нулевой, поэтому последний блок каждой
   страницы изделия навсегда оставался под ней и дочитать его было
   нельзя. Тот же класс ошибки, что отчёт нашёл на demo-b, только там
   он попал в находки, а здесь нет. Граница та же, на которой полоса
   появляется. */
@media (max-width: 768px) {
  body:has(.pdp-mobile-cta) { padding-bottom: 84px; }
}

/* Зоны нажатия, которые не захватил общий блок выше: фишки чертежа,
   переключатель «Чертёж / Фото» и фишки характеристик, 34-40px по
   высоте. Растёт зона, а не рисунок: на вид фишка остаётся прежней, а
   нажатие ловит псевдоэлемент, растянутый до 44px по вертикали. Ряды
   фишек переносятся, поэтому самому ряду даём зазор по вертикали,
   иначе соседние зоны налезают друг на друга и перехватывают
   нажатие. */
@media (pointer: coarse) {
  .bp__legend, .bp__views, .pdp-chips { row-gap: .85rem; }
  .bp__chip, .bp__view, .pdp-chip { position: relative; }
  .bp__chip::after, .bp__view::after, .pdp-chip::after {
    content: '';
    position: absolute;
    left: 0; right: 0; top: 50%;
    height: var(--tap);
    transform: translateY(-50%);
  }
  /* Ползунок мощности: по горизонтали промахнуться трудно, он во всю
     ширину, а вот 22px по вертикали мало. Ручку не трогаем: её
     margin-top считается от дорожки, а не от высоты поля. */
  .pcalc__range { height: var(--tap); }
}

/* Страховка от переполнения на самых узких экранах: раньше здесь шрифт
   и паддинг кнопки на ≤400px незаметно РОСЛИ (.78rem→.82rem), то есть
   правило только усугубляло обрезание надписи. Теперь оба элемента
   полосы получают меньший шрифт и паддинг, а сама полоса, меньшие
   отступы и зазор, чтобы освободить место под текст кнопки. */
@media (max-width: 400px) {
  .pdp-mobile-cta { padding-inline: 10px; gap: 6px; }
  .pdp-mobile-cta .btn-primary,
  .pdp-mobile-cta .btn-secondary { font-size: .72rem; padding-inline: .5rem; }
  .pdp-mobile-cta__tel { font-size: .78rem; padding-inline: .55rem; }
}

/* Ниже 360px строка «Рассчитать цену» не помещается даже с урезанными
   отступами: слово «Цена» короче и полностью верно передаёт действие
   в контексте кнопки рядом с номером телефона. Технически, два span,
   один скрыт медиазапросом, а не JS: JS применяет класс reveal по
   списку селекторов, и ручной .reveal без записи в списке остался бы
   invisible навсегда (см. заметку в catalog.js). */
.cta-order__short { display: none; }
@media (max-width: 359px) {
  .cta-order__full { display: none; }
  .cta-order__short { display: inline; }
}

/* ── Опросный лист на странице котельной ────────────────────────────────
   Проектировщики звонить не любят: им проще скачать бланк, заполнить и
   получить в ответ КП. Строчкой мелкого текста бланк никто не замечал.
   Контурная, не золотая: заливка на странице одна и принадлежит кнопке
   «Рассчитать стоимость». */
.opros--pdp {
  display: block; margin-top: .85rem;
  padding: .8rem 1.05rem; border-radius: var(--r-md);
  border: 1px solid var(--border-g); text-decoration: none;
  transition: background .2s, border-color .2s;
}
.opros--pdp:hover { background: var(--gold-dim); border-color: var(--gold-ink); }
.opros--pdp .opros__t { display: block; font-weight: 700; font-size: .9rem; color: var(--gold-ink); }
.opros--pdp .opros__s { display: block; font-size: .76rem; color: var(--muted-lt); line-height: 1.45; margin-top: .15rem; }

/* ── Светлая тема: фото разделов ИЗКО без серой вуали (замечание Алексея, 09.09) ──
   saturate(.92) и тёмная плёнка ::after задумывались под тёмный фон; на белом
   они читаются как серый фильтр и гасят цвет. В светлой теме отключаем. */
[data-theme="light"] .srow__media img,
[data-theme="light"] .scard__media img,
[data-theme="light"] .sec-band__img { filter: none; }
[data-theme="light"] .srow__media::after,
[data-theme="light"] .scard__media::after { background: transparent; }
