body.modal-open{overflow:hidden}

/* Резерв места под вертикальный скроллбар на ВСЕХ страницах: иначе на короткой странице (без
   скролла) центрированная шапка/контент смещается по горизонтали относительно длинной (со скроллом)
   — меню в шапке «прыгает» при переходах. scrollbar-gutter держит ширину вьюпорта постоянной. */
html{scrollbar-gutter:stable}

/* === МЕХАНИКА общей обвязки (НЕ дизайн) ===
   Дизайн шапки/подвала/карточки модалки/формы заявки приходит ИЗ ИМПОРТА index.html
   (см. pageio.derive_frame → запись хрома, kind="frame"; грузится в base.html после CSS
   страницы). Здесь — только то, чего нет в index и что нужно для работы оболочки:
   полоса-шапка макета, прилипание, оверлей модалки, статус отправки формы. */

/* Полоса шапки на уровне макета (base.html): прилипание — класс is-sticky (переключатель в
   админке). Полоса — прямой потомок body, поэтому sticky работает на всю высоту страницы
   одинаково. Фон здесь — НЕЙТРАЛЬНЫЙ запасной (до первого импорта): цвета полосы выводятся
   из правила `.top` импортированной главной (pageio._derive_shared_css → .site-header в записи
   хрома, грузится после этого файла и перекрывает фон). Оформление содержимого — из хрома. */
.site-header{background:#14181c;position:relative;z-index:60;color:#fff}
.site-header.is-sticky{position:sticky;top:0}
/* Ссылки шапки/подвала оформляем здесь, а не полагаемся на глобальный
   `a{color:inherit;text-decoration:none}` страницы: его нет на части страниц (документы, 404),
   из-за чего пункты меню/ссылки/бренд получали браузерный вид — подчёркивание и фиолетовый
   «посещённый», а на 404 тёмный бренд сливался с тёмной полосой. Цвет шапки — белый (#fff выше),
   бренд и пункты меню наследуют его; цвет ссылок подвала задаёт запись хрома (грузится позже).
   Намеренно НЕ трогаем кнопки-CTA (`.header-actions .btn`): у `.primary/.secondary` свой цвет,
   поэтому ограничиваемся брендом и ссылками <nav>, а не всеми `.site-header a`. */
.site-header .brand,.site-header nav a{color:inherit;text-decoration:none}
footer a{text-decoration:none}
/* Текущий/наведённый пункт меню — ярче (раньше это правило жило в content_page.css и работало
   лишь на контент-страницах; теперь — в хроме, на всех страницах). Специфичность (0,2,2) выше
   `.site-header nav a` (0,1,2), поэтому подсветка не теряется. */
.site-header nav a.active,.site-header nav a:hover{color:#fff}
/* Тот же текущий пункт в мобильной панели — подсвечиваем фоном (как :hover), цвет ярче.
   Фон — нейтральный запасной: акцентная подсветка выводится из `.mobile-nav-panel a:hover`
   импортированной главной (pageio._derive_shared_css) и перекрывает это правило. */
.mobile-nav-panel a.active{background:rgba(255,255,255,.12);color:#fff}
/* Переход к якорю раздела при прилипшей шапке: иначе заголовок раздела прячется под шапкой.
   Значение — запасное на момент загрузки; точную высоту шапки подставляет JS (partials/scripts.html). */
:root:has(.site-header.is-sticky){scroll-padding-top:96px}
/* Поле контейнера шапки вынесено в переменную: от него считается вылет мобильной панели
   (авто-правило `left/right:-<поле>` растягивает её от края до края полосы, см. pageio). */
.site-header{--gb-gutter:22px}
.site-header-inner{width:min(1180px,calc(100% - var(--gb-gutter)*2));margin:0 auto}
/* CTA-кнопки шапки: одинаковая ГЕОМЕТРИЯ на всех страницах. У каждой страницы свой padding/ширина
   кнопок (например home `padding:0 20px`, partners `0 24px`), из-за чего менялась ширина
   .header-actions и «прыгал» зазор бренд↔меню. Жёстко фиксируем тут (специфичность 0,3,0 бьёт
   правила страниц). Цвет/фон кнопок по-прежнему из CSS страницы — полное выравнивание вида
   (в т.ч. цветов) даёт derive в записи обвязки при (ре)импорте. */
.site-header .header-actions .btn{width:auto;min-width:0;flex:0 0 auto;padding:0 20px}

/* Оверлей модалки заявки (открытие/закрытие). Оформление карточки и полей формы — из хрома. */
.modal{position:fixed;inset:0;z-index:9999;display:none;align-items:center;justify-content:center;padding:18px;background:rgba(3,8,10,.72);backdrop-filter:blur(8px)}
.modal.is-open,.modal:target{display:flex}
/* Закрытие: снять один лишь хеш недостаточно (:target не пересчитывается после
   history.replaceState, а кнопкой закрытия у импортированной формы может быть <button>),
   поэтому показ гасится классом — его ставит/снимает partials/scripts.html. */
.modal.is-closed{display:none!important}
.modal-backdrop{position:absolute;inset:0;display:block}
/* Карточка — НАД подложкой. Подложка позиционирована, а .modal-card в импортируемых вёрстках
   обычно нет (position:static), и по правилам отрисовки позиционированный элемент оказывается
   выше — подложка перекрывала карточку и перехватывала клики (модалка закрывалась от клика по
   форме). z-index работает только у позиционированного элемента, поэтому и position:relative. */
.modal-card{position:relative;z-index:1}
/* Страховка от вылезания формы за экран на узких экранах: сетки/поля из импортированной вёрстки
   рассчитаны на свою ширину, а карточка ограничена шириной окна. Ширину и вид полей задаёт
   импорт — здесь только границы. */
.modal-card{max-width:100%;box-sizing:border-box;overflow-x:hidden}
.modal-card *{max-width:100%;box-sizing:border-box}
.modal-card input,.modal-card select,.modal-card textarea{width:100%}
/* Крестик закрытия: в исходниках это обычно <button> (её содержимое центрирует сам браузер), а
   при импорте она становится ссылкой-якорем (pageio.normalize_modal) — центрирование задаём
   здесь. Размер, форма и цвет по-прежнему приходят из CSS импортированной главной. */
.modal-close{display:inline-flex;align-items:center;justify-content:center;line-height:1;text-decoration:none}

/* === Свёртка длинного меню: пункты, которые не помещаются в строку, уезжают в «Ещё ▾» ===
   Пунктов в меню столько, сколько страниц и разделов у сайта, и на узком десктопе строка
   переставала помещаться в полосу. Перенос делает скрипт (partials/scripts.html); здесь —
   механика, без которой измерить переполнение нельзя: меню не переносит пункты на вторую
   строку и не распирает полосу, а лишнее прячется за границей (скрипт как раз и сравнивает
   scrollWidth с clientWidth). Оформление списка выводится из `.mobile-nav-panel` вёрстки
   (pageio._derive_shared_css) — здесь нейтральный запасной вид. */
/* Меню НЕ сжимается и НЕ растягивается: лишние пункты убирает скрипт (см. «⋯» ниже).
   Сжатие (`flex-shrink`) резало последний видимый пункт на полуслове — строка «влезала» по
   замеру, а flex всё равно ужимал меню под остаток места; растягивание (`flex-grow`) разносило
   бренд и кнопки по краям полосы. Без JS меню просто обрежется по краю полосы — страховка
   `overflow:hidden`, раскладку это не ломает. */
.site-header nav{flex:0 0 auto;flex-wrap:nowrap;white-space:nowrap;overflow:hidden}
.site-header .nav-more-wrap{position:relative;flex:0 0 auto}
/* Кнопка свёрнутого меню — крупное многоточие: подписью «Ещё» она забирала бы ту самую
   ширину, ради которой всё и затевалось, и требовала бы перевода. Название — в aria-label. */
.site-header .nav-more{
    display:inline-flex;align-items:center;justify-content:center;cursor:pointer;
    background:none;border:0;margin:0;padding:0 6px;color:inherit;
    font:inherit;font-size:26px;line-height:1;letter-spacing:.02em;
}
.site-header .nav-more[hidden]{display:none}
.site-header .nav-more-list{
    position:absolute;right:0;top:calc(100% + 10px);z-index:70;
    display:none;grid-auto-rows:min-content;gap:4px;min-width:200px;padding:10px;
    border-radius:14px;background:#14181c;box-shadow:0 18px 40px rgba(0,0,0,.28);
}
.site-header .nav-more-list.is-open{display:grid}
.site-header .nav-more-list a{display:block;padding:9px 12px;border-radius:10px;
    color:inherit;text-decoration:none;white-space:nowrap}
/* Текущий пункт подсвечивается и внутри свёрнутого списка: правило `nav a.active` на него не
   действует — он лежит вне <nav>. Фон здесь нейтральный запасной, акцентный выводится из
   вёрстки (pageio.auto_frame_css). Саму кнопку «⋯» помечаем, когда активный пункт спрятан
   в ней, иначе текущий раздел на узком экране никак не виден. */
.site-header .nav-more-list a.active{background:rgba(255,255,255,.12);color:#fff}
.site-header .nav-more-wrap:has(a.active) .nav-more{color:#fff}
/* Свёрнутое меню — десктопная история: на мобильной ширине работает панель «бургера»,
   а `nav` там скрыт (правило выводится при импорте, см. pageio._derive_shared_css). */

/* Чекбокс мобильного меню не должен влиять на раскладку. В вёрстках он скрыт
   `position:absolute;opacity:0` БЕЗ координат, поэтому остаётся в «статической позиции» — там,
   где стоял бы в потоке. Пока строка шапки шире полосы (длинное меню до свёртки), эта позиция
   уезжает вправо, и невидимый чекбокс растягивает документ: страница получает горизонтальную
   прокрутку и полосу пустого фона справа. Прижимаем его к началу полосы. Только для
   `<input>`: вариант переключателя `<button id="navToggle">` — видимый элемент, его не трогаем. */
.site-header input#navToggle{position:absolute;left:0;top:0;width:1px;height:1px;
    margin:0;padding:0;opacity:0;pointer-events:none}

/* Мобильная панель не шире экрана. В вёрстках её ширина задана относительно родителя
   (`width:100%` у контейнера в шапке), и при боковых отступах полосы панель вылезала за правый
   край вьюпорта — пункты и кнопка обрезались. Ограничиваем шириной окна и считаем padding
   внутрь (border-box), не трогая само оформление панели. */
.site-header .mobile-nav-panel,.site-header #mobileNav{max-width:100vw;box-sizing:border-box}
.site-header .mobile-nav-panel *{box-sizing:border-box}

/* И не выше экрана. Пунктов в меню столько, сколько у сайта страниц, и длинное меню на
   невысоком экране (или в альбомной ориентации) не помещается: панель — оверлей, вместе с
   шапкой она прилипшая, прокрутка страницы её низ не показывает, и до последних пунктов с
   кнопкой заявки было не добраться. Даём панели собственную прокрутку; `overscroll-behavior`
   не даёт «протащить» прокрутку на страницу под ней. Значение здесь — запасное (шапка около
   64–76px), точную высоту по фактическому положению панели ставит JS (partials/scripts.html). */
.site-header .mobile-nav-panel{max-height:calc(100vh - 80px);overflow-y:auto;
    overscroll-behavior:contain}
@supports (height:100dvh){
  .site-header .mobile-nav-panel{max-height:calc(100dvh - 80px)}
}

/* Кнопка-CTA в мобильной панели: в вёрстках правило `.mobile-nav-panel a` (обычная ссылка меню:
   display:block, вертикальные отступы) специфичнее правил `.btn`, из-за чего подпись кнопки
   прижималась к левому краю. Селектор ниже заведомо специфичнее обоих — фон, цвет и радиус
   по-прежнему из вёрстки, здесь только раскладка подписи. */
.site-header .mobile-nav-panel a.mobile-menu-cta{
    display:flex;align-items:center;justify-content:center;text-align:center;
    padding-left:18px;padding-right:18px;
}

/* Подвал: элементы сетки по умолчанию имеют min-width:auto и не дают колонкам сжиматься —
   длинная ссылка (почта, реквизиты) распирала сетку за край экрана. Сколько колонок и на каких
   ширинах — задаёт вёрстка главной (её медиазапросы переносятся в обвязку), здесь только защита
   от переполнения. */
footer *{min-width:0}
footer a,footer p{overflow-wrap:anywhere}
/* Исключение — бренд подвала: название компании набрано ОДНИМ словом, и правила выше действовали
   на него ровно наоборот. `overflow-wrap:anywhere` разрешал рвать слово посередине, а `min-width:0`
   снимал у колонки сетки минимум по содержимому (по умолчанию неразрывное слово раздвигало колонку
   под себя) — в итоге название переносилось по буквам и не помещалось в первую колонку.
   Возвращаем слову цельность, а его колонке — минимальную ширину по содержимому: колонка снова
   подстраивается под логотип, защита от длинных ссылок и реквизитов в остальных колонках цела.
   `:has(> .brand)` — грид-элемент, внутри которого лежит бренд (имя класса колонки задаёт вёрстка). */
footer .brand,footer :has(> .brand){min-width:min-content}
footer .brand{overflow-wrap:normal}
/* Ширина контейнера обвязки НЕ должна зависеть от страницы, на которой он показан. Правило
   `footer .container{width:…}` копируется в запись хрома из CSS главной (frame_css_from_markup) и
   задаёт только те свойства, что были в исходнике. Отступы (padding) там не заданы, поэтому в силе
   оставался `.container{padding:0 22px}` из CSS текущей страницы: на страницах-документах контейнер
   подвала терял 44px внутренней ширины (box-sizing:border-box) против обычных страниц — и строка
   копирайта, которая помещается в одну строку впритык, переносилась на вторую. Обнуляем отступы:
   специфичность (0,1,1) выше `.container` страницы, но РАВНА правилу записи хрома, а хром грузится
   позже — если у главной отступы у контейнера всё-таки заданы, они перекроют этот сброс. */
.site-header .container,footer .container{padding-left:0;padding-right:0}

/* Cookie-баннер: дизайн ИМПОРТИРОВАННОГО баннера (.cookie / .cookie button / .cookie .close,
   в т.ч. кнопка-ссылка «Подробнее») приходит ИЗ index.html — derive_frame уносит .cookie* в
   запись обвязки (см. _FRAME_SELECTOR_RE), поэтому правки его стилей делаются в original_pages
   и применяются реимпортом. Правил для голого `.cookie` здесь намеренно нет — они перебивали бы
   вёрстку. Ниже оформлен ТОЛЬКО запасной баннер (partials/cookie.html, класс `gb-cookie`): он
   выводится, когда в комплекте своего баннера не было, и до этого показывался браузерным
   дефолтом — белый прямоугольник во всю ширину и системная кнопка «Принять».
   Оформление нейтральное и самодостаточное, как у плавающей CTA: источника в импорте у него
   нет, а угадывать фирменные цвета не по чему. */
.cookie.gb-cookie{
    position:fixed;left:16px;right:16px;bottom:16px;z-index:80;
    max-width:980px;margin-inline:auto;
    display:flex;align-items:center;justify-content:space-between;gap:16px;flex-wrap:wrap;
    padding:14px 18px;border-radius:14px;
    background:#14181c;color:#e8edf1;
    font:14px/1.45 var(--sans,system-ui,sans-serif);
    box-shadow:0 18px 50px rgba(0,0,0,.35);
}
.cookie.gb-cookie .gb-cookie-actions{display:flex;gap:8px;flex:0 0 auto}
.cookie.gb-cookie button,.cookie.gb-cookie .close{
    min-height:38px;padding:0 18px;border:0;border-radius:10px;
    font:700 14px/1 var(--sans,system-ui,sans-serif);cursor:pointer;text-decoration:none;
    display:inline-flex;align-items:center;justify-content:center;box-sizing:border-box;
}
.cookie.gb-cookie button{background:#fff;color:#14181c}
.cookie.gb-cookie .close{background:rgba(255,255,255,.14);color:#e8edf1}
/* Узкий экран: кнопки уходят под текст и делят строку пополам — иначе «Принять» и «Подробнее»
   прижимались к тексту и вылезали за край. */
@media (max-width:560px){
  .cookie.gb-cookie{left:12px;right:12px;bottom:12px;padding:14px;gap:12px}
  .cookie.gb-cookie .gb-cookie-actions{width:100%}
  .cookie.gb-cookie .gb-cookie-actions>*{flex:1 1 0}
}

/* Плавающая кнопка заявки: глобальная CTA в правом нижнем углу (вкл/выкл в админке).
   z-index ниже оверлея модалки (.modal — 9999), чтобы не висеть поверх открытой формы.
   Оформление нейтральное и самодостаточное (у неё нет источника в импорте). */
.gb-float-cta{
    position:fixed;right:20px;bottom:20px;z-index:9990;
    display:inline-flex;align-items:center;gap:8px;
    padding:14px 22px;border-radius:999px;
    background:#14181c;color:#fff;font:600 15px/1 var(--sans,system-ui,sans-serif);
    text-decoration:none;box-shadow:0 10px 30px rgba(0,0,0,.28);
    transition:transform .16s,box-shadow .16s;
}
.gb-float-cta:hover{transform:translateY(-2px);box-shadow:0 14px 38px rgba(0,0,0,.34)}
.modal.is-open ~ .gb-float-cta,.modal:target ~ .gb-float-cta{display:none} /* скрыта при открытой модалке */
@media (max-width:600px){.gb-float-cta{right:14px;bottom:14px;padding:12px 18px;font-size:14px}}

/* Галки обязательных документов (набор приходит из PayHub — partials/scripts.html). Вид самой
   галки берётся из импортированной вёрстки (.consent-check уносится в обвязку, см.
   pageio._derive_shared_css) — здесь только раскладка списка, скрытие подменяемой встроенной
   галки (её display из вёрстки перебил бы атрибут hidden) и подсветка недостающих после отказа. */
.consent-docs{display:grid;gap:8px}
/* Скрытое — скрыто: display из импортированной вёрстки (.consent-check{display:flex} и т.п.)
   специфичнее браузерного правила для атрибута hidden и перебил бы его. */
.modal-card [hidden]{display:none!important}
.consent-check.is-missing{outline:2px solid #E5484D;outline-offset:4px;border-radius:8px}

/* Статус отправки формы (фича приложения — асинхронная отправка; в index такого нет). */
.form-status{margin:0;padding:11px 14px;border-radius:12px;font-size:14px;line-height:1.45}
.form-status.is-ok{background:#E9FBF4;color:#0B6B53;border:1px solid #B7E8D7}
.form-status.is-error{background:#FDECEC;color:#9A2A2A;border:1px solid #F3C9C9}

/* Мобильное меню: при переходе к якорю секции принудительно прячем панель/подложку
   (страховка для iOS/Safari, если чекбокс остался отмеченным). */
body:has(#platform:target) .mobile-nav-panel,
body:has(#solutions:target) .mobile-nav-panel,
body:has(#services:target) .mobile-nav-panel,
body:has(#scale:target) .mobile-nav-panel,
body:has(#contacts:target) .mobile-nav-panel,
body:has(#contact-modal:target) .mobile-nav-panel,
body:has(#platform:target) .mobile-nav-backdrop,
body:has(#solutions:target) .mobile-nav-backdrop,
body:has(#services:target) .mobile-nav-backdrop,
body:has(#scale:target) .mobile-nav-backdrop,
body:has(#contacts:target) .mobile-nav-backdrop,
body:has(#contact-modal:target) .mobile-nav-backdrop{display:none!important}
