/* VOLZAR: собран автоматически из ds/tokens/*.css и ds/site.css.
   Руками не править, правку затрёт node build/render.mjs. */

/* VOLZAR - Webfonts

   Лицензионных файлов шрифтов заказчик не давал. Берём ближайшие
   с Google Fonts: Montserrat для заголовков, Inter для текста.
   Обе гарнитуры полноценно закрывают кириллицу.

   Раньше здесь лежали @font-face с прямыми ссылками на fonts.gstatic.com.
   Так делать нельзя по двум причинам:
   1. Ссылка привязана к версии семейства (v29), при обновлении она умирает.
   2. Без unicode-range браузер не знает, какие буквы внутри файла,
      и тянет его целиком. Montserrat 700 и 800 к тому же указывали
      на один и тот же файл, то есть ExtraBold фактически не грузился,
      хотя все заголовки на сайте капсом и по-русски.

   Теперь шрифты подключаются одной ссылкой в <head>, см. build/lib/layout.mjs.
   Google отдаёт нужный формат под конкретный браузер и раскладывает
   семейство по unicode-range, поэтому латинская часть для русской
   страницы не скачивается вовсе.

   Если заказчик пришлёт лицензионные файлы: положить их
   в site/ds/assets/fonts/, вернуть сюда @font-face со своими путями
   и убрать ссылку на Google из layout.mjs. Больше ничего менять не нужно,
   имена семейств в typography.css те же. */

/* VOLZAR — цветовые токены
   Принцип: высокий контраст, тиловые «острова» на светлом фоне.
   Без градиентов, без размытых теней.

   КОНТРАСТ. Фирменный тил #2C9991 с белым текстом даёт 3.46:1, это ниже
   порога WCAG AA для обычного текста (4.5:1). Поэтому ramp разведён:
     --blue-500 #2C9991 — фирменный. Декор: бары, точки, лого, рамки,
                          крупные заголовки от 24px, иконки.
     --blue-600 #247E77 — рабочий. Сплошной белый текст: кнопки, шапки
                          таблиц, пилюли. 4.85:1, AA пройден.
     --blue-650 #1F6B65 — поверхности, где белый текст полупрозрачный:
                          тиловые острова. При белом 80 % даёт 4.65:1.
   Не заливать мелкий белый текст на --blue-500.

   ПРАВКА 28.07.2026 по аудиту. Пять пар были ниже AA. Дыра была не в тиле,
   а в двух местах, которые не пересчитывали: полупрозрачный белый поверх
   тила и мелкий тил на светлом тинте. Значения ниже проверяются машиной
   в build/check.mjs, раздел «контраст объявленных пар».

   ПРАВКА 29.07.2026, разбор «сайт блеклый». Замер показал, что все семь
   фоновых токенов лежали в полосе светлоты L* 89-100, то есть страница
   делила себя на части разницей, которой глаз не видит: белый против
   --sand-100 давал 1.16:1, белый против --blue-050 всего 1.08:1.
   Сделано три вещи.

   1. --sand-100 углублён с #ECEFF0 до #E4E9EB. Разница с белым выросла
      с ΔL* 5.7 до 8.0. Дальше двигать нельзя: --graphite-500 на нём
      даёт 4.65:1, а на следующем шаге #E0E6E8 уже 4.52 и запаса нет.

   2. --blue-050 выведен из чередования секций. Он на 3.0 ΔL* от белого
      и на 2.8 от песочного, то есть был третьим фоном, неотличимым
      от двух других. Остаётся как подложка мелких элементов.

   3. АМБЕР ВВЕДЁН В РАБОТУ. Он лежал в токенах с пометкой «акцент»
      и не был использован ни разу: ноль вхождений в site.css и в разметку.
      Правило его применения жёсткое и выведено из замера, а не из вкуса:
      #FFC734 на белом даёт 1.56:1, на песочном 1.35:1, то есть тонкой
      линией на светлом фоне он не виден вовсе. Затемнять его до читаемого
      на белом (нужен #A67608) значит получить коричневый, а не акцент.
      Поэтому:
        амбер ставится ТОЛЬКО на плотный фон либо заливкой под тёмный текст.
        На тиле --blue-650 он даёт 4.02:1, на графите 8.9:1, а графитовый
        текст на самом амбере 10.54:1. Все три выше порога.
        Амбером НИКОГДА не набирается текст: даже --amber-600 на белом
        это 2.02:1.
      Где он стоит: кромка полосы фактов, кромка полосы призыва, маркеры
      списков на тиловых островах, бейдж --badge--accent. */
:root {
  /* ---- Фирменный тил ---- */
  --blue-500: #2C9991;   /* основной фирменный */
  --blue-600: #247E77;   /* hover + поверхности со сплошным белым текстом */
  --blue-650: #1F6B65;   /* острова: белый 80 % на них проходит AA */
  --blue-700: #1C635E;   /* pressed, глубокий, редко */
  --blue-100: #DDEEEC;   /* тинт-поверхность */
  --blue-050: #F1F8F7;   /* самый светлый тинт */

  /* ---- Нейтральные ---- */
  --white:     #FFFFFF;
  --sand-050:  #F5F7F7;  /* почти белый, холодный. Мелкие подложки, не секции */
  --sand-100:  #E4E9EB;  /* холодно-серый фон секций. Был #ECEFF0: 1.16:1
                            к белому, чередование секций не читалось */
  --sand-200:  #DCE1E3;  /* волосяные границы */
  --sand-300:  #C6CDD0;  /* граница поплотнее */
  --graphite-900: #1B2024; /* основной текст */
  --graphite-700: #3B4348; /* вторичный текст */
  --graphite-500: #5F686D; /* подписи. Был #6B7479: на песочном фоне
                              давал 4.13, ниже AA. Теперь 4.93 */
  --graphite-300: #A3ABAF; /* disabled */

  /* ---- Тил вторичный (шапки таблиц, мелкие метки) ---- */
  --teal-500: #2C9991;
  --teal-600: #247E77;
  --teal-100: #DDEEEC;

  /* ---- Функциональные ---- */
  --green-500: #1F9D57;  /* экономия, «да» */
  --green-100: #E4F5EC;
  --red-500:   #C93B3B;  /* недостаток OEM, «нет», текст ошибки формы.
                            Был #D64545: 4.38 на белом, ниже AA. Теперь 5.03 */
  --red-100:   #FBEAEA;
  /* Амбер. Только заливка и кромка, только на плотном фоне.
     Текстом не набирается ни в одном размере, см. шапку файла. */
  --amber-500: #FFC734;  /* кромки и маркеры на тиле и графите */
  --amber-600: #E5AE1C;  /* нажатое состояние амберных элементов */
  --amber-100: #FFF4D6;  /* заливка бейджа, текст на ней графитовый */

  /* ---- Семантические алиасы ---- */
  --surface-page:       var(--white);
  --surface-alt:        var(--sand-100);   /* чередующиеся секции */
  --surface-card:       var(--white);
  --surface-island:     var(--blue-650);   /* тил-блоки: внутри белый текст,
                                              часть его полупрозрачная */
  --surface-tint:       var(--blue-050);
  --surface-disabled:   var(--sand-100);

  --text-strong:        var(--graphite-900);
  --text-body:          var(--graphite-700);
  --text-muted:         var(--graphite-500);
  --text-on-blue:       var(--white);
  --text-on-blue-soft:  rgba(255,255,255,0.80);
  --text-link:          var(--blue-600);

  --border-subtle:      var(--sand-200);
  --border-strong:      var(--sand-300);
  --border-on-blue:     rgba(255,255,255,0.28);

  --accent:             var(--blue-600);   /* кнопки: белый текст, нужен AA */
  --accent-hover:       var(--blue-700);
  --accent-contrast:    var(--white);
  /* Был var(--blue-500). Переведён на --blue-600 29.07 вместе с углублением
     --sand-100: на новом песочном фоне тил-500 даёт 2.82:1, а порог для
     графических объектов 3:1, то есть засечки, маркеры и кольца фокуса
     на песочных секциях перестали бы его проходить. Тил-500 остаётся
     сам по себе и годится там, где размер снимает вопрос: текст от 24px
     и заливки. Мелкое и тонкое берёт --blue-600. */
  --accent-brand:       var(--blue-600);   /* декор без текста */

  /* Разделение работ между двумя цветами. Держать его строго, иначе
     вернётся исходная беда: когда выделено всё, не выделено ничего.
       тил  = куда нажать (кнопка, ссылка, поле в фокусе)
       амбер = куда смотреть (кромка, маркер, бейдж), и только на плотном фоне */
  --accent-mark:        var(--amber-500);
  --on-amber:           var(--graphite-900); /* 10.54:1, единственный текст,
                                                допустимый на амбере */
  --table-head:         var(--blue-600);
  --table-stripe:       var(--sand-050);
}

/* VOLZAR - Typography tokens
   Display: Montserrat ExtraBold, UPPERCASE, tight tracking.
   Body: Inter, normal case. Строгая шкала, дробных кеглей нет.

   Кегли в rem от базы 16px, а не в px: иначе текст не слушается системной
   настройки размера шрифта. Правила и чек-лист: .claude/skills/типографика-и-ритм.
   Перевод: 12=0.75, 14=0.875, 15=0.9375, 16=1, 18=1.125, 20=1.25, 24=1.5. */
:root {
  /* ---- Families ---- */
  --font-display: "Montserrat", "Inter", system-ui, sans-serif; /* @kind font */
  --font-body:    "Inter", system-ui, -apple-system, "Segoe UI", sans-serif; /* @kind font */

  /* ---- Weights ---- */
  --fw-regular: 400; /* @kind font */
  --fw-medium:  500; /* @kind font */
  --fw-semibold:600; /* @kind font */
  --fw-bold:    700; /* @kind font */
  --fw-extra:   800; /* @kind font */

  /* ---- Display scale (Montserrat, uppercase) ----
     ПРАВКА 28.07.2026 по замечаниям заказчика. Шкала опущена на ступень.
     Причина не вкусовая: заголовки набраны капсом ExtraBold, а капс читается
     примерно на четверть медленнее строчных при равном кегле. Прежний H1
     в 52px давал на первом экране пять строк капса, и первое, что делал
     глаз, это не читал их, а пытался охватить. Верхняя граница снята
     до 40px, множитель vw с 4.2 до 3.4: на 1440px H1 теперь 40, а не 52.
     Нижние границы почти не двигались, на телефоне размеры были нормальные. */
  --fs-display:  clamp(2.5rem, 5vw, 4rem);       /* 40-64 */ /* @kind font */
  --fs-h1:       clamp(1.75rem, 3.4vw, 2.5rem);  /* 28-40 */ /* @kind font */
  --fs-h2:       clamp(1.5rem, 2.6vw, 2rem);     /* 24-32 */ /* @kind font */
  --fs-h3-lg:    1.375rem; /* 22 */ /* @kind font */
  --fs-h3:       1.125rem; /* 18 */ /* @kind font */
  --fs-eyebrow:  0.875rem; /* 14 */ /* @kind font */

  /* ---- Body scale (Inter) ----
     Лид опущен с 20 на 18. При 20px и мере 58ch абзац под заголовком
     весил визуально столько же, сколько сам заголовок, и первый экран
     читался как сплошная плита текста. */
  --fs-lead:     1.125rem;  /* 18 */ /* @kind font */
  --fs-md:       1.125rem;  /* 18 */ /* @kind font */
  --fs-body:     1rem;      /* 16 */ /* @kind font */
  --fs-sm:       0.9375rem; /* 15 */ /* @kind font */
  --fs-xs:       0.875rem;  /* 14, пол для текста без капса */ /* @kind font */
  /* 12px разрешён ровно одному случаю: uppercase плюс letter-spacing от 0.08em.
     Такая надпись читается как ярлык, а не как текст. Для всего остального
     пол это --fs-xs. */
  --fs-caps:     0.75rem;   /* 12 */ /* @kind font */

  /* ---- Line heights ---- */
  --lh-tight:    1;    /* @kind font */
  --lh-heading:  1.12; /* @kind font */
  --lh-snug:     1.3;  /* @kind font */
  --lh-body:     1.55; /* @kind font */

  /* ---- Letter spacing ---- */
  --ls-display:  -0.01em; /* @kind font */
  --ls-heading:  0.01em;  /* @kind font */
  --ls-caps:     0.08em;  /* @kind font */
  --ls-caps-wide:0.14em;  /* @kind font */

  /* ---- Длина строки ----
     1ch это ширина знака «0», а она шире среднего знака. Замер на volzar.kz
     28.07.2026, Inter, кириллица: отношение 1.17. Отсюда 58ch ≈ 68 знаков
     (рабочая колонка) и 64ch ≈ 75 знаков (потолок). При смене гарнитуры
     пересчитать замером, сниппет в скилле «типографика-и-ритм», раздел 2. */
  --measure:      58ch;
  --measure-wide: 64ch;
}

/* VOLZAR - Spacing, radii, sizing. 4px base grid. */
:root {
  --space-1:  4px;
  --space-2:  8px;
  --space-3:  12px;
  --space-4:  16px;
  --space-5:  24px;
  --space-6:  32px;
  --space-7:  48px;
  --space-8:  64px;
  --space-9:  96px;
  --space-10: 128px;

  /* ---- Radii ---- (blue islands ~16-20px; pills fully round) */
  --radius-sm:   8px;
  --radius-md:   12px;   /* buttons, inputs */
  --radius-lg:   16px;   /* cards */
  --radius-xl:   20px;   /* blue feature islands */
  --radius-2xl:  28px;
  --radius-pill: 999px;  /* pill section headers, chips */

  /* ---- Layout ---- */
  --container:   1200px;
  --container-wide: 1360px;
  --gutter:      24px;

  /* ---- Control sizing ---- */
  --control-h-sm: 36px;
  --control-h:    44px;   /* min hit target */
  --control-h-lg: 56px;

  /* ---- Borders ---- */
  --border-width: 1px;
  --border-width-strong: 2px;
}

/* VOLZAR - Elevation & motion.
   Brand is flat: NO blur-heavy drop shadows, NO gradients. Depth comes from
   color blocks and hairline borders. Shadows here are subtle and optional. */
:root {
  --shadow-none: none;
  --shadow-hairline: 0 0 0 1px var(--sand-200);
  --shadow-card: 0 1px 2px rgba(26,26,26,0.06), 0 2px 8px rgba(26,26,26,0.04);
  --shadow-raised: 0 4px 16px rgba(26,26,26,0.08);

  /* Motion - restrained, no bounce. Quick functional transitions. */
  --ease-standard: cubic-bezier(0.2, 0, 0, 1); /* @kind other */
  --ease-out: cubic-bezier(0.16, 1, 0.3, 1); /* @kind other */
  --dur-fast: 120ms; /* @kind other */
  --dur-base: 180ms; /* @kind other */
  --dur-slow: 280ms; /* @kind other */
}

/* VOLZAR: глобальные стили и компоненты дизайн-системы.
   Собрано 28.07.2026 при переходе со сборки в браузере на статику.
   Раньше эти правила жили инлайновыми стилями внутри JSX, из-за чего
   медиазапросы к ним не применялись. Теперь всё классами.
   Токены подключаются отдельно: ds/styles.css. */

/* ============================================================
   1. База
   ============================================================ */
*, *::before, *::after { box-sizing: border-box; }
* { margin: 0; padding: 0; }
html { scroll-behavior: smooth; }
body {
  font-family: var(--font-body);
  color: var(--text-strong);
  background: var(--white);
  -webkit-font-smoothing: antialiased;
  line-height: var(--lh-body);
  /* pretty лечит висячий предлог в конце абзаца, break-word спасает от
     горизонтальной прокрутки на «энергоэффективность» при ширине 360px. */
  text-wrap: pretty;
  overflow-wrap: break-word;
}
a { color: inherit; text-decoration: none; }
/* max-width: 100% тут недостаточно, и это стоило нам сломанной мобильной.
   У картинок серий в разметке стоит width="828": это подсказка браузеру
   про пропорции, чтобы не дёргалась вёрстка при загрузке. Но флекс- и
   грид-элемент по умолчанию имеет min-width: auto, то есть не может стать
   уже своего содержимого, а процентный max-width минимум не ограничивает:
   проценты при расчёте минимума считаются неопределёнными и отбрасываются.
   В итоге каждая плитка требовала 828px, две колонки просили 1700px,
   и страница уезжала вбок втрое шире экрана.
   min-width: 0 снимает этот автоматический минимум. Ставим и картинке,
   и каждой обёртке, которая сама является флекс- или грид-элементом. */
img { max-width: 100%; min-width: 0; }
::selection { background: var(--blue-100); }
:focus-visible { outline: 2px solid var(--accent-brand); outline-offset: 2px; }
@media (prefers-reduced-motion: reduce) {
  html { scroll-behavior: auto; }
  *, *::before, *::after { transition-duration: 0.01ms !important; animation-duration: 0.01ms !important; }
}

.wrap { max-width: 1180px; margin: 0 auto; padding-left: clamp(20px, 5vw, 32px); padding-right: clamp(20px, 5vw, 32px); }
.num { font-variant-numeric: tabular-nums; }
/* .visually-hidden удалён 03.08.2026 как мёртвый: ни одного употребления,
   скрытые подписи на сайте живут на aria-label. Понадобится - вернуть
   стандартный блок, а не изобретать свой. */

/* Ссылка перехода к содержанию: не видна, пока не поймает фокус с клавиатуры. */
.skip {
  position: absolute; left: 12px; top: -60px; z-index: 200;
  background: var(--blue-600); color: var(--white);
  padding: 12px 20px; border-radius: var(--radius-md);
  font-weight: 600; font-size: var(--fs-sm);
  transition: top var(--dur-fast) var(--ease-standard);
}
.skip:focus { top: 12px; }
main:focus { outline: none; }

/* Якоря не должны уезжать под липкую шапку. Шапка 74px на десктопе
   и 64px на телефоне, берём с запасом. */
[id] { scroll-margin-top: 88px; }
@media (max-width: 1040px) { [id] { scroll-margin-top: 80px; } }

/* Касания. touch-action убирает задержку 300 мс от ожидания двойного тапа,
   tap-highlight гасит системную серую вспышку поверх фирменных кнопок. */
a, button, label, summary, [role="button"], input, select, textarea {
  touch-action: manipulation;
  -webkit-tap-highlight-color: rgba(44, 153, 145, 0.18);
}

/* ============================================================
   2. Типографика
   ============================================================ */
.display {
  font-family: var(--font-display); font-weight: 800; text-transform: uppercase;
  letter-spacing: var(--ls-heading); line-height: var(--lh-heading); color: var(--graphite-900);
  /* Против висячего слова в последней строке заголовка. */
  text-wrap: balance;
}
.display--light { color: var(--white); }
.h1 { font-size: var(--fs-h1); }
.h2 { font-size: var(--fs-h2); margin-bottom: 16px; }
.h3 { font-size: var(--fs-h3); letter-spacing: 0.02em; line-height: var(--lh-snug); }
.lead { font-size: var(--fs-lead); line-height: 1.5; color: var(--text-body); max-width: var(--measure); text-wrap: pretty; }
.lead--light { color: var(--text-on-blue-soft); }
.body { font-size: var(--fs-body); line-height: var(--lh-body); color: var(--text-body); max-width: var(--measure); text-wrap: pretty; }
/* .body--full, .muted и .h3--lg удалены 03.08.2026 как мёртвые:
   ни разметки, ни эмиттера в build/. Вторичный мелкий текст носит
   .muted-sm, размер заголовка задаёт .h3. */
/* Дисклеймер лежал во всю ширину контейнера: 166 знаков в строке. */
.fine { font-size: var(--fs-xs); line-height: var(--lh-body); color: var(--text-muted); max-width: var(--measure-wide); }

/* Надсечка секции. Стоит на всех 42 страницах, по одной-две на секцию.

   ПРАВКА 29.07, найдено при разборе «сайт блеклый». Здесь висел провал
   контраста, который не поймала ни одна проверка: 14px, вес 600, цвет
   --blue-500, то есть 3.46:1 на белом при норме 4.5. Порог «крупного
   текста» это 24px обычным или 18.66px полужирным, 14px не проходит
   ни по одному. Мимо check.mjs это прошло потому, что пары там объявлены
   поимённо, а .eyebrow в списке не было. Теперь есть.

   Лечится не подкруткой тила, а разделением ролей. Надпись это ярлык,
   а не сообщение: сообщение стоит строкой ниже заголовком. Ярлык уходит
   в --graphite-500 (5.69:1 на белом, 4.65:1 на песочном), а цветом
   работает засечка перед ним. Побочно чинится иерархия: раньше ярлык
   спорил с заголовком цветом, проигрывая ему кеглем.

   Засечка тиловая, а не амберная, потому что фон здесь светлый: амбер
   на белом это 1.56:1, его бы просто не было видно. Берётся --accent-brand,
   то есть тил-600: тил-500 на углублённом песочном даёт 2.82:1 и не проходит
   порог 3:1 для графики, тил-600 даёт 4.05:1. Высота поднята с 2 до 3px:
   на 2px разница между 26px линией и текстом рядом читалась как случайность. */
.eyebrow {
  font-family: var(--font-body); font-weight: 600; font-size: var(--fs-eyebrow);
  letter-spacing: var(--ls-caps); text-transform: uppercase;
  color: var(--graphite-500); margin-bottom: 16px;
  display: flex; align-items: center; gap: 12px;
}
.eyebrow::before { content: ""; width: 26px; height: 3px; background: var(--accent-brand); flex: none; }
/* На тиловых островах фон плотный, и там засечка амберная: 4.02:1. */
.eyebrow--light { color: var(--text-on-blue-soft); }
.eyebrow--light::before { background: var(--accent-mark); }

.summary { border-top: 1px solid var(--border-subtle); padding-top: 16px; margin-top: 24px; }
.summary--light { border-top-color: var(--border-on-blue); }
.summary__label { font-family: var(--font-display); font-weight: 800; text-transform: uppercase; font-size: var(--fs-xs); letter-spacing: 0.08em; color: var(--graphite-900); margin-bottom: 8px; }
.summary--light .summary__label { color: var(--white); }
.summary__text { font-size: var(--fs-body); color: var(--text-body); line-height: var(--lh-body); }
.summary--light .summary__text { color: var(--text-on-blue-soft); }

/* ============================================================
   3. Секции и сетки
   ============================================================ */
.sec { padding: clamp(56px, 8vw, 96px) 0; }
/* Первая секция внутренней страницы. Над ней уже стоят крошки, а в них
   ссылка ростом 44px под палец, то есть под текстом крошек лежит ещё
   около 18px воздуха. Вместе с обычными 96px секции получалось больше
   120px пустоты между крошками и заголовком: на первом экране это
   съедало место, которое должен занимать сам заголовок. На главной
   крошек нет, поэтому модификатор точечный, а не правка .sec. */
.sec--hero { padding-top: clamp(20px, 3vw, 40px); }
.sec-sand { background: var(--sand-100); }
.sec-white { background: var(--white); }
/* .sec-tint выведен из чередования секций 29.07: --blue-050 отличался
   от белого на 1.08:1 и от песочного на 1.07:1, то есть третьего фона
   на деле не существовало, а его наличие мешало держать ритм из двух.
   Класс оставлен: он годится подложкой блока внутри секции, но не самой
   секцией. На главной вхождений больше нет. */
.sec-tint { background: var(--blue-050); }
.sec-head { max-width: 760px; margin-bottom: clamp(24px, 4vw, 48px); }

.grid-2 { display: grid; grid-template-columns: 1fr 1fr; gap: 28px; }
.grid-3 { display: grid; grid-template-columns: repeat(3, 1fr); gap: 24px; }
.grid-4 { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; }
.grid-split { display: grid; grid-template-columns: 0.9fr 1.1fr; gap: 48px; align-items: start; }
@media (max-width: 900px) { .grid-3, .grid-4 { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 820px) { .grid-split { grid-template-columns: 1fr; gap: 30px; } }
@media (max-width: 760px) { .grid-2 { grid-template-columns: 1fr; } }
@media (max-width: 560px) { .grid-3, .grid-4 { grid-template-columns: 1fr; } }

/* ============================================================
   4. Компоненты дизайн-системы
   ============================================================ */

/* --- Кнопка --- */
.btn {
  display: inline-flex; align-items: center; justify-content: center; gap: 10px;
  min-height: var(--control-h); padding: 8px 22px;
  font-family: var(--font-body); font-weight: 600; font-size: var(--fs-sm); letter-spacing: 0.01em;
  border: var(--border-width-strong) solid transparent; border-radius: var(--radius-md);
  /* nowrap тут был вреден: подпись не сжималась, кнопка вылезала
     за контейнер и тянула вбок всю страницу. Разрешаем перенос,
     кнопка растёт вверх, а не вбок. Высота поэтому не фиксированная,
     а минимальная, иначе текст во вторую строку вылезет из рамки.
     Панель внизу экрана это исключение, у неё своя высота: там nowrap
     оставлен, а ужимается отступ, см. раздел 8. */
  cursor: pointer; text-decoration: none; box-sizing: border-box;
  text-align: center; text-wrap: balance;
  transition: background var(--dur-fast) var(--ease-standard),
              border-color var(--dur-fast) var(--ease-standard),
              color var(--dur-fast) var(--ease-standard);
}
/* Высота минимальная, а не жёсткая: подпись в две строки должна
   растить кнопку, а не вылезать из рамки. Однострочная кнопка
   при этом ровно той же высоты, что и была: 8 + строка + 8 меньше
   любой из трёх --control-h. */
.btn--sm { min-height: var(--control-h-sm); padding: 6px 16px; font-size: var(--fs-xs); }
.btn--lg { min-height: var(--control-h-lg); padding: 10px 32px; font-size: var(--fs-md); }
@media (max-width: 560px) { .btn--lg { font-size: var(--fs-body); padding: 10px 20px; } }
.btn--block { width: 100%; }
.btn--primary { background: var(--blue-600); color: var(--white); border-color: var(--blue-600); }
.btn--primary:hover { background: var(--blue-700); border-color: var(--blue-700); }
.btn--secondary { background: transparent; color: var(--blue-600); border-color: var(--blue-600); }
.btn--secondary:hover { background: var(--blue-050); }
.btn--ghost { background: transparent; color: var(--graphite-900); border-color: transparent; }
.btn--ghost:hover { background: var(--sand-100); }
.btn--onblue { background: var(--white); color: var(--blue-600); border-color: var(--white); }
.btn--onblue:hover { background: rgba(255,255,255,0.88); }
/* Нажатие. На телефоне наведения нет, и без :active кнопка никак
   не отвечала на касание: палец опущен, а картинка та же. */
.btn:active { transform: translateY(1px); }
.btn--primary:active { background: var(--blue-700); border-color: var(--blue-700); }
.btn--secondary:active { background: var(--blue-100); }
.btn--ghost:active { background: var(--sand-200); }
.btn--onblue:active { background: rgba(255,255,255,0.76); }
@media (prefers-reduced-motion: reduce) { .btn:active { transform: none; } }
.btn[disabled] { opacity: 0.5; cursor: not-allowed; }
.btn__arrow { width: 16px; height: 16px; margin-right: -2px; flex: none; }

/* --- Карточка ---
   Граница поднята с --border-subtle (#DCE1E3, 1.32:1) до --border-strong
   (#C6CDD0, 1.61:1). Причина: теней в системе нет по решению «бренд плоский»,
   фоны секций близки, и на волосяной границе карточка переставала читаться
   как предмет, лежащий на странице, — она читалась как обведённый кусок
   того же полотна. Глубина в такой системе может прийти только с границы,
   значит граница должна её давать. Внутренние разделители (--border-subtle)
   не трогаем: их работа противоположная, они должны не мешать. */
.card { background: var(--white); border-radius: var(--radius-lg); padding: var(--space-6); border: 1px solid var(--border-strong); }
.card--sand { background: var(--sand-100); }
.card--tint { background: var(--blue-050); }
.card--xl { border-radius: var(--radius-xl); padding: clamp(24px, 3vw, 32px); }
.card--flush { border: none; }

/* --- Тиловый остров --- */
.island {
  position: relative; background: var(--surface-island); color: var(--text-on-blue);
  border-radius: var(--radius-xl); padding: var(--space-7); overflow: hidden;
}
.island--lg { border-radius: var(--radius-lg); }
.island--2xl { border-radius: var(--radius-2xl); }
.island__arrow { position: absolute; top: var(--space-5); right: var(--space-5); width: 56px; height: 56px; }

/* --- Бейдж --- */
.badge {
  display: inline-flex; align-items: center; gap: 8px; padding: 4px 12px;
  border-radius: var(--radius-pill); font-family: var(--font-body); font-weight: 600;
  font-size: var(--fs-caps); letter-spacing: var(--ls-caps); text-transform: uppercase; line-height: 1;
  /* Текст 12px капсом, для него порог AA обычный. На тинте --blue-100
     цвет --blue-600 давал 4.05, поэтому берём --blue-700: 5.85. */
  background: var(--teal-100); color: var(--blue-700);
}
.badge--blue { background: var(--blue-100); color: var(--blue-700); }
.badge--green { background: var(--green-100); color: var(--green-500); }
.badge--red { background: var(--red-100); color: var(--red-500); }
.badge--neutral { background: var(--sand-100); color: var(--graphite-700); }
.badge--solid { background: var(--blue-600); color: var(--white); }
/* Единственный случай, когда амбер стоит на светлой странице: он тут
   не линия, а заливка, и текст на нём графитовый, 10.54:1.
   Правило применения: не больше одного амберного бейджа на карточку
   и не больше трети карточек в сетке. Смысл его в том, что он выделяет
   меньшинство; когда им помечено большинство, он перестаёт работать
   и остаётся просто жёлтым пятном. Сейчас 6 плиток каталога из 23. */
.badge--accent { background: var(--amber-500); color: var(--on-amber); }
/* Бейджи в строку. .scard__pad колоночный, и одиночный бейдж в нём
   растягивался на всю ширину карточки. */
.badgerow { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; }

/* Компонент «Метрика» (.stat) удалён 03.08.2026 вместе с функцией Stat()
   в ds.mjs: ни одного вызова после пересборки главной 29.07. Числа
   на страницах живут в .statcard, .facts и .factband. Понадобится -
   писать заново от них, а не воскрешать старое. */

/* --- Список с маркерами --- */
.bullets { list-style: none; display: flex; flex-direction: column; gap: 12px; }
.bullets li {
  display: flex; gap: 12px; align-items: flex-start; color: var(--graphite-700);
  font-family: var(--font-body); font-size: var(--fs-body); line-height: var(--lh-body);
}
.bullets--light li { color: var(--white); }
.bullets__mark { width: 8px; height: 8px; background: var(--accent-brand); margin-top: 8px; flex: none; }
/* На тиловом острове маркер был белым и сливался с текстом, который тоже
   белый: список выглядел сплошным. Амбер здесь даёт 4.02:1 и отделяет
   маркер от строки, оставаясь на плотном фоне, где он работает. */
.bullets--light .bullets__mark { background: var(--accent-mark); }
.bullets--dot .bullets__mark { width: 6px; height: 6px; border-radius: 50%; margin-top: 8px; }

/* «Пилюля-заголовок» (.pill-head) удалена 03.08.2026 вместе с функцией
   PillHead(): ни одного вызова, заголовки секций держит SectionHead. */

/* --- Таблица --- */
.dtable { border-radius: var(--radius-lg); overflow: hidden; border: 1px solid var(--border-subtle); }
.dtable table { width: 100%; border-collapse: collapse; font-family: var(--font-body); font-size: var(--fs-xs); }
.dtable caption { caption-side: top; text-align: left; padding: 0 0 12px; color: var(--text-muted); font-size: var(--fs-xs); }
.dtable th {
  background: var(--teal-600); color: var(--white); text-align: left; padding: 12px 16px;
  font-family: var(--font-display); font-weight: 800; text-transform: uppercase;
  letter-spacing: var(--ls-caps); font-size: var(--fs-caps); white-space: nowrap;
}
.dtable td { padding: 12px 16px; color: var(--text-body); border-top: 1px solid var(--border-subtle); }
.dtable tbody:not(.dtable__grp) tr:nth-child(even) { background: var(--table-stripe); }
.dtable td:first-child { font-weight: 500; }
.dtable .is-num { text-align: right; font-variant-numeric: tabular-nums; }
.dtable th.is-hl { background: var(--blue-600); }
.dtable td.is-hl { color: var(--blue-600); font-weight: 600; background: var(--blue-050); }

/* Числовая графа. nowrap здесь не косметика: без него диапазон «17,0-20,0»
   в узкой колонке разваливается на три строки по дефису и по запятой,
   и таблица химсостава перестаёт читаться как таблица. */
.dtable .is-val { white-space: nowrap; font-variant-numeric: tabular-nums; }
/* Пустая ячейка это «элемент не нормируется», а не «данных нет».
   Ставим прочерк, чтобы дыру нельзя было принять за обрыв вёрстки. */
.dtable .is-empty::before { content: "-"; color: var(--graphite-300); }

/* Подзаголовок группы внутри таблицы.
   Первая версия была серой плашкой во всю ширину, и под тиловой шапкой
   она читалась как вторая шапка: две тяжёлые полосы подряд выглядят
   ошибкой вёрстки. Поэтому здесь не плашка, а разделитель: фон белый,
   сверху тиловая линия, надпись графитовая. Спутать с шапкой нечего.
   Тил в тексте не годится: на светлом он даёт 4,05:1, а это капс
   в 12px, то есть мелкий текст, которому нужно 4,5:1. Графит даёт 15,4:1.
   Линия, а не inset box-shadow: при border-collapse тень на ячейке
   в части браузеров не рисуется вовсе. */
.dtable__ghead th {
  background: var(--white); color: var(--graphite-900);
  padding: 22px 16px 10px; letter-spacing: var(--ls-caps-wide);
  border-top: 2px solid var(--teal-500);
}
.dtable__grp .dtable__ghead ~ tr:nth-child(odd) { background: var(--table-stripe); }

/* --- Поле формы --- */
.field { display: flex; flex-direction: column; gap: 8px; }
.field__label {
  font-family: var(--font-body); font-weight: 600; font-size: var(--fs-sm);
  letter-spacing: 0.01em; color: var(--text-strong);
}
.field__req { color: var(--accent-brand); }
.field__control {
  width: 100%; box-sizing: border-box; font-family: var(--font-body); font-size: var(--fs-body);
  color: var(--text-strong); background: var(--white);
  border: 2px solid var(--border-strong); border-radius: var(--radius-md);
  padding: 0 16px; height: var(--control-h);
  transition: border-color var(--dur-fast) var(--ease-standard);
}
/* Раньше тут стоял outline: none. Глобальное правило :focus-visible объявлено
   выше, специфичность равная, поэтому побеждало более позднее: у полей формы
   кольца фокуса не было вовсе. Оставляем кольцо и добавляем цвет границы. */
.field__control:focus-visible { border-color: var(--accent-brand); }
.field__control:focus { border-color: var(--accent-brand); }
select.field__control { appearance: none; background-image: none; cursor: pointer; }
textarea.field__control { height: auto; min-height: 112px; padding: 12px 16px; resize: vertical; }
.field__hint { font-size: var(--fs-xs); color: var(--text-muted); line-height: var(--lh-body); }

/* ============================================================
   5. Шапка, подвал, навигация
   ============================================================ */
.ubar { background: var(--graphite-900); color: rgba(255,255,255,.62); font-size: var(--fs-xs); }
.ubar .wrap { display: flex; justify-content: space-between; align-items: center; min-height: 44px; }
/* Телефон и почта в верхней полосе: зона нажатия была 20px. */
.ubar a { transition: color var(--dur-fast) var(--ease-standard); display: inline-flex; align-items: center; min-height: 44px; }
.ubar a:hover { color: var(--white); }
.ubar__right { display: flex; gap: 24px; align-items: center; }
.ubar__phone { color: var(--white); font-weight: 600; }
@media (max-width: 760px) { .ubar__left { display: none; } .ubar .wrap { justify-content: center; } }
/* Ниже 420px телефон и почта дают 281px в ячейке 280px, впритык
   с превышением. Слева скрывать уже нечего, поэтому уходит почта:
   она продублирована в подвале и на странице контактов, а телефон
   в верхней полосе это единственное действие в один тап.

   Цепляемся за класс, а не за href^="mailto": на проде включена
   защита почты Cloudflare, и она переписывает адрес в ссылку
   /cdn-cgi/l/email-protection. Селектор по href молча перестал бы
   работать ровно там, где он нужен. */
@media (max-width: 420px) { .ubar__mail { display: none; } }

header.site { position: sticky; top: 0; z-index: 60; background: var(--white); border-bottom: 1px solid var(--border-subtle); }
.nav { display: flex; align-items: center; height: 72px; gap: 32px; }
.nav__logo { display: flex; align-items: center; }
.menu { display: flex; gap: 24px; align-items: center; height: 100%; list-style: none; }
.menu > li { height: 100%; display: flex; align-items: center; position: relative; }
.menu > li > a, .menu > li > button {
  font-family: var(--font-body); font-size: var(--fs-sm); font-weight: 500; color: var(--graphite-700);
  background: none; border: none; cursor: pointer; display: inline-flex; align-items: center; gap: 7px; height: 100%;
  transition: color var(--dur-fast) var(--ease-standard);
}
.menu > li > a:hover, .menu > li > button:hover,
.menu > li:hover > button, .menu > li:focus-within > button { color: var(--accent-brand); }
.menu > li.is-current > a, .menu > li.is-current > button { color: var(--blue-600); font-weight: 600; }
.caret { width: 8px; height: 8px; border-right: 2px solid currentColor; border-bottom: 2px solid currentColor; transform: rotate(45deg) translateY(-2px); transition: transform var(--dur-base) var(--ease-standard); }
.menu > li:hover .caret, .menu > li:focus-within .caret { transform: rotate(-135deg) translateY(-1px); }
.nav__right { margin-left: auto; display: flex; align-items: center; gap: 16px; }
.nav__phone { font-weight: 700; font-size: var(--fs-sm); white-space: nowrap; transition: color var(--dur-fast); }
.nav__phone:hover { color: var(--accent-brand); }

/* Мега-меню на чистом CSS, без JS */
.mega {
  position: absolute; top: 100%; left: 0; background: var(--white);
  border: 1px solid var(--border-subtle); border-radius: var(--radius-lg);
  min-width: 576px; padding: 24px; box-shadow: var(--shadow-raised);
  opacity: 0; visibility: hidden; transform: translateY(8px);
  transition: opacity var(--dur-base) var(--ease-standard), transform var(--dur-base) var(--ease-standard), visibility var(--dur-base);
  display: grid; grid-template-columns: 1fr 1fr; gap: 4px 24px;
}
.menu > li:hover .mega, .menu > li:focus-within .mega { opacity: 1; visibility: visible; transform: translateY(0); }
.mega__head { grid-column: 1 / -1; font-size: var(--fs-caps); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); font-weight: 600; margin-bottom: 8px; }
.mega a { display: flex; flex-direction: column; gap: 4px; padding: 12px; border-radius: var(--radius-md); transition: background var(--dur-fast) var(--ease-standard); }
.mega a:hover { background: var(--sand-100); }
.mega a b { font-weight: 600; font-size: var(--fs-sm); color: var(--graphite-900); }
.mega a span { font-size: var(--fs-xs); color: var(--text-muted); }
.mega a .eq { font-size: var(--fs-xs); color: var(--accent-brand); font-weight: 500; letter-spacing: .01em; }
.mega__all { grid-column: 1 / -1; }

/* Две колонки в «Продуктах» с 12.08.2026: слева бренды, справа серии.
   Колонка это один элемент грида .mega, поэтому внутри неё раскладка
   своя, флексом. Без обёртки ссылки легли бы в шахматном порядке:
   грид заполняет ячейки по строкам, а не по столбцам.
   .mega__all внутри колонки просто теряет grid-column, это нормально:
   в потоке флекса он и так занимает всю ширину колонки. */
.mega--wide { min-width: 720px; }
.mega__col { display: flex; flex-direction: column; gap: 2px; min-width: 0; }

.burger {
  display: none; background: none; border: none; cursor: pointer;
  flex-direction: column; gap: 4px; padding: 12px; min-width: 44px; min-height: 44px;
  align-items: center; justify-content: center;
}
.burger span { width: 24px; height: 2px; background: var(--graphite-900); display: block; }
@media (max-width: 1040px) { .menu, .nav__phone { display: none; } .burger { display: flex; } .nav { gap: 14px; height: 64px; } }

/* Мобильное меню: чекбокс вместо JS.
   Чекбокс намеренно остаётся в обходе по Tab: открывает шторку <label>,
   а он фокус не принимает, и без этого меню не открыть с клавиатуры.
   Размер нулевой, но фокус на нём подсвечивает бургер. */
.drawer-toggle { position: absolute; width: 1px; height: 1px; opacity: 0; margin: 0; }
.drawer-toggle:focus-visible ~ header .burger { outline: 2px solid var(--accent-brand); outline-offset: 2px; border-radius: var(--radius-md); }
.drawer { position: fixed; inset: 0; background: rgba(26,26,26,.5); z-index: 80; display: none; }
.drawer-toggle:checked ~ .drawer { display: block; }
/* Выше 1040 px шторки нет и бургер не отрисован. Чекбокс при этом оставался
   в обходе по Tab, и Tab плюс пробел разворачивали мобильное меню поверх
   десктопной страницы, а кольцо фокуса висело на невидимом бургере.
   display: none убирает чекбокс из обхода целиком. */
@media (min-width: 1041px) {
  .drawer-toggle { display: none; }
  .drawer { display: none !important; }
}
/* overscroll-behavior: домотав список отраслей, пользователь начинал
   прокручивать страницу под шторкой. */
.drawer__panel { position: absolute; right: 0; top: 0; bottom: 0; width: min(84vw, 360px); background: var(--white); padding: 24px; overflow: auto; overscroll-behavior: contain; }
.drawer__link { display: block; padding: 16px 4px; border-bottom: 1px solid var(--sand-200); font-weight: 600; font-size: var(--fs-body); color: var(--graphite-900); }
.drawer__sub { display: block; padding: 12px 4px 12px 16px; border-bottom: 1px solid var(--sand-200); font-size: var(--fs-sm); color: var(--graphite-700); }
.drawer__close { float: right; font-size: 32px; background: none; border: none; cursor: pointer; line-height: 1; color: var(--graphite-700); min-width: 44px; min-height: 44px; }
.drawer__head { font-size: var(--fs-caps); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); font-weight: 600; margin: 24px 0 8px; }

.foot { background: var(--graphite-900); color: rgba(255,255,255,.6); padding: 56px 0 32px; }
/* Пять колонок с 12.08.2026: к продуктам, отраслям и контактам добавилась
   колонка «Аналоги по брендам». Первая шире остальных, в ней логотип
   и описание. На 820px и ниже раскладка сворачивается в две колонки. */
.foot__grid { display: grid; grid-template-columns: 1.4fr 1fr 1fr 1fr 1fr; gap: 32px; }
.foot h2 { font-family: var(--font-display); font-weight: 800; text-transform: uppercase; color: var(--white); font-size: var(--fs-caps); letter-spacing: 0.1em; margin-bottom: 16px; }
/* Зона нажатия 44px: было 33px, а в подвале 18 ссылок на каждой странице
   и на телефоне это основная навигация после липкой панели. */
.foot a { display: block; padding: 12px 0; font-size: var(--fs-xs); color: rgba(255,255,255,.7); transition: color var(--dur-fast); }
.foot a:hover { color: var(--white); }
.foot__about { margin-top: 16px; font-size: var(--fs-xs); max-width: 34ch; line-height: var(--lh-body); }
/* Строка поставщика под описанием. Тот же приглушённый белый, что
   в .foot__legal: 55 % на графите даёт 5.87:1. Раньше цвет стоял
   инлайновым rgba в шаблоне и шёл мимо проверки палитры. */
.foot__sup { margin-top: 16px; font-size: var(--fs-xs); color: rgba(255,255,255,.55); }
/* Белый 40 % на графите давал 3.75, ниже AA. 55 % даёт 5.87. */
.foot__legal { border-top: 1px solid rgba(255,255,255,.1); margin-top: 40px; padding-top: 24px; display: flex; justify-content: space-between; gap: 16px; flex-wrap: wrap; font-size: var(--fs-xs); color: rgba(255,255,255,.55); }
.foot__legal span { max-width: 70ch; }
@media (max-width: 820px) { .foot__grid { grid-template-columns: 1fr 1fr; } }
/* Не одна колонка, а две. В подвале 18 ссылок, каждая ростом 44px под
   палец, в один столбец это около 800px пустой вертикали в самом низу
   страницы. В две колонки высота падает вдвое, и ни одна ссылка при
   этом не пропадает: перелинковка на сайте держится именно на подвале,
   прятать её под display: none ради вида нельзя.
   Блок с логотипом и описанием остаётся во всю ширину. */
@media (max-width: 620px) {
  .foot__grid { grid-template-columns: 1fr 1fr; gap: 28px 20px; }
  .foot__grid > :first-child { grid-column: 1 / -1; }
}

/* ============================================================
   6. Хлебные крошки
   ============================================================ */
.crumbs { font-size: var(--fs-xs); color: var(--text-muted); padding: 8px 0; }
.crumbs ol { list-style: none; display: flex; flex-wrap: wrap; align-items: center; }
/* Зона нажатия была 20px. Отступ ушёл с контейнера на сами ссылки. */
.crumbs a { display: inline-flex; align-items: center; min-height: 44px; }
.crumbs li { display: inline-flex; align-items: center; }
.crumbs a:hover { color: var(--blue-600); }
.crumbs li + li::before { content: "/"; margin: 0 8px; color: var(--border-strong); }
/* На узком экране четыре уровня не помещаются в строку и переносятся.
   Ссылка в крошках ростом 44px под палец, две строки это 88px почти
   пустого места прямо над заголовком. Оставляем два последних уровня:
   шаг наверх и текущую страницу. Разметка BreadcrumbList в JSON-LD
   лежит отдельно и остаётся полной, на выдачу это не влияет. */
@media (max-width: 560px) {
  .crumbs li:not(:nth-last-child(-n+2)) { display: none; }
  .crumbs li:nth-last-child(2)::before { content: none; margin: 0; }
}

/* ============================================================
   7. Прикладные блоки
   ============================================================ */
.hovercard { transition: border-color var(--dur-base) var(--ease-standard), transform var(--dur-base) var(--ease-standard), box-shadow var(--dur-base) var(--ease-standard); display: block; }
.hovercard:hover { border-color: var(--accent-brand); transform: translateY(-4px); box-shadow: var(--shadow-raised); }

/* --- Первый экран ---
   Фотография изделия вместо схемы «Sulzer ⇄ VOLZAR». Схема сообщала одно
   утверждение и занимала половину экрана, к тому же выносила чужой бренд
   на самое видное место сайта. Фото делает ту же работу («это железо, оно
   существует») и не привязывает нас к одному производителю. */
.hero { padding: clamp(40px, 5vw, 64px) 0 clamp(36px, 4vw, 56px); }
.hero__grid { display: grid; grid-template-columns: 1fr 1fr; gap: clamp(28px, 4vw, 56px); align-items: center; }
/* Ограничения по ширине сняты. Стояло max-width: 15ch, и заголовок ломался
   на пять строк капсом при том, что колонка вдвое шире: строка обрывалась
   не по колонке, а по искусственному потолку. Меру держит сама колонка. */
.hero h1 { margin-bottom: 16px; }
.hero .lead { max-width: none; }
.hero__cta { display: flex; gap: 12px; margin-top: 26px; flex-wrap: wrap; }

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

   Списка «Срок / Гарантия / Запчасти» в левой колонке больше нет: два
   из трёх пунктов слово в слово повторяли полосу фактов сразу под хиро. */
.hero__pic { background: var(--white); border: 1px solid var(--border-subtle); border-radius: var(--radius-xl); overflow: hidden; }
.hero__pic figure { padding: clamp(12px, 2vw, 22px) clamp(12px, 2vw, 22px) 0; }
/* Волосяная рамка внутрь кромки снимка. Фото насоса снято на белом,
   и на белой карточке его край растворялся: где кончается снимок
   и начинается карточка, глаз решал сам. Рамка графитовая на 7 %,
   то есть тонирована в цвет текста, а не бренда: брендовый цвет
   на служебной линии читался бы как ссылка. offset -1px кладёт
   линию внутрь картинки, чтобы она не спорила с рамкой карточки.
   Только тут: у плиток каталога фото лежит через object-fit: contain,
   там рамка элемента не совпадает с рамкой снимка и висела бы в воздухе. */
.hero__pic img { width: 100%; height: auto; display: block; outline: 1px solid rgba(26,26,26,0.07); outline-offset: -1px; }
.hero__cap { display: flex; align-items: baseline; justify-content: space-between; gap: 8px 16px; flex-wrap: wrap; padding: 14px clamp(16px, 2vw, 24px); border-top: 1px solid var(--border-subtle); }
.hero__cap b { font-family: var(--font-display); font-weight: 800; text-transform: uppercase; font-size: var(--fs-xs); letter-spacing: 0.06em; color: var(--graphite-900); }
.hero__cap span { font-size: var(--fs-xs); color: var(--text-muted); }
.hero__specs { display: grid; grid-template-columns: 1fr 1fr; border-top: 1px solid var(--border-subtle); }
.hero__specs > div { padding: 12px clamp(16px, 2vw, 24px); display: flex; flex-direction: column; gap: 2px; }
.hero__specs > div:nth-child(even) { border-left: 1px solid var(--border-subtle); }
.hero__specs > div:nth-child(n+3) { border-top: 1px solid var(--border-subtle); }
.hero__k { font-size: var(--fs-caps); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); font-weight: 600; }
.hero__v { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-sm); color: var(--graphite-900); font-variant-numeric: tabular-nums; }
@media (max-width: 860px) {
  .hero__grid { grid-template-columns: 1fr; gap: 28px; }
  /* Карточка на телефоне не должна занимать целый экран прокрутки. */
  .hero__pic { max-width: 460px; margin: 0 auto; width: 100%; }
}

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

   Шаг 1 (до 28.07). Тиловый остров на шесть колонок мелким белым: числа
   разной длины вставали неровно, «С 2000 ГОДА» ломалось на две строки
   и утаскивало подпись вниз, а плашка наезжала на первый экран
   отрицательным отступом. Разобрали на светлую полосу.

   Шаг 2 (29.07, разбор «сайт блеклый»). Светлая полоса вылечила вёрстку
   и создала другую беду. На первом экране не осталось ни одного плотного
   пятна: хиро стоял на --sand-100, полоса на белом, разница 1.16:1.
   Цифры — самый сильный довод на странице — были покрашены в тот же
   графит, что и подписи под ними, то есть визуально равнялись подписи.

   Возвращаем плотный фон, но без ошибок первого шага: колонок четыре,
   а не шесть; ячейка фиксированной структуры; отрицательного отступа нет,
   полоса стоит под первым экраном, а не поверх него. Цифры белым по тилу
   это 6.27:1, подписи белым 82 % это 4.81:1, обе выше AA.

   Амберная кромка сверху: 4.02:1 на тиле, выше порога 3:1 для графики.
   Это единственная сильная точка первого экрана, и она стоит ровно там,
   куда должен упасть взгляд после заголовка. */
.facts {
  display: grid; grid-template-columns: repeat(4, 1fr);
  margin-top: clamp(20px, 3vw, 36px);
  background: var(--surface-island); color: var(--text-on-blue);
  border-top: 3px solid var(--accent-mark);
  border-radius: 0 0 var(--radius-xl) var(--radius-xl);
  overflow: hidden;
}
.facts__cell { padding: clamp(20px, 2.5vw, 28px) clamp(16px, 2vw, 28px); display: flex; flex-direction: column; gap: 6px; border-left: 1px solid var(--border-on-blue); }
.facts__cell:first-child { border-left: none; }
.facts__v { font-family: var(--font-display); font-weight: 800; text-transform: uppercase; font-size: clamp(1.25rem, 2vw, 1.625rem); line-height: var(--lh-snug); color: var(--white); letter-spacing: 0.01em; font-variant-numeric: tabular-nums; }
/* 82 %, не 80 %: на --blue-650 это 4.81:1 против 4.65. Запас нужен, потому
   что это 14px, то есть мелкий текст с обычным порогом AA. */
.facts__l { font-size: var(--fs-xs); color: rgba(255,255,255,0.82); line-height: 1.45; }
@media (max-width: 860px) {
  .facts { grid-template-columns: repeat(2, 1fr); }
  .facts__cell:nth-child(odd) { border-left: none; }
  .facts__cell:nth-child(n+3) { border-top: 1px solid var(--border-on-blue); }
}
@media (max-width: 420px) {
  .facts { grid-template-columns: 1fr; }
  .facts__cell { border-left: none; }
  .facts__cell + .facts__cell { border-top: 1px solid var(--border-on-blue); }
}
/* Модификатора .facts--card здесь больше нет. Он описывал блок в секции
   завода, а тот блок ушёл при пересборке главной 29.07, и правило висело
   мёртвым: ни одного вхождения в build/pages. Понадобится снова — писать
   заново от нынешнего .facts, а не воскрешать старое. */

/* --- Этапы работы ---
   Было пять одинаковых карточек с рамками: процесс выглядел как пять
   не связанных между собой пунктов, хотя это одна линия от запроса
   до поставки. Рамки сняты, вместо них общая горизонтальная черта,
   проходящая через все пять этапов: gap по горизонтали нулевой,
   поэтому border-top соседних ячеек смыкается в одну непрерывную линию.
   На телефоне та же черта работает разделителем списка. */
.steps { display: grid; grid-template-columns: repeat(5, 1fr); gap: 0; }
.steps--4 { grid-template-columns: repeat(4, 1fr); }
/* Линия, сшивающая этапы, была --blue-100: 1.20:1 к белому, то есть её
   не было. Смысл всего компонента держится на ней — «это одна линия
   от запроса до поставки», — поэтому она переведена на --blue-500,
   3.46:1, выше порога 3:1 для графических объектов. */
.steps__item { border-top: 2px solid var(--accent-brand); padding: 18px 24px 0 0; }
.steps__item:last-child { padding-right: 0; }
/* Иконка и номер в одной строке: номер держит последовательность,
   иконка даёт узнавание с одного взгляда. Порознь они спорят за место,
   вместе читаются как «шаг 03, документ». */
.steps__head { display: flex; align-items: center; gap: 10px; color: var(--blue-600); }
.steps__ico { flex: none; display: block; }
.steps__n { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-h3); line-height: 1; letter-spacing: 0.02em; font-variant-numeric: tabular-nums; }
.steps__t { display: block; font-weight: 600; font-size: var(--fs-sm); color: var(--graphite-900); line-height: 1.4; margin-top: 14px; }
.steps__note { display: block; font-size: var(--fs-xs); color: var(--text-muted); line-height: 1.5; margin-top: 6px; }
@media (max-width: 900px) {
  .steps, .steps--4 { grid-template-columns: repeat(2, 1fr); }
  .steps__item { padding-bottom: 22px; }
}
@media (max-width: 520px) {
  .steps, .steps--4 { grid-template-columns: 1fr; }
  .steps__item { padding-right: 0; }
}

/* --- Чипы отраслей ---
   Раньше это была сетка из семи карточек 150px высотой на отдельной секции.
   Семь плиток ради семи ссылок стоили экран прокрутки на главной.
   Заодно уходит дефект контраста: подписи в плитке красились инлайновым
   style, а инлайн сильнее класса, поэтому правило «под курсором всё белое»
   до них не доставало и серое оставалось серым на тиле. Здесь цвета
   объявлены классами, инлайновых нет. */
.chips { display: flex; flex-wrap: wrap; gap: 10px; }
.chip {
  display: inline-flex; align-items: center; min-height: 44px; padding: 0 18px;
  border: 1px solid var(--border-strong); border-radius: var(--radius-pill);
  font-size: var(--fs-sm); font-weight: 600; color: var(--graphite-900); background: var(--white);
  transition: background var(--dur-fast) var(--ease-standard), border-color var(--dur-fast) var(--ease-standard), color var(--dur-fast) var(--ease-standard);
}
.chip:hover { background: var(--blue-600); border-color: var(--blue-600); color: var(--white); }
.chip:active { background: var(--blue-700); border-color: var(--blue-700); }

/* --- Плитка серии в блоке линейки ---
   Заменила таблицу на шесть колонок. Таблица на главной дублировала
   /zamena/, на телефоне разворачивалась в 36 строк «ключ: значение»
   и вела в никуда: строка серии не была ссылкой целиком. */
/* min-width: 0 по всей цепочке от грид-ячейки до картинки: плитка это
   грид-элемент, внутри флекс-колонка, внутри флекс-обёртка с картинкой.
   Автоматический минимум срабатывает на каждой ступени, снимать надо
   на каждой. См. комментарий к правилу img в начале файла. */
.slink { display: flex; flex-direction: column; gap: 10px; padding: 18px; min-width: 0; }
.slink__pic { background: var(--sand-050); border-radius: var(--radius-md); aspect-ratio: 4 / 3; display: flex; align-items: center; justify-content: center; padding: 10px; min-width: 0; overflow: hidden; }
.slink__pic img { width: 100%; height: 100%; object-fit: contain; display: block; }
.slink__code { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-h3-lg); color: var(--blue-600); letter-spacing: 0.02em; }
.slink__note { font-size: var(--fs-xs); color: var(--text-body); line-height: var(--lh-body); }
/* .grid-4 ниже 560px разворачивается в одну колонку. Для плиток каталога
   это правильно, там в плитке пять строк текста. Здесь в плитке две строки
   и картинка, и одна колонка превращала четыре ссылки в четыре экрана
   прокрутки. Держим две колонки до самого узкого телефона.
   Модификатором, а не через :has(): селектор новее, чем часть парка
   браузеров у промышленных заказчиков, а падать тут нечему. */
@media (max-width: 560px) {
  .grid-4--tiles { grid-template-columns: 1fr 1fr; gap: 12px; }
  .slink { padding: 12px; }
  .slink__pic { padding: 6px; }
}

/* --- Аккордеон вопросов ---
   details/summary, без единой строки скрипта: работает при выключенном JS,
   открывается с клавиатуры и ищется поиском по странице в Chrome.
   Ответы остаются в разметке и в JSON-LD FAQPage целиком. */
.faq { border-top: 1px solid var(--border-subtle); }
.faq__item { border-bottom: 1px solid var(--border-subtle); }
.faq__item > summary {
  display: flex; align-items: center; justify-content: space-between; gap: 16px;
  min-height: 60px; padding: 14px 0; cursor: pointer; list-style: none;
  font-weight: 600; font-size: var(--fs-body); color: var(--graphite-900); line-height: 1.4;
}
.faq__item > summary::-webkit-details-marker { display: none; }
.faq__item > summary:hover { color: var(--blue-600); }
.faq__sign { position: relative; width: 16px; height: 16px; flex: none; }
.faq__sign::before, .faq__sign::after {
  content: ""; position: absolute; background: var(--blue-600);
  transition: transform var(--dur-base) var(--ease-standard);
}
.faq__sign::before { left: 0; top: 7px; width: 16px; height: 2px; }
.faq__sign::after { left: 7px; top: 0; width: 2px; height: 16px; }
.faq__item[open] .faq__sign::after { transform: rotate(90deg); }
.faq__a { padding: 0 0 20px; font-size: var(--fs-sm); color: var(--text-body); line-height: var(--lh-body); max-width: var(--measure-wide); }

/* --- Раскрывающиеся поля формы ---
   Обязательных полей три. Остальные шесть спрятаны, но не выброшены:
   кто готов описать среду и сроки, раскроет и опишет, остальным
   форма стоит трёх касаний. */
.more { grid-column: 1 / -1; }
.more > summary {
  display: inline-flex; align-items: center; gap: 8px; min-height: 44px; cursor: pointer; list-style: none;
  font-size: var(--fs-sm); font-weight: 600; color: var(--blue-600);
}
.more > summary::-webkit-details-marker { display: none; }
.more > summary:hover { color: var(--blue-700); }
.more__sign { position: relative; width: 12px; height: 12px; flex: none; }
.more__sign::before, .more__sign::after { content: ""; position: absolute; background: currentColor; }
.more__sign::before { left: 0; top: 5px; width: 12px; height: 2px; }
.more__sign::after { left: 5px; top: 0; width: 2px; height: 12px; transition: transform var(--dur-base) var(--ease-standard); }
.more[open] .more__sign::after { transform: rotate(90deg); }
.more__grid { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; padding-top: 4px; }
@media (max-width: 620px) { .more__grid { grid-template-columns: 1fr; } }

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

   ПРАВКА 29.07. Стояла на --blue-050 с рамкой --blue-100: 1.08:1 к белому
   и 1.20:1 у рамки. То есть самый конверсионный элемент страницы был
   и самым незаметным на ней, его нельзя было отличить от обычного абзаца.
   Полоса переведена на плотный тил. Левая амберная кромка в 4px даёт
   4.02:1 и работает засечкой: три призыва вдоль страницы теперь читаются
   как один повторяющийся элемент, а не как три случайных блока.

   Кнопка внутри должна быть .btn--onblue: белая на тиле. Тиловая кнопка
   на тиловой полосе не видна, а --btn--secondary с тиловой рамкой
   на этом фоне даёт 1.3:1. */
.cta-bar {
  display: flex; align-items: center; justify-content: space-between;
  gap: 20px 28px; flex-wrap: wrap;
  padding: clamp(20px, 3vw, 28px) clamp(20px, 3vw, 32px);
  border-radius: var(--radius-xl);
  background: var(--surface-island); color: var(--text-on-blue);
  border-left: 4px solid var(--accent-mark);
}
.cta-bar__t { font-weight: 700; font-size: var(--fs-md); color: var(--white); line-height: 1.35; }
/* Тот же 82 %, что и в полосе фактов: 4.81:1 при мелком кегле. */
.cta-bar__n { font-size: var(--fs-sm); color: rgba(255,255,255,0.82); margin-top: 4px; }

/* .stepnum удалён 03.08.2026 как мёртвый: номера шагов набирает .steps__n.
   Урок про инлайновый цвет мимо проверки контраста, ради которого класс
   заводили, живёт машинной проверкой инлайновых цветов в check.mjs. */
/* Ветка недоступной отрасли в выпадающем меню, эмиттер в layout.mjs. */
.ind-tile--off { opacity: .62; }

.brandwall {
  display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px;
  background: var(--sand-200); border: 1px solid var(--sand-200);
  border-radius: var(--radius-lg); overflow: hidden;
}
.brandwall__cell { background: var(--white); display: flex; align-items: center; justify-content: center; padding: 22px; min-height: 112px; min-width: 0; overflow: hidden; }
.brandwall__cell img { display: block; width: 100%; max-width: 240px; height: auto; opacity: .58; transition: opacity var(--dur-base) var(--ease-standard); }
.brandwall__cell:hover img { opacity: 1; }
/* Подписи под логотипами убраны 28.07.2026 по правке заказчика: сам логотип
   уже читается как название, и вторая строка тем же словом капсом делала
   из стены брендов список. Текст не потерян: девять названий перечислены
   в лиде секции обычным текстом, а alt каждой картинки остался на месте,
   поэтому запрос «аналог Warman» по-прежнему находит эту страницу. */
@media (max-width: 900px) { .brandwall { grid-template-columns: repeat(3, 1fr); } .brandwall__cell { min-height: 92px; padding: 16px 12px; } }
/* Три колонки держим почти до самого узкого экрана. Девять логотипов
   в две колонки это пять рядов и около 460px вертикали, на которой
   не сообщается ничего нового: это марки для узнавания, а не картинки
   для разглядывания. В три колонки на 375px логотип получает 76px
   ширины, узнаваемости хватает, а высота падает до 276px.
   Ниже 380px три колонки уже не читаются, там две. */
@media (max-width: 380px) { .brandwall { grid-template-columns: repeat(2, 1fr); } }

/* Карточка бренда на хабе /zamena/. Отличается от стены логотипов
   на главной тем, что это ссылка, а не картинка для узнавания:
   логотип приглушён, но не до .58, иначе кликабельная карточка
   выглядит выключенной. min-width: 0 обязателен: без него длинный
   заголовок «Аналоги насосов Goulds Pumps» распирает грид вбок,
   потому что минимальная ширина элемента грида по умолчанию auto. */
.brandcard { display: flex; flex-direction: column; gap: 10px; min-height: 232px; min-width: 0; }
.brandcard__logo { display: block; width: 100%; max-width: 168px; height: auto; opacity: .72; transition: opacity var(--dur-base) var(--ease-standard); }
.brandcard:hover .brandcard__logo { opacity: 1; }
.brandcard__note { font-size: var(--fs-xs); color: var(--text-muted); }
.brandcard__go { margin-top: auto; font-weight: 600; font-size: var(--fs-xs); color: var(--blue-600); }

/* Параметры: сетка на десктопе, карточки «имя: значение» на телефоне.
   Горизонтальная прокрутка в таблице характеристик убивает чтение. */
.params { display: grid; grid-template-columns: repeat(3, 1fr); gap: 1px; background: var(--border-subtle); border: 1px solid var(--border-subtle); border-radius: var(--radius-lg); overflow: hidden; }
.params--6 { grid-template-columns: repeat(6, 1fr); }
.params__cell { background: var(--white); padding: 16px; display: flex; flex-direction: column; gap: 4px; }
.params__k { font-size: var(--fs-caps); letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); font-weight: 600; }
.params__v { font-family: var(--font-display); font-weight: 800; font-size: var(--fs-md); color: var(--graphite-900); font-variant-numeric: tabular-nums; text-transform: none; letter-spacing: 0; }
@media (max-width: 1040px) { .params--6 { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 620px) {
  .params, .params--6 { grid-template-columns: 1fr; }
  .params__cell { flex-direction: row; align-items: baseline; justify-content: space-between; gap: 16px; padding: 12px 16px; }
  .params__v { font-size: var(--fs-body); text-align: right; }
}

/* Таблица соответствий и любая широкая таблица на телефоне */
@media (max-width: 720px) {
  .dtable--stack thead { display: none; }
  .dtable--stack tr { display: block; border-top: 1px solid var(--border-subtle); padding: 8px 0; }
  .dtable--stack tbody:not(.dtable__grp) tr:nth-child(even) { background: var(--table-stripe); }
  .dtable--stack td { display: flex; justify-content: space-between; gap: 16px; border: none; padding: 8px 16px; text-align: right; }
  .dtable--stack td::before { content: attr(data-k); font-weight: 600; color: var(--text-muted); text-align: left; flex: none; }
  .dtable--stack td:first-child { font-size: var(--fs-sm); }
  /* Строка карточкой: графа, которая не нормируется, на телефоне
     не печатает пустой прочерк, а исчезает. Иначе половина карточки
     это список того, чего в сплаве нет. */
  .dtable--stack .is-empty { display: none; }
  .dtable--stack .dtable__ghead { display: block; padding: 0; border-top: none; }
  .dtable--stack .dtable__ghead th { display: block; white-space: normal; padding: 18px 16px 8px; }
  /* Значение ячейки на телефоне это один флекс-элемент. Если внутри
     лежит блочная сноска, без обёртки она становится вторым элементом
     и встаёт в третью колонку рядом со значением, вместо того чтобы
     идти под ним. */
  .dtable--stack td > .cellv { display: block; text-align: right; }
}

/* ============================================================
   8. Липкая нижняя панель, телефон
   ============================================================ */
.sticky-cta { display: none; }
@media (max-width: 760px) {
  .sticky-cta {
    display: grid; grid-template-columns: 1fr 1fr; gap: 8px;
    position: fixed; left: 0; right: 0; bottom: 0; z-index: 70;
    /* Три значения, а не два. Сокращённый padding из двух это
       «вертикаль | горизонталь», и отступ на вырез экрана уезжал
       по бокам вместо низа: на iPhone кнопки прятались под системную
       полосу-индикатор и сжимались со 144px до 110px. */
    padding: 12px 12px calc(12px + env(safe-area-inset-bottom, 0px));
    background: var(--white); border-top: 1px solid var(--border-subtle);
  }
  /* Кнопка тут во всю ячейку, боковой отступ держит только подпись.
     При 22px «Оставить заявку» просит 161px в ячейке 144px и с nowrap
     вылезает наружу. Панель фиксированной высоты, переносить в две
     строки нельзя, поэтому ужимаем отступ, а не текст. */
  .sticky-cta .btn { width: 100%; height: 48px; min-height: 0; font-size: var(--fs-sm); padding: 0 10px; white-space: nowrap; }
  /* Отступ под панелью должен расти вместе с вырезом, иначе на iPhone
     нижние 27px последнего блока уезжают под неё. */
  body { padding-bottom: calc(80px + env(safe-area-inset-bottom, 0px)); }
}

/* ============================================================
   9. Формы заявки
   ============================================================ */
.leadform { display: grid; grid-template-columns: 1fr 1fr; gap: 16px; }
.leadform__wide { grid-column: 1 / -1; }
.leadform__note { grid-column: 1 / -1; font-size: var(--fs-xs); line-height: var(--lh-body); color: var(--text-muted); }
/* Ссылка на политику: без подчёркивания её не отличить от текста подписи.
   Зона нажатия была 18px, поднята до 44px отступами самой ссылки. */
.leadform__note a { color: var(--blue-600); text-decoration: underline; text-underline-offset: 2px; display: inline-block; padding: 12px 0; }
.leadform__note a:hover { color: var(--blue-700); }
.leadform__error { grid-column: 1 / -1; font-size: var(--fs-xs); color: var(--red-500); font-weight: 600; }
.leadform__trap { position: absolute; left: -9999px; width: 1px; height: 1px; overflow: hidden; }
.leadform__ok { padding: 40px 8px; text-align: center; }
.leadform__ok-title { font-family: var(--font-display); font-weight: 800; text-transform: uppercase; font-size: var(--fs-h3); color: var(--blue-600); }
@media (max-width: 620px) { .leadform { grid-template-columns: 1fr; } }

.contacts-line { margin-top: 32px; font-size: var(--fs-sm); line-height: 2; color: var(--text-body); }
.contacts-line strong { color: var(--graphite-900); }

/* ============================================================
   10. Печать
   ============================================================ */
@media print {
  .ubar, header.site, .sticky-cta, .foot, .drawer { display: none !important; }
  body { padding-bottom: 0; }
}

/* ============================================================
   КАРТОЧКА СЕРИИ И МЕЛКИЕ ПОВТОРЫ
   Раньше эти наборы жили в атрибутах style и повторялись
   по 132 раза на сайт. В атрибут медиазапрос не попадает,
   поэтому мобильную вёрстку было нечем править. Значения
   перенесены один в один, внешний вид не изменился.
   ============================================================ */
.scard__head { padding: 16px 20px; display: flex; flex-direction: column; gap: 4px; }
.scard__body { display: flex; flex-direction: column; gap: 0; min-height: 180px; overflow: hidden; }
/* Картинка в плитке каталога. Пропорция фиксированная, чтобы сетка
   из 23 плиток не прыгала от разной высоты фотографий. */
.scard__pic {
  display: flex; align-items: center; justify-content: center;
  background: var(--sand-050); border-bottom: 1px solid var(--border-subtle);
  aspect-ratio: 4 / 3; padding: 16px; flex: none;
  min-width: 0; overflow: hidden;
}
.scard__pic img { width: 100%; height: 100%; object-fit: contain; display: block; }
.scard__pic--empty { background: var(--sand-100); }
.scard__code {
  font-family: var(--font-display); font-weight: 800; font-size: clamp(1.625rem, 4vw, 2.375rem);
  color: var(--blue-500); letter-spacing: 0.02em;
}
.scard__pad { display: flex; flex-direction: column; gap: 8px; padding: var(--space-6); flex: 1; }
.scard__desc { font-size: var(--fs-sm); color: var(--text-body); line-height: var(--lh-body); }
.scard__meta { margin-top: auto; display: flex; flex-direction: column; gap: 4px; font-size: var(--fs-xs); color: var(--text-muted); }
/* Вся карточка это одна ссылка, поэтому «Характеристики» не отдельная цель
   нажатия. Отступ всё равно поднят до 44px: на телефоне палец попадает
   именно сюда, а разница между попаданием в карточку и мимо неё заметна. */
.scard__more { font-weight: 600; font-size: var(--fs-xs); color: var(--blue-600); display: inline-flex; align-items: center; min-height: 44px; }

.tile-title { font-weight: 600; font-size: var(--fs-sm); color: var(--graphite-900); }
.tile-mini { display: flex; flex-direction: column; gap: 4px; padding: 12px; border-radius: var(--radius-md); font-size: var(--fs-xs); line-height: var(--lh-body); }

/* --- Первый экран страницы «О компании» ---
   Был в одну колонку: заголовок, лид, бейджи, и вся правая половина
   экрана пустая. На широком мониторе это читается как недоделанная
   страница. Правая колонка отдана карточке условий поставки: там
   лежит то, что раньше висело сиротской серой строкой под бейджами
   (гарантия и оговорка про сервис) плюс срок и поставщик. Пустота
   заполнена фактами, а не картинкой ради картинки. */
.hero-about { display: grid; grid-template-columns: 1.15fr 0.85fr; gap: clamp(28px, 4vw, 56px); align-items: start; }
@media (max-width: 900px) { .hero-about { grid-template-columns: 1fr; } }

/* Пары «что : значение» в карточке. Ключ капсом 12px с трекингом,
   то есть по правилу для ярлыков, значение обычным вторичным кеглем. */
.specs { display: flex; flex-direction: column; margin-top: 18px; }
.specs > div { display: flex; flex-direction: column; gap: 4px; padding: 12px 0; border-top: 1px solid var(--border-subtle); }
.specs > div:first-child { border-top: none; padding-top: 0; }
.specs dt { font-size: var(--fs-caps); letter-spacing: var(--ls-caps); text-transform: uppercase; font-weight: 600; color: var(--text-muted); }
.specs dd { font-size: var(--fs-sm); line-height: 1.45; color: var(--graphite-900); }

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

   Стало линией с тремя узлами. Отрезок пройденного пути и его узел
   тиловые и залитые, будущие узлы полые. Сегменты стоят вплотную
   (gap: 0, отступ висит на тексте, а не на ячейке), поэтому три
   отрезка собираются в одну непрерывную линию.

   Цвет не единственный носитель смысла: у текущего этапа вместо срока
   стоит слово «сейчас». Карта лежит на белой карточке намеренно, линия
   --border-strong на песочном фоне даёт 1.32:1, то есть её там нет. */
.road { display: grid; grid-template-columns: repeat(3, 1fr); gap: 0; }
.road__rail { display: block; position: relative; height: 2px; background: var(--graphite-300); }
.road__step--now .road__rail { background: var(--accent-brand); }
.road__dot {
  position: absolute; left: 0; top: 50%; width: 14px; height: 14px; margin-top: -7px;
  box-sizing: border-box; border-radius: 50%; background: var(--white); border: 2px solid var(--graphite-300);
}
.road__step--now .road__dot { background: var(--accent-brand); border-color: var(--accent-brand); }
.road__body { padding: 18px 28px 0 0; }
.road__when { display: block; font-size: var(--fs-caps); letter-spacing: var(--ls-caps); text-transform: uppercase; font-weight: 600; color: var(--text-muted); }
.road__step--now .road__when { color: var(--blue-700); }
.road__what { display: block; margin-top: 8px; font-weight: 600; font-size: var(--fs-sm); line-height: 1.4; color: var(--graphite-900); }
/* На узком экране линия встаёт вертикально, узлы уходят в колонку слева.
   У последнего этапа линия обрезается по узлу: хвост, уходящий в пустоту
   под последним пунктом, читается как «есть и четвёртый этап». */
@media (max-width: 620px) {
  .road { grid-template-columns: 1fr; }
  .road__step { display: grid; grid-template-columns: 14px minmax(0, 1fr); column-gap: 18px; }
  .road__rail { width: 2px; height: auto; justify-self: center; }
  .road__dot { left: 50%; top: 0; margin: 0 0 0 -7px; }
  .road__body { padding: 0 0 24px; }
  .road__step:last-child .road__rail { align-self: start; height: 14px; }
  .road__step:last-child .road__body { padding-bottom: 0; }
}


/* --- Полоса фактов о заводе ---
   Живёт на /o-kompanii/. Раньше разметка носила классы .trust-grid,
   доставшиеся от полосы фактов главной. Саму полосу 29.07 с главной
   убрали вместе с её стилями, а разметка здесь осталась и рисовалась
   голым текстом: «с 2000работает завод», число слипалось с подписью.

   Четыре факта в один ряд. Сначала было шесть в два ряда, и это уже
   не полоса, а таблица, в которой нечего сравнивать. Лишние два убраны
   по смыслу: «Актобе» это не число и не про завод, а площадь цеха
   свёрнута в подпись к общей площади, потому что два соседних числа
   в квадратных метрах глаз читает как одно.

   Кромка над ячейкой амберная и в 2px. По правилу от 29.07 амбер значит
   «смотри сюда» и ставится только на плотный фон: на тиле --blue-650
   он даёт 4.02:1. Белая линия в 1px, стоявшая тут раньше, при 1.6:1
   к фону острова просто терялась. */
.factband { margin-bottom: clamp(24px, 4vw, 40px); }
.factband__grid {
  display: grid; grid-template-columns: repeat(4, 1fr);
  gap: clamp(20px, 3vw, 30px) clamp(20px, 3vw, 36px);
}
.factband__item { display: flex; flex-direction: column; gap: 6px; padding-top: 14px; border-top: 2px solid var(--accent-mark); }
.factband__v {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.5rem, 2.6vw, 2rem); line-height: var(--lh-tight);
  letter-spacing: var(--ls-display); color: var(--white);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.factband__l { font-size: var(--fs-xs); line-height: 1.45; color: var(--text-on-blue-soft); }

/* Мобильная считалась, а не подбиралась на глаз. На 375px полоса
   отдаёт под ячейку 107px: --wrap отнимает 40, --space-7 острова ещё 96,
   колонок две с зазором 24. «18 000 м²» кеглем 24px это около 130px,
   то есть число вылезало бы за ячейку. Поэтому на узком экране
   у острова отступ вдвое меньше, а число опускается на ступень
   шкалы до --fs-lead. На 400px и уже колонка одна: там даже так
   впритык, а число, вылезшее за край, хуже шести строк подряд. */
@media (max-width: 900px) { .factband__grid { grid-template-columns: repeat(2, 1fr); } }
@media (max-width: 560px) {
  .factband .island { padding: var(--space-5); }
  .factband__v { font-size: var(--fs-lead); }
}
@media (max-width: 360px) { .factband__grid { grid-template-columns: 1fr; } }

/* --- Карточка числа в сетке экономики ---
   Ломалось два раза. «до 30-40 %» не влезало в колонку из четырёх
   и рвалось посреди диапазона на «до 30-» и «40 %». И подписи стояли
   на разной высоте: под однострочным числом сразу, под двухстрочным
   ниже, сетка выглядела осыпавшейся.

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

   Диапазону запрещён перенос, подпись прижата к низу: карточки в сетке
   одной высоты, подписи встают в одну линию. */
.card--stat { display: flex; flex-direction: column; }
.statcard { display: flex; flex-direction: column; flex: 1; }
.statcard__pre { font-size: var(--fs-caps); font-weight: 600; letter-spacing: var(--ls-caps); text-transform: uppercase; color: var(--text-muted); margin-bottom: 6px; }
.statcard__v {
  font-family: var(--font-display); font-weight: 800;
  font-size: clamp(1.75rem, 3vw, 2.5rem); line-height: var(--lh-tight);
  letter-spacing: var(--ls-display); color: var(--accent-brand);
  font-variant-numeric: tabular-nums; white-space: nowrap;
}
.statcard__l { margin-top: auto; padding-top: 14px; font-size: var(--fs-xs); line-height: var(--lh-body); color: var(--text-body); }

/* --- Ссылка «дальше»: строка с заголовком и пояснением ---
   Стоит внизу /o-kompanii/ вместо второго призыва к действию. Вся строка
   это одна цель нажатия, поэтому высота поднята до 56px: минимум 44 плюс
   воздух, чтобы три подряд не слипались под пальцем. Левая полоса это
   не декор, а индикатор наведения: на hover она уплотняется, и строка
   отвечает на курсор, не двигая текст. */
.nextlink {
  display: block; text-decoration: none; padding: 12px 16px;
  min-height: 56px; border-radius: var(--radius-md);
  border: 1px solid var(--border-subtle); border-left: 3px solid var(--border-strong);
  /* Токены, а не сырые 0.15s: движение по всей системе одно. */
  background: var(--white); transition: border-color var(--dur-fast) var(--ease-standard), background var(--dur-fast) var(--ease-standard);
}
.nextlink:hover { border-left-color: var(--accent-brand); background: var(--sand-050); }
.nextlink:focus-visible { outline: 2px solid var(--blue-600); outline-offset: 2px; }
.nextlink__t { display: block; font-weight: 600; font-size: var(--fs-sm); color: var(--blue-600); line-height: 1.4; }
.nextlink__n { display: block; font-size: var(--fs-xs); color: var(--text-muted); line-height: var(--lh-body); margin-top: 4px; }

.muted-sm { font-size: var(--fs-xs); color: var(--text-muted); }
.accent { color: var(--blue-600); font-weight: 700; }
.ico { display: block; flex-shrink: 0; }

/* На узком экране карточке серии больше не нужна фиксированная высота:
   она задавалась ради ровной сетки, а в одну колонку сетки нет. */
@media (max-width: 600px) {
  .scard__body { min-height: 0; }
  .scard__head { padding: 16px; }
}
