/* ==========================================================================
   occ54.ru — единый CSS. Источник правды по значениям — docs/design-system.md.
   Все hex — только в этом блоке :root ниже. Компонентные классы — только var().
   ========================================================================== */

/* ---- Шрифты: самохостинг, cyrillic+latin, font-display: swap ---- */

/* Nunito — вариативный файл (один woff2 покрывает вес 700-900, Google
   Fonts отдаёт его же на все три запрошенных начертания), округлые
   терминалы вместо резкого гротеска Fira Sans — "мягче" по прямой
   просьбе владельца 2026-08-14, см. decisions.md. */
@font-face {
    font-family: "Nunito";
    font-style: normal;
    font-weight: 700 900;
    font-display: swap;
    src: url("../fonts/nunito-variable-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+2000-206F, U+20AC, U+2122;
}
@font-face {
    font-family: "Nunito";
    font-style: normal;
    font-weight: 700 900;
    font-display: swap;
    src: url("../fonts/nunito-variable-cyrillic.woff2") format("woff2");
    unicode-range: U+0400-045F, U+0490-0491, U+2116;
}
@font-face {
    font-family: "PT Sans";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/pt-sans-400-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+2000-206F, U+20AC, U+2122;
}
@font-face {
    font-family: "PT Sans";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/pt-sans-400-cyrillic.woff2") format("woff2");
    unicode-range: U+0400-045F, U+0490-0491, U+2116;
}
@font-face {
    font-family: "PT Sans";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("../fonts/pt-sans-700-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+2000-206F, U+20AC, U+2122;
}
@font-face {
    font-family: "PT Sans";
    font-style: normal;
    font-weight: 700;
    font-display: swap;
    src: url("../fonts/pt-sans-700-cyrillic.woff2") format("woff2");
    unicode-range: U+0400-045F, U+0490-0491, U+2116;
}
@font-face {
    font-family: "PT Mono";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/pt-mono-400-latin.woff2") format("woff2");
    unicode-range: U+0000-00FF, U+2000-206F, U+20AC, U+2122;
}
@font-face {
    font-family: "PT Mono";
    font-style: normal;
    font-weight: 400;
    font-display: swap;
    src: url("../fonts/pt-mono-400-cyrillic.woff2") format("woff2");
    unicode-range: U+0400-045F, U+0490-0491, U+2116;
}

/* ---- Токены (docs/design-system.md §1, §2, §5) ---- */

:root {
    /* Палитра — реальный бренд (docs/design-system.md, ревизия 2026-07-13):
       цвета взяты ТОЧНО из логотипа (128 px.svg) и фирменного бланка, не
       подобраны на глаз. --color-signal сохранён как алиас на teal —
       десятки существующих компонентов ссылаются на него по имени, менять
       все точки использования не требуется, меняется только значение. */
    --color-ink: #1A2027;
    --color-anthracite: #383E42;
    --color-paper: #FFFFFF;
    --color-paper-alt: #F4F7F8;
    --color-steel: #5B6672;
    --color-line: #E1E7E8;

    --color-teal: #00A3BD;
    --color-teal-dark: #027E93;
    --color-teal-tint: #E3F3F6;
    --color-red: #DA534F;
    --color-red-dark: #C3413D;
    --color-red-tint: #FBEAE9;
    --color-green: #6BB53E;
    --color-green-tint: #EDF7E6;
    /* Тёплая подложка — только для героя главной (метафора «холод/тепло»
       из слогана, см. .section--hero), не общий токен палитры. */
    --color-warm-tint: #FFF7EC;

    /* teal-dark, не base teal: --color-signal используется как цвет ТЕКСТА/
       интерактивных акцентов (ссылки, фокус-кольцо, CTA конфигуратора) —
       base teal даёт только 3.24:1 контраста на белом, недостаточно для
       обычного текста (нужно 4.5:1 по WCAG AA). Найдено при web-quality-audit
       2026-07-13. */
    --color-signal: var(--color-teal-dark);
    --color-signal-muted: var(--color-teal-tint);
    --color-on-signal: #FFFFFF;
    --color-paper-muted: #B9BEC2;

    --shadow-card: 0 2px 4px rgba(20, 50, 55, 0.05), 0 8px 24px rgba(20, 50, 55, 0.08);
    --shadow-card-hover: 0 12px 28px rgba(20, 50, 55, 0.14);

    /* Поверхности (переопределяются в скоупе Schüco, §3) */
    --surface-base: var(--color-paper);
    --surface-alt: var(--color-paper-alt);
    --text-base: var(--color-ink);
    --space-section: 96px;

    /* Типографика */
    --font-display: "Nunito", sans-serif;
    --font-text: "PT Sans", sans-serif;
    --font-mono: "PT Mono", monospace;

    --font-display-xl-size: 56px;
    --font-display-xl-lh: 60px;
    --font-display-l-size: 40px;
    --font-display-l-lh: 44px;
    --font-heading-size: 24px;
    --font-heading-lh: 30px;
    --font-body-l-size: 18px;
    --font-body-l-lh: 28px;
    --font-body-size: 16px;
    --font-body-lh: 26px;
    --font-caption-size: 14px;
    --font-caption-lh: 20px;
    --font-mono-data-size: 15px;
    --font-mono-data-lh: 22px;
    --font-mono-label-size: 12px;
    --font-mono-label-lh: 16px;

    /* Отступы (шкала кратна 8, §5) */
    --space-0-5: 4px;
    --space-1: 8px;
    --space-2: 16px;
    --space-3: 24px;
    --space-4: 32px;
    --space-5: 48px;
    --space-6: 64px;
    --space-7: 96px;
    --space-8: 128px;

    /* Радиусы и границы (§4, ревизия 2026-07-13: щедрые скругления вместо ≤2px) */
    --radius-sm: 10px;
    --radius-md: 18px;
    --radius-lg: 22px;
    --radius-pill: 980px;
    --radius-none: 0;
    --border-hairline: 1px solid var(--color-line);

    /* Было 1120px — на широких экранах контент выглядел зажатым узким
       островком на фоне серой страницы, владелец попросил шире
       (2026-08-14). */
    --content-max-width: 1360px;
}

/* Вариация раздела Schüco — переопределение токенов, не вторая система (§3) */
[data-brand="schuco"] {
    --surface-base: var(--color-anthracite);
    --surface-alt: #40474C;
    --text-base: var(--color-paper);
    --color-line: #4A5055;
    --space-section: 128px;
    --font-display-xl-size: 64px;
}

@media (min-width: 1024px) {
    :root {
        --font-display-xl-size: 56px;
        --font-display-xl-lh: 60px;
        --space-section: 128px;
    }
    [data-brand="schuco"] {
        --space-section: 176px;
    }
}
@media (max-width: 480px) {
    :root {
        --font-display-xl-size: 34px;
        --font-display-xl-lh: 38px;
        --font-display-l-size: 28px;
        --font-display-l-lh: 32px;
    }
    /* [data-brand=schuco] сидит на <body>, ближе к h1 по дереву, чем :root —
       без явного мобильного переопределения здесь он бы всегда побеждал
       :root и не давал H1 уменьшиться на маленьких экранах (было 64px
       на 390px, реальное горизонтальное переполнение). */
    [data-brand="schuco"] {
        --font-display-xl-size: 36px;
        --font-display-xl-lh: 40px;
    }
}

/* ---- Сброс и база ---- */

*, *::before, *::after { box-sizing: border-box; }
html { -webkit-text-size-adjust: 100%; }
body {
    margin: 0;
    background-color: var(--surface-base);
    color: var(--text-base);
    font-family: var(--font-text);
    font-size: var(--font-body-size);
    line-height: var(--font-body-lh);
    /* sticky-бар всегда внизу — резервируем ему место, чтобы контент не прятался под ним */
    padding-bottom: 56px;
}
/* Декоративный градиент по всей высоте страницы убран (2026-08-14) — при
   чередовании прозрачных/закрашенных .section он давал "полосатый",
   периодичный узор при скролле длинной страницы, владелец отметил как
   некрасиво. Холод→тепло градиент остаётся ТОЛЬКО в герое главной
   (.section--hero, самодостаточная секция) — не расползается по всей
   странице. Вне героя — плоский фон: белые .section чередуются с
   var(--surface-alt) секциями, как было исходно. */
img { max-width: 100%; height: auto; display: block; }
a { color: inherit; }

h1, h2, h3 { font-family: var(--font-display); margin: 0; }
h1 {
    font-size: var(--font-display-xl-size);
    line-height: var(--font-display-xl-lh);
    font-weight: 900;
}
h2 {
    font-size: var(--font-display-l-size);
    line-height: var(--font-display-l-lh);
    font-weight: 800;
}
h3 {
    font-size: var(--font-heading-size);
    line-height: var(--font-heading-lh);
    font-weight: 700;
}
p { margin: 0 0 var(--space-2); }

/* Единственный допустимый визуальный "подъём" — фокус (§4) */
:focus-visible {
    outline: 2px solid var(--color-signal);
    outline-offset: 2px;
}

.container {
    max-width: var(--content-max-width);
    margin: 0 auto;
    padding: 0 var(--space-2);
}
@media (min-width: 640px) {
    .container { padding: 0 var(--space-4); }
}
/* На широком экране фикс-максимум даёт непропорционально растущие поля
   (1920px → 280px пустоты с каждой стороны, на ультрашироких ещё больше) —
   владелец 2026-08-14: "отступ контейнера должен быть по 5% от общей
   ширины экрана". Выше порога прежнего --content-max-width отступ
   становится процентным, а не фиксированным, и растёт вместе с экраном. */
@media (min-width: 1360px) {
    .container { max-width: none; padding: 0 5%; }
}

/* Однотонный серый везде (2026-08-14) — раньше .section/.section--alt
   чередовали белый/серый, теперь оба варианта одного цвета (класс в
   шаблонах не убран — просто не влияет на фон, см. .section--alt ниже). */
.section {
    /* Было --space-7 (96px) — владелец попросил компактнее (2026-08-14). */
    padding: var(--space-6) 0;
    background: var(--surface-alt);
}
/* Холод→тепло градиент — не только в герое главной, а в "шапке" КАЖДОЙ
   страницы (первая секция внутри main, независимо от типа шаблона) —
   уточнено владельцем 2026-08-14. Значения переходов совпадают с .hero
   для единообразия. Не в скоупе Schüco — там своя тёмная территория без
   декора (§3 design-system.md, справочно).
   Градиент — на самой секции (ширина вьюпорта): здесь, в отличие от героя
   главной, НЕТ декора (иней/стеклопакет), который надо было бы держать в
   одной системе координат с градиентом — та проблема была только у .hero
   (см. decisions.md), сюда не переносится.
   Высота — владелец 2026-08-14: "градиент надо делать по высоте как на
   главной странице" — на страницах без героя (просто h1+кнопка) секция
   была короткой (~250px), диагональ на таком узком по высоте блоке
   визуально не читалась так же, как высокая полоса героя (~280-340px).
   min-height + вертикальное центрирование подтягивают высоту к диапазону
   героя главной без копирования его сложной вёрстки (иней/стеклопакет —
   только на главной, здесь не нужны). Градиент — на самой секции (flex-
   контейнере), а не на вложенном .container: иначе он красится только по
   высоте центрированного контента, а не по всей высоте min-height секции,
   оставляя серые полосы сверху/снизу (найдено сразу же при проверке). */
body:not([data-brand="schuco"]) main > .section:first-child {
    background-color: var(--color-paper-alt);
    background-image: linear-gradient(115deg, var(--color-teal-tint) 0%, var(--color-teal-tint) 52%, var(--color-warm-tint) 78%, var(--color-warm-tint) 100%);
    display: flex;
    align-items: center;
    min-height: 260px;
}
@media (min-width: 640px) {
    body:not([data-brand="schuco"]) main > .section:first-child { min-height: 320px; }
}
body:not([data-brand="schuco"]) main > .section:first-child > .container {
    width: 100%;
}
.section--alt { background: var(--surface-alt); }

/* Моноширинные данные — цены, сроки, размерные выноски (§0, §2) */
.data {
    font-family: var(--font-mono);
    font-size: var(--font-mono-data-size);
    line-height: var(--font-mono-data-lh);
    letter-spacing: 0.02em;
    font-variant-numeric: tabular-nums;
}
/* PT Sans, не mono: это подпись/метка (UI-текст), не табличные данные —
   моноширинный капс был приёмом старого "аскетичного" дизайна, отменённого
   2026-08-14 (см. decisions.md). Mono остаётся только там, где реально
   нужно табличное выравнивание цифр (.data, цены, номера заказов). */
.label {
    font-family: var(--font-text);
    font-weight: 700;
    font-size: 13px;
    line-height: 1.4;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-steel);
}

/* Размерная выноска — сигнатурный приём для чисел (§0) */
.callout {
    display: inline-flex;
    align-items: baseline;
    gap: var(--space-1);
    padding-top: var(--space-1);
    border-top: 1px solid var(--color-signal);
}
.callout::before {
    content: "";
}

/* ---- Шапка (§7.1) ---- */

.site-header {
    background: color-mix(in srgb, var(--surface-base) 85%, transparent);
    backdrop-filter: blur(20px) saturate(160%);
    -webkit-backdrop-filter: blur(20px) saturate(160%);
    border-bottom: var(--border-hairline);
    position: sticky;
    top: 0;
    z-index: 10;
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .site-header { background: var(--surface-base); }
}
/* container-класс убран с этого элемента 2026-08-14 (владелец: "растянуть
   на всю ширину экрана") — шапка идёт во весь вьюпорт, паддинги свои,
   не унаследованные от .container. */
.site-header__inner {
    display: flex;
    align-items: center;
    justify-content: space-between;
    gap: var(--space-2);
    padding: var(--space-2);
}
@media (min-width: 640px) {
    .site-header__inner { padding: var(--space-2) var(--space-4); }
}
@media (min-width: 1360px) {
    .site-header__inner { padding: var(--space-2) 5%; }
}
.site-header__logo {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    text-decoration: none;
    white-space: nowrap;
    flex-shrink: 0;
}
.site-header__mark {
    width: 44px;
    height: 37px;
    flex-shrink: 0;
}
.site-header__wordmark {
    display: flex;
    flex-direction: column;
    font-family: var(--font-display);
    font-weight: 900;
    font-size: 14px;
    line-height: 1.15;
    letter-spacing: 0.01em;
    text-transform: uppercase;
    color: var(--color-teal-dark);
}
@media (max-width: 480px) {
    .site-header__wordmark { display: none; }
    .site-header__mark { width: 40px; height: 34px; }
}
.site-header__nav {
    display: none;
}
.site-header__phone {
    font-family: var(--font-mono);
    /* Крупнее и жирнее на мобильном — владелец 2026-08-14. У PT Mono нет
       реального начертания 700 (Google Fonts отдаёт только 400 на любой
       запрошенный вес — проверено), браузер синтезирует жирность сам;
       text-stroke добавляет плотности глифам, раз настоящего bold-файла
       не существует. */
    font-size: 17px;
    font-weight: 700;
    -webkit-text-stroke: 0.4px currentColor;
    /* red-dark, не base red: red-текст на белом даёт только 4.07:1,
       недостаточно для обычного текста (нужно 4.5:1) — базовый red
       остаётся точным цветом бланка/логотипа для заливок (кнопка, бейджи). */
    color: var(--color-red-dark);
    text-decoration: none;
    white-space: nowrap;
}
.site-header__burger {
    background: var(--color-paper-alt);
    border: none;
    border-radius: 50%;
    width: 44px;
    height: 44px;
    display: flex;
    align-items: center;
    justify-content: center;
    cursor: pointer;
    flex-shrink: 0;
    transition: background-color 150ms ease;
}
.site-header__burger:hover { background: var(--color-teal-tint); }
.site-header__burger span,
.site-header__burger span::before,
.site-header__burger span::after {
    content: "";
    display: block;
    width: 18px;
    height: 2px;
    background: var(--text-base);
    position: relative;
}
.site-header__burger span::before { top: -6px; position: absolute; }
.site-header__burger span::after { top: 6px; position: absolute; }

@media (min-width: 640px) {
    .site-header__phone { font-size: 18px; }
}

/* Десктоп — горизонтальная навигация в шапке вместо бургера/мобильного
   оверлея (не «увеличенная мобильная версия», см. .claude/gotchas.md). */
@media (min-width: 960px) {
    .site-header__nav {
        display: flex;
        align-items: center;
        gap: var(--space-4);
        flex: 1;
        justify-content: center;
    }
    .site-header__nav a {
        text-decoration: none;
        font-weight: 700;
        font-size: var(--font-caption-size);
        color: var(--text-base);
        white-space: nowrap;
        padding: var(--space-1) var(--space-2);
        border-radius: var(--radius-pill);
        transition: background-color 150ms ease, color 150ms ease;
    }
    .site-header__nav a:hover {
        color: var(--color-teal-dark);
        background: var(--color-teal-tint);
    }
    .site-header__burger { display: none; }
    .nav-overlay { display: none !important; }
}

/* ---- Мобильное меню: полноэкранный оверлей (§7.1), не поверх sticky-бара ---- */

/* Центрированная композиция (логотип сверху, пункты по центру, без
   разделительных линий — воздух вместо hairline) — по референсу живого
   сайта occ54.ru, владелец отметил его мобильное меню как удачное
   (2026-08-14). */
/* Плавное появление/скрытие — владелец 2026-08-14: "выпадение с переходом
   со 100% прозрачности в 0% и обратно", уточнено — "плавное выпадение"
   (не просто fade на месте, а сдвиг сверху вниз, как открывающаяся
   шторка). display:none нельзя анимировать напрямую, поэтому всегда
   display:flex, а видимость держит связка opacity+visibility (visibility
   переключается с задержкой — мгновенно при открытии, только ПОСЛЕ
   анимации при закрытии, иначе оверлей пропадёт и потеряет
   интерактивность одномоментно, без плавности). */
/* Владелец 2026-08-14: сдвиг убран совсем, осталось только изменение
   прозрачности (1с) — без transform. visibility ждёт ту же долгую
   анимацию (1000мс), иначе оверлей стал бы неинтерактивным/скрытым
   раньше, чем реально закончит растворяться.
   Замечено владельцем: в Chrome анимация работает, в Яндекс.Браузере —
   нет (мгновенно). CSS на сервере идентичен рабочему в Chrome — значит
   дело не в разметке/значениях, а в самом браузере. Яндекс.Браузер
   (Chromium-форк) имеет собственный режим "Турбо"/экономии трафика,
   который, по документированному поведению, умеет отключать CSS-анимации/
   эффекты для экономии ресурсов на слабом канале — стоит проверить именно
   это в настройках браузера, прежде чем гадать дальше с длительностью. */
.nav-overlay {
    position: fixed;
    inset: 0;
    bottom: 56px;
    background: var(--surface-base);
    z-index: 15;
    padding: var(--space-4) var(--space-2) var(--space-4);
    overflow-y: auto;
    display: flex;
    flex-direction: column;
    opacity: 0;
    visibility: hidden;
    transition: opacity 1000ms ease, visibility 0s linear 1000ms;
}
.nav-overlay.is-open {
    opacity: 1;
    visibility: visible;
    transition: opacity 1000ms ease, visibility 0s linear 0s;
}
.nav-overlay__close {
    background: var(--color-paper-alt);
    border: none;
    border-radius: 50%;
    width: 44px;
    height: 44px;
    align-self: flex-end;
    cursor: pointer;
    font-size: 20px;
    flex-shrink: 0;
}
.nav-overlay__mark {
    width: 72px;
    height: 61px;
    margin: var(--space-2) auto var(--space-4);
    flex-shrink: 0;
}
.nav-overlay__list {
    list-style: none;
    margin: 0;
    padding: 0;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: var(--space-4);
}
.nav-overlay__list a {
    display: block;
    text-decoration: none;
    font-family: var(--font-display);
    font-weight: 700;
    font-size: var(--font-heading-size);
    color: var(--color-teal-dark);
    text-align: center;
}

/* ---- Sticky-бар: телефон + MAX + Telegram + квиз (§7.2) ---- */

/* Матовое стекло (iOS tab-bar), скруглённые верхние углы (единый язык с
   футером/карточками) — переработано 2026-08-14, владелец отметил старую
   версию (плоская плашка, жёсткие разделители, моно-капс подписи, тонкие
   геометрические значки-загадки) как "бельмо на глазу". */
.sticky-bar {
    position: fixed;
    left: 0;
    right: 0;
    bottom: 0;
    z-index: 20;
    display: grid;
    grid-template-columns: repeat(4, 1fr);
    background: color-mix(in srgb, var(--color-anthracite) 86%, transparent);
    backdrop-filter: blur(20px) saturate(160%);
    -webkit-backdrop-filter: blur(20px) saturate(160%);
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
    box-shadow: 0 -8px 24px rgba(20, 50, 55, .12);
}
@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))) {
    .sticky-bar { background: var(--color-anthracite); }
}
.sticky-bar__item {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: 4px;
    min-height: 60px;
    color: var(--color-paper-muted);
    text-decoration: none;
    font-family: var(--font-text);
    font-weight: 700;
    font-size: 11.5px;
    touch-action: manipulation;
    transition: color 150ms ease, background-color 150ms ease;
}
.sticky-bar__item svg { width: 22px; height: 22px; }
.sticky-bar__item:hover, .sticky-bar__item:active {
    color: var(--color-paper);
    background: rgba(255, 255, 255, .06);
}
/* "Позвонить" — главное действие, тот же красный, что и первичные кнопки
   сайта (срочное действие), не просто ещё один равноправный пункт. */
.sticky-bar__item--primary { color: var(--color-red-tint); }
.sticky-bar__item--primary:hover, .sticky-bar__item--primary:active { color: #fff; }
.sticky-bar__item--primary svg { color: var(--color-red-tint); }

/* ---- Футер ---- */

.site-footer {
    background: var(--color-anthracite);
    color: var(--color-paper);
    padding: var(--space-6) 0 var(--space-5);
    margin-bottom: 56px; /* место под sticky-бар */
    /* Скруглённые верхние углы — "лист", а не плоский обрубок страницы,
       единый язык со скруглёнными карточками/кнопками сайта. */
    border-radius: var(--radius-lg) var(--radius-lg) 0 0;
}
.site-footer__name {
    font-family: var(--font-display);
    font-weight: 800;
    font-size: 20px;
}
.site-footer a { color: var(--color-paper); }
.site-footer__meta {
    /* PT Sans, не PT Mono: это обычный юридический абзац (название ИП,
       ИНН, адрес), не табличные данные — моноширинный шрифт здесь читался
       чужеродно, "не красиво". Моно оставлен только для реально табличных
       данных (цены, номера в .data). */
    font-family: var(--font-text);
    font-size: var(--font-caption-size);
    line-height: 1.6;
    color: var(--color-paper-muted);
    margin-top: var(--space-3);
}

/* ---- Хлебные крошки ---- */

.breadcrumbs {
    font-family: var(--font-text);
    font-size: 13px;
    color: var(--color-steel);
    padding: var(--space-2) 0;
}
.breadcrumbs a { text-decoration: none; }
.breadcrumbs a:hover { text-decoration: underline; }
.breadcrumbs__sep { margin: 0 var(--space-1); }

/* ---- Кнопка (§7.3) ---- */

.btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    gap: var(--space-1);
    font-family: var(--font-text);
    font-weight: 700;
    /* 19px, не --font-body-size (16px): у белого текста на --color-red фоне
       контраст 4.07:1 — проходит WCAG AA только по порогу "крупного текста"
       (жирный ≥18.66px, 3:1), а не обычного текста (4.5:1). Красный — точный
       бренд-цвет письма/логотипа, менять сам hex нельзя (см. §1), поэтому
       поднимаем размер вместо цвета. */
    font-size: 19px;
    padding: var(--space-2) var(--space-4);
    /* Pill-форма — iOS-стиль (по просьбе владельца 2026-08-14), было
       radius-sm (10px). */
    border-radius: var(--radius-pill);
    text-decoration: none;
    cursor: pointer;
    border: 1px solid transparent;
    transition: background-color 150ms ease, transform 150ms ease, box-shadow 150ms ease;
    touch-action: manipulation;
}
/* Первичная — --color-red (срочное действие, §7.4), не teal */
.btn--primary {
    background: var(--color-red);
    color: var(--color-on-signal);
    box-shadow: var(--shadow-card);
}
.btn--primary:hover {
    background: var(--color-red-dark);
    box-shadow: var(--shadow-card-hover);
    transform: translateY(-2px);
}
.btn--secondary {
    background: transparent;
    border-color: var(--color-teal);
    /* teal-dark, не base teal: teal-текст на белом даёт только 3.24:1,
       недостаточно для обычного текста (нужно 4.5:1) — см. §1 design-system.md,
       teal-dark специально описан для этого случая. */
    color: var(--color-teal-dark);
}
.btn--secondary:hover { background: var(--color-teal-tint); }
.btn--tertiary {
    background: none;
    color: var(--color-teal-dark);
    padding-left: 0;
    padding-right: 0;
    text-decoration: underline;
}
.btn:disabled {
    background: var(--color-steel);
    color: var(--color-paper);
    cursor: not-allowed;
    box-shadow: none;
    transform: none;
}
.btn--block { width: 100%; }
/* Владелец 2026-08-14: "кнопка вызвать мастера и тел, разнеси по 2
   строкам" — на герое главной текст+телефон в один ряд заставляли номер
   переноситься посреди цифр на узких экранах. Отдельный модификатор, не
   правка .btn целиком — остальные кнопки сайта однострочные. */
.btn--stacked {
    flex-direction: column;
    gap: 2px;
    line-height: 1.25;
}

/* Пульсирующее кольцо — только для ОДНОГО акцентного CTA (герой главной),
   не на каждую .btn--primary сайта: "один оркестрованный момент лучше
   рассеянных эффектов" (см. процесс скила frontend-design). */
.btn--pulse { position: relative; }
.btn--pulse::after {
    content: "";
    position: absolute;
    inset: 0;
    border-radius: inherit;
    box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-red) 45%, transparent);
    animation: ring-pulse 2.6s ease-out infinite;
    pointer-events: none;
}
@keyframes ring-pulse {
    0% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-red) 45%, transparent); }
    70% { box-shadow: 0 0 0 14px color-mix(in srgb, var(--color-red) 0%, transparent); }
    100% { box-shadow: 0 0 0 0 color-mix(in srgb, var(--color-red) 0%, transparent); }
}
@media (prefers-reduced-motion: reduce) {
    .btn--pulse::after { animation: none; }
}

/* ---- Таблица цен (§7.4) ---- */

.price-table {
    width: 100%;
    border-collapse: collapse;
}
.price-table th {
    text-align: left;
    font-family: var(--font-text);
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-steel);
    font-weight: 700;
    padding: var(--space-1) var(--space-2);
    border-bottom: var(--border-hairline);
}
.price-table td {
    padding: var(--space-2);
    border-bottom: var(--border-hairline);
    font-family: var(--font-text);
}
.price-table td.data { font-family: var(--font-mono); white-space: nowrap; }
.price-table caption {
    text-align: left;
    font-family: var(--font-text);
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-steel);
    padding-bottom: var(--space-1);
}

@media (max-width: 640px) {
    .price-table, .price-table thead, .price-table tbody, .price-table th, .price-table td, .price-table tr {
        display: block;
    }
    .price-table thead { display: none; }
    .price-table tr {
        border-bottom: var(--border-hairline);
        padding: var(--space-2) 0;
    }
    .price-table td {
        border-bottom: none;
        padding: var(--space-0-5) 0;
        display: flex;
        justify-content: space-between;
        gap: var(--space-2);
    }
    .price-table td::before {
        content: attr(data-label);
        font-family: var(--font-text);
        font-weight: 700;
        font-size: 13px;
        text-transform: uppercase;
        letter-spacing: 0.04em;
        color: var(--color-steel);
        flex-shrink: 0;
    }
}

/* ---- Факты об объекте (ЖК) ---- */

.object-facts {
    display: grid;
    gap: var(--space-2);
    margin: 0 0 var(--space-3);
}
.object-facts > div {
    padding-bottom: var(--space-2);
    border-bottom: var(--border-hairline);
}
.object-facts dt { margin-bottom: var(--space-0-5); }
.object-facts dd { margin: 0; font-family: var(--font-text); }

/* ---- Герой главной (§7.6) ---- */

/* Секция героя — полноэкранная тёплая/холодная подложка (метафора слогана
   «держим границу между холодом и теплом целой»), см. .hero__canvas/.hero__seal. */
.section--hero {
    position: relative;
    overflow: hidden;
    background-color: var(--color-paper-alt);
}

/* Градиент — на .hero, во всю ширину вьюпорта (не .container): владелец
   2026-08-14 — "контейнер тоже на всю ширину, а то градиент както обрезано
   смотрится". Раньше градиент жил на .container и обрывался на
   --content-max-width, оставляя однотонные поля по краям на широких
   экранах. .hero__glazing/.hero__weather-cold остаются позиционированы
   в процентах от ЭТОГО ЖЕ .hero (не от вложенного .hero__grid) — так что
   декор и градиент всегда в одной системе координат и не расходятся
   (тот самый баг с --content-max-width от 2026-08-14, см. decisions.md).
   Контент (текст/иллюстрация) — во вложенном .hero__grid с классом
   .container, чтобы не растягиваться на весь экран вместе с фоном. */
.hero {
    position: relative;
    background-image: linear-gradient(115deg, var(--color-teal-tint) 0%, var(--color-teal-tint) 52%, var(--color-warm-tint) 78%, var(--color-warm-tint) 100%);
}
.hero__grid {
    position: relative;
    display: grid;
    grid-template-columns: 1.4fr 1fr;
    /* Увеличенный зазор (было --space-5=48px) — иначе лого/бейджи в правой
       колонке заезжали на стеклопакет, который стоит на границе колонок
       (see .hero__glazing). Замечено владельцем 2026-08-14. */
    gap: 260px;
    align-items: center;
}
/* Стеклопакет вид с торца — привязан к .hero (теперь во всю ширину
   вьюпорта, см. выше), НЕ к вложенному .hero__grid: декор синхронизирован
   с градиентом, который тоже на .hero. Буквальная метафора: два стекла,
   зазор между ними — там и проходит граница холода/тепла — холодное
   стекло со снегом снаружи, тёплое с конденсатом изнутри, который со
   временем испаряется. */
/* Снег — по всей холодной части градиента героя (не только у стеклопакета),
   владелец явно попросил шире, "по всей территории холодной части". */
.hero__weather-cold {
    position: absolute;
    inset: 0;
    width: 58%;
    overflow: hidden;
    pointer-events: none;
}

/* Дистанционная рамка сверху/снизу (реальный конструктив стеклопакета —
   спейсер держит стёкла на фиксированном расстоянии по периметру), чёткие
   границы стёкол, широкий зазор — по замечанию владельца "выглядит не
   естественно" (2026-08-14). */
.hero__glazing {
    position: absolute;
    top: 6%;
    bottom: 6%;
    left: 57%;
    width: 88px;
    display: flex;
    flex-direction: column;
    pointer-events: none;
    box-shadow: var(--shadow-card);
    border-radius: 4px;
    overflow: hidden;
}
/* Дистанционная рамка — тёмный металл (реальный спейсер алюминиевый/
   тёмно-серый, не брендовый акцент), заметнее прежней. Референс от
   владельца 2026-08-14: тёмная рамка по контуру + глянцевый блик на
   стекле — фотореализма в CSS не будет, но эти два приёма читаются. */
.hero__glazing-spacer {
    flex-shrink: 0;
    height: 12px;
    background: linear-gradient(180deg, #7A828B, #3E444B);
    border-top: 1px solid #949CA4;
    border-bottom: 1px solid #2B2F34;
}
.hero__glazing-body {
    position: relative;
    flex: 1;
    display: flex;
}
.hero__pane {
    position: relative;
    width: 20px;
    flex-shrink: 0;
    overflow: hidden;
    box-sizing: border-box;
    border-top: 3px solid #4A5058;
    border-bottom: 3px solid #4A5058;
}
.hero__pane--cold {
    background: linear-gradient(180deg, rgba(255, 255, 255, .65), var(--color-teal-tint) 92%);
    border-left: 3px solid #4A5058;
}
.hero__pane--warm {
    background: linear-gradient(180deg, rgba(255, 255, 255, .55), var(--color-warm-tint) 92%);
    border-right: 3px solid #4A5058;
}
/* Глянцевый блик по диагонали — имитация отражения на стекле. */
.hero__pane--cold::before,
.hero__pane--warm::before {
    content: "";
    position: absolute;
    inset: -20% -60%;
    background: linear-gradient(115deg, transparent 40%, rgba(255, 255, 255, .8) 48%, transparent 56%);
}
/* Блик по краю стекла — тонкая яркая линия, чтобы читалось именно как
   стекло, не просто цветная плашка. */
.hero__pane--cold::after,
.hero__pane--warm::after {
    content: "";
    position: absolute;
    top: 4%;
    bottom: 4%;
    width: 2px;
    background: rgba(255, 255, 255, .85);
}
.hero__pane--cold::after { left: 3px; }
.hero__pane--warm::after { right: 3px; }
.hero__cavity {
    position: relative;
    width: 46px;
    flex-shrink: 0;
    background: rgba(255, 255, 255, .18);
}
/* Граница холода/тепла — буквально в зазоре между стёклами, не
   произвольная кривая линия по всему герою. */
.hero__cavity::before {
    content: "";
    position: absolute;
    left: 50%;
    top: 0;
    bottom: 0;
    width: 2px;
    background: var(--color-teal);
    box-shadow: 0 0 8px color-mix(in srgb, var(--color-teal) 55%, transparent);
    transform: translateX(-50%) scaleY(0);
    transform-origin: top;
    animation: glazing-boundary-grow 1s .2s cubic-bezier(.2,.7,.2,1) forwards;
}
@keyframes glazing-boundary-grow { to { transform: translateX(-50%) scaleY(1); } }

.snowflake {
    position: absolute;
    top: -8%;
    border-radius: 50%;
    background: #fff;
    box-shadow: 0 0 3px rgba(255, 255, 255, .8);
    opacity: 0;
    animation-name: snow-fall, snow-sway;
    animation-timing-function: linear, ease-in-out;
    animation-iteration-count: infinite, infinite;
    animation-direction: normal, alternate;
}
@keyframes snow-fall {
    0% { top: -8%; opacity: 0; }
    12% { opacity: .9; }
    85% { opacity: .6; }
    100% { top: 106%; opacity: 0; }
}
@keyframes snow-sway {
    from { transform: translateX(-3px); }
    to { transform: translateX(3px); }
}

.droplet {
    position: absolute;
    border-radius: 60% 60% 60% 5%;
    background: linear-gradient(160deg, rgba(255, 255, 255, .9), rgba(150, 190, 210, .55));
    opacity: 0;
    animation: droplet-cycle 6.5s ease-in-out infinite;
}
@keyframes droplet-cycle {
    0% { opacity: 0; transform: scale(.5) rotate(-45deg); }
    25% { opacity: .85; transform: scale(1) rotate(-45deg); }
    65% { opacity: .85; transform: scale(1) rotate(-45deg); }
    100% { opacity: 0; transform: scale(.4) translateY(4px) rotate(-45deg); }
}

@media (prefers-reduced-motion: reduce) {
    .snowflake { animation: none; opacity: .6; top: 40%; }
    .droplet { animation: none; opacity: .5; transform: scale(1) rotate(-45deg); }
    .hero__cavity::before { animation: none; transform: translateX(-50%) scaleY(1); }
}
@media (max-width: 860px) {
    .hero__glazing, .hero__weather-cold { display: none; }
}
.hero__lead {
    font-size: var(--font-body-l-size);
    line-height: var(--font-body-l-lh);
    color: var(--color-steel);
    max-width: 46ch;
}
/* Без панели-подложки: логотип и бейджи стоят прямо на градиенте героя —
   заливной короб перекрывал слишком много (был непропорционально крупным
   на широких экранах). */
.hero__illustration {
    position: relative;
    display: flex;
    align-items: center;
    justify-content: center;
    min-height: 260px;
}
.hero__illustration > svg { width: 44%; max-width: 220px; height: auto; }
.hero__badge {
    position: absolute;
    display: inline-flex;
    align-items: center;
    gap: var(--space-1);
    background: var(--color-paper);
    border-radius: var(--radius-sm);
    box-shadow: var(--shadow-card);
    padding: var(--space-1) var(--space-2);
    font-size: var(--font-caption-size);
    font-weight: 700;
    white-space: nowrap;
}
.hero__badge--1 { top: 10%; left: 6%; }
.hero__badge--2 { bottom: 10%; right: 6%; }
.hero__badge-icon { width: 18px; height: 18px; color: var(--color-green); flex-shrink: 0; }

@media (max-width: 860px) {
    /* gap:260px (заведён для десктопного двухколоночного .hero__grid, чтобы
       бейджи/лого не наезжали на стеклопакет между колонками) в одну колонку
       превращался в вертикальный gap между иллюстрацией и текстом —
       на мобильном был огромный пустой градиентный пролёт (~260px) между
       лого/бейджами и заголовком. Владелец 2026-08-14: "снизу очень большое
       расстояние до след блока". */
    .hero__grid { grid-template-columns: 1fr; gap: var(--space-4); }
    .hero__illustration { order: -1; min-height: 200px; }
    .hero__badge { font-size: 11px; padding: var(--space-0-5) var(--space-1); }
    /* Владелец 2026-08-14: "кнопка по центру" (в мобильной версии) — .btn
       обычно inline-flex (сам по себе не центрируется margin:auto), здесь
       делаем block+fit-content именно на мобильном, не трогая desktop,
       где кнопка осталась слева вместе с заголовком/текстом. */
    .hero__text .btn--stacked { display: flex; width: fit-content; margin-left: auto; margin-right: auto; }
    /* Иней/линия-шов — метафора "холод слева / тепло справа" держится на
       двухколоночной раскладке. В одну колонку герой становится намного
       выше, а SVG-линия (viewBox 1160×600) растягивается на весь этот
       рост и уродливо искажается — на мобильном проще и честнее её не
       показывать, чем чинить искажение. */
    .hero__canvas, .hero__seal { display: none; }
}

/* ---- Тезис-слоган (§0) ---- */

.thesis {
    max-width: 720px;
    margin: 0 auto;
    text-align: center;
    font-family: var(--font-display);
    font-weight: 800;
    font-size: var(--font-display-l-size);
    line-height: var(--font-display-l-lh);
    text-wrap: balance;
}
.thesis em { font-style: normal; color: var(--color-teal); }
/* "холодом"/"теплом" выделены отдельно от остального курсива — владелец
   2026-08-14: заглавными + цветом стороны метафоры (холод=синий/teal-dark,
   тепло=красный). -dark варианты, не базовые teal/red — на белом фоне у
   базовых недостаточно контраста для текста (см. decisions.md, 2026-07-13). */
.thesis__cold { text-transform: uppercase; color: var(--color-teal-dark); }
.thesis__warm { text-transform: uppercase; color: var(--color-red-dark); }

/* ---- Траст-ряд фактов ----
   Один настоящий счётчик (15 лет — реально считаемый факт, анимируется
   при скролле, см. main.js) отделён от трёх качественных фактов (Schüco/
   24-7/своё производство — не числа, не должны визуально притворяться
   ими тем же гигантским шрифтом, что вводило в заблуждение). */

.trust-row {
    display: flex;
    align-items: center;
    flex-wrap: wrap;
    gap: var(--space-4);
}
.trust-row__hero {
    display: flex;
    align-items: baseline;
    gap: var(--space-1);
    padding-right: var(--space-4);
    border-right: 1px solid var(--color-line);
}
.trust-row__value {
    font-family: var(--font-mono);
    font-weight: 700;
    font-size: 28px;
    line-height: 1;
    color: var(--color-ink);
    font-variant-numeric: tabular-nums;
}
.trust-row__label {
    font-size: var(--font-caption-size);
    color: var(--color-steel);
}
.trust-row__facts {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-3);
    flex: 1;
}
.trust-row__fact {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    font-size: 14.5px;
    font-weight: 700;
}
.trust-row__fact svg { width: 18px; height: 18px; flex-shrink: 0; }
.trust-row__fact span { font-weight: 400; color: var(--color-steel); }

@media (max-width: 640px) {
    .trust-row { flex-direction: column; align-items: flex-start; gap: var(--space-3); }
    .trust-row__hero { border-right: none; padding-right: 0; }
}

/* ---- Плитки хабов (главная) ---- */

.hub-grid {
    display: grid;
    grid-template-columns: repeat(2, 1fr);
    gap: var(--space-1);
    /* Владелец 2026-08-14 (мобильная версия): промежуток от заголовка
       "Все услуги" до плиток был слишком тесным. */
    margin-top: var(--space-3);
}
@media (min-width: 768px) {
    .hub-grid { grid-template-columns: repeat(4, 1fr); }
}
/* Стиль iOS-ярлыка: крупная иконка + мелкая некрикливая подпись, щедрые
   поля от края блока, более круглые "squircle"-подобные углы (по просьбе
   владельца 2026-08-14, было — 24px жирным почти впритык к краям). */
.hub-tile {
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    gap: var(--space-2);
    text-align: center;
    min-width: 0;
    min-height: 128px;
    padding: var(--space-4) var(--space-3);
    background: var(--color-paper);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);
    text-decoration: none;
    /* Плитка всегда светлая карточка (в т.ч. в тёмном скоупе Schüco) —
       цвет текста фиксированный ink, НЕ var(--text-base) (тот в схоупе
       Schüco белый и слился бы с белым фоном плитки). */
    color: var(--color-ink);
    font-family: var(--font-display);
    font-weight: 700;
    font-size: 16px;
    line-height: 1.3;
    transition: box-shadow 150ms ease, transform 150ms ease;
    touch-action: manipulation;
}
.hub-tile:hover {
    box-shadow: var(--shadow-card-hover);
    transform: translateY(-3px);
}
.hub-tile__icon {
    width: 56px;
    height: 56px;
    border-radius: 18px;
    display: flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
}
.hub-tile__icon svg { width: 28px; height: 28px; }
.hub-tile__icon--teal { background: var(--color-teal-tint); color: var(--color-teal); }
.hub-tile__icon--red { background: var(--color-red-tint); color: var(--color-red); }
.hub-tile__icon--green { background: var(--color-green-tint); color: var(--color-green); }

/* ---- Карточка кейса до/после (§7.5) ---- */

.case-card {
    background: var(--color-paper);
    color: var(--color-ink);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
    padding: var(--space-2);
}
.case-card__photos {
    display: grid;
    grid-template-columns: 1fr 1fr;
    gap: var(--space-1);
}
.case-card__photos img { border: var(--border-hairline); }
.case-card__address { font-family: var(--font-mono); font-size: var(--font-caption-size); color: var(--color-steel); margin-top: var(--space-2); }
.case-card__duration { font-family: var(--font-mono); font-size: var(--font-mono-data-size); }

@media (max-width: 480px) {
    .case-card__photos { grid-template-columns: 1fr; }
}

/* ---- FAQ (§7.6) ---- */

.faq-item {
    border-bottom: var(--border-hairline);
}
.faq-item summary {
    padding: var(--space-2) 0;
    cursor: pointer;
    list-style: none;
    display: flex;
    align-items: center;
    justify-content: space-between;
    font-family: var(--font-text);
    font-weight: 700;
    gap: var(--space-2);
}
.faq-item summary::-webkit-details-marker { display: none; }
.faq-item__icon {
    flex-shrink: 0;
    width: 16px;
    height: 16px;
    position: relative;
}
.faq-item__icon::before, .faq-item__icon::after {
    content: "";
    position: absolute;
    background: var(--text-base);
    top: 50%; left: 50%;
    transform: translate(-50%, -50%);
}
.faq-item__icon::before { width: 16px; height: 2px; }
.faq-item__icon::after { width: 2px; height: 16px; transition: transform 150ms ease; }
.faq-item[open] .faq-item__icon::after { transform: translate(-50%, -50%) rotate(90deg); }
.faq-item p { padding-bottom: var(--space-2); color: var(--color-steel); }

/* ---- Форма (§7.7) ---- */

.form-field { margin-bottom: var(--space-2); }
.form-field label {
    display: block;
    font-family: var(--font-text);
    font-weight: 700;
    font-size: 13px;
    color: var(--color-steel);
    margin-bottom: var(--space-1);
}
.form-field input,
.form-field textarea {
    width: 100%;
    font-family: var(--font-text);
    font-size: var(--font-body-size);
    padding: var(--space-2);
    border: var(--border-hairline);
    border-radius: var(--radius-sm);
    background: var(--surface-base);
    color: var(--text-base);
}
.form-field input:focus-visible,
.form-field textarea:focus-visible {
    outline: 2px solid var(--color-signal);
    outline-offset: 2px;
}
.form-field--optional label::after {
    content: " (необязательно)";
    text-transform: none;
    color: var(--color-steel);
    letter-spacing: normal;
}
.form-field__error {
    color: var(--color-red);
    font-size: var(--font-caption-size);
    margin-top: var(--space-0-5);
}
.form-consent {
    font-size: var(--font-caption-size);
    color: var(--color-steel);
}
.form-consent a { color: var(--color-teal-dark); }

.lead-form__thanks {
    background: var(--color-green-tint);
    color: var(--color-ink);
    border-radius: var(--radius-md);
    padding: var(--space-3);
}
.lead-form__submit-error {
    color: var(--color-red);
    font-size: var(--font-caption-size);
    margin-top: var(--space-2);
}

/* Honeypot — скрыт визуально, но доступен ботам-заполнителям форм */
.form-field--honeypot {
    position: absolute;
    left: -9999px;
    width: 1px;
    height: 1px;
    overflow: hidden;
}

/* =====================================================================
   Конфигуратор москитных сеток — вендорный JS (public/assets/js/vendor/
   mosquito-configurator.js, класс MosquitoConfigurator), НЕ трогаем его —
   он сам создаёт DOM с этими именами классов (.cfg-*). Здесь только
   внешний вид под токены docs/design-system.md: hairline вместо теней,
   radius-sm вместо их 12-16px, без градиентов/крупных скруглений.
   ===================================================================== */

.cfg-wrap {
    display: grid;
    grid-template-columns: 280px 1fr;
    gap: var(--space-3);
}
@media (max-width: 860px) {
    .cfg-wrap { grid-template-columns: 1fr; }
}

.cfg-panel {
    border: var(--border-hairline);
    overflow-x: hidden;
    overflow-y: auto;
}
/* embedded-режим (см. cfgOptions.mode в nets-configurator.php) — обычный
   поток страницы, без sticky (была бы конфликт со скроллом сайта), НО
   высота по-прежнему ограничена высотой канвас-превью (то же правило
   §7 design-system.md «на 1440px нет ощущения пустоты» — здесь наоборот,
   не должно быть ощущения «колонка растянута выше канваса», см.
   .claude/gotchas.md, разбор /bugs 2026-07-13: без этого ограничения
   левая панель конфигуратора вытягивалась заметно выше самого канваса). */
.cfg-wrap--embedded .cfg-panel {
    position: static;
    max-height: 70vh;
}
.cfg-wrap--embedded .cfg-right {
    position: static;
    height: auto;
    max-height: none;
}

.cfg-section {
    padding: 10px 14px;
    border-bottom: var(--border-hairline);
}
.cfg-section:last-child { border-bottom: none; }
.cfg-section-title {
    font-family: var(--font-text);
    font-weight: 700;
    font-size: 11px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-steel);
    margin-bottom: var(--space-1);
}

.cfg-type-cards { display: flex; flex-direction: column; gap: 6px; }
.cfg-type-card {
    display: flex;
    align-items: center;
    gap: var(--space-1);
    padding: 7px 10px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-sm);
    cursor: pointer;
    background: var(--surface-base);
    touch-action: manipulation;
}
.cfg-type-card:hover { border-color: var(--color-signal); }
.cfg-type-card.active { border-color: var(--color-signal); background: var(--color-signal-muted); }
.cfg-type-icon { font-size: 18px; width: 26px; text-align: center; flex-shrink: 0; }
.cfg-type-name { font-family: var(--font-text); font-weight: 700; font-size: 12px; line-height: 1.2; }
.cfg-type-desc { font-size: 10px; color: var(--color-steel); margin-top: 1px; }

.cfg-mesh-btns { display: flex; flex-wrap: wrap; gap: 6px; }
.cfg-mesh-btn {
    padding: 4px 10px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-sm);
    background: var(--surface-base);
    color: var(--text-base);
    font-family: var(--font-text);
    font-weight: 700;
    font-size: 11px;
    cursor: pointer;
    touch-action: manipulation;
}
.cfg-mesh-btn:hover { border-color: var(--color-signal); }
.cfg-mesh-btn.active { border-color: var(--color-signal); background: var(--color-signal); color: var(--color-on-signal); }

.cfg-colors { display: flex; flex-wrap: wrap; gap: var(--space-1); }
.cfg-color-swatch {
    width: 28px;
    height: 28px;
    border-radius: var(--radius-sm);
    cursor: pointer;
    border: 2px solid var(--color-line);
    position: relative;
    touch-action: manipulation;
}
.cfg-color-swatch.active { border-color: var(--color-signal); outline: 2px solid var(--color-signal); outline-offset: 1px; }
.cfg-color-swatch[title]:hover::after {
    content: attr(title);
    position: absolute;
    bottom: calc(100% + var(--space-1));
    left: 50%;
    transform: translateX(-50%);
    background: var(--color-anthracite);
    color: var(--color-paper);
    font-size: 11px;
    padding: var(--space-0-5) var(--space-1);
    border-radius: var(--radius-sm);
    white-space: nowrap;
    pointer-events: none;
    z-index: 5;
}

.cfg-dim-row { display: grid; grid-template-columns: 1fr 1fr; gap: var(--space-1); }
.cfg-label {
    display: block;
    font-family: var(--font-mono);
    font-size: var(--font-mono-label-size);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-steel);
    margin-bottom: var(--space-0-5);
}
.cfg-input {
    width: 100%;
    padding: 7px 10px;
    border: var(--border-hairline);
    border-radius: var(--radius-sm);
    background: var(--surface-base);
    color: var(--text-base);
    font-family: var(--font-mono);
    font-size: 13px;
    box-sizing: border-box;
}
.cfg-input:focus-visible { outline: 2px solid var(--color-signal); outline-offset: 2px; }
.cfg-checkbox-row {
    display: flex;
    align-items: center;
    gap: 6px;
    margin-top: 7px;
    cursor: pointer;
    font-size: 12px;
}

.cfg-qty-row { display: flex; align-items: center; gap: var(--space-1); }
.cfg-qty-btn {
    width: 30px;
    height: 30px;
    border: var(--border-hairline);
    border-radius: var(--radius-sm);
    background: var(--surface-base);
    font-size: 16px;
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    touch-action: manipulation;
}
.cfg-qty-btn:hover { background: var(--color-signal); color: var(--color-on-signal); border-color: var(--color-signal); }
.cfg-qty-val { font-family: var(--font-mono); font-size: 15px; min-width: 22px; text-align: center; }

.cfg-options { display: flex; flex-direction: column; gap: var(--space-1); }
.cfg-opt-row { display: flex; flex-direction: column; gap: var(--space-0-5); }
.cfg-opt-label { font-size: 11px; font-weight: 700; color: var(--color-steel); }
.cfg-prop-group { display: flex; gap: var(--space-0-5); flex-wrap: wrap; }
.cfg-prop-btn {
    padding: 4px 10px;
    border: 1px solid var(--color-line);
    border-radius: var(--radius-sm);
    background: var(--surface-base);
    color: var(--text-base);
    font-size: 11px;
    cursor: pointer;
    line-height: 1.4;
    touch-action: manipulation;
}
.cfg-prop-btn:hover { border-color: var(--color-signal); }
.cfg-prop-btn.active { background: var(--color-signal); border-color: var(--color-signal); color: var(--color-on-signal); }
.cfg-prop-btn[data-val="no"].active { background: var(--surface-alt); border-color: var(--color-line); color: var(--text-base); }
.cfg-prop-sub { display: none; margin-top: var(--space-0-5); }
.cfg-prop-sub.visible { display: flex; gap: var(--space-0-5); flex-wrap: wrap; }

.cfg-right { display: flex; flex-direction: column; }
.cfg-canvas-wrap {
    border: var(--border-hairline);
    display: flex;
    flex-direction: column;
}
.cfg-canvas-head {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: var(--space-2);
    border-bottom: var(--border-hairline);
    font-family: var(--font-mono);
    font-size: var(--font-mono-label-size);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-steel);
}
.cfg-canvas-zoom { display: flex; gap: var(--space-0-5); }
.cfg-zoom-btn {
    width: 28px;
    height: 28px;
    border: var(--border-hairline);
    border-radius: var(--radius-sm);
    background: var(--surface-base);
    color: var(--text-base);
    cursor: pointer;
    display: flex;
    align-items: center;
    justify-content: center;
    touch-action: manipulation;
}
.cfg-zoom-btn:hover { background: var(--color-signal); color: var(--color-on-signal); border-color: var(--color-signal); }
[data-cfg="canvas"] {
    display: block;
    width: 100%;
    aspect-ratio: 1;
    max-height: 70vh;
    background: var(--surface-alt);
}
.cfg-canvas-dims {
    padding: var(--space-1) var(--space-2);
    font-family: var(--font-mono);
    font-size: var(--font-caption-size);
    color: var(--color-steel);
    border-top: var(--border-hairline);
    text-align: center;
}

.cfg-price-bar {
    display: flex;
    align-items: center;
    gap: var(--space-3);
    padding: var(--space-3);
    border-top: var(--border-hairline);
    flex-wrap: wrap;
}
.cfg-price-info { flex: 1; min-width: 0; }
.cfg-price-label {
    font-family: var(--font-mono);
    font-size: var(--font-mono-label-size);
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-steel);
    margin-bottom: var(--space-0-5);
}
.cfg-price-total { font-family: var(--font-mono); font-size: 24px; font-weight: 700; color: var(--color-signal); line-height: 1; }
.cfg-price-breakdown {
    font-family: var(--font-mono);
    font-size: var(--font-caption-size);
    color: var(--color-steel);
    margin-top: var(--space-0-5);
    white-space: nowrap;
    overflow: hidden;
    text-overflow: ellipsis;
}
.cfg-price-breakdown span { color: var(--text-base); }
.cfg-order-btn {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    flex-shrink: 0;
    padding: var(--space-2) var(--space-3);
    background: var(--color-signal);
    color: var(--color-on-signal);
    border: none;
    border-radius: var(--radius-sm);
    font-family: var(--font-text);
    font-size: var(--font-body-size);
    font-weight: 700;
    cursor: pointer;
    text-decoration: none;
    white-space: nowrap;
    touch-action: manipulation;
}
.cfg-order-btn:hover { background: var(--color-teal-dark); }
.cfg-order-btn:disabled { background: var(--color-steel); cursor: not-allowed; }

.cfg-skeleton {
    background: linear-gradient(90deg, var(--surface-alt) 25%, var(--color-line) 50%, var(--surface-alt) 75%);
    background-size: 200% 100%;
    animation: cfgShimmer 1.2s infinite;
    border-radius: var(--radius-sm);
    height: 36px;
}
@keyframes cfgShimmer { 0% { background-position: 200%; } 100% { background-position: -200%; } }
@media (prefers-reduced-motion: reduce) {
    .cfg-skeleton { animation: none; }
}

.nets-configurator__bots {
    display: flex;
    flex-wrap: wrap;
    gap: var(--space-1);
    margin-top: var(--space-2);
}
.nets-configurator__bots .btn { margin-top: 0; }

/* ---- Перелинковка (смежные услуги / полезно знать) ---- */

.related-links {
    list-style: none;
    margin: 0 0 var(--space-4);
    padding: 0;
}
.related-links li { border-bottom: var(--border-hairline); }
.related-links a {
    display: block;
    padding: var(--space-2) 0;
    text-decoration: none;
    color: var(--color-signal);
    font-weight: 700;
}
.related-links a:hover { text-decoration: underline; }

/* ---- Утилиты ---- */

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

@media (prefers-reduced-motion: reduce) {
    * {
        transition-duration: 0.001ms !important;
        animation-duration: 0.001ms !important;
    }
}


/* ---- Квиз «Что случилось с окном?» (§7.8) ---- */

.quiz {
    max-width: 560px;
    padding: var(--space-3);
    background: var(--color-paper);
    color: var(--color-ink);
    border-radius: var(--radius-lg);
    box-shadow: var(--shadow-card);
    scroll-margin-top: var(--space-3);
}
.quiz__progress {
    font-family: var(--font-text);
    font-weight: 700;
    font-size: 13px;
    color: var(--color-steel);
    margin: 0 0 var(--space-1);
    padding-bottom: var(--space-1);
    border-bottom: 1px solid var(--color-line);
}
.quiz__step[hidden] { display: none; }
.quiz__question {
    font-family: var(--font-display);
    font-size: var(--font-heading-size);
    line-height: var(--font-heading-lh);
    margin: 0 0 var(--space-2);
}
.quiz__options {
    display: flex;
    flex-direction: column;
    gap: var(--space-1);
    margin-bottom: var(--space-2);
}
.quiz__option {
    display: block;
    width: 100%;
    text-align: left;
    font-family: var(--font-text);
    font-size: var(--font-body-size);
    padding: var(--space-2);
    background: var(--color-paper-alt);
    border: 1px solid transparent;
    border-radius: var(--radius-sm);
    cursor: pointer;
    transition: background-color 150ms ease, border-color 150ms ease;
    touch-action: manipulation;
}
.quiz__option:hover { background: var(--color-teal-tint); border-color: var(--color-teal); }
.quiz__option:focus-visible { outline: 2px solid var(--color-signal); outline-offset: 2px; }
.quiz__result {
    font-family: var(--font-text);
    font-size: var(--font-body-size);
    line-height: var(--font-body-lh);
    padding: var(--space-2);
    margin-bottom: var(--space-2);
    background: var(--color-teal-tint);
    border-radius: var(--radius-md);
}
.quiz__result:empty { display: none; }
.quiz [data-quiz-back] { margin-top: var(--space-1); }

@media (max-width: 480px) {
    .quiz { max-width: none; }
}

/* ---- Личный кабинет (Этап 7.5) ---- */

.lk-auth {
    max-width: 420px;
}
.lk-auth__notice {
    margin-top: var(--space-2);
    padding: var(--space-2);
    background: var(--color-signal-muted);
    color: var(--color-ink);
    border-radius: var(--radius-sm);
    font-size: var(--font-body-size);
}
.lk-auth [data-lk-back] { margin-top: var(--space-1); }

.lk-dashboard h2 {
    margin-top: var(--space-4);
}
.lk-orders {
    display: flex;
    flex-direction: column;
    gap: var(--space-2);
}
.lk-order {
    padding: var(--space-2);
    background: var(--color-paper);
    color: var(--color-ink);
    border-radius: var(--radius-md);
    box-shadow: var(--shadow-card);
}
.lk-order__head {
    display: flex;
    justify-content: space-between;
    align-items: baseline;
    gap: var(--space-1);
    margin-bottom: var(--space-1);
}
.lk-order__number {
    font-family: var(--font-mono);
}
.lk-order__status {
    font-family: var(--font-text);
    font-weight: 700;
    font-size: 13px;
    text-transform: uppercase;
    letter-spacing: 0.04em;
    color: var(--color-signal);
}
.lk-order__service {
    font-weight: 700;
    margin: 0 0 var(--space-0-5);
}
.lk-order__address {
    color: var(--color-steel);
    margin: 0 0 var(--space-1);
}

/* ---- Живая анимация по всему сайту (2026-08-14, по прямой просьбе
   владельца "больше анимации, более живой сайт") ----
   Общий принцип: появление карточек при скролле (main.js добавляет/снимает
   .is-visible через IntersectionObserver) + micro-interactions на hover/
   active. prefers-reduced-motion отключает и то, и другое. */

.reveal {
    opacity: 0;
    transform: translateY(22px);
    transition: opacity .6s cubic-bezier(.2,.7,.2,1), transform .6s cubic-bezier(.2,.7,.2,1);
}
.reveal.is-visible { opacity: 1; transform: translateY(0); }

.hub-tile__icon { transition: transform .25s ease; }
.hub-tile:hover .hub-tile__icon { transform: scale(1.1) rotate(-4deg); }

.faq-item summary { transition: color .2s ease; }
.faq-item summary:hover { color: var(--color-teal-dark); }

.btn:active { transform: scale(.96); }
.btn--primary:active { transform: scale(.96); }

.card__icon, .hero__badge { transition: transform .25s ease; }
.hero__badge:hover { transform: translateY(-2px); }

@media (prefers-reduced-motion: reduce) {
    .reveal {
        opacity: 1;
        transform: none;
        transition: none;
    }
    .hub-tile:hover .hub-tile__icon,
    .btn:active,
    .btn--primary:active,
    .hero__badge:hover {
        transform: none;
    }
}
