/* ============================================================
   UniBuilder — base/shared global.css   [Epic 9 Themes Platform · Ф1]
   ОБЩИЙ фундамент, эмитируемый для ЛЮБОЙ активной темы (включая default
   и будущие): :root ДЕФОЛТ-токены (нейтральная база) + компонент-слой
   (.ct/.sh/.btn/.badge/.fi/.ico/.reveal/.ub-form-*/каталог) + hook-классы.
   Грузится ПЕРВЫМ; тема-global.css (bold-modern/новые) — ПОСЛЕ, переопределяет
   :root своими значениями (каскад). Все правила на var(--*) токенах.
   ⚠️ Токен-имена = жёсткий контракт: template.php читают их напрямую.
   Ф3 токенизирует base-блоки, Ф2 добавит недостающие оси — не здесь.
   ============================================================ */

:root{
  /* Цвета: primary/accent производны от настроек CMS (--ub-* из ColorPaletteService).
     Дефолты (fallback var()) — спокойная нейтральная база indigo/violet, НЕ тема-специфичные. */
  --p:var(--ub-primary,#4F46E5);--ph:var(--ub-primary-hover,#4338CA);--pl:var(--ub-primary-light,#E0E7FF);--p50:#EEF2FF;
  --a:var(--ub-accent,#8B5CF6);--ah:var(--ub-accent-hover,#7C3AED);--al:var(--ub-accent-light,#EDE9FE);
  /* Градиенты: primary→accent производный; тёмные фоны — нейтральный slate (theme-neutral). */
  --gp:linear-gradient(135deg,var(--p),var(--a));
  --gd:linear-gradient(135deg,#0F172A,#1E293B,#334155);
  --gs:linear-gradient(135deg,var(--p50),var(--al));
  --gh:linear-gradient(160deg,#0F172A 0%,#1E293B 40%,#334155 70%,#475569 100%);
  --dk:#0F172A;--dc:#1E293B;--ds:#334155;
  /* Нейтрали: точный Tailwind gray (theme-neutral). */
  --n50:#F9FAFB;--n100:#F3F4F6;--n200:#E5E7EB;--n300:#D1D5DB;
  --n400:#9CA3AF;--n500:#6B7280;--n600:#4B5563;--n700:#374151;
  --n800:#1F2937;--n900:#111827;
  /* Семантика (theme-neutral) + светлые тинты. */
  --ok:#10B981;--wrn:#F59E0B;--err:#EF4444;--inf:#3B82F6;
  --ok50:#ECFDF5;--wrn50:#FFFBEB;--err50:#FEF2F2;
  /* Шрифты: производны от панели типографики; дефолт (fallback) — системные (без внешней зависимости). */
  --fh:var(--typography-secondary-font,system-ui,-apple-system,'Segoe UI',Roboto,sans-serif);
  --fb:var(--typography-primary-font,system-ui,-apple-system,'Segoe UI',Roboto,sans-serif);
  --h1:var(--typography-font-size-h1,clamp(2.5rem,5vw,3.75rem));--h2:var(--typography-font-size-h2,clamp(2rem,4vw,3rem));
  --h3:var(--typography-font-size-h3,clamp(1.5rem,3vw,2rem));--h4:var(--typography-font-size-h4,clamp(1.25rem,2vw,1.5rem));
  /* Радиусы / тени / транзишн. */
  /* [Темы-B 2026-08-10] Транзишн-токены ПЕРЕЕХАЛИ из blocks-base PREAMBLE (тот линкуется только bold-modern) —
     нужны ВСЕМ темам (--tr ниже и хром .btn/.fi их читают). */
  --transition-duration:.2s;--transition-easing:ease;
  --rs:6px;--rm:10px;--rl:16px;--rxl:24px;--rf:9999px;
  --sh-sm:0 10px 40px color-mix(in srgb,var(--dk) 8%,transparent);
  --sh-brand:0 0 40px color-mix(in srgb,var(--p) 15%,transparent);
  --sh-modal:0 25px 50px -12px color-mix(in srgb,var(--dk) 25%,transparent);
  --tr:transform var(--transition-duration,.2s) var(--transition-easing,ease),box-shadow var(--transition-duration,.2s) var(--transition-easing,ease),border-color var(--transition-duration,.2s) var(--transition-easing,ease),background-color var(--transition-duration,.2s) var(--transition-easing,ease),color var(--transition-duration,.2s) var(--transition-easing,ease),opacity var(--transition-duration,.2s) var(--transition-easing,ease);
  /* [Epic9 Ф2] Расширенный контракт — 6 осей стиля темы (светлые нейтральные дефолты:
     #fff поверхность / скруглённые кнопки / 1px бордер / 16px body — текущий вид не меняется).
     Ф3 переведёт хардкод вариаций (#fff→--surface, px-радиусы→--r-*) на эти токены. */
  --surface:#ffffff;--surface-2:var(--n50);--surface-3:var(--n100);       /* фон карт/секций (ось тёмных тем) */
  --section-py:80px;--section-py-lg:96px;--section-py-md:64px;--section-py-sm:56px;  /* вертикальный ритм секций (--md=средние 9 секций, 5a) */
  --s1:4px;--s2:8px;--s3:16px;--s4:24px;--s5:40px;--s6:64px;              /* шкала отступов/gap (4px-база) */
  --r-btn:var(--rm);--r-card:var(--rl);--r-input:var(--rs);               /* семантич. радиусы (форма — ось темы: pill/square) */
  --bw:1px;--bw-2:2px;                                                     /* ширина бордера */
  --fs-body:1rem;--fs-sm:.875rem;--fs-lg:1.125rem;                        /* размеры body/small/lead текста */
  /* [Epic9 Ф3d-1] Контракт-токены дотокенизации: дефолты = ТЕКУЩИЕ литералы
     (bold-modern байт-нейтральна). Тема (Лёгкая) задаст свои значения потом. */
  --heading-weight:600;--heading-tracking:-.02em;--lh-heading:1.2;--lh-body:1.7;                       /* типографика заголовков/body */
  --heading-gradient:var(--n900);   /* [шаг6] заливка акцент-заголовка (accent-headline): дефолт=сплошной --n900 (обычный тёмный, clip-safe; НЕ none — оно ломает -webkit-text-fill:transparent). Тема задаёт градиент. */
  --title-weight:700;--stat-value-size:clamp(2rem,4vw,3rem);--price-size:clamp(1.5rem,3vw,2.125rem);   /* эмфатика: числа/цены */
  --stat-value-size-sm:clamp(1.75rem,3.5vw,2.5rem);                                                    /* [5a] компактные числа (stats/cards) */
  --sh-btn:0 4px 15px color-mix(in srgb,var(--p) 30%,transparent);--sh-btn-hover:0 6px 20px color-mix(in srgb,var(--p) 40%,transparent);  /* тень CTA */
  --sh-focus:0 0 0 3px color-mix(in srgb,var(--p) 12%,transparent);--sh-focus-err:0 0 0 3px color-mix(in srgb,var(--err) 12%,transparent); /* focus-ring полей (единый, устраняет alpha-дрейф) */
  --card-featured-border:var(--bw) solid var(--p);--card-featured-accent:var(--gp);                    /* выделенная карта: бордер/планка (тема выключает transparent/none) */
  --badge-display:inline-flex;   /* [шаг7] показ eyebrow-ярлыков (.ub-eyebrow над заголовком): дефолт=показ. Тема-тумблер (theme_badge_display) выставляет none→скрыть ВСЕ eyebrow. Функц. .badge (pricing-план/code/caption) НЕ трогает. */
  /* [футер-хром] тема РЕШАЕТ фон/текст подвала per-case (как --card-featured-*). Дефолты = ТЕКУЩАЯ
     дарк-схема (bold-modern/дефолт неизменны). Тема задаёт свои → футер меняется от темы к теме.
     Читаются: renderFooterBlock isDark-ветка (bg/text инлайн) + .ub-footer-* классы (muted/heading/link/border). */
  --footer-bg:#1f2937;--footer-text:#ffffff;--footer-muted:#9ca3af;--footer-heading:#ffffff;
  --footer-link:#d1d5db;--footer-link-hover:#ffffff;--footer-border:#374151;
  /* [follow-up] соц-иконки-круги футера: подложка. Дефолт = текущий white/10 (нейтр на ТЁМНЫХ
     футерах). Светлый футер темы (soft/strict #f2f2f3/#fff) задаёт тёмный-субтл контраст. */
  --footer-social-bg:rgba(255,255,255,0.1);--footer-social-hover:rgba(255,255,255,0.2);
}

/* — Base / typography — */
.bm-scope *,body *{box-sizing:border-box}
body{font-family:var(--fb);font-size:var(--fs-body);color:var(--n800);line-height:var(--lh-body);-webkit-font-smoothing:antialiased;overflow-x:hidden}
body img{max-width:100%;display:block}
body a{color:var(--p);text-decoration:none}
h1,h2,h3,h4{font-family:var(--fh);font-weight:var(--heading-weight);line-height:var(--lh-heading);letter-spacing:var(--heading-tracking);color:var(--n900)}
h1{font-size:var(--h1)}h2{font-size:var(--h2)}h3{font-size:var(--h3)}h4{font-size:var(--h4)}
/* [headingTag-В1 2026-08-10] div-режим заголовка (headingTag=div): заголовок-DIV вне outline получает
   типографику заголовка (теги h1-h4 её имеют выше; размер — из per-template пина .{$sc} .bm-t/.bm-it).
   Скоуп ТОЛЬКО div.bm-t/div.bm-it — дефолтный тег-каскад тем/кастомов НЕ трогаем. */
div.bm-t,div.bm-it{font-family:var(--fh);font-weight:var(--heading-weight);line-height:var(--lh-heading);letter-spacing:var(--heading-tracking);color:var(--n900)}
/* [Темы-B 2026-08-10] Страховка пустых <p> + reduced-motion для .bm-* — ПЕРЕЕХАЛИ из blocks-base PREAMBLE
   (нужны всем темам; blocks-base линкуется только bold-modern). Реестр легитимных пустых <p> см. SOURCE_OF_TRUTH. */
p:empty{display:none}
@media (prefers-reduced-motion:reduce){[class*="bm-"]{transition-duration:.01ms !important;animation-duration:.01ms !important;animation-iteration-count:1 !important}.has-hover-lift,.has-hover-zoom,.has-hover-glow{transition-duration:.01ms !important}}

/* — Container — */
/* [Волна12 Ч.3] ЕДИНАЯ ширинная система: max-width каскад --block-w(блок, эмитится buildBlockStyles
   на секции) → --container-max(сайт, :root) → 1200px. --block-w НЕ задан → var() падает на прежнее
   значение → БАЙТ-В-БАЙТ для контента без block-width (весь существующий контент во всех темах). */
/* [Кросс-тема 2026-07-20] position:relative+z-index:1 — контент НАД блок-оверлеем (absolute-затемнение
   фоновой картинки, buildOverlayHtml). Было ТОЛЬКО в bold-modern/global.css (Волна12 N3) + scoped в 3
   hero-вариациях → на остальных темах затемнение накрывало текст любого не-hero блока (аудит-факт).
   Порт сюда безопасен: декоров ::before/::after у тем НЕТ (grep-факт 6 тем), для блока без оверлея
   подъём ничего не меняет (нет конкурирующих positioned-слоёв) — скрин-нейтральность доказана ×7. */
.ct{max-width:var(--block-w,var(--container-max,1200px));margin:0 auto;padding:0 24px;position:relative;z-index:1}
/* [Волна8 Ш · решение Михаила A] Хром (шапка/футер/коммерция на Tailwind .container, до 1536)
   сводится к ширине контента: _base грузится ПОСЛЕ tailwind.css → этот max-width перебивает
   адаптивные брейкпоинты .container (640/768/1024/1280/1536). Пусто → фолбэк 1200 = ширина .ct.
   Гуттеры .container (px-4 sm:px-6 lg:px-8) остаются свои — сведена ТОЛЬКО max-width. */
.container{max-width:var(--container-max,1200px)}

/* [Волна13 N15] per-device видимость блока. Класс ub-hide-* эмитит renderBlock из settings.visibility
   (UI «Видимость по устройствам»). SSG-инвариант: блок ВСЕГДА в HTML, скрытие ТОЛЬКО CSS @media на клиенте
   (НЕ серверное условие по user-agent → статика корректна для всех устройств). Границы = существующие
   значения сайта: 768 (совпадает с @media блоков/tailwind md) + 1200 (--container-max, = подписи UI
   «Desktop 1200px+ / Tablet 768-1199 / Mobile ≤767»). Новые классы → БАЙТ-В-БАЙТ для контента без visibility.
   !important — надёжно бьёт display блока (section/flex-hero). Общий слой _base → работает на ВСЕХ темах. */
@media (max-width:767px){.ub-hide-mobile{display:none!important}}
@media (min-width:768px) and (max-width:1199px){.ub-hide-tablet{display:none!important}}
@media (min-width:1200px){.ub-hide-desktop{display:none!important}}

/* [P2] Режимы отображения телефонов шапки (renderHeaderPhones). Дефолт horizontal НЕ имеет своего класса
   (использует прежние утилиты items-center gap-4 → байт-нейтр). Классы ниже — только vertical/dropdown, аддитивно. */
.ub-phones-vertical{flex-direction:column;align-items:flex-start;gap:2px;line-height:1.35}
.ub-phones-dropdown{position:relative;gap:6px}
.ub-phones-dropdown .ub-phones-more{cursor:pointer;background:none;border:none;padding:0 2px;font-size:.7rem;line-height:1;color:inherit;opacity:.7;transition:opacity .15s ease}
.ub-phones-dropdown .ub-phones-more:hover{opacity:1}
.ub-phones-dropdown .ub-phones-list{position:absolute;top:100%;right:0;z-index:60;display:none;flex-direction:column;gap:8px;min-width:max-content;margin-top:6px;padding:10px 14px;background:#fff;border:1px solid var(--n200,#e5e7eb);border-radius:var(--r-card,8px);box-shadow:0 8px 24px rgba(0,0,0,.12)}
/* [П7-П5] hover-мост: невидимая полоса над списком перекрывает 6px-зазор (margin-top) —
   курсор по пути от триггера к списку не покидает :hover-зону и выпадашка не закрывается. */
.ub-phones-dropdown .ub-phones-list::before{content:'';position:absolute;top:-6px;left:0;right:0;height:6px}
/* Раскрытие: hover — десктоп; focus-within (по tap/фокусу на кнопке ▾) — тач-устройства/клавиатура.
   [Ч3 грейс-закрытие] display:flex постоянный + visibility/opacity с transition-delay .25s на скрытие:
   микро-соскок курсора с контейнера/списка больше НЕ захлопывает выпадашку мгновенно («пока не
   кликнешь — не попадёшь»); visibility:hidden отключает клики/фокус закрытого списка как раньше. */
.ub-phones-dropdown .ub-phones-list{display:flex;visibility:hidden;opacity:0;transition:opacity .12s ease,visibility 0s linear .25s}
.ub-phones-dropdown:hover .ub-phones-list,
.ub-phones-dropdown:focus-within .ub-phones-list{visibility:visible;opacity:1;transition-delay:0s}

/* [Ч2-группа] Контакты шапки (телефоны+почта+соцсети) — визуально одна группа: внутренний
   интервал 14px, отбивка от меню 28px; mr-3 частей внутри группы нейтрализуется (иначе двойной гэп).
   Обёртка появляется только при непустых контактах (иначе байт-нейтр); бургер/топбар не задеты. */
.ub-header-contacts{display:flex;align-items:center;gap:14px;margin-left:28px}
.ub-header-contacts .ub-header-phones,.ub-header-contacts .ub-header-email,.ub-header-contacts .ub-header-socials{margin-right:0}

/* [Бургер-контакты] Контакты в мобильной бургер-панели: телефоны списком → почта → соцсети.
   Язык мобильного меню (block py-2 + hover-токен темы); разделитель/цвета — токены с фолбэком.
   Сама панель .ub-mobile-nav md:hidden → на десктопе копия не видна без доп-правил. */
.ub-burger-contacts{border-top:1px solid var(--n200,#e5e7eb);margin-top:8px;padding-top:8px}
.ub-burger-contacts .ub-bc-socials{display:flex;align-items:center;gap:18px;padding:10px 0 4px;font-size:1.15rem}
/* На мобиле контакты живут в бургере: топбар-копии settings-зон скрываются
   (header-зоны уже hidden md:flex утилитами — их не трогаем, байт-нейтр). */
@media (max-width:767px){
  .ub-topbar-phones,.ub-topbar-email,.ub-topbar-socials{display:none!important}
  /* [W14-П2] пустая контакт-группа топбара на мобиле не должна занимать место (margin-left) */
  .ub-topbar .ub-header-contacts{display:none!important}
}
/* [W14-П2] в топбаре группа прижата вправо соседями — отбивка слева не нужна (в шапке остаётся 28px) */
.ub-topbar .ub-header-contacts{margin-left:0}

/* ── [W18-обратный порт geoanalitik] Выпадающее меню шапки ──
   Было в разметке: Tailwind w-48 (192px) + whitespace-nowrap → длинные пункты вылезали за белую
   панель (факт: geoanalit «Услуги» + скрин «БестПрайсКомплект»). Разметка теперь несёт только
   позиционирование (absolute/left/top/hidden/z), вид панели — здесь и ТОКЕНАМИ: 7 тем наследуют
   свои радиус/бордер/поверхность автоматически. --sh-dd — опциональный токен тени для тем;
   дефолт — та же мягкая тень, что у выпадашки телефонов (.ub-phones-list). */
.dropdown-child{min-width:12rem;width:max-content;max-width:min(34rem,92vw);padding:.4rem 0;background:var(--surface,#fff);border:var(--bw,1px) solid var(--n200,#e5e7eb);border-radius:var(--r-card,12px);box-shadow:var(--sh-dd,0 8px 24px rgba(0,0,0,.12));overflow:hidden}
.ub-dd-link{white-space:normal;overflow-wrap:anywhere;line-height:1.4;padding:.65rem 1.1rem;color:var(--n700,#374151);transition:background-color .15s ease,color .15s ease}
.ub-dd-link:hover{background:var(--pl,#EEF2FF);color:var(--p,#4F46E5)}

/* [W18-Ч3] Логотип разработчика в подвале (настройки footer_developer_*): бейдж рядом с
   копирайтом во всех 5 шаблонах футера. Без настроек не рендерится вовсе (байт-нейтр). */
.ub-footer-dev{display:inline-flex;align-items:center;gap:8px;margin-left:16px;vertical-align:middle;opacity:.85;transition:opacity .2s ease;color:inherit}
.ub-footer-dev:hover{opacity:1}
.ub-footer-dev img{height:24px;width:auto;display:block}
/* [W23] Расположение бейджа «отдельным блоком по центру» (footer_developer_layout=block):
   центрирован под копирайтом, разумный отступ сверху. Внутри блока inline-отступ обнуляется.
   Высота картинки — по настройке footer_developer_logo_height (chrome-tuning). */
.ub-footer-dev-block{display:flex;justify-content:center;align-items:center;margin-top:20px}
.ub-footer-dev-block .ub-footer-dev{margin-left:0}

/* [W2-cols] Per-device колонки сеток. Vars (--cols-d/t/d) эмитит buildBlockStyles НА СЕКЦИИ из
   settings.columns/columnsTablet/columnsMobile; атрибут-селектор [style*="--cols-"] матчит ТОЛЬКО
   блоки с заданной настройкой → без неё прежняя сетка шаблона (байт-в-байт), с ней — !important
   перебивает scoped-CSS и legacy inline (features content.columns). Грид-элементы обеих веток:
   .bm-g (основной) · .bm-alt (services/standard) · .bm-h (steps/standard). Новый грид-класс в новой
   вариации → дописать сюда (гайд вариаций §5). Брейкпоинты = N15: ≤767 / 768–1199 / ≥1200.
   Фолбэки: mobile 1 · tablet 2 · desktop 3 (заданное всегда главнее). CSS-var, НЕ динамический
   Tailwind (класс 'md:grid-cols-N' пуржится при сборке — документированный урок).
   [W18-Ч5] + .bm-ls (features/list) и .bm-tl (steps/timeline): гриды существовали, но в списке
   не были зарегистрированы — настройка колонок в этих вариациях молча не работала.
   display:grid в базовом правиле — для вариаций, где контейнер flex (partners/standard):
   grid-template-columns инертен на flex; включается ТОЛЬКО при заданной настройке колонок
   (атрибут-гейт), без неё раскладка вариации байт-в-байт. */
[style*="--cols-"] :is(.bm-g,.bm-alt,.bm-h,.bm-ls,.bm-tl){display:grid!important;grid-template-columns:repeat(var(--cols-m,1),1fr)!important}
@media (min-width:768px) and (max-width:1199px){[style*="--cols-"] :is(.bm-g,.bm-alt,.bm-h,.bm-ls,.bm-tl){grid-template-columns:repeat(var(--cols-t,2),1fr)!important}}
@media (min-width:1200px){[style*="--cols-"] :is(.bm-g,.bm-alt,.bm-h,.bm-ls,.bm-tl){grid-template-columns:repeat(var(--cols-d,3),1fr)!important}}

/* — Section header — */
.sh{text-align:center;max-width:640px;margin:0 auto 48px}
.sh .badge{margin-bottom:12px}
.sh p{color:var(--n500);font-size:var(--fs-lg);margin-top:12px}

/* — Buttons — */
.btn{display:inline-flex;align-items:center;justify-content:center;gap:8px;font-family:var(--fb);font-weight:600;border:none;cursor:pointer;transition:var(--tr);white-space:nowrap;text-decoration:none}
.btn:hover{transform:translateY(-1px)}
.btn-l{padding:14px 32px;font-size:1rem;border-radius:var(--r-btn)}
.btn-m{padding:10px 24px;font-size:.875rem;border-radius:var(--r-btn)}
.btn-s{padding:7px 16px;font-size:.75rem;border-radius:var(--r-btn)}
.btn-p{background:var(--gp);color:#fff;box-shadow:var(--sh-btn)}
.btn-o{background:transparent;color:var(--p);border:var(--bw-2) solid var(--p)}
.btn-o:hover{background:var(--p);color:#fff}
.btn-w{background:#fff;color:var(--n900)}
.btn-d{background:var(--dk);color:#fff}
.btn-gh,.btn-l.btn-gh{background:transparent;color:var(--p)}
.btn-gh:hover{background:var(--p50)}

/* — Badge — */
.badge{display:inline-flex;padding:4px 14px;border-radius:var(--rf);font-size:.75rem;font-weight:600}
.bg-p{background:var(--pl);color:var(--p)}
.bg-a{background:var(--al);color:var(--dk)}
.bg-g{background:var(--gp);color:#fff}
.bg-d{background:var(--dk);color:#fff}
/* [шаг7] eyebrow-ярлык (над заголовком секции/hero) — display управляется темой (--badge-display). Определён ПОСЛЕ .badge → при равной специфичности (0,1,0) выигрывает для .badge.ub-eyebrow. Дефолт inline-flex = визуально идентично .badge. Функц. .badge (без .ub-eyebrow) не затронут. */
.ub-eyebrow{display:var(--badge-display,inline-flex)}

/* — Footer chrome (тема-управляемый подвал) — семантик-классы на токенах; дефолт=текущая дарк-схема.
     renderFooterBlock isDark-ветка ставит эти классы вместо Tailwind-серых → тема красит per-case. */
.ub-footer-muted{color:var(--footer-muted,#9ca3af)}
.ub-footer-heading{color:var(--footer-heading,#ffffff)}
.ub-footer-link{color:var(--footer-link,#d1d5db);transition:var(--tr)}
.ub-footer-link:hover{color:var(--footer-link-hover,#ffffff)}
.ub-footer-border{border-color:var(--footer-border,#374151)}
.ub-footer-social{background:var(--footer-social-bg,rgba(255,255,255,0.1))}
.ub-footer-social:hover{background:var(--footer-social-hover,rgba(255,255,255,0.2))}
/* — Footer menu — сброс браузерных маркеров/отступа у списков меню-колонок футера (навигация без
     буллетов). Вертикальный ритм пунктов держит space-y-1 (margin на li), а не padding ul → цел. */
.ub-footer-menu{list-style:none;margin:0;padding:0}

/* — Hero hook (тема-декор hero) — пустой в base (нейтрально). Корень hero-вариаций несёт `.ub-hero`
     (base blocks/hero/variations/*), тема цепляет декор (напр. business: blueprint-точки на светлых hero).
     Светлые hero (standard/centered-clean) используют scoped `background-color:` → `background-image`
     свободен для темы. Тёмные градиент-hero (large/video) scoped-`background:var(--gh)` перебивает — сетку не принимают. */

/* — Forms — */
.fi{width:100%;padding:12px 16px;border:var(--bw) solid var(--n200);border-radius:var(--r-input);font-size:var(--fs-body);font-family:var(--fb);background:var(--surface);color:var(--n800);transition:var(--tr)}
.fi:focus{outline:none;border-color:var(--p);box-shadow:var(--sh-focus)}
.fi::placeholder{color:var(--n500)}
.fg{margin-bottom:20px}
.fl{display:block;font-size:var(--fs-sm);font-weight:500;color:var(--n700);margin-bottom:6px}
.fi-dk{background:rgba(255,255,255,.06);border-color:rgba(255,255,255,.12);color:#fff}
.fi-dk:focus{border-color:var(--p)}
.fi-dk::placeholder{color:var(--n500)}
.fl-dk{color:var(--n300)}
.fi.err{border-color:var(--err);box-shadow:var(--sh-focus-err)}
.fi.err::placeholder{color:color-mix(in srgb,var(--err) 50%,transparent)}
.fg-err{font-size:.75rem;color:var(--err);margin-top:6px;display:none;align-items:center;gap:4px}
.fg.has-error .fg-err{display:flex}
.fg-success{color:var(--ok);text-align:center;padding:24px;background:rgba(16,185,129,.08);border:1px solid rgba(16,185,129,.2);border-radius:var(--rl);display:none;font-weight:500}
.fg-success.show{display:block}

/* — Icon — */
.ico{width:48px;height:48px;margin-bottom:16px;transition:transform .4s cubic-bezier(.34,1.56,.64,1)}

/* — Reveal on scroll — */
.reveal{opacity:0;transform:translateY(24px);transition:opacity .6s ease-out,transform .6s cubic-bezier(.4,0,.2,1)}
.reveal.visible{opacity:1;transform:none}
@media(prefers-reduced-motion:reduce){.reveal{opacity:1;transform:none;transition:none}}

/* — Responsive base — */
@media(max-width:768px){
  .ct{padding:0 16px}
  .sh{margin-bottom:32px}
  .btn-l{padding:12px 24px;font-size:.9375rem}
}
@media(max-width:375px){
  .ct{padding:0 14px}
  .btn-l{width:100%}
}

/* — Modal form (renderFormForModal output) — шрифт-литералы токенизированы (var(--fb)/var(--fh)) — */
.ub-modal-body .ub-form,.ub-form{display:flex;flex-direction:column;gap:16px}
.ub-form-field{display:flex;flex-direction:column;gap:6px;margin:0}
.ub-form-label{font-family:var(--fb);font-size:.875rem;font-weight:600;color:var(--n800,#1E293B);line-height:1.4}
.ub-form-required{color:var(--a,#EC4899);font-weight:700;margin-left:2px}
.ub-form-control{width:100%;padding:12px 16px;border:var(--bw) solid var(--n200,#E2E8F0);border-radius:var(--r-input);font-size:var(--fs-body);font-family:var(--fb);background:var(--surface);color:var(--n800,#1E293B);transition:transform var(--transition-duration,.2s) var(--transition-easing,ease),box-shadow var(--transition-duration,.2s) var(--transition-easing,ease),border-color var(--transition-duration,.2s) var(--transition-easing,ease),background-color var(--transition-duration,.2s) var(--transition-easing,ease),color var(--transition-duration,.2s) var(--transition-easing,ease),opacity var(--transition-duration,.2s) var(--transition-easing,ease);box-sizing:border-box;-webkit-appearance:none;appearance:none}
.ub-form-control:focus{outline:none;border-color:var(--p,#4F46E5);box-shadow:var(--sh-focus)}
.ub-form-control::placeholder{color:var(--n500)}
textarea.ub-form-control{min-height:110px;resize:vertical;line-height:1.6}
select.ub-form-control{cursor:pointer;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='8' viewBox='0 0 12 8' fill='none'%3E%3Cpath d='M1 1.5L6 6.5L11 1.5' stroke='%2364748B' stroke-width='2' stroke-linecap='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 16px center;padding-right:40px}
.ub-form-submit,.ub-btn-primary{display:inline-flex;align-items:center;justify-content:center;width:100%;padding:14px 32px;margin-top:8px;font-family:var(--fb);font-size:1rem;font-weight:600;color:#fff;background:var(--gp);border:none;border-radius:var(--r-btn);box-shadow:var(--sh-btn);cursor:pointer;transition:transform .2s ease,box-shadow .2s ease}
.ub-form-submit:hover,.ub-btn-primary:hover{transform:translateY(-1px);box-shadow:var(--sh-btn-hover)}
.ub-modal-container{font-family:var(--fb)}
.ub-modal-title,.ub-modal-header h3{font-family:var(--fh)}

/* — Catalog: hide native number spinners + qty/filter controls (tokenized) — */
.ub-filter-price-min,.ub-filter-price-max,.ub-product-qty,.ub-item-qty,.ub-qty-input,
.ub-catalog-filters input[type=number],.ub-product-card input[type=number],.ub-product-item input[type=number]{
  -moz-appearance:textfield;appearance:textfield}
.ub-filter-price-min::-webkit-inner-spin-button,.ub-filter-price-max::-webkit-inner-spin-button,
.ub-product-qty::-webkit-inner-spin-button,.ub-item-qty::-webkit-inner-spin-button,.ub-qty-input::-webkit-inner-spin-button,
.ub-catalog-filters input[type=number]::-webkit-inner-spin-button,
.ub-filter-price-min::-webkit-outer-spin-button,.ub-filter-price-max::-webkit-outer-spin-button,
.ub-product-qty::-webkit-outer-spin-button,.ub-item-qty::-webkit-outer-spin-button,.ub-qty-input::-webkit-outer-spin-button,
.ub-catalog-filters input[type=number]::-webkit-outer-spin-button{-webkit-appearance:none;margin:0}
.ub-qty{display:inline-flex;align-items:center;border:1.5px solid var(--n200,#E2E8F0);border-radius:var(--r-input);overflow:hidden}
.ub-qty-btn,.ub-qty-minus,.ub-qty-plus,.ub-item-minus,.ub-item-plus{width:36px;height:36px;border:none;background:var(--n50,#F8FAFC);cursor:pointer;font-size:16px;color:var(--n700,#334155);display:flex;align-items:center;justify-content:center;line-height:1;transition:background .15s}
.ub-qty-btn:hover,.ub-qty-minus:hover,.ub-qty-plus:hover,.ub-item-minus:hover,.ub-item-plus:hover{background:var(--pl);color:var(--p)}
.ub-qty-input,.ub-product-qty,.ub-item-qty{width:46px;height:36px;text-align:center;border:none;border-left:1px solid var(--n200);border-right:1px solid var(--n200);font-size:14px;font-family:inherit;outline:none}
.ub-qty-input:focus-visible,.ub-product-qty:focus-visible,.ub-item-qty:focus-visible{outline:2px solid color-mix(in srgb,var(--p) 40%,transparent);outline-offset:-2px}
.ub-catalog-filters input[type=number]{border:1.5px solid var(--n200,#E2E8F0);border-radius:var(--r-input);padding:9px 12px;font-family:inherit}
.ub-catalog-filters input[type=number]:focus{outline:none;border-color:var(--p);box-shadow:var(--sh-focus)}
.ub-apply-filters{background:var(--gp)!important;border:none!important}
.ub-apply-filters:hover{filter:brightness(1.05)}

/* — Hook-классы: активация theme-классов шапки/футера/меню/коммерции через токены — */
.ub-text-theme{color:var(--p)}
.hover\:ub-text-theme:hover{color:var(--p)}
.ub-bg-theme{background:var(--p)}
.ub-menu-link{transition:color .15s ease}
.ub-ring-theme,.focus\:ub-ring-theme{--tw-ring-color:var(--p)}
.group:hover .ub-group-text-theme{color:var(--p)}
.hover\:ub-bg-theme:hover{background:var(--ph)}
.ub-border-theme{border-color:var(--p)}
.hover\:ub-border-theme:hover{border-color:var(--p)}
/* Сток = семантика (success/warn/error), не зависит от theme_color. */
.ub-text-ok{color:var(--ok)}.ub-bg-ok{background:var(--ok)}.ub-bg-ok-50{background:var(--ok50)}.ub-border-ok{border-color:var(--ok)}
.ub-text-wrn{color:var(--wrn)}.ub-bg-wrn{background:var(--wrn)}.ub-bg-wrn-50{background:var(--wrn50)}
.ub-text-err{color:var(--err)}.ub-bg-err{background:var(--err)}.ub-bg-err-50{background:var(--err50)}.ub-border-err{border-color:var(--err)}
.hover\:ub-text-err:hover{color:var(--err)}

/* — PDP «В корзину» компакт — */
.ub-product-detail .ub-pdp-buy{min-width:220px;flex:0 0 auto}
@media(max-width:640px){.ub-product-detail .ub-pdp-buy{width:100%;flex:1 1 100%}}
