/* MKK Curling Club Styles — компонентный слой поверх дизайн-системы.
   Все базовые токены (цвет/отступы/скругления/типографика/тени/z/easing) вынесены в
   css/design-system.css (подключается ПЕРЕД этим файлом). Здесь — только адаптивные
   переопределения токенов (в media-блоках ниже: --promo-h, --head-gap, burger-*) и стили. */
body{font-family:var(--font-sans);color:var(--ink-body);background:var(--ice-0)}
h1,h2,h3{color:var(--ink-cold);text-wrap:balance;font-weight:800}
h1{font-size:clamp(44px,5.6vw,80px);line-height:1.1}
h2{font-size:clamp(32px,3.6vw,52px);line-height:1.12}
.container-mkk{--bs-gutter-x:40px;width:100%;max-width:1400px;margin-inline:auto;padding-inline:calc(var(--bs-gutter-x)*.5)}
.sec{padding-block:var(--sec-pad)}
.btn-mkk{display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-3);border:0;border-radius:100px;font:500 15px/1 'Onest',sans-serif;padding:17.5px 28px 16.5px;text-decoration:none;cursor:pointer;transition:transform .3s var(--ease-out),box-shadow .3s var(--ease-out),background .3s var(--ease-out),border-color .3s var(--ease-out)}
.btn-mkk-primary{background:var(--grad-cta);color:#fff;border:1px solid transparent}
.btn-mkk-primary:hover{transform:translateY(-1px);box-shadow:0 14px 34px -14px rgba(11,170,236,.55)}
.btn-mkk-light{background:#fff;color:var(--ink-cold);border:1px solid rgba(20,48,60,.14)}
.btn-mkk-light:hover{transform:translateY(-1px);background:var(--ice-1);border-color:var(--cyan-2)}
.btn-mkk-ghost{background:transparent;color:#fff;border:1px solid var(--glass-br)}
:focus-visible{outline:2px solid var(--cyan-2);outline-offset:2px}

/* ── PROMO BAR ── */
/* ── LENIS (плавный скролл) — ОБЯЗАТЕЛЬНАЯ CSS из README Lenis ──────────────────────────────────
   Root cause сломанного скролла (найден systematic-debugging, репро колесом): Bootstrap Reboot
   ставит `scroll-behavior:smooth` на :root; Lenis каждый кадр зовёт window.scrollTo(), и браузерная
   smooth-анимация рестартится на каждом кадре — нативный scrollY замерзает, а lenis.scroll убегает
   (419→5365 при native=0). На живой машине = «прокидывает через блоки, зависает, назад не крутится».
   Гейтим по классу `lenis` (его вешает Lenis при инициализации, подтверждено): при активном JS —
   scroll-behavior:auto (плавность даёт сам Lenis); без JS класса нет → Bootstrap-smooth остаётся для
   нативных якорей. `height:auto` и прочие — тоже из канонической CSS Lenis. */
html.lenis{scroll-behavior:auto!important}
html.lenis,html.lenis body{height:auto}
.lenis.lenis-stopped{overflow:hidden}
.lenis.lenis-smooth [data-lenis-prevent]{overscroll-behavior:contain}
.lenis.lenis-smooth iframe{pointer-events:none}

/* --promo-h / --nav-h определены в design-system.css. Важно: --nav-h на :root (НЕ на #site-nav): его читает и .hero-in
   (не потомок нава!) — кастомные свойства наследуются только вниз; финальное ревью поймало
   регресс E4 (padding-top резолвился в 0 на коротких вьюпортах, H1 уходил под нав) */
#promo{position:fixed;inset-inline:0;top:0;z-index:calc(var(--z-nav) + 1);height:var(--promo-h);background:var(--ice-2);overflow:hidden}
#promo .promo-in{height:100%;display:flex;align-items:center;gap:var(--sp-4)}
.promo-badge{display:inline-flex;align-items:center;justify-content:center;height:22px;padding-inline:var(--sp-2);margin-inline-end:10px;border-radius:50px;background:var(--cyan-2);color:#fff;font:600 12px/1 'Onest',sans-serif;flex:none}
.promo-txt{margin:0;color:var(--ink-cold);font-size:14px;font-weight:500;flex:1 1 auto;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.promo-link{flex:none;color:var(--cyan-2);font-size:13px;font-weight:600;text-decoration:none;white-space:nowrap}
.promo-link:hover{text-decoration:underline}
.promo-x{flex:none;display:inline-flex;align-items:center;justify-content:center;width:26px;height:26px;border:0;border-radius:50%;background:transparent;color:var(--ink-mut);font-size:20px;line-height:1;cursor:pointer;transition:background .2s,color .2s}
.promo-x:hover{background:rgba(20,48,60,.08);color:var(--ink-cold)}

/* ── SITE NAV ── */
/* Top-state (on hero) = полностью прозрачный header per Figma 2008:10748 — никакого стекла/фона/бордера.
   Белый фон, тёмные ссылки и цветной лого появляются только в .scrolled (см. ниже). */
#site-nav{position:fixed;inset-inline:0;top:0;transform:translateY(var(--promo-h));z-index:var(--z-nav);height:var(--nav-h);background:transparent;border-bottom:1px solid transparent;transition:background .3s,border-color .3s,transform .3s var(--ease-out)}
#site-nav .navbar{height:var(--nav-h);display:flex;align-items:center;justify-content:space-between;flex-wrap:wrap}
#site-nav.scrolled{background:var(--ice-0);border-bottom-color:rgba(20,48,60,.1)}
.nav-logo{display:inline-flex;align-items:center;line-height:0}
.nav-logo img{height:40px;width:auto;display:block}
.nav-logo .logo-on-light{display:none}
#site-nav.scrolled .logo-on-dark{display:none}
#site-nav.scrolled .logo-on-light{display:block}
/* Логотип | Меню | CTA — три самостоятельные группы, разнесённые по контейнеру 1360 (Figma 2008:10748: Logo —
   Menu Items — Button, все три — прямые flex-дети одного justify-between ряда), а не слипшиеся у левого края.
   Bootstrap оборачивает меню+CTA в свой .navbar-collapse div — на десктопе убираем эту обёртку из коробочной
   модели через display:contents, чтобы .mkk-menu и .nav-cta стали настоящими flex-детьми #site-nav .navbar
   наравне с .nav-logo (то есть ИМЕННО 3-групповой space-between, а не 2-групповой с зажатым внутри дуэтом).
   !important обязателен: сам Bootstrap задаёт .navbar-expand-lg .navbar-collapse{display:flex!important}
   на этом же брейкпоинте (bootstrap.min.css), обычная специфичность его не перебивает. */
@media (min-width:992px){#site-nav .navbar-collapse{display:contents!important}}
.mkk-menu{display:flex;align-items:center;gap:var(--sp-6);list-style:none;margin:0;padding:0}
.nav-link{position:relative;display:inline-flex;align-items:center;gap:var(--sp-2);padding:0;margin:0;color:#fff;font-size:16px;font-weight:500;text-decoration:none;white-space:nowrap;transition:color .25s var(--ease-out)}
/* Клиент: «Большеваты отступы между пунктами». Сверка с Figma 2008:10748 (Menu Items > Right) даёт
   gap-[32px] — РОВНО как в текущем .mkk-menu{gap:32px}, число уже верное. Реальная причина «расползания»:
   Bootstrap задаёт .navbar-expand-lg .navbar-nav .nav-link{padding-right/left:var(--bs-navbar-nav-link-padding-x)}
   (8px по умолчанию, внутри @media >=992px) — специфичность (0,3,0) перебивает и одиночный .nav-link{padding:0}
   (0,1,0), и компаунд .mkk-menu .nav-link (0,2,0), т.к. наш <ul> носит класс navbar-nav, а <nav> — navbar-expand-lg
   (оба нужны для бутстраповской collapse-механики бургера). К каждому пункту добавлялось по 8px слева/справа
   поверх 32px gap — суммарно ~48px «на глаз» между текстами вместо 32px. #site-nav .nav-link (ID+класс = 1,1,0)
   бьёт любую чисто классовую комбинацию Bootstrap независимо от порядка подключения файлов. */
#site-nav .nav-link{padding-inline:0}
/* Task 14 polish #7 (a11y, found live in Tab-walk): Bootstrap's own .nav-link:focus-visible rule
   (outline:0;box-shadow:0 0 0 .25rem rgba(13,110,253,.25)) — specificity (0,2,0) — beats the sitewide
   bare :focus-visible{outline:2px solid var(--cyan-2)} rule (0,1,0) up top, so the 4 top-level header
   links (О клубе/Керлинг/Услуги и мероприятия/Ресторан — the .has-dropdown triggers, plain .nav-link
   with no other class) were tabbing to Bootstrap's default blue ring instead of the site's cyan focus
   style used everywhere else (CTA buttons, hero cards — those all carry .btn-mkk or another class that
   already sits at (0,2,0)+ and doesn't collide the same way). #site-nav .nav-link:focus-visible
   (1,2,0 — the #site-nav id) beats Bootstrap's rule outright; box-shadow:none clears its ring so the
   two treatments don't stack. */
#site-nav .nav-link:focus-visible{outline:2px solid var(--cyan-2);outline-offset:2px;box-shadow:none}
.nav-link:hover{color:var(--cyan-1)}
/* Task 15 (client round 2, п.2): фирменный хедер-хаб хочет ХОВЕР = лёгкое выцветание (не чистый
   белый/не акцент), а АКТИВНЫЙ/открытый триггер дропдауна = акцентный cyan-2 — в обоих состояниях
   нава (прозрачный над hero / белый .scrolled). Базовый `.nav-link:hover{color:var(--cyan-1)}` выше
   НЕ трогаем — тот же класс .nav-link несёт и Bootstrap-табы цен (.mkk-tabs .nav-link), которым
   cyan-1-хвер не менялся по этому фидбеку. Вместо этого — #site-nav-скоуп с id-специфичностью,
   которая гарантированно бьёт голый `.nav-link:hover` независимо от порядка объявления. */
#site-nav .nav-link:hover,#site-nav .nav-link:focus{color:rgba(255,255,255,.72)}
.nav-chev{flex:none;color:currentColor;opacity:.8}
#site-nav.scrolled .nav-link{color:var(--ink-cold)}
#site-nav.scrolled .nav-link:hover,#site-nav.scrolled .nav-link:focus{color:rgba(20,48,60,.7)}
.nav-cta{flex:none}
/* Мобильный блок контактов — третий child .navbar-collapse, но на десктопе в раскладку 2 групп (меню/CTA)
   не участвует и полностью скрыт; появляется только в мобильной панели (см. media max-width:991.98px). */
.nav-mobile-contacts{display:none}

/* ── NAV DROPDOWNS (desktop, per Figma 2311:13364) ── */
/* Панель: белый фон, radius-32, padding-24, full-width контейнера (1360), floats flush под хедером (0 gap).
   Пункты: обводка --border-blue (#c7d3ff@46%), radius-16, h-164, иконка 48 + подпись 18/Medium по центру.
   Открытие — ТОЛЬКО клик (.is-open на li), :hover-открытие убрано по клиентскому фидбеку («дропдауны
   должны открываться по клику»). Клавиатура: Enter/Space на триггере открывает (эмулирует клик),
   Escape закрывает и возвращает фокус на триггер — см. initMobileSubmenus() в main.js (общая логика
   для десктопа и мобильного аккордеона, единый класс-переключатель .is-open на обеих раскладках). */
.has-dropdown{position:static}
.nav-dropdown{position:absolute;left:0;right:0;top:100%;z-index:calc(var(--z-nav) + 1);display:flex;gap:var(--sp-4);padding:var(--sp-5);margin:0;background:#fff;border-radius:var(--r-lg);box-shadow:0 32px 64px -24px rgba(20,48,60,.35);opacity:0;visibility:hidden;transform:translateY(-8px);transition:opacity .25s var(--ease-out),transform .25s var(--ease-out),visibility 0s linear .25s}
.has-dropdown.is-open .nav-dropdown{opacity:1;visibility:visible;transform:translateY(0);transition:opacity .25s var(--ease-out),transform .25s var(--ease-out),visibility 0s}
.nav-drop-item{display:flex;flex:1 1 0;min-width:0;flex-direction:column;align-items:center;justify-content:center;gap:var(--sp-4);height:164px;padding:var(--sp-4);border:1px solid var(--border-blue);border-radius:var(--r-md);color:var(--ink-body);font-size:18px;font-weight:500;text-align:center;text-decoration:none;line-height:1.3;transition:background .2s var(--ease-out),border-color .2s var(--ease-out)}
.nav-drop-item:hover,.nav-drop-item:focus-visible{background:var(--background-bg);border-color:var(--cyan-2)}
.ndi-ic{flex:none;font-size:32px;line-height:1}
.nav-dropdown-wide{flex-wrap:wrap}
.nav-dropdown-wide .nav-drop-item{flex:1 1 calc(25% - 12px)}

/* burger */
.burger{width:40px;height:40px;padding:0;border:0;background:transparent;display:none;flex-direction:column;align-items:center;justify-content:center;gap:6px;cursor:pointer}
.burger span{display:block;width:22px;height:2px;border-radius:2px;background:#fff;transition:background .3s,transform .3s var(--ease-out),opacity .3s var(--ease-out)}
#site-nav.scrolled .burger span{background:var(--ink-cold)}
.burger[aria-expanded="true"] span:first-child{transform:translateY(4px) rotate(45deg)}
.burger[aria-expanded="true"] span:last-child{transform:translateY(-4px) rotate(-45deg)}

@media (max-width:991.98px){
  :root{--promo-h:33px}
  .promo-badge{height:20px;font-size:11px}
  .promo-txt{font-size:12px}
  .promo-link{font-size:12px}
  .burger{display:flex}
  /* ── Мобильное меню — полный ребилд по Figma 2060:13816 «Меню открыто» (клиент: «вообще бред,
     не то что я дал» — предыдущая версия строила меню как ОДНУ плавающую карточку с закруглением
     28px на весь блок логотип+бургер+пункты. В ноде это ДВА разных слоя:
       1) узкая плавающая ТАБЛЕТКА (48px высотой, radius-100, инсет 16px, top 12px) — только
          лого + крестик-закрытие, отдельный «остров» с белым фоном и backdrop-blur;
       2) залитая на весь экран (edge-to-edge, БЕЗ радиуса/тени/отступов) панель bg #F8FAFF —
          именно в ней лежат пункты меню/CTA/контакты, начинается на 92px от верха (= 12 top-таблетки
          + 48 высота + 32 gap до первого пункта).
     Раньше #site-nav (сама шапка) просто перекрашивалась в .scrolled-белый и оставалась во всю
     ширину 70px высотой — визуально давало «сплошной белый прямоугольник», а не таблетку с меню
     под ней per макет. Ниже #site-nav при открытой панели уменьшается до 48px/radius-100/инсет —
     схлопывается в таблетку; .navbar-collapse становится полноэкранной заливкой без радиуса/тени. */
  :root{--burger-pill-h:48px;--burger-pill-gap:12px}
  /* ── Мобильный хедер = плавающая ПИЛЮЛЯ ВСЕГДА (Figma «Header Mobile/Default» 343×48, инсет 16, top 12).
     Роман выбрал «пилюля всегда»: закрытый = полупрозрачная стеклянная пилюля над hero; .scrolled =
     непрозрачно-белая пилюля; открытое меню = уже пилюля (правило :has(.show) ниже перебивает по
     специфичности (1,2,0) > (1,0,0)). BACKDROP-FILTER НЕЛЬЗЯ (см. коммент ниже про containing-block для
     fixed .navbar-collapse) — «стекло» даём полупрозрачной тёмной заливкой без блюра. Цвет/бургер белые
     в закрытом, тёмные в .scrolled — это уже делает существующая логика .scrolled, здесь только ФОРМА. */
  #site-nav{top:0;transform:none;inset-inline:16px;width:auto;height:var(--burger-pill-h);margin-top:calc(var(--promo-h) + var(--burger-pill-gap));border-radius:100px;background:rgba(0,0,0,.24);border:0;box-shadow:none}
  /* 2px-блюр (нода backdrop-blur-[2px]) отдаём ПСЕВДОЭЛЕМЕНТУ, не самому #site-nav: backdrop-filter на
     #site-nav создал бы containing-block для fixed .navbar-collapse и запер полноэкранное меню в 48px-
     пилюлю (см. коммент ниже). ::before — не предок .navbar-collapse, блюр безопасен. */
  #site-nav::before{content:"";position:absolute;inset:0;border-radius:inherit;backdrop-filter:blur(2px);-webkit-backdrop-filter:blur(2px);pointer-events:none;z-index:-1}
  /* padding:0 (не только -inline): Bootstrap .navbar даёт padding-block:.5rem, из-за него контент
     пилюли сползал вниз (верх 16 / низ 8 у лого — фидбэк Романа). Обнуляем вертикальный паддинг —
     лого/бургер центрируются симметрично в 48px через align-items:center. */
  #site-nav .navbar{height:var(--burger-pill-h);padding:0 var(--sp-4);align-items:center}
  /* Лого 24px (нода: symbol 24h + white-horizontal 20h). Десктопный 40px-лого вылезал за пилюлю — фидбэк Романа. */
  #site-nav .nav-logo img{height:24px}
  #site-nav.scrolled{background:#fff;box-shadow:0 12px 28px -10px rgba(20,48,60,.22)}
  /* backdrop-filter НЕ используем здесь (нода: backdrop-blur-[2px]) — на элементе с position:fixed
     свойства transform/filter/backdrop-filter создают новый containing-block для fixed-потомков;
     #site-nav — родитель .navbar-collapse (тоже position:fixed) в разметке, поэтому блюр на #site-nav
     "запирал" бы панель меню внутрь маленькой таблетки 48px вместо всего вьюпорта. Непрозрачный белый
     (.94 альфа) даёт визуально почти идентичный результат без этого архитектурного конфликта. */
  /* isolation:isolate — #site-nav обязан стать полноценным stacking-context, а не просто
     position:fixed+z-index (последнее не мешает fixed-потомку .navbar-collapse красить общий
     контекст поверх СОБСТВЕННОГО фона предка — фон предка всегда «за» контентом детей независимо
     от z-index детей, если у самого предка нет своего изолированного контекста). С isolate любой
     z-index внутри #site-nav сравнивается ТОЛЬКО внутри него — .navbar-collapse{z-index:-1} теперь
     гарантированно уходит под собственный фон #site-nav (белая таблетка-пилюля), а не только под
     отдельные иконки лого/крестика. */
  /* Открытое меню: пилюля хедера = чистый #fff и НЕ сливается с #F8FAFF-фоном меню (фидбэк Романа).
     ВАЖНО про порядок отрисовки: панель (.navbar-collapse) — negative-z ребёнок этого stacking-context
     (isolation:isolate), её сплошная заливка #F8FAFF рисуется ПОВЕРХ собственного фона+тени #site-nav
     (фон/тень контекста-корня = самый низ). Из-за этого белый фон и тень пилюли были невидимы — панель
     их перекрывала, «всё одним цветом» (фидбэк Романа). Решение: сам #site-nav прозрачный; белую пилюлю
     + мягкую тень рисуем на ::before c z-index:-1 (ВЫШЕ панели z-index:-2, но НИЖЕ лого/крестика) — тень
     ложится на панель и остаётся видимой. Тени/бордера в ноде нет жёсткого — только мягкая приподнятость. */
  #site-nav:has(.navbar-collapse.show){top:0;transform:none;inset-inline:16px;width:auto;height:var(--burger-pill-h);margin-top:calc(var(--promo-h) + var(--burger-pill-gap));isolation:isolate;background:transparent;border:0;border-radius:100px;box-shadow:none}
  #site-nav:has(.navbar-collapse.show)::before{display:block;background:#fff;box-shadow:0 6px 22px -2px rgba(13,36,52,.22),0 2px 6px rgba(13,36,52,.12);backdrop-filter:none;-webkit-backdrop-filter:none;z-index:-1}
  #site-nav:has(.navbar-collapse.show) .navbar{height:var(--burger-pill-h);padding-inline:var(--sp-4)}
  #site-nav:has(.navbar-collapse.show) .navbar-collapse{z-index:-2}
  #site-nav:has(.navbar-collapse.show) .nav-logo img{height:24px}
  #site-nav:has(.navbar-collapse.show) .nav-logo .logo-on-dark{display:none}
  #site-nav:has(.navbar-collapse.show) .nav-logo .logo-on-light{display:block}
  #site-nav:has(.navbar-collapse.show) .burger span{background:var(--ink-cold)}
  /* Кнопка брони в РАСКРЫТОМ меню — всегда синяя (правило Романа: «мобильное меню всегда светлое,
     и кнопка там всегда синяя»). Правило «белая кнопка над синим херо» (см. #site-nav:not(.scrolled)
     :has(~ .hero-blue) .nav-cta ниже по файлу) не знает про раскрытое меню: #site-nav как был
     сиблингом .hero-blue, так и остаётся — и белая кнопка оказывалась на белой панели.
     Специфичность считана: там (1,3,0) — id + .scrolled + .hero-blue + .nav-cta. Здесь (1,4,0):
     добавлен .navbar-collapse + .show. Выигрывает по весу, а не по порядку — поэтому правку
     ниже по файлу можно двигать, не ломая эту. */
  #site-nav:not(.scrolled):has(.navbar-collapse.show) .nav-cta{background:var(--grad-cta);color:#fff}
  /* Полноэкранная заливка (не карточка): фон начинается СРАЗУ под промо-баром (без разрыва —
     в ноде таблетка плавает НАД сплошной заливкой, а не над «дыркой» до неё), контент внутри
     отступает от таблетки через padding-top, а не через inset самой панели (иначе между низом
     таблетки и фоном виден кусок hero/видео вместо сплошного fill). Без радиуса/тени/боковых
     отступов — панель edge-to-edge, ровно как в ноде. */
  #site-nav .navbar-collapse{position:fixed;inset:var(--promo-h) 0 0;max-height:none;overflow-y:auto;flex-direction:column;align-items:stretch;gap:0;padding:calc(var(--burger-pill-gap) + var(--burger-pill-h) + 32px) 16px 24px;margin:0;background:var(--background-bg);border-radius:0;box-shadow:none}
  /* Bootstrap раскрывает .navbar-collapse в display:BLOCK — из-за этого flex-direction/margin-top:auto не
     работали, контакты висели в потоке (193px до низа). Форсим flex при .show → контакты margin-top:auto
     прижимаются к нижнему краю меню (фидбэк Романа). */
  #site-nav .navbar-collapse.show{display:flex}
  .mkk-menu{flex-direction:column;align-items:stretch;gap:var(--sp-6);width:100%;padding:0}
  .mkk-menu li{width:100%}
  .nav-link{width:100%;padding:2px 0;color:var(--ink-cold);justify-content:space-between;font-size:24px;border-bottom:0}
  .nav-chev{width:16px;height:16px;color:var(--ink-mut);transition:transform .25s var(--ease-out)}
  .nav-cta{display:flex;height:56px;margin:var(--sp-6) 0 0}

  /* Аккордеон подменю (нода: раскрыт один пункт — "Керлинг" — метка становится цветной #00A1FF,
     шеврон переворачивается, пункты выезжают списком с иконкой 24 + текстом 16, гэп 12 между
     пунктами и 14 от заголовка группы до первого пункта). Использует ту же разметку
     .nav-dropdown/.nav-drop-item, что и десктопный клик-дропдаун — здесь просто другой визуал
     вместо floating-панели. */
  /* Раскрытие подменю — ПЛАВНОЕ (фидбэк Романа: «скачет всё сильно, если с пункта на пункт
     переходишь»). Было display:none → display:flex, а display не анимируется вообще, поэтому
     список появлялся мгновенно и соседние пункты дёргались.
     Анимируем max-height + opacity + padding-top. padding-top ОБЯЗАТЕЛЬНО в переходе: иначе
     закрытый блок продолжает занимать 16px и между пунктами остаётся лишний воздух.
     visibility снимаем с задержкой на длину анимации — чтобы ссылки закрытого подменю
     не ловили фокус, но при этом успели доиграть закрытие.
     max-height 520 — с запасом: самое длинное подменю («Услуги и мероприятия», 8 пунктов)
     на планшете занимает ~384. Точную высоту дать нельзя, она разная у каждого пункта. */
  .has-dropdown .nav-dropdown{position:static;display:flex;flex-direction:column;gap:var(--sp-3);padding:0;margin:0;background:transparent;box-shadow:none;border-radius:0;
    opacity:0;visibility:hidden;transform:none;max-height:0;overflow:hidden;
    transition:max-height .34s var(--ease-out),opacity .22s var(--ease-out),padding-top .34s var(--ease-out),visibility 0s linear .34s}
  #site-nav .has-dropdown.is-open>.nav-link{color:var(--cyan-2)}
  .has-dropdown.is-open .nav-chev{color:var(--cyan-2);transform:scaleY(-1)}
  .has-dropdown.is-open .nav-dropdown{max-height:520px;opacity:1;visibility:visible;padding-top:var(--sp-4);
    transition:max-height .34s var(--ease-out),opacity .22s var(--ease-out) .06s,padding-top .34s var(--ease-out),visibility 0s}
  .nav-dropdown-wide{flex-wrap:nowrap}
  .nav-drop-item{flex:none;flex-direction:row;justify-content:flex-start;height:auto;width:100%;padding:0;border:0;border-radius:0;gap:var(--sp-3);font-size:16px;font-weight:500;color:rgba(63,63,63,.8);text-align:left}
  .nav-drop-item:hover,.nav-drop-item:focus-visible{background:transparent;border-color:transparent;color:var(--ink-cold)}
  /* Иконка подпункта — ФИКСИРОВАННЫЙ КВАДРАТ (фидбэк Романа: «начало текста каждого подпункта
     пляшет»). Причина: в разметке иконка — то эмодзи-глиф, то <img height=26>, и ширины у них
     разные. Поэтому в «Услугах» (все эмодзи) текст стоял ровно, а в «О клубе» и «Ресторане»,
     где эмодзи вперемешку с картинками, съезжал.
     Даём боксу жёсткую ширину и центрируем содержимое — текст всегда стартует с одной вертикали. */
  .ndi-ic{flex:none;display:inline-flex;align-items:center;justify-content:center;width:28px;font-size:24px}
  .ndi-ic img{max-width:100%;height:auto}

  /* Контакты внизу панели (Figma 2065:14440): инсет ШИРЕ, чем у пунктов меню (32px против 16px —
     сверено по ноде: left-[32px] w-[311px] на фрейме 375, тогда как пункты меню на left-[16px]
     w-[343px]) — доп. 16px компенсируем padding-inline на самом блоке. 2 пилюли в ряд (gap 6),
     email на всю ширину под ними (тот же gap 6 от ряда), копирайт — через больший gap 25px. */
  /* Боковой отступ блока — НОЛЬ: 16px до края экрана уже даёт паддинг самой панели, и бейджи
     встают ровно по одной вертикали с пунктами меню и кнопкой брони. Раньше блок держал
     собственные 16 сверху (итого 32 от края) — бейджи оказывались уже остальных элементов
     меню и теряли 32px ширины, которых как раз не хватало ряду на 390. */
  .nav-mobile-contacts{display:flex;flex-direction:column;align-items:stretch;gap:var(--sp-5);margin-top:auto;padding:40px 0 var(--sp-1)}
  .nav-mobile-contacts .nmc-copy{text-align:center}
  .nmc-buttons{display:flex;flex-direction:column;align-items:stretch;gap:var(--sp-2);width:100%}
  /* Бейджи контактов — ПО ШИРИНЕ КОНТЕЙНЕРА (фидбэк Романа: «такие маленькие, что и пальцем
     тяжело попасть»). Было 28px высоты и hug по контенту — вдвое ниже минимальной тач-цели 44px.
     Стало: ряд на всю ширину, две пилюли делят её поровну (flex:1), высота --sp-7 = 48.
     Центрирование теперь даёт justify-content внутри самой пилюли, а не схлопывание бокса,
     поэтому align-items:center на родителе снят — иначе он вернул бы hug. */
  .nmc-row{display:flex;gap:var(--sp-2);width:100%}
  /* flex:1 1 auto, а НЕ flex:1 — принципиально. flex:1 = flex-basis:0, то есть ряд делится
     поровну и длинный телефон получает столько же, сколько короткое «Вконтакте», упираясь
     текстом в бордер. С basis:auto пилюли стартуют от своего контента, а свободное место
     делится поверх — у каждой остаётся свой воздух. */
  .nmc-row .nmc-pill{flex:1 1 auto;min-width:0}
  .nmc-pill{display:inline-flex;align-items:center;justify-content:center;gap:var(--sp-2);
    height:var(--sp-7);padding:0 var(--sp-4);border:1px solid rgba(63,63,63,.8);border-radius:222px;
    color:rgba(63,63,63,.8);font-size:var(--text-sm);font-weight:500;text-decoration:none;white-space:nowrap}
  .nmc-pill svg{flex:none}
  /* Почта — hug по контенту и по центру (фидбэк Романа: адрес влезает целиком, растягивать
     не надо). Ряд из телефона и ВК при этом делит ширину блока пополам. */
  .nmc-pill-wide{width:auto;align-self:center}
  /* Узкие экраны: когда телефон и ВК перестают помещаться в ряд — ВСЕ ТРИ в столбик,
     и все три HUG по контенту, по центру (правило Романа: «а то они как в армии все как один»).
     flex:none обязателен — в колоночном флексе flex-basis идёт по ГЛАВНОЙ оси, то есть
     по высоте, и height:48 схлопывается до высоты контента (ловил на 23px). */
  @media (max-width:359.98px){
    .nmc-row{flex-direction:column;align-items:center}
    .nmc-row .nmc-pill{flex:none;width:auto}
    .nmc-pill-wide{width:auto;align-self:center}
  }
  .nmc-copy{margin:0;color:rgba(63,63,63,.8);font-size:12px;opacity:.5}
}
@media (min-width:992px){
  /* Task 15 (client round 2, п.2): было `color:inherit` — «чисто мобильный визуал, триггер остаётся
     белым/тёмным как обычная ссылка» (прежнее решение). Живой repro: inherit тянет computed color у
     родителя <li>, а тот ни разу не задаёт свой color явно — цепочка наследования уходит ДО самого
     body{color:var(--ink-body)} (#3F3F3F, «почти чёрный»), что и давало клиентский баг независимо от
     top/scrolled состояния нава (оба варианта .nav-link задают color ЯВНО на самом элементе — inherit
     их обходит целиком, читая родителя, а не то, каким был бы color без этого правила). Клиент теперь
     хочет открытый триггер акцентным (var(--cyan-2)) в ОБОИХ состояниях нава — тем же цветом, что уже
     красит мобильный аккордеон (.has-dropdown.is-open .nav-link ниже в мобильном блоке). Специфичность
     #site-nav .mkk-menu ... (id+4 класса) намеренно выше двух новых hover-правил выше (id+2/3 класса) —
     открытое состояние обязано перебивать hover, а не мигать дим-цветом при наведении на уже открытый
     триггер. */
  #site-nav .mkk-menu .has-dropdown.is-open>.nav-link{color:var(--cyan-2)}
}
/* ── HERO ── */
#hero{position:relative;min-height:100svh;display:flex;align-items:flex-end;overflow:hidden;isolation:isolate;color:#fff}
#heroVideo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;filter:saturate(.9) brightness(.95);z-index:0}
/* Скрим по референсу 2004:10497: в макете затемнение заметно интенсивнее прежнего (.10->.78) — верх
   (у нава) уже ощутимо темнее чистого видео, низ (у карточек) почти непрозрачный тёмно-синий. Альфы
   .44->.90 подобраны РАСЧЁТОМ, не на глаз: живой сэмпл пикселей видео внутри bbox .hero-slogan дал
   до rgb(253,255,255) в отдельных кадрах (белая стена/бумага в сюжете) — при .25->.85 контраст
   .hero-slogan (rgba(255,255,255,.92)) на высоте саба (~56% #hero, между 20%- и 100%-стопами)
   падал до 3.48-4.44:1 в зависимости от кадра. Пересчитано на чистый белый (255,255,255) как
   абсолютный худший случай (future-proof на любой кадр автоплей-видео, не только сэмплированный
   момент) — базовый .44->.90 давал 4.72:1. Роман (фаза редизайнов): усилить скрим под заголовком —
   ramp углублён до 4 стопов (.40 верх -> .56 -> .80 в зоне H1/слогана -> .97 у карточек), контраст в
   зоне текста поднят до ~6:1, видео сверху остаётся читаемым. */
.hero-scrim{position:absolute;inset:0;background:linear-gradient(180deg,rgba(10,32,50,.40),rgba(10,32,50,.56) 40%,rgba(10,32,50,.8) 64%,rgba(10,32,50,.97));z-index:1}
#frostDust{position:absolute;inset:0;width:100%;height:100%;z-index:2;pointer-events:none}
/* Task 9: морозная пыль отключена на мобиле (perf per brief) — initFrostDust() в motion.js уже не
   запускает rAF-цикл ниже 768px, display:none тут — второй, независимый от JS уровень (канвас просто
   не занимает место в рендер-дереве даже до/без JS, и защищает от «пустого» канваса, если по какой-то
   причине JS ещё не успел решить, рисовать в него или нет). */
@media (max-width:767.98px){#frostDust{display:none}}
/* padding-top обязан учитывать промо-бар: #site-nav фиксирован и сдвинут вниз на --promo-h, значит контенту
   нужно очистить и промо, и сам хедер. Figma 2004:10497: header-box 86px + gap 48px до Title = 134px —
   у нас header без доп. паддинга-обёртки (--nav-h=70px впритык), поэтому 70+48=118px в состоянии без промо,
   что и даёт то же визуальное расстояние; formula ниже добавляет --promo-h сверху для состояния "промо видно".
   Клиент: на вьюпортах меньшей высоты (~700-750px) H1 уходил ПОД нав — #hero использует align-items:flex-end
   (контент прижат к низу), а padding-top был фиксированным числом (не зависел от высоты вьюпорта), поэтому
   при нехватке высоты весь контент-стек «выталкивал» свой верх (где начинается H1) за пределы вьюпорта вверх,
   под фиксированный хедер. Жёсткий гейт: padding-top НИКОГДА не опускается ниже (promo+nav+24px) — это чистый
   зазор под хедером; clamp() ниже уменьшает паддинг СВЕРХ этого пола пропорционально высоте вьюпорта (5vh),
   так что на низких вьюпортах паддинг зажимается к полу, а не остаётся прежним 158px и не толкает H1 вверх. */
.hero-in{position:relative;z-index:3;width:100%;padding-top:clamp(calc(var(--promo-h) + var(--nav-h) + 24px),calc(var(--promo-h) + var(--nav-h) + 5vh),calc(var(--promo-h) + var(--nav-h) + 48px));padding-bottom:clamp(32px,3vw,40px)}
/* Текст-группа hero (H1+слоган): внутренний отступ группы (H1→слоган) держим ТУЖЕ внешнего
   (слоган→кнопки) — закон близости, иначе слоган «отклеивается» от заголовка к кнопкам (фидбэк
   Романа). Сумма (internal+external) = прежним 6vh (2vh+4vh), так что общая высота hero-стека и
   гарантия «влезает в один вьюпорт» не меняются; меняется только распределение. */
.hero-h1{margin:0 0 clamp(var(--sp-2),2vh,var(--sp-4));color:#fff}
/* Task 9 hero-вход: .hero-title-line — маска (overflow:hidden), .htl-inner — то, что реально
   транслейтится по Y в initHeroIntro (gsap.from yPercent:110). Раньше сам .hero-title-line был
   display:block без вложенной обёртки — GSAP не может одновременно клипать и двигать один и тот же
   элемент (overflow:hidden отсекает just-in-time по границам САМОГО себя, а transform у него же не
   создаёт новый видимый "порез", т.к. клип и контент — один узел), поэтому текст обёрнут во
   вложенный .htl-inner (см. index.html) — маска остаётся неподвижной, едет только контент внутри неё. */
.hero-title-line{display:block;overflow:hidden}
.htl-inner{display:inline-block}
.hero-dim{color:rgba(255,255,255,.49)}
.hero-slogan{margin:0 0 clamp(var(--sp-5),4vh,var(--sp-6));max-width:666px;color:rgba(255,255,255,.92);font-size:clamp(16px,1.6vw,22px);font-weight:400;line-height:1.4}
/* Перенос слогана по макету (Figma 2004:10497): «...громко кричат» / «и непонятно...» — управляемый
   <br>, а не случайный перенос по ширине контейнера. Виден только >=768px (там, где ширина строки
   реально позволяет второй строке начаться с «и», как в макете); на мобиле — естественный wrap. */
.slogan-br{display:none}
@media (min-width:768px){.slogan-br{display:inline}}
.hero-cta{display:flex;flex-wrap:wrap;align-items:center;gap:var(--sp-4);margin-bottom:clamp(24px,8vh,80px)}
.hero-cards{display:grid;grid-template-columns:repeat(5,1fr);gap:var(--sp-4);list-style:none;margin:0;padding:0}
/* Высота карточки — тоже clamp по vh (не фиксированный 168px): на низких вьюпортах (700-750px) карточки
   должны сжаться, а не выталкивать нижний край блока за пределы экрана — весь hero-стек (H1+саб+кнопки+
   карточки) обязан помещаться в один вьюпорт по требованию клиента. */
.hero-card{display:flex;flex-direction:column;align-items:center;justify-content:space-between;gap:var(--sp-4);height:clamp(120px,20vh,168px);padding:20px;background:var(--glass-bg);border:1px solid var(--glass-br);border-radius:var(--r-lg);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);color:#fff;text-align:center;font:500 16px/1.3 'Onest',sans-serif;text-decoration:none;transition:transform .3s var(--ease-out),background .3s var(--ease-out)}
.hero-card:hover{transform:translateY(-6px);background:rgba(255,255,255,.18)}
.hero-card:focus-visible{outline-offset:4px}
.hc-emoji{flex:none;width:56px;height:56px;object-fit:contain}
/* Камень-эмодзи: в исходном PNG контент смещён вниз на +8/112 ≈ 7.1% (padT24/padB7 — остальные эмодзи
   центрированы), из-за чего в первой карточке «не по центру» (фидбэк Романа). Квадрат в квадрате —
   object-position не помогает; правим сдвигом на -7.1% (в % от высоты элемента = независимо от размера,
   чинит и мобилку 32px, и десктоп 56px, без пересборки ассета). */
.hc-stone{transform:translateY(-7.1%)}
@media (max-width:767.98px){
  /* Боковые поля контейнера = 16px (нода: контент и хедер на x=16, ширина 343) вместо десктопных 20px. */
  .container-mkk{--bs-gutter-x:32px}
  /* ── Мобильный hero строго по Figma 2203:34953 / Title 2062:20796 ──
     Title в ноде = flex-col gap-16 items-center TEXT-CENTER → H1 и слоган ПО ЦЕНТРУ (не влево, как на
     десктопе — это был мой промах). H1 40px (нода 335×88 = 2 строки). Слоган 16px Onest Medium(500)
     lh1.3, центр. Отступы ноды: H1→слоган 16 (базовый clamp), слоган→кнопки 40, кнопки→карточки 44.
     На мобиле hero скроллится (878>vh) — «в один вьюпорт» это десктоп-требование, здесь фикс-значения. */
  .hero-h1{font-size:40px;line-height:1.1;text-align:center}
  .hero-slogan{margin-bottom:40px;text-align:center;font-weight:500;line-height:1.3}
  .hero-cta{flex-direction:column;align-items:center;gap:var(--sp-3);margin-bottom:44px}
  .hero-cta .btn-mkk{width:auto}
  /* Синяя (primary) кнопка чуть шире для визуального баланса (нода: primary 260 / secondary 217) —
     решение Романа. min-width, чтобы текст всё равно влезал, но кнопка не «жалась». */
  .hero-cta .btn-mkk-primary{min-width:260px}
  /* Экшн-карточки: вертикальный стек full-width (нода — НЕ горизонтальный скролл), 68px, gap 12.
     ⚡ Внутренняя раскладка — по прямому решению Романа (НЕ как в ноде «текст→эмодзи»): ЭМОДЗИ СЛЕВА +
     текст, СПРАВА шеврон-аффорданс «нажимается/ведёт на страницу» — иначе на мобиле карточки читались
     как простой список (на десктопе плиточная раскладка это делала очевидным). */
  .hero-cards{display:flex;flex-direction:column;gap:var(--sp-3);overflow:visible;padding:0}
  .hero-card{flex-direction:row;justify-content:flex-start;align-items:center;gap:var(--sp-3);width:100%;min-width:0;height:68px;padding:0 20px;border-radius:var(--r-md);text-align:left}
  .hc-emoji{width:32px;height:32px}
  .hero-card::after{content:"";flex:none;margin-left:auto;width:9px;height:9px;border-top:2px solid rgba(255,255,255,.6);border-right:2px solid rgba(255,255,255,.6);transform:rotate(45deg)}
}
/* ── TRUST STRIP ── */
#trust{border-block:1px solid rgba(20,48,60,.08)}
/* ЗАКОН БЛИЗОСТИ ВНУТРИ ПОЛОСЫ (правка Романа, свежий взгляд).
   Внутри айтема две РАЗНЫЕ группы: «4.7 + звёзды» — это оценка, а логотип — источник оценки.
   Отступы были одинаковые (8 везде), и группы читались как один сплошной ряд.
   Стало три уровня воздуха: 8 внутри оценки (b↔звёзды), 20 между логотипом и оценкой
   (8 gap + 12 margin), 48 между Google и Яндексом. Ратио ~2.5x на каждом уровне —
   иерархия читается однозначно. */
.trust-in{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:var(--sp-4) var(--sp-7);padding-block:20px}
/* Fix Wave B, п.2: trust-item is now an <a> (was <span>) — same interim URLs as the "Читать
   отзывы" links in #reviews (Google search / Яндекс.Карты). text-decoration:none overrides the
   Bootstrap-reboot default (a{text-decoration:underline}); opacity hover mirrors the existing
   .ep-thumb:hover img pattern rather than an underline, which would draw messily across a
   flex row mixing a logo image with text and star SVGs. */
.trust-item{display:inline-flex;align-items:center;gap:var(--sp-2);color:var(--ink-mut);font-size:15px;font-weight:500;white-space:nowrap;text-decoration:none;cursor:pointer;transition:opacity .25s var(--ease-out)}
.trust-item:hover{opacity:.7}
.trust-item b{color:var(--ink-cold);font-weight:700;font-variant-numeric:tabular-nums}
/* margin-right складывается с gap контейнера: 8 + 12 = 20 между логотипом и оценкой. */
.trust-logo{display:block;height:20px;width:auto;flex:none;object-fit:contain;margin-right:var(--sp-3)}
.stars{display:inline-flex;align-items:center;gap:2px;color:var(--gold);flex:none}
.stars svg{flex:none;display:block}
@media (max-width:575.98px){
  /* Google/Яндекс — В ОДНУ СТРОКУ (фидбэк Романа: было в столбец): nowrap + компактно, чтобы 2 айтема
     влезли в 375 (лого 16, звёзды 14, шрифт 12, узкий gap). */
  /* Аккуратно уменьшаем всё до единого мелкого размера + больше воздуха между Google и Яндекс,
     чтобы ушло ощущение тесноты (фидбэк Романа: «размеры скачут»). */
  /* Те же три уровня воздуха, что на десктопе, но пересчитанные под мелкий кегль:
     5 внутри оценки, 12 между логотипом и оценкой (5 + 7), 32 между Google и Яндексом. */
  .trust-in{flex-wrap:nowrap;justify-content:center;gap:var(--sp-6);padding-block:var(--sp-4)}
  .trust-item{font-size:12px;gap:5px}
  .trust-logo{height:13px;margin-right:7px}
  .trust-item .stars{gap:1px}
  .trust-item .stars svg{width:12px;height:12px}
}

/* ── ICE LANES (Task 10, «Один бросок»: #lane-1/#lane-2 — DOM-разделители между секциями, уже
   стояли в разметке пустыми с Task 7 как задел под стоун; здесь получают лёд+разметку). Полоса —
   горизонтальная лента льда во всю ширину секции, 140px высотой на десктопе. Три.js-канвас
   (#stoneCanvas, ниже) рисует поверх этого фона на десктопе — CSS-разметка не декоративный тупик, а
   видимый "рельс" ПОД сценой даже когда сцена не смогла загрузиться (RM/no-WebGL, см. .stone-css).

   Fix Wave C, п.5 (клиент: «полосы не читаются как дорожка для керлинга» — были просто лёд + 2
   красные вертикальные чёрточки, без единого узнаваемого элемента настоящего керлинг-листа).
   Редизайн добавляет три элемента реального листа, не трогая структуру разметки (#lane-1/#lane-2
   остаются пустыми div — всё ниже чистый CSS, stone.js читает только getBoundingClientRect() этих
   элементов и не заботится об их содержимом, см. bindLane в stone.js):
     1) ДОМ (house) — концентрические кольца-мишень (button/cyan-2/white/cyan-1, тот же язык, что уже
        несёт .house-rings у финального #cta-house — не новая палитра, а её отражение здесь, как
        "промежуточная" мишень на пути к финальной). Один круглый radial-gradient со сплошными
        цветовыми диапазонами (двойные color-stop) — дешевле и надёжнее, чем 4 отдельных DOM-узла.
        Позиция ЗАВИСИТ от направления проезда стоуна (bindLane: dir=1 едет СЛЕВА НАПРАВО,
        dir=-1 едет СПРАВА НАЛЕВО — см. initStoneScene) — дом стоит у того края, КУДА едет камень.
        КОНТРАКТ: направление несёт АТРИБУТ data-dir на самой полосе, НЕ её id.
          data-dir="r" — финиш справа (камень едет вправо, dir=1)
          data-dir="l" — финиш слева  (камень едет влево,  dir=-1)
        Раньше это сидело на #lane-1/#lane-2, и третья полоса (birthday.html) осталась бы вообще
        без разметки — пришлось бы дублировать 47 правил в трёх слоях. Атрибут снимает вопрос:
        любая новая полоса просто объявляет своё направление. Вес правил стал (0,2,0) вместо
        (1,1,0) — по-прежнему выше базовых .lm-* (0,1,0), порядок в файле сохранён.
        CY=55%, не 50% — совпадает с фактической линией проезда стоуна (bindLane: sy=r.top+r.height*.55,
        брифф verbatim «чуть ниже геометрического центра»), дом визуально сидит НА пути камня.
     2) ЦЕНТРАЛЬНАЯ ЛИНИЯ — тонкая линия во всю длину полосы (реальный curling: идёт по центру листа
        вдоль направления броска — наша полоса ГОРИЗОНТАЛЬНА и ЕСТЬ направление броска, значит линия
        тоже горизонтальна, во всю ширину). Второй background-layer, той же Y=55%, что и дом (дом в
        реальном керлинге стоит НА центральной линии).
     3) HOG LINES — уже существовали (::before/::after, вертикальные, т.к. пересекают ПОПЕРЁК
        направления броска), но при opacity:.55/3px читались слишком блекло на светлом льду (клиент:
        "не читается"). Подняты opacity .55→.85 и толщина 3→4px — та же позиция (12%/88%), просто
        заметнее.
   Не буквальная копия эталонных диаграмм клиента (задача не требует 1:1) — цель "очевидно, что это
   керлинг-дорожка", не чертёж. .stone-css fallback (RM/no-WebGL, ниже по файлу) не тронут — он
   переопределяет ТОЛЬКО ::before/::after (hog lines → морозный след), фон/дом/линия остаются видимы
   и под фолбэком тоже. */
/* Разметка листа — ТОЧНЫЕ пропорции из присланных Романом Way.svg (весь рисунок) и Aim.svg (дом).
   Полная спека — в комментарии перед .lm ниже. Поверхность — чистый светлый лёд (без тёмных теней;
   позже заменим на сгенерённую акварельную текстуру). */
.ice-lane{
  --blue:#149FD5;--red:#FF544E;--line-edge:rgba(6,187,255,.38);--line-mid:rgba(6,187,255,.21);
  position:relative;height:164px;overflow:hidden;
  border-block:1px solid rgba(140,190,218,.22);
  background:#fff;
  /* road2: у верх/низ кромок — мягкое СИНЕЕ свечение (#0E8BFF ~.29 + blur), не тёмная тень.
     Разметка (.lm-*) выше и не затрагивается */
  box-shadow:inset 0 11px 24px -6px rgba(14,139,255,.3),inset 0 -11px 24px -6px rgba(14,139,255,.3);
}
/* Лёд ice4 (road2): текстура multiply над белым при 88% (12% белая вуаль). Multiply над белым =
   identity → фактически ice4@88%. Разные позиции crop — полосы не идентичны. ice1/ice2/ice3
   остались в assets. Разметка .lm-* — поверх. */
/* Текстура — на АТРИБУТ, не на ID: страниц с полосами больше одной, и их число не фиксировано
   (birthday.html несёт три). Список ID пришлось бы дописывать на каждую новую полосу — [data-lane]
   ловит любую. Вес (0,1,0) = у .ice-lane выше, поэтому правило обязано стоять НИЖЕ него
   (там background:#fff шорткатом сбрасывает background-image). */
[data-lane]{
  background-image:linear-gradient(rgba(255,255,255,.12),rgba(255,255,255,.12)),url(../design/img/ice4.jpg);
  background-repeat:no-repeat,no-repeat;
  background-size:auto,cover;
  background-blend-mode:normal,multiply;
}
/* Кроп льда — единственное, что остаётся пер-полосным (полосы не должны быть идентичны). ID (1,0,0)
   бьёт [data-lane] выше, как и задумано. */
#lane-1{background-position:center,26% 42%}
#lane-2{background-position:center,74% 58%}
#lane-3{background-position:center,50% 22%}
/* Разметка = дочерние .lm-* с ТОЧНЫМИ пропорциями из Way.svg (viewBox 1835×242, масштаб k=H/242).
   Дом = Aim.svg (чёткий вектор, без пикселей), равноудалён между синим бэклайном и ближней хог-
   линией. Хог-линии симметричны (обе на 398/1835 от своего края). Центральная линия — 5 сегментов
   c разрывами (динамика, не «3 линии»). Ти — короткие штрихи сверху/снизу дома. Синий у самого края,
   шире красных (это финиш). Всё зеркалится по краю финиша (lane1 справа / lane2 слева). */
.lm{position:absolute;pointer-events:none}
.lm-back{top:0;bottom:0;width:12px;background:var(--blue)}
.lm-hog{top:0;bottom:0;width:7px;background:var(--red);transform:translateX(-50%)}
.lm-tee{width:3px;background:var(--line-edge);transform:translateX(-50%)}
.lm-tee-t{top:0;height:16px}
.lm-tee-b{bottom:0;height:16px}
.lm-c{top:50%;height:3px;transform:translateY(-50%);background:var(--line-mid)}
.lm-c-fin,.lm-c-fe{background:var(--line-edge)}   /* road2: сегменты у краёв ярче (0.38), середина тише (0.21) */
.lm-c-mid{left:min(402px,44%);right:min(402px,44%)}
.lm-house{top:50%;width:135px;height:135px;transform:translate(-50%,-50%);background:url(../design/img/house.svg) center/contain no-repeat}
[data-dir="l"] .lm-back{left:0}
[data-dir="l"] .lm-house{left:138px}
[data-dir="l"] .lm-tee{left:138px}
[data-dir="l"] .lm-hog-a{left:270px}
[data-dir="l"] .lm-hog-b{right:270px;transform:translateX(50%)}
[data-dir="l"] .lm-c-fin{left:0;right:calc(100% - 72px)}
[data-dir="l"] .lm-c-near{left:203px;right:calc(100% - 353px)}
[data-dir="l"] .lm-c-far{right:203px;left:calc(100% - 353px)}
[data-dir="l"] .lm-c-fe{right:0;left:calc(100% - 155px)}
[data-dir="r"] .lm-back{right:0}
[data-dir="r"] .lm-house{right:138px;transform:translate(50%,-50%)}
[data-dir="r"] .lm-tee{right:138px;transform:translateX(50%)}
[data-dir="r"] .lm-hog-a{right:270px;transform:translateX(50%)}
[data-dir="r"] .lm-hog-b{left:270px}
[data-dir="r"] .lm-c-fin{right:0;left:calc(100% - 72px)}
[data-dir="r"] .lm-c-near{right:203px;left:calc(100% - 353px)}
[data-dir="r"] .lm-c-far{left:203px;right:calc(100% - 353px)}
[data-dir="r"] .lm-c-fe{left:0;right:calc(100% - 155px)}
@media (max-width:767px){
  .ice-lane{height:78px}
  .lm-back{width:6px}
  .lm-hog{width:4px}
  .lm-house{width:58px;height:58px}
  .lm-tee-t,.lm-tee-b{height:9px}
  .lm-c-fin,.lm-c-fe{display:none}
  .lm-c-mid{left:min(124px,34%);right:min(124px,34%)}
  [data-dir="l"] .lm-house{left:42px}
  [data-dir="l"] .lm-tee{left:42px}
  [data-dir="l"] .lm-hog-a{left:80px}
  [data-dir="l"] .lm-hog-b{right:80px}
  [data-dir="l"] .lm-c-near{left:30px;right:calc(100% - 108px)}
  [data-dir="l"] .lm-c-far{right:30px;left:calc(100% - 108px)}
  [data-dir="r"] .lm-house{right:42px}
  [data-dir="r"] .lm-tee{right:42px}
  [data-dir="r"] .lm-hog-a{right:80px}
  [data-dir="r"] .lm-hog-b{left:80px}
  [data-dir="r"] .lm-c-near{right:30px;left:calc(100% - 108px)}
  [data-dir="r"] .lm-c-far{left:30px;right:calc(100% - 108px)}
}

/* ── SEC-HEAD-SPLIT (H2 left / lead right; reused by later sections) ── */
/* Fix Wave B, п.1: align-items end→start — client: the two-column heading row bottom-aligned the
   H2 and lead paragraph, reading as a broken grid whenever their line counts differ (short H2,
   lead wraps 2-3 lines). Top-aligning both columns is the correct default for a heading+intro
   pair — they should start on the same line, not end on one. */
.sec-head-split{align-items:end;row-gap:var(--sp-5);margin-bottom:var(--head-gap)}
.sec-head-split h2{margin:0}
.lead-txt{margin:0;color:var(--ink-body);font-size:18px;font-weight:500;line-height:1.5;letter-spacing:-.02em}
/* Лид «О клубе»: на десктопе полный текст, короткий — только на мобилке (свап ниже, ≤767). */
.lead-short{display:none}
.h2-accent{color:#0089BD}

/* ── МОБИЛЬНАЯ ДИЗАЙН-СИСТЕМА ЗАГОЛОВКОВ СЕКЦИЙ (нода 2062:21280 «Heading» и парные) ──
   На мобиле ВСЕ секц-заголовки ЦЕНТРИРОВАНЫ (нода: Heading = flex-col gap-16 items-center text-center),
   H2 24px SemiBold(600), лид 14px Regular lh1.3. Десктопный .sec-head-split (2-кол H2-слева/лид-справа)
   схлопывается в центр-стек; .sec-head-c (цены/отзывы) уже центр — добираем типографику. Отступы ноды:
   H2→лид 16 (gap), заголовок-блок→контент 32 (Heading 164 → Cards 196). ⚡ Кикер-бейджи (наш апрув-
   элемент, в ноде их нет) сохраняем — центрируются автоматически через text-align:center. */
@media (max-width:767.98px){
  h2{font-size:24px}
  /* Единый отступ заголовок→контент для ВСЕХ секций мобилки = 40 (десктоп так же унифицирован через
     --head-gap). Раньше был разнобой: клуб/события/отзывы 32, цены 64. Переопределяем один токен —
     sec-head-split / prices-heading / reviews-h2 все сидят на var(--head-gap), поэтому наследуют 40. */
  :root{--head-gap:40px}
  .sec-head-split{text-align:center;align-items:stretch;row-gap:var(--sp-4)}
  .sec-head-split h2,.sec-head-c h2,.reviews-h2,.prices-heading h2{font-weight:600}
  .lead-txt{font-size:14px;font-weight:400;line-height:1.3;letter-spacing:0;text-wrap:pretty}
  /* Свап лида «О клубе»: короткий вариант только на мобилке (десктоп — полный, см. выше). */
  .lead-full{display:none}
  .lead-short{display:inline}
  /* события: у бенто свой margin-top — на мобиле обнуляем, чтобы отступ заголовок→контент задавал
     ТОЛЬКО .sec-head-split margin-bottom (=--head-gap 40), а не суммировался с mt бенто. */
  #events .events-bento{margin-top:0}
}

/* ── SWEEP-АКЦЕНТЫ ЗАГОЛОВКОВ (Task 8, spec §5.11) ── Узкая цианова полоса под ключевыми H2
   (клуб/события используют .sec-head-split, цены — .prices-heading h2, отзывы — .reviews-h2).
   ::after рисуется всегда (44×3, transform:scaleX(0) — не layout-свойство, безопасно для
   no-JS/CSS-only просмотра — полоса просто останется свёрнутой, не "прыгающим" элементом);
   .sweep-on навешивается motion.js через ScrollTrigger once при входе секции — тогда полоса
   скейлится по X и по ней однократно пробегает блик (keyframes). Reduced-motion уже глушит все
   transition/animation глобально (конец файла), поэтому здесь доп. RM-гварда не нужно — но раз
   .sweep-on ставит только JS (который сам ранний-return на RM), при RM класс никогда не появится
   и полоса останется в исходном (свёрнутом) состоянии — приемлемо, т.к. чисто декоративный акцент. */
.sec-head-split h2,.prices-heading h2,.reviews-h2{position:relative;padding-top:20px}
.sec-head-split h2::after,.prices-heading h2::after,.reviews-h2::after{content:"";position:absolute;left:0;top:0;width:44px;height:3px;background:var(--cyan-2);transform-origin:0 50%;transform:scaleX(0);transition:transform .6s var(--ease-out)}
.reviews-h2::after{left:50%;transform:translateX(-50%) scaleX(0)}
.sec-head-split h2.sweep-on::after,.prices-heading h2.sweep-on::after{transform:scaleX(1)}
.reviews-h2.sweep-on::after{transform:translateX(-50%) scaleX(1);animation:sweepGlint 1s var(--ease-out) .1s 1}
.sec-head-split h2.sweep-on::after,.prices-heading h2.sweep-on::after{animation:sweepGlint 1s var(--ease-out) .1s 1}
@keyframes sweepGlint{0%{box-shadow:0 0 0 0 rgba(11,170,236,0)}40%{box-shadow:0 0 12px 2px rgba(11,170,236,.75)}100%{box-shadow:0 0 0 0 rgba(11,170,236,0)}}

/* ── BANNER SPECIALS (1:1 Figma 2008:11296; swappable via data-theme) ──
   Node: column layout (headline, then CTA button), radius 24, padding/gap 32, 3 rotated confetti
   SVG layers (2009:10292/10218/10255) — no separate "%" glyph in this node (confirmed again this
   wave: full-page metadata scan of 2004:10496 shows no "%" instance anywhere near the banner/hero
   either). E5: client supplied their own 3D "%" render (root spec.png) and asked for it placed per
   their original mockup screenshot — right side, large, cropped by the banner edge, decorative only
   (aria-hidden, no text). Positioned as .bs-pct below: right-aligned + vertically centered, sized
   off banner height so it scales with the banner's own box, z-index 1 (same decorative layer as
   confetti — both sit behind h3/button at z-index 2, so on any width where space gets tight it goes
   under the copy rather than over it); hidden below 576px where the banner column gets narrow and
   text already spans full width, per "не перекрывает текст/кнопку". */
.banner-discount-section{padding-top:var(--sec-pad)}
.club-intro-home{padding-top:0}
.banner-specials{position:relative;overflow:hidden;isolation:isolate;display:flex;flex-direction:column;align-items:flex-start;gap:var(--sp-6);padding:var(--sp-6);margin-bottom:140px;border-radius:24px;--banner-bg:linear-gradient(90deg,rgb(43,131,235) 0%,rgb(29,199,254) 100%);background:var(--banner-bg);color:#fff;transition:transform .3s var(--ease-out),box-shadow .3s var(--ease-out)}
/* Тема месяца: переключается атрибутом data-theme на .banner-specials.
   Новая тема = один селектор с переопределением --banner-bg (+ при желании цвета текста/CTA). */
.banner-specials[data-theme="default"]{--banner-bg:linear-gradient(90deg,rgb(43,131,235) 0%,rgb(29,199,254) 100%)}
/* Contrast-safety scrim: exact Figma fill (rgb(43,131,235)->rgb(29,199,254)) fails white-text AA on its lighter/cyan half.
   Flat dark layer under the whole banner keeps worst-case contrast ≥4.5:1 while staying subtle enough that the
   brand gradient + confetti decoration still read through clearly (measured 4.86:1 at the lightest/cyan stop). */
.banner-specials::before{content:"";position:absolute;inset:0;z-index:0;background:rgba(8,20,32,.22)}
.banner-specials:hover{transform:translateY(-6px);box-shadow:0 24px 48px -20px rgba(11,90,170,.45)}
.banner-specials h3{position:relative;z-index:2;max-width:666px;margin:0;color:#fff;font-size:clamp(26px,3.1vw,44px);line-height:1.2;letter-spacing:-.02em}
.banner-specials .btn-mkk-light{position:relative;z-index:2;flex:none}
/* Текст CTA: полный на десктопе, короткий («Все спецпредложения») на мобилке (свап ниже, <576). */
.banner-specials .bs-cta-short{display:none}
.banner-specials .confetti{position:absolute;inset:0;z-index:1;width:100%;height:100%;pointer-events:none}
/* Fix Wave B, п.3: static confetti layers (.bs-confetti×3, ex-SVG per-layer fix documented in a
   prior wave) REMOVED per client — "убери мои статические конфетти, оставь твои анимированные,
   чтобы ВСЕ были анимированы". Only the live canvas.confetti (js/motion.js initConfetti) remains;
   its particle count was raised so it reads as full-banner confetti on its own — see motion.js. */
/* E6 client fix: "% завалился вообще" (крупный, обрезан, кренится). Root cause was the SOURCE PNG,
   not just CSS — banner-pct.png was a 600×600 canvas with the glyph inset by asymmetric transparent
   padding (12.33% left / 7% right / 11% top / 14.33% bottom, measured via alpha-channel bbox scan),
   while the old rule sized the WHOLE padded canvas by width (clamp ...px, height:auto) and hung it
   PAST the banner edge (right:-6%). Net effect: the visible glyph inside that canvas rendered far
   smaller than the box implied, off-centered within its own padding, and the negative right offset
   plus overflow:hidden cropped it — reading as "fell over" even though the glyph's own diagonal bar
   is a normal % design, not a broken rotation. Fixed the asset first (sharp-cli extract to the alpha
   bbox, safety margin 2px, then palette-optimized 636KB-source-derived 99.6KB->72.8KB) so the file's
   own bounding box now matches its visible content almost exactly (488×452, ~0.4% residual padding
   each side) — no more compensating math needed for invisible canvas padding.
   Sizing: height:92% (near the top of the 85-95% target — client's own reference mockup shows the
   glyph large/bold within the banner, just never actually cropped once "полностью виден" is honored)
   resolves against .banner-specials's own height —
   valid because the parent is position:relative with a used height from its flex/content layout,
   which is exactly the case CSS percentage-heights-on-abs-pos-descendants resolves against; width:auto
   preserves the (now-accurate) 1.08 intrinsic aspect ratio, same auto-axis mechanism the previous rule
   already relied on, just flipped to the axis that actually needs to drive the size. Position: real
   right inset (not negative) keeps it fully inside the banner's own overflow:hidden box instead of
   hanging off the edge; top:50%+translateY(-50%) now centers correctly since there's no more
   asymmetric baked-in padding throwing off the visual center within the box. No extra rotate() —
   compared directly against the client's own reference mockup crop, the glyph's tilt already matches
   (natural 3D-render perspective on the diagonal bar), so any additional rotation would move it AWAY
   from the reference, not toward it. */
.bs-pct{position:absolute;z-index:1;right:4%;top:50%;transform:translateY(-50%);height:92%;width:auto;max-width:36%;pointer-events:none;filter:drop-shadow(0 20px 40px rgba(8,20,32,.28))}
@media (max-width:991.98px){.bs-pct{right:3.5%;height:86%;max-width:32%}}
@media (max-width:575.98px){.bs-pct{display:none}}
/* Fix Wave B, п.4: hover-pop on the "%" glyph, triggered by hovering the BANNER (glyph itself is
   pointer-events:none, purely decorative) — scale+rotate+brightness, transform/filter only, no
   layout properties. The base rule already centers the glyph via translateY(-50%); the hover rule
   must repeat that before adding scale/rotate or the new transform value would replace centering
   instead of composing with it. RM override collapses back to the bare centering transform (no
   added scale/rotate) — the sitewide RM rule at EOF only shortens transition-duration, it doesn't
   zero the end value, so an explicit reset is needed to actually honor "no transform" under RM. */
.bs-pct{transition:transform .4s var(--ease-out),filter .4s var(--ease-out)}
.banner-specials:hover .bs-pct{transform:translateY(-50%) scale(1.06) rotate(3deg);filter:drop-shadow(0 20px 40px rgba(8,20,32,.28)) brightness(1.08)}
@media (prefers-reduced-motion:reduce){.banner-specials:hover .bs-pct{transform:translateY(-50%)}}
@media (max-width:575.98px){
  /* Клуб-баннер по ноде 2062:21390: компактный — паддинг 16/12, gap 14, радиус 12, заголовок 16 SemiBold
     lh1.3, кнопка-пилюля h26/px10/py4/12px. (3D-% скрыт ниже 576 отдельным правилом — в ноде его нет.) */
  /* Отступы вокруг баннера (Роман): от баннера до блока «О клубе» = БОЛЬШЕ (96), от дорожки до баннера
     = стандартный/меньше (см. #club padding-top ниже). */
  .banner-specials{padding:16px 12px;gap:14px;border-radius:12px;margin-bottom:96px}
  .banner-specials h3{max-width:60%;font-size:16px;font-weight:600;line-height:1.3;letter-spacing:0}
  .banner-specials .btn-mkk-light{height:26px;padding:4px 10px;font-size:12px;gap:8px}
  /* Свап текста CTA: убираем «Смотреть» — на мобилке кнопка компактная, короткий вариант читаемее. */
  .banner-specials .bs-cta-full{display:none}
  .banner-specials .bs-cta-short{display:inline}
  /* 3D-% — откат к контейнерному варианту (Роман: bleed-эксперименты не зашли). БЕЗ искажения:
     только height + width:auto, БЕЗ max-width (клампил ширину и плющил глиф). Справа внутри баннера. */
  .bs-pct{display:block;height:86%;width:auto;max-width:none;right:6px;top:50%}
  .banner-specials::before{background:rgba(8,20,32,.3)}
}

/* ── CLUB CARDS (per Figma 2002:25753/2019:10167/2019:10190: full-bleed photo, overlapping
   white panel floats 8px from the card edge, pictogram top-right of the panel) ── */
.club-cards{--bs-gutter-x:32px;--bs-gutter-y:32px}
.club-card{position:relative;display:flex;flex-direction:column;justify-content:flex-end;align-items:center;gap:var(--sp-3);height:100%;aspect-ratio:432/400;padding:var(--sp-2);border:1px solid rgba(255,255,255,.25);border-radius:var(--r-md);overflow:hidden;isolation:isolate;transition:transform .3s var(--ease-out),box-shadow .3s var(--ease-out)}
.club-card:hover{transform:translateY(-6px);box-shadow:0 24px 40px -22px rgba(20,48,60,.28)}
.club-card-photo{position:absolute;inset:0;z-index:-1;display:block;width:100%;height:100%;object-fit:cover}
.club-card-body{width:100%;flex:none;padding:var(--sp-4);border-radius:var(--r-sm);background:rgba(255,255,255,.94);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}
.club-card-title{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-3);margin-bottom:var(--sp-2)}
.club-card-title h3{margin:0;color:var(--ink-cold);font-size:20px;font-weight:500;letter-spacing:-.02em}
.club-card-title h3 span{font-variant-numeric:tabular-nums}
.club-card-ic{flex:none;display:block}
.club-card-body p{margin:0;color:var(--ink-mut);font-size:15px;line-height:1.4}
/* Fix Wave B, п.5: margin-top 40→48px — client: the gap from the card row to the button pair read
   as "almost glued" against the height of the cards above; 48px reads as a clear, deliberate
   section break without turning the buttons into their own visually detached block. */
.club-actions{display:flex;justify-content:center;gap:var(--sp-5);margin-top:var(--sp-7);flex-wrap:wrap}
@media (max-width:767.98px){
  /* Клубные карточки по ноде 2062:21351: карточка ФИКС 264px (не aspect 432/400 = 318 на 343 — была
     выше макета), белая панель p16/r12, текст-группа gap 20 (title→описание было 8), тайтл 18 Medium,
     описание 14 Regular. Гаттер 18 — уже как в ноде. */
  .club-cards{--bs-gutter-y:18px}
  /* Клуб-карточки: скругление 16 (r-md) — норм (Роман), НЕ трогаем. По ноде 2062:21351: фикс 264,
     тайтл 18, тайтл→описание 20, описание 14 (цвет как в ноде). */
  .club-card{aspect-ratio:auto;height:264px}
  .club-card-title{margin-bottom:20px}
  .club-card-title h3{font-size:18px}
  .club-card-body p{font-size:14px;color:rgba(63,63,63,.8)}
  /* Кнопки «Забронировать» + «Подробнее» — вертикальный стек с ЭТАЛОННЫМ hero-отступом 12 (был 24). */
  .club-actions{margin-top:32px;flex-direction:column;align-items:center;gap:var(--sp-3)}
  /* Единое скругление карточек 16 на мобиле (Роман): бенто и цены были 24/28 — к 16 (клуб уже 16).
     ВАЖНО: id-специфичность (#events/#prices), т.к. базовые .eb-tile/.price-card идут НИЖЕ в файле и
     при равной специфичности перебивали бы этот медиа-блок. Плюс имя большой бенто-плитки 28→20 (на
     мобиле все плитки равны — размеры не должны скакать). */
  #events .eb-tile{border-radius:16px}
  #events .eb-big .eb-name{font-size:20px}
  #prices .price-card,#prices .price-card-teal,#prices .price-card-purple,#prices .price-card-blue-purple{border-radius:16px}
  /* Sticky-CTA «Забронировать» снизу — УДАЛЯЕМ (Роман: с браузерной строкой съедает треть экрана). */
  #stickyCta{display:none}
}

/* ── EVENTS (2×2 Figma grid, node 2108:13369 — client-restored; hover-slice
   redesign was rejected as "каша", removed entirely per feedback) ──
   E5 client fixes: (a) section bg #F8FAFF full-bleed per node 2032:10075 (node's own "Block" frame
   is 1440 wide with the fill, while "Content" inside is the usual 1360 container — the fill extends
   past the container on both sides, not just inside it; #events itself carries the bg here since a
   <section> box is naturally full-width, only .container-mkk inside it is width-capped). Previously
   this was unset (transparent), so white cards sat directly on the page's own white bg with zero
   separation — client: "карточки сливаются". (b) grid-auto-rows:1fr (not just align-items:stretch)
   forces BOTH rows of the 2×2 grid to share one common row height (the tallest card's content across
   ALL 4, not merely per-row) — align-items:stretch alone only equalizes cards WITHIN the same row,
   which happened to look fine at the one width tested but isn't guaranteed once copy changes. (c)
   .event-photo now stretches via height:100% (removed the old min-height-only approach that let it
   size independently of the actual card-grid height) — min-height kept as a mobile safety floor only,
   not the primary sizing mechanism on desktop/tablet where it sits next to the grid. */
#events{background:var(--background-bg)}
.events-row{--bs-gutter-x:32px;--bs-gutter-y:var(--sp-6);align-items:stretch}  /* gutter-y 32: зазор карточки→слайдер при мобильной стопке (24 читалось «прилепленным») */
/* E6 client fix: карточки hug по контенту. E5's grid-auto-rows:1fr + height:100% equalized all 4
   cards to the tallest one — client rejected the resulting «пустота под текстом» (empty fill under
   short copy). Both removed: rows are now auto (each row = its tallest card's own content), and
   align-items:start stops the default grid stretch WITHIN a row too, so every card hugs exactly its
   own content and rows top-align. The grid container itself is auto-height again (no height:100%),
   so the column's height comes from the cards' summed content — and the photo column tracks THAT
   (see .event-photo below). */
.event-cards{display:grid;grid-template-columns:1fr 1fr;gap:var(--sp-4);align-items:start}
/* Радиус = --r-lg КАК У СЛАЙДЕРА рядом (были разные 16/28 — недопустимо, фидбэк); паддинг 24 (--sp-5,
   деск-токен крупных карточек — 16 мелко). Мобилка: радиус 16 + паддинг 16 в медиа ниже. */
.event-card{display:flex;flex-direction:column;align-items:flex-start;gap:var(--sp-5);padding:var(--sp-5);background:#fff;border-radius:var(--r-lg);text-decoration:none;transition:transform .3s var(--ease-out),box-shadow .3s var(--ease-out)}
.event-card:hover{transform:translateY(-6px);box-shadow:0 20px 36px -20px rgba(20,48,60,.22)}
.ec-ic-box{display:flex;align-items:center;justify-content:center;flex:none;width:60px;height:60px;padding:14px;border-radius:var(--r-sm);background:var(--background-bg)}
.ec-ic{display:block;width:32px;height:32px;object-fit:contain}
.event-card h3{margin:0;color:var(--ink-cold);font-size:20px;font-weight:400;line-height:1.3}

/* E6: desktop min-height:480px removed — photo column must equal the CARD GRID's own hug height,
   not impose its own floor. Chain: .events-row{align-items:stretch} stretches the col-lg-5 to the
   row height; row height is driven by the col-lg-7 content (the hugged grid — the photo column
   contributes no intrinsic height since the img inside is absolutely positioned); height:100% then
   fills the stretched column exactly. The old 480px floor could EXCEED the hugged grid height and
   push the row taller than the cards — exactly the mismatch the client flagged. min-height stays
   only <992px (stacked layouts), where the photo is alone in its own wrapped row and the absolute
   img gives it zero intrinsic height — without a floor it would collapse to 0 there. */
.event-photo{position:relative;height:100%;border-radius:var(--r-lg);overflow:hidden}
/* Task 9 initGalleryCrossfade() (motion.js) drives this element's opacity directly via
   gsap.fromTo(...,{opacity:.15},{opacity:1,duration:.25,...}) on every thumb switch. A CSS
   `transition:opacity` here previously pre-wired for this same purpose actively broke it once GSAP
   started writing inline opacity every tick: the browser tried to CSS-transition FROM the stale
   opacity TOWARD each new value GSAP set, so at tween-progress 0 (opacity:.15 just written) the
   transition hadn't caught up yet and getComputedStyle still read the OLD value (1) — same collision
   class as .review-card's transform/transition fight (see initReviewsDrift() comment in motion.js).
   No other rule ever toggles this element's opacity via CSS (grep confirmed — no :hover/class here),
   so removing the transition outright (rather than scoping an override class, as done for
   .review-card, which DOES still need its CSS transition for an unrelated :hover effect) is the
   clean fix: GSAP now fully owns this element's opacity, nothing else needs a declarative fallback. */
.event-photo-main{position:absolute;inset:0;width:100%;height:100%;object-fit:cover}
.event-photo-thumbs{position:absolute;left:50%;bottom:24px;transform:translateX(-50%);display:flex;gap:var(--sp-3);width:calc(100% - 48px);padding:var(--sp-3);background:#fff;border-radius:var(--r-md);z-index:5}  /* z>оверлея кроссфейда (3): лента-превью — константа, меняется только фото ПОД ней */
/* E6: превью-кнопки получают явный hover-стиль (полупрозрачное cyan-кольцо + лёгкое затемнение фото),
   активная — полное кольцо var(--cyan-2); cursor:pointer был и остаётся. Ring lives on an ::after
   overlay, NOT on the button's own box-shadow: an INSET shadow paints below the element's content
   layer, and the <img> child fills the button 100%×100% — so E5's aria-pressed ring (box-shadow inset
   directly on .ep-thumb) was being fully covered by the photo and effectively invisible, which is
   plausibly why the client re-requested an "active frame" that nominally already existed. The ::after
   (absolute, inset:0, pointer-events:none) stacks above the replaced element, so the ring actually
   shows. Paint-only transitions (box-shadow/opacity) per the project-wide hover waiver. */
.ep-thumb{position:relative;flex:1 1 0;min-width:0;height:78px;padding:0;border:0;border-radius:var(--r-sm);overflow:hidden;cursor:pointer;background:transparent}
.ep-thumb img{display:block;width:100%;height:100%;object-fit:cover;transition:opacity .25s var(--ease-out)}
.ep-thumb::after{content:"";position:absolute;inset:0;border-radius:inherit;pointer-events:none;transition:box-shadow .3s var(--ease-out)}
.ep-thumb:hover img{opacity:.82}
.ep-thumb:hover::after{box-shadow:0 0 0 2px rgba(11,170,236,.45) inset}
.ep-thumb[aria-pressed="true"]::after{box-shadow:0 0 0 2px var(--cyan-2) inset}

@media (max-width:991.98px){
  /* margin-top убран: bootstrap gutter-y(24) УЖЕ даёт зазор карточки→фото — вдвоём получалось 48 («липкость» ритма) */
  .event-photo{min-height:280px}
}
@media (max-width:767px){
  .event-cards{grid-template-columns:1fr;gap:var(--sp-3)}
  .event-card{padding:var(--sp-4)}
  /* было min-height:340px — на 343px ширины почти квадрат, фото «вытянуто» (фидбэк).
     Пропорция 4:3 от фактической ширины: 343 → ~257px. */
  .event-photo{min-height:0;aspect-ratio:4/3}
  .event-photo-thumbs{bottom:16px;width:calc(100% - 32px);gap:var(--sp-2);padding:var(--sp-2)}
  .ep-thumb{height:56px}
}

/* ── PRICES (monthly cards + BS tabs) ── */
.prices-heading{display:flex;flex-direction:column;align-items:center;gap:var(--sp-6);margin-bottom:var(--head-gap);text-align:center}
.prices-heading h2{margin:0}
.mkk-tabs{position:relative;display:flex;flex-wrap:nowrap;gap:var(--sp-1);align-items:center;justify-content:center;width:fit-content;max-width:100%;margin-inline:auto;padding:6px;list-style:none;background:#fff;border:1px solid var(--border-blue);border-radius:100px}
/* Мобилка (Роман: «верни как было, не одной пилюлей»): табы = отдельные БЕЙДЖИ — у контейнера нет
   фона/бордера/паддинга, пилюли переносятся по центру. Неактивная — белая с обводкой, активная —
   залитый градиент, «%»-акцент — белая с синим текстом. Индикатор (один ряд) на мобиле прячем. */
@media (max-width:767.98px){
  /* id-специфичность (#prices), т.к. базовые .mkk-tabs .nav-link идут НИЖЕ в файле и перебивали бы. */
  #prices .mkk-tabs{display:flex;flex-wrap:wrap;justify-content:center;gap:8px;max-width:100%;margin-inline:auto;overflow:visible;background:transparent;border:0;padding:0;border-radius:0}
  /* По 2 таба в ряд (Роман): каждый бейдж = половина ширины, текст сократили — стали крупнее и ровнее. */
  #prices .mkk-tabs .nav-item{flex:1 1 calc(50% - 4px);max-width:calc(50% - 4px)}
  #prices .mkk-tabs .nav-link,#prices .mkk-tabs .mkk-tab-link{width:100%;height:auto;justify-content:center;padding:12px 8px;font-size:14px;white-space:nowrap;background:#fff;border:1px solid var(--border-blue);border-radius:100px}
  #prices .mkk-tabs .nav-link.active,#prices .mkk-tabs:has(.tab-ind) .nav-link.active{background:var(--grad-cta);border-color:transparent;color:#fff}
  #prices .mkk-tabs .mkk-tab-link-accent{background:#fff;border-color:var(--border-blue);color:#00a1ff}
  #prices .tab-ind{display:none}
}
.mkk-tabs .nav-item{flex:none}
/* Task 9 морф-индикатор: .tab-ind — единственный span, который initPriceTabs() добавляет в #priceTabs
   (сиблинг <li>, НЕ внутрь них — так gsap может свободно двигать/ресайзить его по x/width независимо
   от текста таба). Он лежит ПОД текстом (z-index:0 против z-index:1 у .nav-link/.mkk-tab-link) и под
   собственным градиентным фоном активного таба, поэтому пока JS не создал индикатор (no-JS, RM —
   initMotion() рано выходит и initPriceTabs() никогда не вызывается) активная пилюля рисуется старым
   способом — .nav-link.active сохраняет свой градиент как есть. Как только индикатор существует
   (:has() ниже), .active-фон гасится (transparent) — это ЕДИНСТВЕННОЕ, что теперь рисует пилюлю, и
   именно это делает её "морфинг" видимым (иначе мгновенная смена .active-класса на кнопках перекрывала
   бы плавно скользящий индикатор под ними на каждом клике). */
.tab-ind{position:absolute;top:6px;left:0;height:40px;border-radius:100px;background:var(--grad-cta);border:0;z-index:0;pointer-events:none}
.mkk-tabs:has(.tab-ind) .nav-link.active{background:transparent;color:#fff}
/* «% Спецпредложения» — не BS-таб, а обычная ссылка (/specials.html), но той же пилюльной
   формы в общем ряду (Figma 2065:14470 / 2065:17357: 4-й Button — тот же паттерн, только
   акцентный цвет текста вместо активного градиента). Отдельный класс .mkk-tab-link (не
   .nav-link!) обязателен: Bootstrap Tab.js сканирует ЛЮБОЙ .nav-link внутри своего
   [role=tablist]-родителя по имени класса (независимо от data-bs-toggle) и молча вешает
   на него role="tab"/aria-selected="false"/tabindex="-1" — это ломает ссылку (выкидывает
   из таб-order, объявляет скринридером как невыбранный таб вместо перехода на страницу).
   Одинаковый box-model достигается общим селектором ниже, семантика — раздельными классами. */
.mkk-tabs .nav-link,.mkk-tabs .mkk-tab-link{position:relative;z-index:1;display:flex;align-items:center;height:40px;padding-inline:20px;border:0;border-radius:100px;background:transparent;color:var(--ink-body);font:600 14px/1 'Onest',sans-serif;white-space:nowrap;cursor:pointer;text-decoration:none;transition:color .3s var(--ease-out),background .3s var(--ease-out)}
.mkk-tabs .nav-link.active{--tab-grad:linear-gradient(172deg,var(--cyan-1) 5.65%,var(--cyan-2) 129.47%);background:var(--tab-grad);color:#fff;font-weight:600}
.mkk-tabs .mkk-tab-link-accent{color:#00a1ff}
.mkk-tabs .mkk-tab-link-accent:hover{color:var(--cyan-2)}
/* Компактнее на мобиле, чтобы 4 таба легли в 2 ряда (а не 3): меньше высота/паддинг/шрифт. */
@media (max-width:575.98px){.mkk-tabs .nav-link,.mkk-tabs .mkk-tab-link{padding-inline:8px;font-size:13px}}

/* E6 client fix: gutter 30->32px per node math — rent tab row is 3×432px cards + 2×32px gaps = 1360
   (exactly the container width), so with Bootstrap's padding-gutter model (row outer = 1360+32,
   col = 464, card = col − 32 gutter padding = 432) every rent card lands on the node's exact 432px
   without pinning width manually. justify-content:center is a no-op while full rows fill 100%, but
   keeps partial rows (any future 1-2 card month set) centered instead of left-hugging. */
.price-cards{--bs-gutter-x:32px;--bs-gutter-y:24px;justify-content:center}
.price-card{position:relative;display:flex;flex-direction:column;gap:40px;height:100%;padding:var(--sp-6);border-radius:var(--r-lg);color:#fff;isolation:isolate;overflow:hidden;background:linear-gradient(136.97deg,rgb(71,118,230) 1.73%,rgb(84,141,233) 105.06%);transition:transform .3s var(--ease-out),box-shadow .3s var(--ease-out)}
/* Contrast-safety overlay: raw Figma gradient's lighter/right stop rgb(84,141,233) fails white-text AA (3.30:1).
   Flat dark layer over the whole card (not just text zone — fill is a solid card bg, no decorative art to preserve
   behind it, unlike the specials banner) darkens both stops; worst-case verified below at .24 alpha. */
.price-card::before{content:"";position:absolute;inset:0;z-index:0;background:rgba(10,32,50,.24);pointer-events:none}
.price-card:hover{transform:translateY(-6px);box-shadow:0 24px 44px -22px rgba(30,70,150,.4)}
.price-card-current{box-shadow:0 0 0 2px var(--cyan-1) inset}
.price-card-current:hover{box-shadow:0 0 0 2px var(--cyan-1) inset,0 24px 44px -22px rgba(30,70,150,.4)}
.price-card-top{position:relative;z-index:1;display:flex;flex-direction:column;align-items:center;gap:20px;text-align:center}
.price-card-badges{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--sp-4)}
.price-badge{display:inline-flex;align-items:center;padding:6px var(--sp-2);border-radius:10px;background:#fff;color:#4a7ce7;font:500 18px/1.3 'Onest',sans-serif}
.price-badge-now{display:inline-flex;align-items:center;padding:6px var(--sp-2);border-radius:10px;background:rgba(255,255,255,.2);color:#fff;font:600 13px/1.3 'Onest',sans-serif;letter-spacing:.02em;text-transform:uppercase}
.price-card h3{margin:0;color:#fff;font-size:30px;font-weight:600;letter-spacing:-.01em}
.price-card-price{display:flex;align-items:center;gap:20px;margin:0;font-variant-numeric:tabular-nums}
.price-old{position:relative;color:rgba(255,255,255,.36);font-size:24px;font-weight:500}
.price-old::after{content:"";position:absolute;left:0;right:0;top:50%;height:2px;background:#a691ed}
.price-now{display:inline-flex;align-items:center;gap:3px;color:#fff}
.price-now b{font-size:24px;font-weight:600;font-style:normal}
.price-now i{font-size:12px;font-weight:400;font-style:normal;opacity:.5}
.price-card-div{position:relative;z-index:1;height:1px;background:linear-gradient(90deg,rgba(255,255,255,0),rgba(255,255,255,.5) 52%,rgba(255,255,255,0))}
.price-card-list{position:relative;z-index:1;display:flex;flex-direction:column;gap:var(--sp-4);margin:0;padding:0;list-style:none}
.price-card-list li{display:flex;align-items:center;justify-content:center;gap:var(--sp-2);color:#fff;font-size:14px;font-weight:500;text-align:center}
.price-card-list svg{flex:none;color:#fff}
/* E6 client fix: dark navy-glass CTA (rgba(10,32,50,.32)) replaced with the SAME light pill already
   used on the group/events tabs (.price-cards-2 .price-card-cta below) — client wants one consistent
   light button style across all three price tabs, not just two of them. Width/layout on THIS base
   class is untouched (still width:100% — the rent/monthly cards' single full-bleed CTA per their own
   node layout; the group/events tabs' hug-content + centered behavior lives entirely in the
   .price-cards-2 override further down and still applies there unchanged). */
.price-card-cta{position:relative;z-index:1;background:rgba(255,255,255,.2);color:#fff;width:100%;font-size:14px;padding:var(--sp-4) 28px}
/* клиентское решение: светлые кнопки по макету, WCAG ~3.3:1 принят заказчиком */
.price-card-cta:hover{transform:translateY(-1px);background:rgba(255,255,255,.3);box-shadow:none}
.price-card-btns{position:relative;z-index:1;display:flex;gap:var(--sp-3);width:100%}
.price-card-btns .price-card-cta{width:auto;flex:1 1 0}

/* Card gradient variants — «Групповые занятия» (2065:14466) и «Мероприятия» (2065:17353)
   panels reuse the same .price-card shape (badges/h3/price/div/list/cta) as the rent tab,
   just with a different fill per card; contrast overlay (.price-card::before) already
   covers all variants since it targets the shared base class. Radius override: both nodes
   specify rounded-[24px], not the --r-lg (28px) the rent-tab .price-card inherited from an
   earlier task's token pick — scoped to these variants only, doesn't touch the rent cards. */
.price-card-teal,.price-card-purple,.price-card-blue-purple{border-radius:24px}
.price-card-teal{background:linear-gradient(148.5deg,rgb(0,121,145) 10.65%,rgb(54,179,190) 129.86%)}
.price-card-purple{background:linear-gradient(163.22deg,rgb(132,79,217) 18.59%,rgb(97,88,237) 98.68%)}
.price-card-blue-purple{background:linear-gradient(to right,#8e54e9,#4776e6)}
/* E5/E6 client fix: nodes 2065:14466/2065:17353 both give the card a fixed w-[432px] (same width as
   the monthly rent cards) inside a gap-[32px] justify-center row — NOT the col-lg-6 (50%) these
   panels inherited from the rent tab's markup. Card width is pinned on .price-card itself (not the
   .col- wrapper): Bootstrap columns carry their own gutter padding (padding-inline: gutter/2), so
   constraining the WRAPPER to 432px would leave only ~400px for the actual card inside it (E5
   measured that mistake live before shipping).
   E6 re-fix — client: «разъезжаются к краям» (cards drift to the edges, live-measured 263px apart).
   E5's `flex:0 0 auto` on the columns was NOT enough: Bootstrap's own .col-lg-6 rule is
   `flex:0 0 auto; width:50%` — identical flex shorthand, and the width:50% declaration SURVIVED the
   E5 override (nothing ever unset it), so each column still spanned half the 1390px row while its
   432px card hugged the column's left padding edge; justify-content:center was centering two
   half-width columns (already 100% combined = zero free space), not the cards. width:auto at ≥992px
   kills Bootstrap's 50% so each column shrink-wraps its 432px card (+16px gutter padding per side),
   and center-justification finally has real free space to distribute: cards sit centered, exactly
   32px apart (16+16 gutter padding between card edges — matching the node's gap-[32px]). Scoped to
   ≥992px only: below lg Bootstrap's stacked width:100% behavior must stay (a width:auto column with
   a width:100% card inside is circular sizing — breaks the mobile layout). */
.price-cards-2{--bs-gutter-x:32px;--bs-gutter-y:24px;justify-content:center}
.price-cards-2>[class*="col-"]{flex:0 0 auto;max-width:100%}
@media (min-width:992px){.price-cards-2>[class*="col-"]{width:auto}}
.price-cards-2 .price-card{width:432px;max-width:100%}
@media (max-width:575.98px){.price-cards-2 .price-card{width:100%}}
/* Layout-only override now (E6 made the light pill color the BASE .price-card-cta style everywhere —
   see above — so background/hover here would just duplicate it; kept scoped to this block for the
   LAYOUT differences only): compact (hugs its own text, NOT width:100% like the rent tab), h-48,
   padding 28/16. Both node variants (get_design_context on 2065:14466) wrap their CTA(s) in a
   `flex justify-center` "Buttons" row, even the single-button "Разовое занятие" card — so the lone
   CTA is CENTERED across the card, not stuck to the left. Two things had to change beyond just
   `width:auto` on the button: (1) .price-card itself is `display:flex;flex-direction:column` with no
   align-items set, so its default `align-items:stretch` was force-stretching the lone .price-card-cta
   (a direct flex child, no .price-card-btns wrapper around it in that markup) to the full card width
   regardless of the button's own width property — width:auto alone doesn't cancel flex stretch, only
   align-self does; caught live via getBoundingClientRect (368px instead of hug-content ~103px) before
   shipping. (2) .price-card-btns needed justify-content:CENTER to match the node (an earlier pass here
   mistakenly wrote flex-start — corrected against the actual extracted JSX rather than eyeballing the
   screenshot, where centered vs. left-aligned is easy to misjudge at this content width). */
.price-cards-2 .price-card-cta{align-self:center;width:auto;height:48px;padding:var(--sp-4) 28px;font-size:14px}
.price-cards-2 .price-card-btns{justify-content:center}
.price-cards-2 .price-card-btns .price-card-cta{width:auto;flex:none}

.mkk-alert{display:flex;gap:20px;align-items:center;padding:var(--sp-5);margin-top:var(--sp-6);border-radius:var(--r-lg);background:#fff;border:1px solid var(--border-blue)}
.mkk-alert-ic{flex:none;color:var(--cyan-2)}
.mkk-alert-txt{display:flex;flex-direction:column;gap:var(--sp-3)}
.mkk-alert-txt p{margin:0;color:var(--ink-body);font-size:16px;line-height:1.3}
.mkk-alert-txt a{color:var(--cyan-2);font-weight:500}
.mkk-alert-txt a:hover{text-decoration:none}

@media (max-width:767.98px){
  .price-cards{--bs-gutter-y:18px}
  .price-card{padding:var(--sp-5);gap:28px}
  /* Дисклеймер по ноде 2113:14884 (фидбэк Романа «как в фигме»): амбер-тинт, центр-колонка,
     иконка-предупреждение сверху (амбер), текст 12px по центру, радиус 12. */
  /* Дисклеймер на мобилке = как десктоп (белый+бордер): грязный оранжевый на синем фоне убран (Роман). */
  .mkk-alert{flex-direction:column;align-items:center;gap:16px;padding:12px;border-radius:12px;background:#fff;border:1px solid var(--border-blue);margin-top:var(--sp-5)}
  .mkk-alert-ic{color:var(--cyan-2)}
  .mkk-alert-txt{align-items:center;gap:8px}
  .mkk-alert-txt p{font-size:12px;text-align:center}
}

/* ── REVIEWS ── */
.reviews-h2{margin:0;text-align:center}  /* head-gap теперь на родителе .sec-head-c, не на самом h2 */
.reviews-cards{--bs-gutter-x:32px;--bs-gutter-y:24px}
.review-card{display:flex;flex-direction:column;align-items:center;gap:var(--sp-5);height:100%;padding:var(--sp-7);text-align:center;background:#fff;border:2px solid rgba(199,211,255,.46);border-radius:var(--r-lg);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);transition:transform .3s var(--ease-out),box-shadow .3s var(--ease-out)}
.review-card:hover{transform:translateY(-6px);box-shadow:0 24px 40px -22px rgba(20,48,60,.2)}
/* Task 9 initReviewsDrift(): gsap.to(...,{y:...,repeat:-1,yoyo:true}) continuously overwrites this
   element's inline `transform` every tick. Left combined with the `transition:transform .3s` above,
   the browser tries to CSS-transition BETWEEN each of GSAP's rapid successive values (a moving
   target it can never actually catch), and the two compose into visibly wrong, overshooting values
   (measured live: rendered translateY briefly reaching ~21px against the tween's own intended ±6px
   range) instead of a clean sway — a textbook GSAP+CSS-transition collision on the same property.
   .is-drifting (added once by initReviewsDrift, permanent for the page's lifetime — drift never stops
   existing, only pauses/resumes) drops transform from the transition list so GSAP's writes land
   instantly, exactly as intended; box-shadow keeps its own .3s transition untouched. Trade-off: the
   hover-lift's transform now applies as a snap instead of an eased slide while under this class — a
   minor, purely cosmetic cost, preferred over the alternative (a visibly broken/erratic ambient sway
   any time drift and the hover transition raced each other). */
.review-card.is-drifting{transition:box-shadow .3s var(--ease-out)}
.review-logo{display:block;height:64px;width:auto}
.review-card .stars{color:var(--gold)}
.review-rating{margin:0;color:var(--ink-cold);font-size:24px;font-weight:500;font-variant-numeric:tabular-nums}
.review-count{margin:-14px 0 0;color:rgba(63,63,63,.5);font-size:16px;font-weight:500}
.review-link{color:var(--cyan-2);font-size:15px;font-weight:600;text-decoration:none}
.review-link:hover{text-decoration:underline}
@media (max-width:767.98px){
  /* Отзывы Google/Яндекс — В ОДНУ СТРОКУ (2 карточки рядом), НЕ столбцом (прямое требование Романа;
     нода 2063:22336 тоже показывает их side-by-side). Компактнее под ~163px: лого/шрифты меньше, gutter 16,
     ссылку «Читать отзывы» скрываем — в мобильной ноде её нет. */
  .reviews-cards{--bs-gutter-x:16px}
  .reviews-cards>[class*="col-"]{flex:0 0 50%;max-width:50%}
  /* Больше воздуха внутри (фидбэк Романа: тесно vs фигма): выше вертик. паддинг + гэпы, звёзды мельче
     (были крупные/тесные), лого чуть меньше. */
  /* отзывы: заголовок→карточки — единый --head-gap (40), как у всех секций (убрал 32-переопределение). */
  .review-card{padding:26px 12px;gap:18px}
  .review-logo{height:28px}
  .review-card .stars svg{width:18px;height:18px}
  .review-rating{font-size:18px}
  /* количество ближе к «X из 5.0» (фидбэк Романа, см. фигму) */
  .review-count{font-size:13px;margin-top:-10px}
  .review-link{display:none}
}

/* ── CTA-HOUSE → перспективная ледовая сцена (dom.svg из Фигмы Романа). Итерация 1: текст/CTA убраны,
   блок = сцена на всю ширину: лёд ice4 + дорожка в 3D-перспективе + дом-мишень (эллипсы). Верхний
   белый градиент внутри самой сцены = плавный заход из-под карточек отзывов. Камни (2 стоят в доме +
   жёлтый катится и толкает) — итерация 2; старый bindFinale отключён в stone.js. ── */
#cta-house{padding:0;background:#fff}
.cta-scene-sec{position:relative;height:230vh}                 /* трек прокрутки: +холостой скролл после касания (было 200vh) */
.cta-pin{position:sticky;top:0;height:100vh;display:flex;align-items:flex-end;overflow:hidden}   /* пин на весь экран, сцена НИЗОМ к низу: под сценой белого нет (ни на сцене, ни у футера); воздух-разбег сверху */
.dom-scene{position:relative;width:100%;line-height:0}
.dom-scene-svg{display:block;width:100%;height:auto}
.finale-canvas{position:absolute;inset:0;width:100%;height:100%;pointer-events:none}
/* Мобилка: сцена dom.svg при 375px всего ~161px высотой — в десктопном пине (230vh трек + 100vh
   flex-end) это давало ~650px белой дыры над сценой. На мобиле пин/трек не нужен (скролл-хореография
   финала — десктопная): сцена рендерится инлайн своей натуральной высотой, вплотную к футеру, без
   дыры и без .sec-паддинга. Камни финала на мобиле ЖИВЫ: прогресс хореографии пересчитан под непин-ленту (finale-stones.js, MOB-ветка scrollP). */
/* ГРАНИЦА 991.98, А НЕ 767 (фидбэк Романа по планшету: «километровый отступ до анимации
   от отзывов»). На 768–991 работал ПОЛНЫЙ десктопный пин: трек 230vh + .cta-pin height:100vh
   с align-items:flex-end, а dom.svg на этой ширине даёт всего ~330px — секция раздувалась
   до 2760px, из которых ~700 приходилось на белую дыру над сценой, плюс 2.3 экрана холостого
   скролла. Непин-вариант это снимает и при этом НЕ убивает моушн: камни финала здесь живые,
   прогресс хореографии пересчитан под непин-ленту (finale-stones.js, ветка MOB).
   ВАЖНО: граница обязана совпадать с matchMedia в finale-stones.js:81 — там своя шкала
   прогресса для непин-режима, и если границы разъедутся, на 768–991 камни поедут по чужой шкале. */
@media (max-width:991.98px){
  .cta-scene-sec{height:auto;padding-block:0}
  .cta-pin{position:static;height:auto;display:block;overflow:hidden}
  /* Лента крупнее (по фидбеку): фикс. высота + svg cover (preserveAspectRatio=slice) — сцена
     заполняет ленту по высоте, обрезаясь по бокам (дом остаётся по центру, xMidYMid). */
  .dom-scene{height:clamp(240px,40vh,320px)}
  .dom-scene-svg{width:100%;height:100%}
}

/* .house-glow (Task 12, «Один бросок» финал) — эхо padel-мяча: та же цианова радиальная подсветка
   под предметом, что уже стоит образным ориентиром в брифе (padel-мяч в других промо-материалах
   клуба). Живой (WebGL) путь: элемент вставляется JS'ом (bindFinale/makeHouseGlow, stone.js) ПЕРВЫМ
   ребёнком #house — z-order "за стоуном" достигается ДВУМЯ вещами разом: DOM-порядок внутри #house
   (кольца .ring идут следом) И более низкий стэкинг-контекст относительно #stoneCanvas (тот несёт
   явный z-index:var(--z-stone)=900, у .house-glow z-index не задан вовсе — auto гарантированно ниже
   900 в том же контексте предков). opacity стартует 0 (брифф: "0 until p>.7") — управляется gsap.set
   в setGlowOpacity на каждый scrub-тик, ЗДЕСЬ только начальное состояние на случай доли секунды
   между insertBefore и первым onUpdate. transform:scale стартует от 1 (то же самое рассуждение —
   первый gsap-пульс сам поставит 1→1.12, здесь просто безопасная точка покоя). pointer-events:none —
   декоративный слой, никогда не перехватывает клики по CTA-кнопкам под/рядом. */
/* Task 14 polish #1: cyan glow vs light-blue r1 ring (#CFE9F8) read low-contrast at the original
   rgba(62,197,254,.5) — that's --cyan-1 alone, which sits too close in luminance to the ring it glows
   on top of. Deepened to a --cyan-1/--cyan-2 mix skewed toward the darker/more saturated --cyan-2
   (#0BAAEC) at higher alpha (.68) + wider blur spread (24px->30px, ellipse enlarged to match so the
   glow still reads soft, not a hard-edged blob) — verified against a house-region crop, see
   task-14-report.md. */
.house-glow{position:absolute;left:50%;top:50%;width:240px;height:54px;margin:-27px 0 0 -120px;
  background:radial-gradient(ellipse at center,rgba(24,172,238,.68),transparent 70%);
  filter:blur(30px);opacity:0;transform:scale(1);pointer-events:none;z-index:1}

/* ── FOOTER + LEAD FORM (Figma 2019:10261) ── */
#footer{position:relative;overflow:hidden;isolation:isolate;color:#fff}
.footer-bg{position:absolute;inset:0;z-index:0}
.footer-bg img{display:block;width:100%;height:100%;object-fit:cover}
.footer-scrim{position:absolute;inset:0;z-index:1;background:rgba(0,0,0,.2)}
.footer-in{position:relative;z-index:2;padding-block:60px 40px;display:flex;flex-direction:column;gap:80px}

/* -- form CTA (per Figma 2019:10261: "Напишите нам" is a single button, not inline inputs —
   the actual form lives in the modal below, per node 2126:15964) -- */
.footer-form{display:flex;flex-direction:column;align-items:center;gap:44px;text-align:center}
.footer-form-text{display:flex;flex-direction:column;align-items:center;gap:var(--sp-5)}
.footer-form-text h2{margin:0;color:#fff;max-width:574px}
.footer-form-text p{margin:0;max-width:666px;color:#fff;font-size:18px;line-height:1.5}
.footer-form-btn{height:53px;padding-inline:var(--sp-6);background:#fff;color:var(--ink-cold)}
.footer-form-btn:hover{background:var(--ice-1)}

/* -- footer card (white panel) -- */
.footer-card{background:#fff;border-radius:var(--r-md);padding:40px;display:flex;flex-direction:column;gap:44px;color:var(--ink-body)}
.footer-card-top{display:flex;align-items:flex-start;justify-content:space-between;gap:40px;flex-wrap:wrap}
.footer-logo-addr{display:flex;flex-direction:column;align-items:flex-start;gap:var(--sp-2);max-width:393px}
.footer-logo{display:inline-flex;line-height:0}
.footer-logo img{height:56px;width:auto;display:block}
.footer-addr{margin:var(--sp-4) 0 0;color:var(--ink-mut);font-size:15px;font-weight:500}
.footer-addr svg{display:none}
.footer-hours{margin:0;color:var(--ink-mut);font-size:15px;font-weight:500}
.footer-menu{display:flex;gap:var(--sp-8);flex-wrap:wrap}
.footer-col-title{margin:0 0 var(--sp-5);color:var(--ink-cold);font-size:16px;font-weight:500}
.footer-col ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:var(--sp-4)}
.footer-col a{color:rgba(63,63,63,.8);font-size:16px;text-decoration:none}
.footer-col a:hover{color:var(--cyan-2)}
.link-like{background:none;border:0;padding:0;margin:0;color:rgba(63,63,63,.45);font:inherit;font-size:16px;text-align:left;cursor:not-allowed}
.footer-div{height:1px;background:#dbdbdb}
.footer-bottom{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-5);flex-wrap:wrap}
.footer-pills{display:flex;flex-wrap:wrap;gap:var(--sp-3)}
.footer-pill{display:inline-flex;align-items:center;gap:var(--sp-2);height:36px;padding:0 var(--sp-5);border:1px solid rgba(63,63,63,.8);border-radius:222px;color:rgba(63,63,63,.8);font-size:14px;font-weight:500;text-decoration:none;white-space:nowrap;transition:background .25s var(--ease-out),color .25s var(--ease-out)}
.footer-pill svg{flex:none}
.footer-pill:hover{background:var(--ink-cold);border-color:var(--ink-cold);color:#fff}
.footer-copy{margin:0;color:rgba(63,63,63,.8);font-size:16px;opacity:.5}
@media (max-width:767.98px){
  /* Иерархия CTA-баннера (Роман): «Напишите нам» = один элемент (заголовок+текст+кнопка) — держим
     его плотно (текст→кнопка 24), а до карточки футера отступ заметно больше (64). Было 44 и 48 —
     на вид одинаково, иерархии нет. */
  .footer-in{padding-block:40px var(--sp-5);gap:var(--sp-8)}
  .footer-form{gap:var(--sp-5)}
  .footer-form-text h2{font-size:28px}
  .footer-form-text p{font-size:15px}
  .footer-card{padding:var(--sp-5);gap:var(--sp-6)}
  /* Фидбэк Романа: было — лого/контакты по центру, а меню прижато влево «полотном без разбивки».
     Делаем ВСЁ по центру: меню — вертикальный стек трёх групп (Керлинг/Услуги/Информация), у каждой
     центрированный заголовок + центрированные ссылки. Чёткая разбивка по секциям + центр. */
  .footer-card-top{gap:var(--sp-6);align-items:center}
  /* Отступы меню (Роман, точные): между блоками 20, заголовок блока→пункты 12, между пунктами 8. */
  /* между блоками меню — 32 (Роман: пробуем 32 вместо 20), заголовок→пункты 12, пункты 8. */
  .footer-menu{flex-direction:column;align-items:center;gap:32px}
  .footer-col{align-items:center;text-align:center}
  .footer-col-title{margin-bottom:12px}
  .footer-col ul{align-items:center;gap:8px}
  .footer-logo-addr{width:100%;align-items:center;text-align:center}
  /* Порядок низа: сначала кнопки-контакты, потом «© МКК 2025» в самом конце (Роман) → column, не reverse. */
  .footer-bottom{align-items:center;flex-direction:column;gap:var(--sp-4)}
  .footer-pills{justify-content:center}
  .footer-copy{text-align:center}
}
@media (max-width:575.98px){
  .footer-menu{width:100%;gap:32px}
}

/* ── LEAD MODAL (Bootstrap modal shell + mkk styles per Figma 2126:15964 "Обратный звонок") ──
   Merge with footer "Напишите нам": the CTA button in .footer-form opens this modal via
   data-bs-toggle; every other conversion CTA site-wide ([data-open-modal]) opens it too via
   initLeadModalTriggers() in main.js. #leadForm inside carries the same sendLead/showToast
   contract as before; data-event pre-select now targets a hidden input (node has no visible
   select — see main.js comment). */
.modal-backdrop{--bs-backdrop-bg:#0A2032;--bs-backdrop-opacity:.6}
.lead-modal{position:relative;overflow:hidden;border:0;border-radius:24px;box-shadow:20px 20px 20px rgba(0,0,0,.08)}
.lead-modal-photo{height:190px}
/* Fix Wave A2, п.1: object-position по X — геометрический no-op при текущих пропорциях блока
   (500×190 на ≥576px, box-aspect 2.63:1 шире, чем 16:9/1.78:1 у footer-bg.jpg) — cover при таком
   соотношении ВСЕГДА показывает полную ширину кадра без горизонтальной обрезки (подтверждено A/B:
   object-position 0% и 100% дают пиксель-в-пиксель идентичный рендер, см. wave-a2-test-objpos-*.png).
   Круг-мишень в исходнике уже на ~52.6% ширины — это и есть потолок центровки без смены кропа
   исходника/высоты блока. 52% ниже не двигает текущий рендер, но фиксирует корректное значение на
   случай, если пропорции блока изменятся (напр. вырастет height) — тогда центровка сработает сразу. */
.lead-modal-photo img{display:block;width:100%;height:100%;object-fit:cover;object-position:52% 50%}
.lead-modal-close{position:absolute;top:20px;right:20px;z-index:2;display:flex;width:24px;height:24px;padding:0;border:0;background:transparent;cursor:pointer}
.lead-modal-close svg{display:block;width:100%;height:100%}
.lead-modal-body{display:flex;flex-direction:column;gap:var(--sp-5);padding:20px;background:var(--background-bg)}
.lead-modal-text{display:flex;flex-direction:column;gap:var(--sp-2)}
.lead-modal-text h2{margin:0;font-size:24px;font-weight:600}
.lead-modal-text p{margin:0;color:rgba(63,63,63,.8);font-size:16px;line-height:1.3}
/* Fix Wave A2, п.2: единая система отступов — ОДИН механизм (margin-top на не-первом элементе
   каждой группы), без container-level gap. Раньше gap:12 на #leadForm складывался с разрозненными
   margin-top на .agree(4px)/.btn-mkk(8px) — получались нигде не объявленные впрямую 16px и 20px,
   отсюда клиентское «внизу заруинил». Теперь: 12px — единый ритм между полями и до чекбокса; 24px —
   осознанно увеличенный отступ перед кнопкой (кнопке нужна более выраженная пауза, «отлепить» от
   чекбокса). padding у .lead-modal-body (20px/16px моб.) уже симметричен по всем 4 сторонам —
   дабл-чек подтверждён, отдельного правила не требуется. */
#leadForm{display:flex;flex-direction:column}
.lm-field{margin:0}
.lm-field+.lm-field{margin-top:var(--sp-3)}
.lm-field input{width:100%;height:48px;padding:0 var(--sp-4);border:1px solid rgba(18,16,14,.12);border-radius:44px;background:#fff;color:var(--ink-cold);font:400 14px/1.3 'Onest',sans-serif}
.lm-field input::placeholder{color:rgba(63,63,63,.8)}
.lm-field input:focus-visible{outline:2px solid var(--cyan-2);outline-offset:2px}
/* Современный чекбокс (Fix Wave A2, п.3) — заменяет голый <input type=checkbox> из .agree (правило
   удалено как осиротевшее). margin-top:12px держит тот же единый 12px-ритм, что и .lm-field+.lm-field —
   чекбокс визуально продолжает группу полей, отдельный акцент только у кнопки ниже. */
.lm-check{display:flex;gap:var(--sp-3);align-items:flex-start;cursor:pointer;font-size:12px;line-height:1.45;color:var(--ink-mut);margin-top:var(--sp-3)}
.lm-check input{position:absolute;opacity:0;width:1px;height:1px}
.lm-check-box{flex:0 0 auto;width:20px;height:20px;border-radius:7px;border:1.5px solid rgba(20,48,60,.25);background:#fff;display:grid;place-items:center;transition:background .2s var(--ease-out),border-color .2s var(--ease-out);margin-top:1px}
.lm-check-box svg{width:13px;height:13px;fill:none;stroke:#fff;stroke-width:2.4;stroke-linecap:round;stroke-linejoin:round;stroke-dasharray:20;stroke-dashoffset:20;transition:stroke-dashoffset .25s var(--ease-out) .05s}
.lm-check input:checked+.lm-check-box{background:var(--cyan-2);border-color:var(--cyan-2)}
.lm-check input:checked+.lm-check-box svg{stroke-dashoffset:0}
.lm-check input:focus-visible+.lm-check-box{outline:2px solid var(--cyan-2);outline-offset:2px}
@media (prefers-reduced-motion:reduce){.lm-check-box,.lm-check-box svg{transition:none}}
#leadForm .btn-mkk{margin-top:var(--sp-5);width:100%}
@media (max-width:575.98px){
  .lead-modal-photo{height:140px}
  .lead-modal-body{padding:var(--sp-4)}
}

/* ── STONE CANVAS (Task 10, «Один бросок») ── единственный полноэкранный fixed-канвас, на который
   stone.js рендерит Three.js-сцену; z-index:var(--z-stone)=900 — намеренно НИЖЕ nav/sticky/toast/
   курсора (1030+), но выше обычного document-контента, ведёт себя как декоративный слой ПОД UI-
   хромом. pointer-events:none — канвас никогда не перехватывает клики/hover у контента под ним
   (карточки, CTA, дропдауны и т.д. остаются кликабельными сквозь него на всех зонах, не только в
   пределах .ice-lane/#house). aria-hidden уже стоит в разметке (index.html) — канвас декоративен,
   ничего голосового в нём нет. */
#stoneCanvas{position:fixed;inset:0;width:100%;height:100%;pointer-events:none;z-index:var(--z-stone)}

/* .stone-css — fallback без реальной 3D-сцены (RM ИЛИ WebGL недоступен, см. applyStoneFallback()
   в main.js): статичный CSS-стоун поверх #house (тот же язык, что .house-rings — гранит+красная
   ручка, просто эллипс+псевдоэлементы вместо canvas) и статичный морозный след поверх .ice-lane
   (полоса просто выглядит "тронутой", без движущегося камня — Task 10 и так не двигает стоун по
   полосам, скролл-скраб это Task 11, так что статика здесь не теряет анимационных возможностей,
   которых пока и не было). Оба правила активны ТОЛЬКО когда JS явно добавил класс — без JS/до
   добавления класса секции остаются как были (пустая лента льда/пустой дом), т.к. ни одно из этих
   правил не квалифицируется без .stone-css на элементе. */
/* (морозный след на полосе через ::before/::after удалён — разметка листа теперь дочерние .lm-*,
   всегда видимые в т.ч. без WebGL/при RM, отдельный псевдо-след не нужен) */
#house.stone-css{position:relative}
/* Task 12 доп.: третий box-shadow-слой — фолбэк-глоу, эхо padel-мяча, тот же цианов тон, что живой
   .house-glow (JS-путь, см. правило .house-glow чуть выше по файлу — WebGL-сцена вставляет тот
   DOM-элемент через bindFinale/makeHouseGlow в stone.js; здесь же, в CSS-only фолбэк-пути, третьего
   псевдоэлемента у одного селектора не бывает (::before/::after уже заняты гранитом/ручкой ниже),
   поэтому глоу — ДОПОЛНИТЕЛЬНЫЙ слой в том же box-shadow этого же ::before, не отдельный узел).
   Task 14 polish #1: цвет/спред синхронизированы с живым .house-glow (тот же --cyan-1/--cyan-2 микс,
   выше alpha, шире спред) — см. коммент там. Task 14 polish #2: top сдвинут на +20px (та же посадка
   стоуна в эллипс кольца, что и live-путь в bindFinale — см. REST_Y_OFFSET в stone.js), ::after
   держит прежний относительный отступ от ::before (calc сохраняет "-18px над центром тела"). */
#house.stone-css::before{content:'';position:absolute;left:50%;top:calc(50% + 20px);width:120px;height:74px;background:var(--stone);border-radius:50%;transform:translate(-50%,-50%);box-shadow:inset 0 -10px 18px rgba(0,0,0,.25),0 12px 24px -8px rgba(20,48,60,.35),0 0 56px 8px rgba(24,172,238,.58)}
#house.stone-css::after{content:'';position:absolute;left:50%;top:calc(50% + 20px);width:46px;height:14px;background:var(--stone-red);border-radius:100px;transform:translate(-50%,calc(-50% - 18px))}
/* Reduced-motion: статика на финальном кадре, БЕЗ анимации вовсе. Сайтовый глобальный RM-килл в
   конце файла (animation-duration:.001ms!important) уже гасит любую CSS-анимацию де-факто до
   неразличимости — но здесь идём дальше явным animation:none на самом правиле, чтобы computed-стиль
   читался буквально "none", а не "0.001ms завершённая", как того требует чек-лист верификации задачи
   ("verify computed animation none under RM") — не полагаемся на то, что сверхкороткая длительность
   и "none" визуально неотличимы, они отличимы в getComputedStyle(). */
@media (prefers-reduced-motion:reduce){#house.stone-css::before{animation:none}}
/* No-WebGL, но motion разрешён (RM НЕ активен) — брифф явно допускает мягкий CSS-пульс именно в этом
   случае ("CSS fallback + CSS glow with gentle pulse allowed"). Гейт через саму RM media query (не
   доп. класс) — единственный сигнал "motion ok", уже используемый всей остальной таблицей стилей.
   Анимируем ТОЛЬКО box-shadow (не transform:scale — ::before уже несёт
   transform:translate(-50%,-50%) для центрирования; отдельная scale-анимация на том же transform
   потребовала бы совмещать оба в одном keyframe, а box-shadow-пульс сам по себе уже читается как
   "дыхание" глоу без риска сбить позиционирование). */
@media (prefers-reduced-motion:no-preference){#house.stone-css::before{animation:houseGlowPulse 1.8s ease-in-out infinite}}
@keyframes houseGlowPulse{
  0%,100%{box-shadow:inset 0 -10px 18px rgba(0,0,0,.25),0 12px 24px -8px rgba(20,48,60,.35),0 0 56px 8px rgba(24,172,238,.58)}
  50%{box-shadow:inset 0 -10px 18px rgba(0,0,0,.25),0 12px 24px -8px rgba(20,48,60,.35),0 0 74px 16px rgba(24,172,238,.72)}
}

/* ── TOAST ── */
/* Тост успеха — центрированная карточка со скримом (Figma 2126-16197) */
.mkk-toast{position:fixed;inset:0;z-index:var(--z-toast);display:flex;align-items:center;justify-content:center;padding:20px;background:rgba(20,48,60,0);opacity:0;visibility:hidden;transition:opacity .3s var(--ease-out),background .3s var(--ease-out),visibility .3s}
.mkk-toast.is-on{opacity:1;visibility:visible;background:rgba(20,48,60,.34)}
.mkk-toast-card{position:relative;display:flex;flex-direction:column;align-items:center;gap:var(--sp-5);width:min(500px,100%);padding:40px var(--sp-6);border-radius:20px;background:#fff;box-shadow:0 30px 80px -20px rgba(20,48,60,.4);text-align:center;transform:translateY(14px) scale(.97);transition:transform .4s var(--ease-out)}
.mkk-toast.is-on .mkk-toast-card{transform:none}
.mkk-toast-close{position:absolute;top:16px;right:16px;display:flex;align-items:center;justify-content:center;width:32px;height:32px;border:0;border-radius:50%;background:var(--background-bg);color:var(--ink-mut);cursor:pointer;transition:background .2s var(--ease-out)}
.mkk-toast-close:hover{background:var(--ice-2)}
.mkk-toast-icon{display:flex;align-items:center;justify-content:center;flex:none;width:72px;height:72px;border-radius:36px;background:var(--grad-cta);color:#fff;box-shadow:0 12px 28px -8px rgba(11,170,236,.5)}
.mkk-toast-text{display:flex;flex-direction:column;gap:var(--sp-3)}
.mkk-toast-title{margin:0;font:600 24px/1.3 'Onest',sans-serif;color:var(--ink-body)}
.mkk-toast-sub{margin:0;font:400 16px/1.3 'Onest',sans-serif;color:#6b7280;text-wrap:balance}
@media (prefers-reduced-motion:reduce){.mkk-toast-card{transition:none;transform:none}}

/* ── STICKY CTA (mobile only) ── */
#stickyCta{position:fixed;left:12px;right:12px;bottom:12px;z-index:var(--z-sticky);transform:translateY(calc(100% + 24px));opacity:0;transition:transform .35s var(--ease-out),opacity .35s var(--ease-out);pointer-events:none}
#stickyCta.is-on{transform:translateY(0);opacity:1;pointer-events:auto}
#stickyCta .btn-mkk{display:flex;width:100%;box-shadow:0 16px 32px -12px rgba(11,170,236,.5)}
@media (min-width:768px){#stickyCta{display:none}}

@media (prefers-reduced-motion:reduce){*{animation-duration:.001ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}

/* ── ЯКОРНЫЕ ЦЕЛИ: отступ под фиксированный хром (промо+нав) ── финальное ревью, Important #3.
   Работает и в no-JS пути (нативные #-прыжки), Lenis-путь дублирует расчёт offset'ом в
   initAnchorScroll (Lenis scrollTo НЕ читает scroll-margin сам). */
#hero,#club,#events,#prices,#reviews,#cta-house,#footer,#trust{scroll-margin-top:calc(var(--promo-h,40px) + var(--nav-h) + 12px)}

/* ===== legal / content pages (oferta.html, cancellation.html, 404.html) =====
   Wave D. Shared "Editorial Ice" shell for the 3 sub-pages: header/promo/nav + footer are copied
   verbatim from index.html (see those files) — GSAP/ScrollTrigger/Lenis/Three.js are NOT loaded here
   (homepage-only), so these rules are pure CSS, no motion.js hooks. Gradient hero band matches the
   Figma docs/legal template nodes (2346:13695 oferta / 2346:13696 cancellation / 2346:13694 404) —
   reuses the sitewide --grad-cta token, same gradient the primary buttons already use. Body copy sits
   in a ~760px centered column per spec (narrower than the homepage's 1400px .container-mkk) — legal
   text reads best at prose width, not full section width. */
/* Симметрия: зазор нав→контент = контент→низ блока (Роман). Десктоп — оба 60 (подняли верх с 48→60). */
.legal-hero{position:relative;padding:calc(var(--promo-h) + var(--nav-h) + 60px) 0 60px;background:linear-gradient(105deg,#2649A6 0%,#2B83EB 45%,#1DC7FE 100%);color:#fff}
.legal-hero-in{display:flex;flex-direction:column;align-items:flex-start;gap:var(--sp-4)}
.legal-back{display:inline-flex;align-items:center;gap:var(--sp-2);color:rgba(255,255,255,.8);font-size:14px;font-weight:500;text-decoration:none;transition:color .2s var(--ease-out)}
.legal-back:hover{color:#fff}
.legal-hero h1{margin:0;color:#fff;font-size:clamp(34px,4.8vw,56px);line-height:1.08;letter-spacing:-.01em}
.legal-hero-sub{margin:0;max-width:920px;color:rgba(255,255,255,.66);font-size:clamp(16px,1.9vw,24px);line-height:1.32;letter-spacing:-.01em}
.legal-main{background:var(--ice-0)}
.legal-col{max-width:760px;margin-inline:auto;padding-block:clamp(48px,7vw,80px)}
.legal-col h2{margin:0 0 var(--sp-5);font-size:clamp(24px,2.8vw,32px)}
.legal-entity+.legal-entity{margin-top:var(--sp-8)}
.legal-h3{margin:0 0 var(--sp-4);color:var(--ink-cold);font-size:clamp(18px,2vw,21px);font-weight:700}
.legal-lead{margin:0 0 var(--sp-5);color:var(--ink-mut);font-size:16px;line-height:1.6}
.legal-toc{display:flex;flex-direction:column;gap:var(--sp-3);margin:0 0 40px;padding:20px var(--sp-5);border:1px solid var(--border-blue);border-radius:var(--r-md);background:var(--ice-1)}
.legal-toc-label{margin:0 0 2px;color:var(--ink-mut);font-size:13px;font-weight:600;text-transform:uppercase;letter-spacing:.04em}
.legal-toc a{color:var(--cyan-2);font-weight:500;text-decoration:none}
.legal-toc a:hover{text-decoration:underline}
.legal-divider{border:0;border-top:1px solid rgba(20,48,60,.1);margin:36px 0}
.legal-divider-major{border-top-width:2px;margin:56px 0}
.legal-p{margin:0 0 20px;color:var(--ink-body);font-size:16px;line-height:1.7}
.legal-clause{display:flex;gap:var(--sp-3);margin:0 0 var(--sp-4);color:var(--ink-body);font-size:16px;line-height:1.65}
.legal-clause b{flex:none;min-width:32px;color:var(--ink-cold);font-weight:700}
.legal-sublist{display:flex;flex-direction:column;gap:var(--sp-2);margin:var(--sp-2) 0 var(--sp-4);padding:0;list-style:none}
.legal-sublist li{position:relative;padding-left:20px;color:var(--ink-body);font-size:15.5px;line-height:1.6}
.legal-sublist li::before{content:"–";position:absolute;left:0;color:var(--ink-mut)}
.legal-requisites{margin:0 0 var(--sp-2);padding:20px var(--sp-5);border-radius:var(--r-md);background:var(--ice-1);font-size:15px;line-height:1.7;color:var(--ink-body)}
.legal-requisites p{margin:0}

/* -- Приложение №1 price tables -- */
.legal-price-table{width:100%;margin:0 0 var(--sp-2);border-collapse:collapse;font-size:14.5px}
.legal-price-table th{padding:10px var(--sp-2);color:var(--ink-mut);font-weight:500;font-size:12.5px;text-transform:uppercase;letter-spacing:.03em;text-align:left;border-bottom:1px solid rgba(20,48,60,.14)}
.legal-price-table td{padding:9px var(--sp-2);border-bottom:1px solid rgba(20,48,60,.06);color:var(--ink-body)}
.legal-price-table tr.legal-price-cat th{padding:22px var(--sp-2) var(--sp-2);color:var(--ink-cold);font-weight:700;font-size:15px;text-transform:none;letter-spacing:0;border-bottom-color:rgba(20,48,60,.06)}
.legal-price-table td:last-child,.legal-price-table th:last-child{text-align:right;white-space:nowrap;font-variant-numeric:tabular-nums}
.legal-price-table td:nth-child(2){color:var(--ink-mut);white-space:nowrap}

/* -- cancellation.html cards (Figma 2346:13696): white card, title + circular emoji badge, each
   policy line in a tinted "alert" pill — tint derives from --stone-red (existing token) rather than
   a new hardcoded red, per project convention of reusing tokens. */
.legal-cards{display:flex;flex-direction:column;gap:var(--sp-5);margin:0 0 var(--sp-2)}
.legal-card{background:var(--ice-0);border:1px solid rgba(20,48,60,.08);border-radius:var(--r-lg);padding:var(--sp-6);box-shadow:0 20px 44px -32px rgba(20,48,60,.28)}
.legal-card-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);margin-bottom:var(--sp-5)}
.legal-card-head h2{margin:0;font-size:clamp(19px,2.3vw,24px)}
.legal-card-icon{flex:none;width:48px;height:48px;object-fit:contain}
.legal-alert-list{display:flex;flex-direction:column;gap:var(--sp-3);margin:0;padding:0;list-style:none}
.legal-alert{padding:var(--sp-5);border-radius:var(--r-md);background:rgba(226,86,74,.07);color:var(--ink-body);font-size:clamp(15px,1.7vw,18px);line-height:1.5}
.legal-alert b{font-weight:600;color:var(--ink-cold)}
.legal-alert-note{margin:var(--sp-1) var(--sp-1) 0;color:var(--stone-red);font-size:14px;font-weight:500}

/* -- 404.html (Figma 2346:13694): full-bleed photo + dark scrim, same transparent-over-dark #site-nav
   treatment the homepage hero already uses (no extra nav CSS needed — it's the nav's default state). */
.notfound-hero{position:relative;min-height:100svh;display:flex;align-items:center;justify-content:center;overflow:hidden;isolation:isolate;color:#fff;text-align:center;background:radial-gradient(120% 92% at 50% 28%,#1b3f61 0%,#0f2740 46%,#081726 100%)}
.notfound-in{position:relative;z-index:2;display:flex;flex-direction:column;align-items:center;gap:var(--sp-4);max-width:760px;padding:calc(var(--promo-h) + var(--nav-h) + 40px) 24px 64px}
.notfound-num{margin:0;font-size:clamp(96px,22vw,320px);line-height:1;font-weight:800;letter-spacing:-.02em;background:linear-gradient(180deg,rgba(255,255,255,.92),rgba(255,255,255,.22) 78%);-webkit-background-clip:text;background-clip:text;color:transparent}
.notfound-text{display:flex;flex-direction:column;gap:var(--sp-3)}
.notfound-text h1{margin:0;color:#fff;font-size:clamp(24px,3.4vw,40px)}
.notfound-text p{margin:0;color:rgba(255,255,255,.82);font-size:16px;line-height:1.5}
.notfound-btns{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--sp-4);margin-top:20px}

@media (max-width:767.98px){
  /* Мобилка: верхний зазор нав→контент по факту ≈42 (calc промо/нав перекрывает низ пилюли на ~10),
     поэтому низ 32→42, чтобы верх и низ совпали (Роман). */
  .legal-hero{padding:calc(var(--promo-h) + var(--nav-h) + 32px) 0 42px}
  .legal-requisites{padding:var(--sp-4) 18px}
  /* Мобилка (Роман): все отступы внутри карточки ≤16 (край экрана = 16, иначе баланс ломается).
     Иконка-эмодзи в шапке — по центру текста (было flex-start → казалась не по центру).
     Скоуп .legal-wide (0,2,0) обязателен: базовые .legal-card{padding:clamp(24…)} и др. идут НИЖЕ
     в файле и при равной специфичности перебивали бы мобильные значения. */
  .legal-wide .legal-card{padding:var(--sp-4)}
  .legal-wide .legal-card-head{align-items:center;margin-bottom:var(--sp-4)}
  .legal-card-icon{width:32px;height:32px}
  .legal-wide .legal-alert-list{gap:var(--sp-3)}
  .legal-wide .legal-alert{padding:var(--sp-4)}
  .legal-price-table{font-size:13.5px}
}

/* legal pages — generated oferta body helpers (Wave D, added when wiring pages) */
.legal-p{margin:0 0 20px;color:var(--ink-body);font-size:16px;line-height:1.7}
.legal-clause>span{flex:1;min-width:0}
.legal-doc-title{margin:52px 0 20px;text-align:center;font-size:clamp(19px,2.4vw,26px)}
.legal-col>.legal-doc-title:first-child{margin-top:0}
.legal-appx{margin:var(--sp-8) 0 6px;text-align:center;color:var(--cyan-2);font-size:clamp(18px,2vw,22px)}
.legal-pre-wrap{overflow-x:auto;margin:0 0 28px;border:1px solid var(--border-blue);border-radius:var(--r-md);background:var(--ice-1)}
.legal-pre{margin:0;padding:20px var(--sp-5);font-family:ui-monospace,'Cascadia Code',Consolas,'Courier New',monospace;font-size:13px;line-height:1.55;color:var(--ink-body);white-space:pre;min-width:max-content}

/* ===== события — редизайн «Мозаика» (бенто, Figma-фото). Старый .event-cards/.event-photo сохранён выше (резерв, откат вставкой фрагмента). ===== */
.events-bento{display:grid;grid-template-columns:2fr 1fr 1fr;grid-template-rows:236px 236px;gap:var(--sp-4);margin-top:40px}
.eb-tile{position:relative;display:flex;align-items:flex-end;border-radius:var(--r-lg);overflow:hidden;text-decoration:none;isolation:isolate;background:var(--ink-cold)}
.eb-big{grid-row:1 / span 2}
.eb-wide{grid-column:2 / span 2}
.eb-photo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 28%;z-index:0;transition:transform .5s var(--ease-out)}
.eb-tile::after{content:'';position:absolute;inset:0;z-index:1;background:linear-gradient(180deg,rgba(20,48,60,0) 36%,rgba(20,48,60,.74))}
.eb-tile:hover .eb-photo,.eb-tile:focus-visible .eb-photo{transform:scale(1.05)}
.eb-ic{position:absolute;top:16px;left:18px;z-index:2;display:inline-flex;width:44px;height:44px;align-items:center;justify-content:center;border-radius:50%;background:rgba(255,255,255,.18)}
.eb-ic img{width:26px;height:26px;display:block}
.eb-cap{position:relative;z-index:2;padding:var(--sp-6);color:#fff}
.eb-name{margin:0;color:#fff;font-size:20px;font-weight:800;line-height:1.18;letter-spacing:-.01em}
.eb-big .eb-name{font-size:28px;max-width:15ch}
.eb-hook{margin:0;color:rgba(255,255,255,.9);font-size:14px;line-height:1.4;max-width:38ch;opacity:0;transform:translateY(6px);transition:opacity .3s var(--ease-out),transform .3s var(--ease-out)}
.eb-tile:hover .eb-hook,.eb-tile:focus-visible .eb-hook{opacity:1;max-height:88px;transform:none}
.eb-tile:focus-visible{outline:3px solid var(--cyan-2);outline-offset:2px}
@media (max-width:991.98px){
  .events-bento{grid-template-columns:1fr 1fr;grid-template-rows:220px 184px 184px;margin-top:var(--sp-6)}
  .eb-big{grid-row:1;grid-column:1 / span 2}
  .eb-wide{grid-column:1 / span 2}
  .eb-hook{opacity:1;max-height:88px;transform:none}
}
@media (max-width:575px){
  .events-bento{grid-template-columns:1fr;grid-template-rows:repeat(4,180px);gap:var(--sp-3)}
  .eb-big,.eb-wide{grid-column:auto;grid-row:auto}
}

/* ===== ЦЕНЫ — редизайн по референсу (Роман): тёмный ледяной фон + БЕЛЫЕ единые карточки, целостный
   таб-бар (одна пилюля + залитый акцент-индикатор), компактно, имя-действие в бейдже, цена = герой.
   Скоуп .prices-ice; базовые градиентные .price-card* выше = резерв (откат = снять класс .prices-ice). ===== */
/* Фон секции — ледяной тинт (НЕ белый): на нём белые карточки читаются выделенно и чисто. */
.prices-ice{background:var(--ice-2)}
/* Карточка: белая, компактная, ЛЕВОЕ выравнивание — цена считывается сходу (как в референсе). */
.prices-ice .price-card{gap:var(--sp-5);padding:var(--sp-5);background:#fff;color:var(--ink-cold);border:1px solid var(--border-blue);border-radius:20px;box-shadow:0 1px 2px rgba(20,48,60,.04),0 16px 32px -24px rgba(20,48,60,.24);overflow:visible;isolation:auto}
.prices-ice .price-card::before{display:none}
.prices-ice .price-card:hover{transform:translateY(-6px);box-shadow:0 22px 44px -22px rgba(20,48,60,.3)}
/* Бейджи в ОДИН ряд (Роман): имя + месяц + скидка в одну строку, цена — на своей строке ниже. */
.prices-ice .price-card-top{flex-direction:row;flex-wrap:wrap;align-items:center;justify-content:flex-start;gap:var(--sp-3) var(--sp-2);text-align:left}
/* Бейдж-ряд слева; месяц — нейтральный, скидка — красная. */
.prices-ice .price-card-badges{justify-content:flex-start;gap:var(--sp-2)}
.prices-ice .price-badge{background:#E9F3FB;color:#2E93D4;font:600 13px/1.3 'Onest',sans-serif;letter-spacing:.02em;padding:5px var(--sp-3);border-radius:50px;border:0}
.prices-ice .price-badge-off{background:#FBEBE9;color:var(--stone-red)}
/* Имя-действие (бывший крупный h3) → компактный АКЦЕНТНЫЙ бейдж, идёт первым (Роман: название тоже в бейдж). */
.prices-ice .price-card h3{order:-1;display:inline-flex;align-items:center;padding:5px var(--sp-3);border-radius:50px;background:rgba(11,170,236,.1);color:var(--cyan-2);font:700 12px/1.3 'Onest',sans-serif;letter-spacing:.05em;text-transform:uppercase}
/* Цена — герой карточки. */
.prices-ice .price-card-price{flex-basis:100%;order:1;gap:var(--sp-3);font-variant-numeric:normal}
.prices-ice .price-now,.prices-ice .price-now b{color:var(--ink-cold)}
.prices-ice .price-now b{font-size:clamp(30px,2.4vw,36px);font-weight:800;letter-spacing:-.02em}
.prices-ice .price-now i{color:var(--ink-mut);opacity:1;font-size:14px}
.prices-ice .price-old{color:var(--ink-mut);font-size:16px}
.prices-ice .price-old::after{background:var(--ink-mut)}
.prices-ice .price-card-div{display:none}
/* Список — левый, компактный. */
.prices-ice .price-card-list{gap:var(--sp-3)}
.prices-ice .price-card-list li{justify-content:flex-start;text-align:left;color:var(--ink-body)}
.prices-ice .price-card-list svg{color:var(--cyan-2)}
/* Кнопка — на всю ширину, акцентная (единая у всех карточек). */
.prices-ice .price-card-cta{width:100%;align-self:stretch;justify-content:center;background:var(--grad-cta);color:#fff;border:0}
.prices-ice .price-card-cta:hover{filter:brightness(1.06);box-shadow:0 14px 30px -14px rgba(11,170,236,.5)}
/* Единый белый вид: снимаем выделение «текущей» карточки и ленту «Лучшая цена», цветные варианты → белые. */
.prices-ice .price-card-current{border:1px solid var(--border-blue);box-shadow:0 1px 2px rgba(20,48,60,.04),0 16px 32px -24px rgba(20,48,60,.24)}
.prices-ice .price-card-current:hover{box-shadow:0 22px 44px -22px rgba(20,48,60,.3)}
.prices-ice .price-card-current .price-card-cta{background:var(--grad-cta);color:#fff;border:0}
.prices-ice .price-card-tag{display:none}
.prices-ice .price-card-teal,.prices-ice .price-card-purple,.prices-ice .price-card-blue-purple{background:#fff}

/* Round-3: подзаг в .sec-head-split кап-выравнивается с крупным H2 (не «улетает» вверх). Только десктоп-сплит. */
@media (min-width:992px){.sec-head-split .lead-txt{padding-top:0}}

/* Кнопки нового дизайна: full-width акцент у одиночных; в паре (Купить+Условия) второй — светлый outline.
   Перебиваем .price-cards-2-оверрайды (тот старый HUG/центр) id-специфичности .prices-ice-скоупом. */
.prices-ice .price-card-btns{justify-content:stretch;width:100%;gap:var(--sp-3)}
.prices-ice .price-card-btns .price-card-cta{flex:1 1 0;width:auto}
.prices-ice .price-card-btns .price-card-cta:last-child{background:#fff;color:var(--ink-cold);border:1px solid rgba(20,48,60,.16)}
.prices-ice .price-card-btns .price-card-cta:last-child:hover{filter:none;background:var(--ice-2);border-color:var(--cyan-2)}
.prices-ice .price-cards-2 .price-card-cta{width:100%;align-self:stretch;height:auto}
.prices-ice .price-cards-2 .price-card-btns{justify-content:stretch}
.prices-ice .price-cards-2 .price-card-btns .price-card-cta{flex:1 1 0;width:auto}
.prices-heading h2::after{left:50%;transform:translateX(-50%) scaleX(0)}
.prices-heading h2.sweep-on::after{transform:translateX(-50%) scaleX(1)}

/* Round-3 шаг 4: события-плитки ведут на страницы (не модалку) — кнопка «Подробнее» по ховеру */
.eb-more{display:inline-flex;align-items:center;gap:var(--sp-1);margin-top:0;max-height:0;overflow:hidden;font-size:13px;font-weight:500;color:#fff;background:rgba(255,255,255,.16);border:1px solid rgba(255,255,255,.3);padding:0 var(--sp-4);border-radius:50px;opacity:0;transition:opacity .3s var(--ease-out),max-height .3s var(--ease-out),margin-top .3s var(--ease-out),padding .3s var(--ease-out),background .2s var(--ease-out)}
.eb-tile:hover .eb-more,.eb-tile:focus-visible .eb-more{opacity:1;max-height:44px;margin-top:var(--sp-3);padding:var(--sp-2) var(--sp-4)}
.eb-tile:hover .eb-more{background:rgba(255,255,255,.26)}
@media (max-width:991.98px){.eb-more{opacity:1;max-height:44px;margin-top:var(--sp-3);padding:var(--sp-2) var(--sp-4)}}

/* Round-3 шаг 4: модалка по Figma 2143-6095 — шапка(лого+X) → фото 124px → центр-заголовок → селектор+дивайдер → поля */
.lead-modal{display:flex;flex-direction:column;gap:20px;padding:var(--sp-5);background:#fff;overflow:hidden}
.lead-modal-head{display:flex;align-items:center;justify-content:space-between;width:100%}
.lead-modal-logo{height:32px;width:auto;display:block}
.lead-modal-close{position:static;display:flex;align-items:center;justify-content:center;width:32px;height:32px;padding:0;border:0;border-radius:50%;background:var(--background-bg);color:var(--ink-body);cursor:pointer;flex:none;transition:background .2s var(--ease-out)}
.lead-modal-close:hover{background:var(--ice-2)}
.lead-modal-photo{height:124px;border-radius:16px;overflow:hidden;width:100%;margin:0}
.lead-modal-photo img{width:100%;height:100%;object-fit:cover;object-position:center}
.lead-modal-body{display:flex;flex-direction:column;gap:var(--sp-4);padding:0;background:transparent}
.lead-modal-title{margin:0 0 var(--sp-1);text-align:center;font-size:20px;font-weight:600;color:var(--ink-body);line-height:1.3}
.lm-select-field{position:relative;margin:0}
.lm-select{width:100%;height:48px;padding:0 44px 0 var(--sp-4);border:1px solid rgba(18,16,14,.12);border-radius:44px;background:#fff;color:var(--ink-cold);font:400 14px/1.3 'Onest',sans-serif;-webkit-appearance:none;appearance:none;cursor:pointer}
.lm-select:focus-visible{outline:2px solid var(--cyan-2);outline-offset:2px}
.lm-select-chev{position:absolute;right:16px;top:50%;transform:translateY(-50%);color:var(--ink-mut);pointer-events:none}
.lm-divider{height:1px;width:calc(100% - 38px);margin:2px auto;background:var(--border-blue)}

/* Round-3 шаг 4 фиксы: X-крестик не гигантский (старое svg{width:100%} растягивало на весь круг); поля формы модалки с gap (селектор не слипается с инпутом); эмодзи-бейджи плиток убраны (не читались); ДР-заголовок в 2 строки */
.lead-modal-close svg{width:16px;height:16px}
#leadForm{display:flex;flex-direction:column;gap:var(--sp-4)}
#leadForm .lm-field+.lm-field{margin-top:0}
#leadForm .lm-check{margin-top:0}
.eb-ic{display:none}
.eb-big .eb-name{max-width:none}

/* ── Бенто-карточки: мобильный редизайн (фидбэк Романа) ── теперь внутри больше места:
   1) весь текст в НИЖНЕМ-ЛЕВОМ углу, паддинг 16 (было 32); 2) «Подробнее» → КРУГЛЫЙ бейдж со стрелкой
   ↗ (45° вверх) в ПРАВОМ-ВЕРХНЕМ углу — обозначает, что карточка кликабельна; 3) затемнение снизу
   ТЕМНЕЕ (.74→.92, старт выше) — белый текст читается. #events-специфичность: базовые .eb-* выше в файле.

   ГРАНИЦА 991.98, А НЕ 767.98 (фидбэк Романа по планшету): на 768–991 бенто держало ДЕСКТОПНЫЕ
   внутренние паддинги 32 — для планшетной карточки это съедало почти всю плашку; затемнение
   стартовало с 36% и белый текст на светлых фото не читался; «Подробнее» оставалась широкой
   кнопкой. Роман: «тут надо взять формат мобилки, кнопки унести в формат кнопки-стрелки».
   Поэтому не дублирую набор правил в планшетный слой, а расширяю границу этого блока —
   формат один, точка правки одна. Мобилке от этого ничего не меняется. */
@media (max-width:991.98px){
  #events .eb-tile::after{background:linear-gradient(180deg,rgba(20,48,60,0) 14%,rgba(20,48,60,.5) 48%,rgba(20,48,60,.92))}
  #events .eb-cap{padding:16px}
  #events .eb-name,#events .eb-big .eb-name{font-size:18px;max-width:none}
  #events .eb-reveal{max-height:none;margin-top:6px;overflow:visible}
  #events .eb-hook{opacity:1;max-height:none;transform:none;font-size:13px}
  #events .eb-more{display:none}
  #events .eb-tile::before{content:"";position:absolute;top:12px;right:12px;z-index:3;width:36px;height:36px;border-radius:50%;background:#fff url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%2314303c' stroke-width='2.6' stroke-linecap='round' stroke-linejoin='round'%3E%3Cline x1='7' y1='17' x2='17' y2='7'/%3E%3Cpolyline points='7 7 17 7 17 17'/%3E%3C/svg%3E") center/17px no-repeat;box-shadow:0 2px 8px rgba(0,0,0,.22)}
}

/* Кастомный дропдаун типа заявки (замена системного select) — Round-3, node 2143-6095 */
.lm-combo{position:relative}
.lm-combo .lm-select{position:absolute;width:1px;height:1px;padding:0;margin:0;opacity:0;pointer-events:none;clip:rect(0 0 0 0);overflow:hidden}
.lm-combo-btn{display:flex;align-items:center;gap:var(--sp-3);width:100%;height:48px;padding:0 var(--sp-4);border:1px solid rgba(18,16,14,.12);border-radius:44px;background:#fff;color:var(--ink-cold);font:400 14px/1.3 'Onest',sans-serif;text-align:left;cursor:pointer;transition:border-color .2s var(--ease-out),box-shadow .2s var(--ease-out)}
.lm-combo-btn:hover{border-color:rgba(18,16,14,.24)}
.lm-combo.is-open .lm-combo-btn{border-color:var(--cyan-2);box-shadow:0 0 0 3px rgba(11,170,236,.12)}
.lm-combo-btn:focus-visible{outline:2px solid var(--cyan-2);outline-offset:2px}
.lm-combo-value{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}
.lm-combo-chev{flex:none;display:flex;color:var(--ink-mut);transition:transform .25s var(--ease-out)}
.lm-combo.is-open .lm-combo-chev{transform:rotate(180deg)}
.lm-combo-list{position:absolute;z-index:30;top:calc(100% + 8px);left:0;right:0;max-height:264px;overflow-y:auto;margin:0;padding:var(--sp-2);list-style:none;background:#fff;border:1px solid var(--border-blue);border-radius:20px;box-shadow:0 18px 44px rgba(20,48,60,.18);animation:lmComboIn .18s var(--ease-out) both}
@keyframes lmComboIn{from{opacity:0;transform:translateY(-8px) scale(.98)}to{opacity:1;transform:none}}
.lm-combo-list li{display:flex;align-items:center;gap:var(--sp-3);padding:var(--sp-3) var(--sp-4);border-radius:12px;font:400 14px/1.25 'Onest',sans-serif;color:var(--ink-cold);cursor:pointer;transition:background .14s var(--ease-out),color .14s var(--ease-out)}
.lm-combo-list li:hover,.lm-combo-list li.is-active{background:var(--ice-2)}
.lm-combo-list li.is-selected{color:var(--cyan-2);font-weight:600}
.lm-combo-list li.is-selected::after{content:'✓';margin-left:auto;padding-left:var(--sp-2);color:var(--cyan-2);font-weight:700}
.lm-combo-list::-webkit-scrollbar{width:9px}
.lm-combo-list::-webkit-scrollbar-thumb{background:var(--border-blue);border-radius:8px;border:2px solid #fff}
@media (prefers-reduced-motion:reduce){.lm-combo-list{animation:none}.lm-combo-chev{transition:none}}

/* Реальные иконки в дропдауне (лого клуба/ресторана, тарелка, offer) вместо эмодзи — Round-3 */
.ndi-ic img{display:block;height:32px;width:auto;max-width:38px;object-fit:contain}

/* Модалка «Условия использования абонемента» (Figma 2069-20974) */
.cond-modal{position:relative;display:flex;flex-direction:column;gap:var(--sp-5);padding:var(--sp-6);border:0;border-radius:24px;background:#fff}
.cond-modal-close{position:absolute;top:24px;right:24px}
.cond-title{font:600 20px/1.3 'Onest',sans-serif;color:var(--ink-body);margin:0;padding-right:44px}
.cond-body{display:flex;flex-direction:column;gap:var(--sp-3)}
.cond-body p{font:400 14px/1.4 'Onest',sans-serif;color:rgba(63,63,63,.8);margin:0}
.cond-alert{margin:0;padding:var(--sp-4);border-radius:16px;background:rgba(0,123,255,.04);font:400 12px/1.45 'Onest',sans-serif;color:rgba(0,123,255,.7)}
.cond-close-btn{height:56px;border:1px solid rgba(63,63,63,.4);border-radius:222px;background:#fff;font:500 16px/1.3 'Onest',sans-serif;color:rgba(63,63,63,.8);cursor:pointer;transition:background .2s var(--ease-out),border-color .2s var(--ease-out)}
.cond-close-btn:hover{background:var(--background-bg);border-color:rgba(63,63,63,.7)}

/* Reveal-обёртка (hook+more): истинный коллапс до 0 в покое (overflow:hidden), чтобы нижний отступ карточки совпадал с боковым; раскрытие по ховеру/на мобиле */
.eb-reveal{max-height:0;overflow:hidden;margin-top:0;transition:max-height .4s var(--ease-out),margin-top .4s var(--ease-out)}
.eb-tile:hover .eb-reveal,.eb-tile:focus-visible .eb-reveal{max-height:180px;margin-top:var(--sp-3)}
@media (max-width:991.98px){.eb-reveal{max-height:180px;margin-top:var(--sp-3)}}

/* Юр-страницы round-3: боди во всю ширину, крупнее алерты, синий/красный варианты, белая кнопка в тёмной шапке */
.legal-wide{padding-block:clamp(44px,6vw,64px)}
/* Содержание (Роман): на десктопе липкий список слева, карточки уезжают вправо — пользователь сразу
   видит разделы и быстро переключается. На ≤991 содержание скрыто, карточки на всю ширину. */
.legal-layout{display:flex;align-items:flex-start;gap:clamp(24px,3vw,48px)}
.legal-cards{flex:1 1 auto;min-width:0}
.legal-toc{position:sticky;top:calc(var(--nav-h) + var(--sp-5));flex:0 0 clamp(220px,22vw,280px);display:flex;flex-direction:column;padding:var(--sp-5);background:var(--ice-0);border:1px solid var(--border-blue);border-radius:var(--r-lg);box-shadow:0 20px 44px -32px rgba(20,48,60,.28)}
.legal-toc-title{margin:0 0 var(--sp-3);color:var(--ink-mut);font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.1em}
.legal-toc-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:2px}
.legal-toc-list a{display:block;padding:10px 12px;border-radius:var(--r-sm);color:var(--ink-body);font-size:14px;line-height:1.32;text-decoration:none;transition:color .2s var(--ease-out),background .2s var(--ease-out)}
.legal-toc-list a:hover{color:var(--cyan-2);background:var(--ice-2)}
.legal-toc-list a.is-active{color:var(--cyan-2);background:var(--ice-2);font-weight:600}
.legal-card[id]{scroll-margin-top:calc(var(--nav-h) + var(--sp-5))}
@media (max-width:991.98px){.legal-layout{display:block}.legal-toc{display:none}}
.legal-alert-list{gap:var(--sp-5)}
.legal-card{border-color:var(--border-blue);border-radius:24px;padding:clamp(24px,3.6vw,40px)}
.legal-card-head{margin-bottom:var(--sp-6)}
.legal-alert-err{color:var(--stone-red);font-weight:500}
.legal-alert-info{background:rgba(0,123,255,.05)}
/* Кнопка «Забронировать» на страницах с тёмным/цветным херо (легал-страницы, ресторан). Белой она должна быть ТОЛЬКО на десктопе
   поверх синего херо, т.е. пока хедер вверху (не .scrolled). При скролле хедер белеет → кнопка обязана
   вернуться в синюю, иначе бело-на-белом теряется (баг Романа). На мобиле кнопка живёт в бургер-меню
   (всегда светлое, от цвета хедера не зависит) → всегда синяя, как на главной. Поэтому скоуп — только
   ≥992 и :not(.scrolled); во всех прочих случаях действует базовый .btn-mkk-primary (синий градиент). */
@media (min-width:992px){
  .legal-page #site-nav:not(.scrolled) .nav-cta,
  .page-resto #site-nav:not(.scrolled) .nav-cta,
  .page-halls #site-nav:not(.scrolled) .nav-cta{background:#fff;color:var(--ink-body)}
  .legal-page #site-nav:not(.scrolled) .nav-cta:hover,
  .page-resto #site-nav:not(.scrolled) .nav-cta:hover,
  .page-halls #site-nav:not(.scrolled) .nav-cta:hover{background:#fff;color:var(--cyan-2)}
}

/* Официальная информация — реквизиты (dt/dd) + список документов */
.legal-req{margin:0}
.legal-req>div{display:flex;flex-wrap:wrap;gap:var(--sp-1) var(--sp-5);padding:var(--sp-4) 0;border-bottom:1px solid var(--border-blue)}
.legal-req>div:first-child{padding-top:0}
.legal-req>div:last-child{border-bottom:0;padding-bottom:0}
.legal-req dt{flex:0 0 240px;color:var(--ink-mut);font-size:15px;line-height:1.4}
.legal-req dd{flex:1 1 220px;margin:0;color:var(--ink-cold);font-size:16px;font-weight:500;line-height:1.4}
.legal-doclinks{display:flex;flex-direction:column;gap:var(--sp-3);margin:0;padding:0;list-style:none}
.legal-doclinks a{color:var(--cyan-2);font-weight:500;font-size:17px;text-decoration:none}
.legal-doclinks a:hover{text-decoration:underline}

/* Оферта: 2 колонки (содержание слева + документ справа) + прайс-таблицы */
.legal-2col{display:grid;grid-template-columns:250px 1fr;gap:56px;align-items:start}
.legal-toc-side{position:sticky;top:calc(var(--promo-h) + var(--nav-h) + 16px);max-height:calc(100vh - var(--promo-h) - var(--nav-h) - 32px);overflow-y:auto;padding:var(--sp-5);border:1px solid var(--border-blue);border-radius:var(--r-md);background:var(--ice-1)}
.legal-toc-h{margin:0 0 var(--sp-4);color:var(--ink-mut);font-size:12px;font-weight:700;text-transform:uppercase;letter-spacing:.06em}
.legal-toc-list,.legal-toc-list ul{list-style:none;margin:0;padding:0;display:flex;flex-direction:column}
.legal-toc-list{gap:var(--sp-3)}
.legal-toc-list>li>a{display:block;color:var(--ink-cold);font-weight:600;font-size:15px;line-height:1.25;text-decoration:none}
.legal-toc-list ul{gap:var(--sp-2);margin:var(--sp-3) 0 2px;padding-left:var(--sp-4);border-left:1px solid var(--border-blue)}
.legal-toc-list ul a{color:var(--ink-mut);font-weight:500;font-size:13.5px;text-decoration:none}
.legal-toc-list a:hover{color:var(--cyan-2)}
.legal-doc{min-width:0}
.legal-table-wrap{overflow-x:auto;margin:0 0 28px;border:1px solid var(--border-blue);border-radius:var(--r-md)}
.legal-table-wrap .legal-price-table{margin:0}
.legal-table-wrap .legal-price-table td,.legal-table-wrap .legal-price-table th{padding-inline:var(--sp-4)}
.legal-price-head th{color:var(--ink-mut);font-weight:600}
/* 991.98, а не одиночные 900: в проекте было ДВЕ системы оглавления с разными точками слома —
   .legal-2col падал на 900, а .legal-layout на 991. На 901–991 оферта держала сайдбар 250px,
   тогда как соседняя страница правил уже была в одну колонку. Свёл к общей границе полосы. */
@media (max-width:991.98px){.legal-2col{grid-template-columns:1fr;gap:20px}.legal-toc-side{position:static;max-height:none}}

/* ================= Микроанимации (Трек 1) — жизнь на блоках ================= */
.btn-mkk{position:relative}
[data-count-to]{display:inline-block}
.prices-ice{position:relative}
#prices .container-mkk{position:relative;z-index:1}

/* 1 · Камень-лоадер (сабмит формы / ожидания) — замена спиннера */
.mkk-stone-loader{display:inline-block;width:22px;height:22px;border-radius:50%;background:#5c6c77;box-shadow:inset 0 0 0 3px #3c4952;position:relative;vertical-align:middle;animation:mkkSpin 1.05s linear infinite}
.mkk-stone-loader::before{content:"";position:absolute;top:2px;left:50%;margin-left:-3px;width:6px;height:9px;border-radius:3px;background:var(--cyan-1)}
@keyframes mkkSpin{to{transform:rotate(360deg)}}
.btn-mkk .btn-load{display:none}
.btn-mkk.is-loading{pointer-events:none}
.btn-mkk.is-loading .btn-txt{visibility:hidden}
.btn-mkk.is-loading .btn-load{display:inline-flex;align-items:center;justify-content:center;position:absolute;inset:0}

/* 2 · Иней по льду — блик по ледяным карточкам прайса (ховер) */
.prices-ice .price-card::after{content:"";position:absolute;inset:0;z-index:1;border-radius:inherit;pointer-events:none;background:linear-gradient(115deg,transparent 40%,rgba(255,255,255,.5) 50%,transparent 60%);background-size:250% 100%;background-position:170% 0;opacity:0}
.prices-ice .price-card:hover::after{opacity:1;animation:mkkGleam 1s var(--ease-out)}
@keyframes mkkGleam{from{background-position:170% 0}to{background-position:-70% 0}}

/* 3 · Мазок щётки — светлый мазок по главным кнопкам (ховер) */
.btn-mkk-primary{overflow:hidden}
.btn-mkk-primary::after{content:"";position:absolute;top:0;left:-60%;width:42%;height:100%;background:linear-gradient(100deg,transparent,rgba(255,255,255,.42),transparent);transform:skewX(-16deg);pointer-events:none;opacity:0}
.btn-mkk-primary:hover::after{opacity:1;animation:mkkSweep .72s var(--ease-out)}
@keyframes mkkSweep{from{left:-60%}to{left:130%}}

/* 4 · Дом-мишень — концентрические кольца (маркер-компонент) */
.mkk-house{display:inline-block;width:16px;height:16px;border-radius:50%;vertical-align:middle;background:radial-gradient(circle,#d1483b 0 24%,#fff 24% 45%,#2f74c0 45% 71%,rgba(214,229,240,.9) 71% 100%);animation:mkkPulse 3.2s ease-in-out infinite}
.mkk-house-eyebrow{display:flex;justify-content:center;margin-bottom:var(--sp-4)}
@keyframes mkkPulse{0%,100%{transform:scale(1)}50%{transform:scale(1.14)}}

/* 6 · Ледяные искры — редкие искры в фоне ледовых секций */
.mkk-sparkles{position:absolute;inset:0;pointer-events:none;overflow:hidden;z-index:0}
.mkk-sparkles i{position:absolute;width:22px;height:22px;background:var(--cyan-2);filter:drop-shadow(0 0 6px rgba(11,170,236,.55));clip-path:polygon(50% 0,60% 40%,100% 50%,60% 60%,50% 100%,40% 60%,0 50%,40% 40%);opacity:0;animation:mkkTwinkle 3.4s ease-in-out infinite}
@keyframes mkkTwinkle{0%,100%{opacity:0;transform:scale(.3)}44%,58%{opacity:.95;transform:scale(1)}}

/* bonus · idle-дрейф декоративных камней */
.mkk-drift{animation:mkkDrift 5.5s ease-in-out infinite}
@keyframes mkkDrift{0%,100%{transform:translateY(0) rotate(0deg)}50%{transform:translateY(-5px) rotate(2.5deg)}}

@media (prefers-reduced-motion:reduce){
  .prices-ice .price-card:hover::after,.btn-mkk-primary:hover::after,.mkk-house,.mkk-sparkles i,.mkk-drift{animation:none}
  .mkk-sparkles i{opacity:.75}
}

/* Секционный кикер — пример на 2 блоках (текст-кикер + кикер-бейдж), заголовки по левому краю */
/* text-indent компенсирует трейлинг letter-spacing (.12em добавляется и справа от последней буквы,
   утаскивая текст влево от центра бейджа) — глифы встают ровно по центру. Проверено на всех кикерах. */
.sec-kicker{display:inline-block;margin:0 0 20px;color:var(--cyan-2);font:700 13px/1 'Onest',sans-serif;text-transform:uppercase;letter-spacing:.12em;text-indent:.06em}
.sec-kicker-badge{padding:var(--sp-2) var(--sp-4);border-radius:50px;background:rgba(11,170,236,.1)}
.sec-kicker + h2{padding-top:0;line-height:1.04}
.sec-kicker + h2::after{display:none}

/* Кикер по центру (цены, отзывы) — обёртка центрирует бейдж над заголовком */
/* Центрированная шапка секции — НЕСЁТ head-gap сама (как .sec-head-split/.prices-heading).
   Раньше его приходилось дописывать в каждый блок отдельно (about-big/prices-rules-sec/gc-why) —
   забыл дописать = зазор 0. Единая точка крепления: контейнер заголовка. */
.sec-head-c{text-align:center;margin-bottom:var(--head-gap)}
.sec-head-c h2{margin:0}  /* как у .sec-head-split h2 / .prices-heading h2: зазор несёт контейнер, не h2 */
/* Исключение: когда .sec-head-c вложен в .prices-heading — гэп несёт внешняя обёртка (там ещё табы) */
.prices-heading .sec-head-c{margin-bottom:0}

/* Магнитные кнопки: transform ведёт GSAP — убираем CSS-переход по transform и hover-лифт,
   иначе они конфликтуют с покадровым transform от GSAP и кнопка «залипает» при уходе курсора */
[data-magnetic]{transition:box-shadow .3s var(--ease-out),background .3s var(--ease-out),border-color .3s var(--ease-out)}
[data-magnetic]:hover{transform:none}

/* ═══════════════ О КЛУБЕ (about.html) ═══════════════
   Общий хедер/промо/отзывы/футер + новые блоки на дизайн-системе:
   hero-about (теги+тайтл), «Самый большой» (план+текст+стат-бар+2 кнопки),
   «Не только керлинг» (2×2 эмодзи-карточки + фото), «Ярче и красочней» (галерея 4×2). */

/* — Hero: то же видео, во всю высоту экрана (как index), контент по центру: теги + тайтл + 2 кнопки.
   #hero.hero-about — перебиваем ID-специфичность базового #hero (flex-end → center; min-height 100svh). */
#hero.hero-about{align-items:center}
.hero-in-about{text-align:center;padding-bottom:clamp(32px,4vh,56px)}
.hero-tags{display:flex;flex-wrap:wrap;justify-content:center;gap:12px;margin-bottom:clamp(28px,5vh,52px)}
/* padding-block асимметричный (13/9): глифы Onest при line-height:1 сидят выше центра ема —
   оптическая компенсация 2px вниз, высота пилюли та же (22px вертикали суммарно) */
.hero-tag{display:inline-flex;align-items:center;padding:13px 20px 9px;border-radius:100px;background:var(--glass-bg);border:1px solid var(--glass-br);backdrop-filter:blur(16px);-webkit-backdrop-filter:blur(16px);color:#fff;font:500 15px/1 'Onest',sans-serif}
/* text-wrap:balance убран: перебалансировка строк ВО ВРЕМЯ GSAP-входа тайтла давала подёргивание
   (фриз). CTA отделён от тайтла увеличенным отступом (фидбэк). */
.hero-h1-about{font-size:clamp(38px,6.6vw,92px);line-height:1.02;letter-spacing:-.03em;font-weight:800;text-transform:uppercase;margin-bottom:clamp(44px,8vh,88px);text-wrap:wrap}
.hero-h1-about .hero-title-line{white-space:nowrap}  /* строки тайтла заданы разметкой — перенос по дефису («КЕРЛИНГ-/КЛУБ») запрещён */
.hero-h1-about .htl-inner{will-change:transform}
.hero-in-about .hero-cta{justify-content:center}

/* — «Самый большой»: сетка ТОЧНО из Figma-1360: план 619 / текст 701 / зазор 40. План заполняет
   свою колонку от левого края контейнера (никаких «капов»/центрирования — фидбэк Романа). */
.about-big .ab-row{display:grid;grid-template-columns:minmax(0,619fr) minmax(0,701fr);gap:40px;align-items:start;margin-bottom:clamp(24px,3vw,40px)}
.ab-image img{width:100%;height:auto;display:block;border-radius:var(--r-lg)}
/* Десктоп: текст выровнен по ВЕРХУ плана (align-items:start выше), а сам план подрезан сверху/снизу
   поровну (cover по центру) до ~высоты текста — чтобы под текстом не было провала до счётчика.
   13/5 ≈ 2.6:1: при колонке 556px план ~214px против текста ~197px — почти вровень. Мобилка не
   режется (план во всю ширину, natural). */
@media (min-width:992px){
  .ab-image{aspect-ratio:13/5;overflow:hidden;border-radius:var(--r-lg)}
  .ab-image img{height:100%;object-fit:cover;object-position:center}
}
.ab-text p{margin:0 0 var(--sp-4);max-width:62ch;color:var(--ink-body);font-size:clamp(16px,1.15vw,18px);line-height:1.62}
.ab-text p:last-child{margin-bottom:0}

/* — Счётчик: крупные карты с count-up (data-count-to), ховер-лифт — */
.ab-stats{display:grid;grid-template-columns:repeat(3,1fr);gap:clamp(14px,1.6vw,22px);margin-bottom:clamp(28px,3.5vw,44px)}
.ab-stat{position:relative;display:flex;flex-direction:column;align-items:center;gap:8px;padding:clamp(30px,3.6vw,46px) 20px;text-align:center;background:linear-gradient(180deg,#fff,var(--ice-2));border:1px solid rgba(11,170,236,.16);border-radius:var(--r-lg);box-shadow:var(--shadow-sm),var(--shadow-md);transition:transform .35s var(--ease-out),box-shadow .35s var(--ease-out)}
.ab-stat:hover{transform:translateY(-4px);box-shadow:var(--shadow-lg)}
.ab-stat-num{color:var(--cyan-2);font:800 clamp(46px,6vw,76px)/1 'Onest',sans-serif;letter-spacing:-.03em}
.ab-stat-label{max-width:18ch;color:var(--ink-body);font-size:clamp(14px,1vw,16px);font-weight:500;line-height:1.3}
.ab-cta{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--sp-4)}

/* — «Не только керлинг, но и отдых»: переиспользован слайдер-блок (events-row/event-cards/
   event-photo — стили и JS initEventsGallery уже в проекте). Лёгкий тинт секции для ритма. */
.about-leisure{background:var(--ice-1)}

/* — «Ярче и красочней»: H2 + кнопка справа, галерея 4×2 — */
.about-gallery-cta{display:flex;align-items:end;justify-content:flex-end}
.ag-grid{display:grid;grid-template-columns:repeat(4,1fr);gap:clamp(12px,1.4vw,18px)}
.ag-card{position:relative;display:block;aspect-ratio:322/239;overflow:hidden;border-radius:var(--r-lg);background:var(--ice-2)}
.ag-card img{width:100%;height:100%;object-fit:cover;display:block;transition:transform .6s var(--ease-out)}
.ag-card:hover img{transform:scale(1.05)}

@media (max-width:991.98px){
  .about-big .ab-row{grid-template-columns:1fr;gap:var(--sp-5);margin-bottom:var(--sp-6)}
  /* Галерея: мобильный порядок из Figma — заголовок → фото → кнопка ПОСЛЕ фото.
     .sec-head-split → display:contents: h2-колонка и кнопка-колонка становятся прямыми
     flex-детьми контейнера и переупорядочиваются; text-align/стили h2 наследуются как раньше. */
  .about-gallery .container-mkk{display:flex;flex-direction:column}
  .about-gallery .sec-head-split{display:contents}
  .about-gallery .sec-head-split>div:first-child{order:1;margin-bottom:var(--head-gap)}
  .about-gallery .ag-grid{order:2}
  .about-gallery-cta{order:3;margin-top:var(--sp-6);justify-content:center}
  .ag-grid{grid-template-columns:repeat(2,1fr)}
}
@media (max-width:767px){
  /* Хиро: тайтл максимально крупный В РАМКАХ 2 СТРОК — лимитирует ДЛИННАЯ строка «КЕРЛИНГ-КЛУБ»
     (7.615em ширины): 343px/7.615 = 45px @375 → 11.9vw (с запасом 3px). 12.6vw ломал её переносом
     по дефису на 3-ю строку — замерено. Бейджи компактнее + самый длинный первым (2 ряда). */
  .hero-h1-about{font-size:clamp(38px,11.9vw,52px)}
  .hero-tag{padding:12px 16px 8px;font-size:13px}  /* та же оптическая компенсация 2px вниз, что на десктопе */
  .hero-tags .hero-tag:nth-child(2){order:-1}
  /* Радиусы карточек на мобиле — по системе 16px (тот же паттерн, что #events .eb-tile / #prices .price-card) */
  .ab-stat,.ag-card,.ab-image img,.event-photo,.event-card,.offer-card,.offer-modal-card,.contact-card,.route-card,.route-map{border-radius:16px}
  .ab-stats{gap:var(--sp-3);margin-bottom:var(--sp-6)}
}
@media (max-width:575.98px){
  .ab-stats{grid-template-columns:1fr}
  /* кнопки hug по центру (в один ряд не помещаются: 220+150+16 > 343), НЕ во всю ширину — фидбэк */
}
@media (prefers-reduced-motion:reduce){
  .ag-card img{transition:none}
  .ab-stat{transition:none}
}

/* ═══════════════ HERO внутренних страниц (галерея/контакты/спец/цены) ═══════════════
   Видео-фон как на главной, но короче (~480px), контент по центру: заголовок + подзаголовок + CTA. */
/* ЭТАЛОННАЯ разметка (одобрена Романом на контактах): высота 478, контент якорится СВЕРХУ,
   тайтл ~82px@1440 → саб (гэп 8) → кнопка (гэп 48). Едина для ВСЕХ hero внутренних страниц. */
/* Геометрия страничного херо — на КЛАССЕ, а не на #hero. Раньше position/flex/overflow/color
   жили только в правиле #hero (по id), поэтому ВТОРОЙ херо на странице (или любая копия с другим
   id) их не получал и разъезжался. Класс делает блок самодостаточным. */
.hero-page{position:relative;display:flex;align-items:flex-start;overflow:hidden;isolation:isolate;
  color:#fff;min-height:clamp(430px,60vh,478px)}
#hero.hero-page{min-height:clamp(430px,60vh,478px);align-items:flex-start}
/* Нижний отступ херо — РЕАЛЬНЫЙ, а не остаток от min-height. Раньше стоял 0, и «воздух» снизу
   был просто разницей (478 − высота контента): вырастал заголовок — воздух схлопывался (99→27),
   а дальше блок рос бы вообще без низа. Теперь низ фиксирован токеном, блок растёт под контент. */
.hero-in-page{text-align:left;padding-bottom:var(--sp-8)}
.hero-h1-page{font-size:clamp(38px,5.7vw,82px);line-height:1.05;letter-spacing:-.02em;font-weight:800;color:#fff;text-wrap:balance;margin:0 0 clamp(8px,1vh,12px)}
.hero-page-sub{margin:0 0 clamp(32px,6vh,48px);color:rgba(255,255,255,.92);font-size:clamp(15px,1.5vw,22px);font-weight:500;line-height:1.4}
.hero-in-page .hero-cta{justify-content:flex-start;margin-bottom:0}  /* сброс нижнего margin с главной (там под CTA карточки) — иначе центрирование даёт лишний низ */

/* ═══ АВТО-ЛЕЙАУТ ХЕРО (.hero-stack) — принцип «hug», как auto-layout в Figma ═══
   Отступы живут МЕЖДУ элементами и группами (gap), а НЕ на самих элементах (margin).
   Поэтому удаление/добавление строки (подзаголовок, вторая строка тайтла) ничего не ломает:
   группа схлопывается, зазоры остаются. Раньше отступ до кнопки нёс margin подзаголовка —
   убрали подзаголовок, и кнопка прилипла к заголовку. Больше так не сломается.

   Вертикаль зеркальная: хедер→заголовок = кнопка→низ = --sec-pad (тот же ритм, что у секций,
   поэтому зазор до маркера следующего блока читается одинаково). Сверху добавляется вылет
   промо+нава, т.к. они лежат поверх херо. */
.hero-stack{
  /* ОПТИЧЕСКАЯ КОМПЕНСАЦИЯ ВЕРХА. Зеркальность по боксам (96/96) даёт визуально НЕравные поля:
     глаз меряет от низа ЛОГОТИПА до верха БУКВ, а бокс — от низа нав-контейнера до бокса строки.
     Замер: нав-бокс ниже логотипа на 15px + пустое поле над буквами (leading + капитель) 10px
     = 25px лишних сверху. Поэтому верх уменьшаем на эту величину — равенство оптическое, не
     арифметическое. Меняется тюнингом одной ручки. */
  --hero-optical-top:25px;
  display:flex;flex-direction:column;align-items:flex-start;
  gap:var(--sp-6);                                                       /* группа текста → кнопка */
  padding-top:calc(var(--promo-h,40px) + var(--nav-h) + var(--sec-pad) - var(--hero-optical-top));
  padding-bottom:var(--sec-pad)}                                          /* кнопка → низ */
.hero-stack .hero-txt{display:flex;flex-direction:column;gap:var(--sp-2)} /* заголовок → подзаголовок */
.hero-stack .hero-h1-page,.hero-stack .hero-page-sub,.hero-stack .hero-cta{margin:0}

/* Кегль заголовка в конфигурации херо с вектор-иллюстрацией (.hero-specials) — задаётся ЧИСЛОМ
   СТРОК (правило Романа): 1 строка → 90, 2 строки → 72 с межстрочным 110%.
   Модификаторы, а не id-правило: вешаются на любой такой херо. vw-множители подобраны так,
   чтобы на 1440 давать ровно 90 и 72, а на мобилке садиться (фикс. кегль туда не влезает). */
.hero-h1-1line{font-size:clamp(36px,6.25vw,90px);line-height:1.05}
.hero-h1-2line{font-size:clamp(32px,5vw,72px);line-height:1.1}
@media (max-width:767px){
  /* эталон-мобилка: герой НА ВСЮ ВЫСОТУ экрана (галерея/контакты/спец одинаково), контент по
     центру и чуть ниже — контент секций начинается за сгибом, без белого «хвоста» */
  .hero-page{min-height:100svh}
  #hero.hero-page{min-height:100svh}
  .hero-in-page{text-align:center;margin-top:26px}
  .hero-in-page .hero-cta{justify-content:center}
  .hero-page-sub{margin-bottom:32px}
  /* На мобилке херо центрируется. text-align:center центрирует ТЕКСТ, но не БОКСЫ: .hero-cta —
     флекс-элемент .hero-stack, а тот стоит на align-items:flex-start, поэтому бокс кнопки
     схлопывался по контенту и липнул влево. Центрируем сами боксы — тогда и кнопка по центру. */
  .hero-stack{align-items:center}

  /* ── ХЕРО ДНЯ РОЖДЕНИЯ: ТЕСТ «не на всю высоту» (по запросу Романа) ──
     Остальные мобильные херо остаются 100svh — это эталон, его не трогаем. Здесь пробуем hug:
     100svh давала 812 при контенте ~366, то есть 409px пустоты под кнопкой — низ вчетверо тяжелее
     верха. Снимаем min-height, высоту держат паддинги (§4.1), верх и низ становятся сопоставимы.
     Верхний отступ Роман одобрил как есть — он приходит из базового .hero-in и НЕ переопределяется. */
  #hero.hero-birthday{min-height:0}
  /* Нижний отступ ЗЕРКАЛИТ верхний, а не задан числом. Верхний зазор (реальный низ пилюли → H1)
     раскладывается так: pad-top = --promo-h + --nav-h + 5vh, плюс margin-top:26 у .hero-in-page,
     минус реальный низ пилюли (--promo-h + gap 12 + высота 48). --promo-h сокращается, остаётся
     70 + 5vh + 26 − 60 = 36 + 5vh. Клампы берём те же, что у pad-top (24…48 вместо 5vh).
     Поэтому при любой высоте вьюпорта верх и низ остаются равными сами собой, без подгонки. */
  .hero-birthday .hero-in-page{padding-bottom:clamp(60px,calc(36px + 5vh),84px)}
  .hero-birthday .hero-h1-page{font-size:40px;margin-bottom:var(--sp-4)}
  .hero-birthday .hero-page-sub{margin-bottom:var(--sp-6)}
}

/* ЭТАЛОН синего hero-блока без фото/видео (Hero.svg Романа, 1440×478): градиент #3EC5FE→#0BAAEC
   (почти вертикальный) + белое размытое свечение право-низ (982×878, rx 439, blur 121, opacity .82)
   ПОД фоновой графикой — оно и даёт узору читаемость. Применяется: контакты, спецпредложения,
   шапка цен — и все будущие синие блоки. */
.hero-blue{position:relative;overflow:hidden;background:linear-gradient(184deg,#3EC5FE 0%,#0BAAEC 100%)}
.hero-blue::before{content:"";position:absolute;right:max(-285px,-19.8vw);top:29%;width:min(982px,68.2vw);height:min(878px,61vw);border-radius:50%;background:#fff;opacity:.82;filter:blur(clamp(70px,8.4vw,121px));pointer-events:none}
/* Кнопка хедера над синим hero — БЕЛАЯ до скролла (по фидбеку, обсуждалось); после скролла — обычная.
   .hero-birthday идёт этим же правилом: фото-херо под тёмной вуалью — такой же тёмный фон, что и
   синий градиент, градиентная кнопка на нём теряется. */
#site-nav:not(.scrolled):has(~ .hero-blue) .nav-cta,
#site-nav:not(.scrolled):has(~ .hero-birthday) .nav-cta{background:#fff;color:var(--ink-cold)}
#site-nav:not(.scrolled):has(~ .hero-blue) .nav-cta:hover,
#site-nav:not(.scrolled):has(~ .hero-birthday) .nav-cta:hover{box-shadow:0 14px 34px -14px rgba(255,255,255,.55)}

/* ═══════════════ СПЕЦПРЕДЛОЖЕНИЯ (specials.html) ═══════════════ */
#hero.hero-specials{overflow:hidden}  /* база — эталон .hero-blue; поверх — полный герой-svg Романа */
.hero-specials .hero-scrim{display:none}
/* Деск: percent.svg (1440×478) = ВЕСЬ герой одним файлом (%, конфетти, эффекты) — фулл-блид cover */
.hs-bg{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center right;pointer-events:none}
/* Мобилка: percentmob.svg (375×608) = ВЕСЬ мобильный герой одним файлом (%, конфетти, свечение) */
.hs-bg-mob{display:none;position:absolute;inset:0;width:100%;height:100%;object-fit:cover;pointer-events:none}
.specials-tabs{display:flex;width:fit-content;gap:4px;padding:5px;border-radius:100px;background:var(--ice-2);margin:0 auto clamp(32px,4vw,48px)}
.sp-tab{padding:11px 32px;border-radius:100px;border:0;background:transparent;color:var(--ink-body);font:600 15px/1 'Onest',sans-serif;cursor:pointer;transition:background .25s var(--ease-out),color .25s var(--ease-out)}
.sp-tab.is-active{background:var(--grad-cta);color:#fff;box-shadow:0 6px 16px -8px rgba(11,170,236,.6)}
.offers-grid{display:grid;grid-template-columns:1fr 1fr;gap:clamp(16px,1.8vw,32px)}
.offer-card{position:relative;display:flex;align-items:center;min-height:200px;padding:clamp(24px,2.6vw,32px);border-radius:var(--r-lg);background:var(--card-bg);overflow:hidden;transition:transform .3s var(--ease-out),box-shadow .3s var(--ease-out)}
.offer-card:hover{transform:translateY(-4px);box-shadow:var(--shadow-lg)}
.oc-body{position:relative;z-index:1;max-width:62%}
.oc-head{display:flex;align-items:center;flex-wrap:wrap;gap:10px;margin-bottom:12px}
.oc-head h3{margin:0;color:var(--ink-cold);font-size:clamp(20px,1.9vw,26px);font-weight:800;letter-spacing:-.02em}
.oc-badge{display:inline-flex;align-items:center;padding:5px 12px;border-radius:100px;background:var(--badge);color:#fff;font:700 14px/1 'Onest',sans-serif;white-space:nowrap}
.oc-desc{margin:0 0 clamp(16px,2vw,22px);color:var(--ink-body);font-size:clamp(14px,1vw,15px);line-height:1.45}
.oc-btn{align-self:flex-start}
.oc-icon{position:absolute;right:clamp(14px,2vw,26px);top:50%;transform:translateY(-50%);width:clamp(96px,10vw,150px);height:auto;pointer-events:none}
.offers-empty{display:flex;flex-direction:column;align-items:center;gap:16px;padding:clamp(48px,6vw,80px) 24px;text-align:center;color:var(--ink-body)}
.oe-emoji{font-size:56px;line-height:1}
.offers-empty p{margin:0;font-size:clamp(16px,1.3vw,18px);line-height:1.5}
.offer-modal{position:fixed;inset:0;z-index:1200;display:flex;align-items:center;justify-content:center;padding:20px}
.offer-modal[hidden]{display:none}
.offer-modal-scrim{position:absolute;inset:0;background:rgba(10,32,50,.55);backdrop-filter:blur(3px);-webkit-backdrop-filter:blur(3px)}
.offer-modal-card{position:relative;width:100%;max-width:500px;background:#fff;border-radius:var(--r-lg);box-shadow:var(--shadow-lg);padding:clamp(28px,3vw,36px);animation:offerModalIn .28s var(--ease-out)}
@keyframes offerModalIn{from{opacity:0;transform:translateY(16px) scale(.98)}to{opacity:1;transform:none}}
.offer-modal-close{position:absolute;right:18px;top:18px;width:34px;height:34px;display:flex;align-items:center;justify-content:center;border:0;border-radius:50%;background:var(--ice-2);color:var(--ink-cold);cursor:pointer;transition:background .2s}
.offer-modal-close:hover{background:var(--ice-1)}
.omc-head{display:flex;align-items:center;gap:12px;margin:0 40px 20px 0}
.omc-head h2{margin:0;color:var(--ink-cold);font-size:clamp(22px,2.2vw,28px);font-weight:800}
.omc-conditions{list-style:none;margin:0 0 24px;padding:0;display:flex;flex-direction:column;gap:10px}
.omc-conditions li{position:relative;padding:14px 16px 14px 46px;border-radius:var(--r-md);background:var(--ice-1);color:var(--ink-body);font-size:14px;line-height:1.4}
.omc-conditions li::before{content:"";position:absolute;left:16px;top:15px;width:18px;height:18px;border-radius:50%;background:var(--grad-cta)}
.omc-conditions li::after{content:"";position:absolute;left:22px;top:19px;width:5px;height:9px;border:solid #fff;border-width:0 2px 2px 0;transform:rotate(45deg)}
/* Кнопки модалки — СТОЛБЦОМ на всю ширину (Figma 436×56 + 436×56; в ряд праймери ломалась в 2 строки) */
.omc-actions{display:flex;flex-direction:column;gap:12px}
.omc-actions .btn-mkk{width:100%;justify-content:center;white-space:nowrap}
@media (max-width:767px){
  /* ═ Мобилка СТРОГО по Figma 2127:7967 ═ */
  /* герой на всю высоту экрана (фидбэк: под 608-героем торчал белый кусок секции); фон — весь
     percentmob.svg (%, конфетти, свечение), object-fit cover заполняет экран, % центр-низ */
  #hero.hero-specials{min-height:100svh}
  .hs-bg{display:none}
  .hs-bg-mob{display:block;object-position:center bottom}
  .hero-specials .hero-in-page{margin-top:26px}  /* контент чуть ниже, аддитивно к нав-отступу (фидбэк) */
  .hero-specials.hero-blue::before{display:none}  /* свечение уже внутри percentmob.svg */
  .hero-specials .hero-h1-page{font-size:clamp(32px,8.8vw,36px)}
  /* Мобильный кегль в этом херо диктует САМОЕ ДЛИННОЕ СЛОВО, а не число десктопных строк.
     Базовые 33px@375 подобраны под «Спецпредложения» (15 знаков, 201px уже на 33px — больше не влезает).
     У .hero-h1-2line самое длинное слово короче («Подарочный», 10 знаков), поэтому кегль поднимаем:
     13vw даёт 48.75@375 → слово 297px в контейнере 343, поле по 23 на сторону. 13.5vw пробовали —
     на 320px оставалось 12.5px, меньше самих полей контейнера (16), слово оптически липло к краям.
     Потолок 52 — как у контактов/галереи (52–54), чтобы мобильные херо звучали в один голос.
     Селектор (0,2,0) — вровень с базовым выше и объявлен после, поэтому выигрывает. */
  .hero-specials .hero-h1-2line{font-size:clamp(40px,13vw,52px)}
  .hero-specials .hero-page-sub{max-width:260px;margin-inline:auto}
  /* табы месяца — компактные пилюли 32px по центру */
  .sp-tab{padding:8px 16px;font-size:13px}
  /* карточки: поля страницы 20 (у контейнера 16 → +4), зазор 16 */
  .offers-grid{grid-template-columns:1fr;gap:16px;margin-inline:4px}
  .offer-card{min-height:0;padding:16px;align-items:flex-start}
  .oc-body{position:static;max-width:100%}
  .oc-head h3{font-size:15px}
  .oc-badge{padding:3px 6px;font-size:13px}
  .oc-desc{font-size:13px;max-width:223px;margin-bottom:24px}
  .oc-btn{padding:11px 16px 9px;font-size:13px}          /* «Условия» 88×36 */
  .oc-icon{right:-23px;bottom:-22px;top:auto;transform:none;width:130px}  /* эмодзи 130, углом за карточку (обрезается) */
}

/* ═══════════════ СТОИМОСТЬ УСЛУГ (prices.html) ═══════════════
   Hero — как «Правила отмены» (.legal-hero: узкий тёмно-синий градиент, белый текст, левый контент).
   Белая нав-CTA над ним + переиспользованные блоки: #prices, .banner-specials, .legal-card. */
#site-nav:not(.scrolled):has(~ .prices-hero) .nav-cta{background:#fff;color:var(--ink-cold)}
#site-nav:not(.scrolled):has(~ .prices-hero) .nav-cta:hover{box-shadow:0 14px 34px -14px rgba(255,255,255,.55)}
/* Блок цен на этой странице — без заголовка (он в герое): герой → сразу к табам. */
.prices-page-block{padding-top:clamp(36px,4.5vw,64px)}
.prices-heading-tabsonly{margin-bottom:clamp(32px,4vw,52px)}
/* Баннер спец «между» блоками с РАВНЫМ зазором: у самого баннера внутри абсолютный %-арт ломает
   математику паддинга секции, поэтому зазор задают СОСЕДИ одинаковым значением (--gap-banner), а
   секция баннера и его div — без своих отступов. */
:root{--gap-banner:clamp(64px,7vw,110px)}
.prices-page-block{padding-bottom:clamp(36px,4.5vw,64px)}  /* голубой блок: свой симметричный низ */
.prices-banner-sec{padding-block:var(--gap-banner)}        /* БЕЛЫЕ зазоры сверху и снизу баннера — равны */
.prices-banner-sec .banner-specials{margin:0}
.prices-rules-sec{padding-top:0}                           /* маркер правил у белого края — нижний зазор задаёт баннер */
/* Контейнер правил взял .legal-wide РАДИ одобренных мобильных отступов карточек (внутр.≤16<внешн.),
   но его вертикальный padding-block (44–64) сдвинул бы маркер вниз и сломал зазор баннер→маркер (90) —
   гасим: внешний ритм тут задают баннер (верх) и .prices-rules-sec pb (низ). */
.prices-rules-sec .legal-wide{padding-block:0}
/* «Лоск» карточек тарифов — ТОЛЬКО на странице цен (.prices-page-block, главную не трогаем):
   мягкий верхний блик (глянец), тень-парение и ховер-лифт с усилением тени. */
.prices-page-block .price-card{box-shadow:0 20px 46px -26px rgba(30,70,150,.5)}
.prices-page-block .price-card::after{content:"";position:absolute;inset:0;z-index:0;pointer-events:none;background:radial-gradient(135% 95% at 12% -12%,rgba(255,255,255,.24),transparent 56%)}
.prices-page-block .price-card:hover{transform:translateY(-6px);box-shadow:0 34px 62px -26px rgba(30,70,150,.56)}
@media (prefers-reduced-motion:reduce){.prices-page-block .price-card:hover{transform:none}}

/* ═══════════════ ФОТОГАЛЕРЕЯ (gallery.html) ═══════════════
   Фильтр-табы (Все/Керлинг/Корпоративы/Ресторан) → показывают секции по data-cat. Карточки — .ag-card/.ag-grid. */
/* Фото-фон героя (Figma, вместо видео) — та же геометрия, что у #heroVideo */
.hero-photo{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;object-position:center 20%;z-index:0}  /* кадр смещён вверх: головы в верхней трети фото, центр-кроп их резал */
.hero-photo-mob{display:none}  /* деск — горизонтальное фото; мобилка — вертикальный кроп (центр. группа) */
/* Галерея-герой ВЫШЕ обычного page-hero на десктопе (фидбэк) — фото просторнее.
   ТОЛЬКО деск (min-width): на мобилке остаётся 100svh из общего .hero-page-блока.
   Контент центрируется по вертикали (align-items:center + сброс нав-паддинга) — отступы
   сверху/снизу примерно равны (фидбэк: контент был прибит к верху, низ пустовал). */
@media (min-width:768px){
  #hero.hero-gallery{min-height:clamp(520px,64vh,640px);align-items:center}
  .hero-gallery .hero-in-page{padding-top:0}
}

/* ═══ ДЕСКТОП: херо ДНЯ РОЖДЕНИЯ — отступы и кегли по прямой спеке Романа ═══
   Числа заданы заказчиком: хедер→H1 80, H1→саб 24, саб→кнопка 48, низ херо 120, H1 72, саб 24.
   Токенов на 80 и 120 в шкале нет, но оба лежат на сетке 8pt — пишем литералами.

   ГЛАВНОЕ: align-items:flex-start + min-height:0, а НЕ центрирование. При центрировании отступы
   задаются свободным местом, а не паддингами, и управлять ими нельзя — это уже проходили на
   планшетном херо галереи (комментарий ниже в планшетном блоке). Высоту держит контент+паддинги
   (hug, §4.1): правим кегль или добавляем строку — верх и низ остаются 80/120.

   Верх считается от ФОРМУЛЫ промо+нав: на десктопе она даёт ровно 110, что совпадает с реальным
   низом бокса шапки (замер), поэтому поправка -10, нужная на планшете, тут НЕ применяется. */
@media (min-width:992px){
  #hero.hero-birthday{min-height:0;align-items:flex-start}
  .hero-birthday .hero-in{padding-top:calc(var(--promo-h) + var(--nav-h) + 80px)}
  .hero-birthday .hero-in-page{padding-bottom:120px}
  /* 72 ровно на 1440: 72/1440 = 5vw. Ниже по ширине — плавно уменьшается. */
  .hero-birthday .hero-h1-page{font-size:clamp(38px,5vw,72px);margin-bottom:var(--sp-5)}
  /* 24 ровно на 1440: 24/1440 = 1.667vw. */
  .hero-birthday .hero-page-sub{font-size:clamp(15px,1.667vw,24px);margin-bottom:var(--sp-7);max-width:800px}
}
@media (max-width:767px){
  .hero-photo-desk{display:none}
  .hero-photo-mob{display:block;object-position:center top}
  /* мобилка галереи: тайтл крупнее, но «Фотогалерея» держится в 16px-полях (14vw@375=52.5px →
     текст ~332px < 343 внутренних; 15vw давал 356px и вылезал за поле справа) */
  .hero-gallery .hero-h1-page{font-size:clamp(42px,14vw,58px)}
  .hero-gallery .hero-in-page{margin-top:clamp(64px,15vh,130px)}
}
/* Скелетон загрузки: шиммер в карточке, пока фото не загрузилось (is-loaded ставит main.js) */
.ag-card::before{content:"";position:absolute;inset:0;background-color:var(--ice-2);background-image:linear-gradient(100deg,transparent 32%,rgba(255,255,255,.75) 50%,transparent 68%);background-size:220% 100%;background-position:120% 0;animation:agShimmer 1.4s ease infinite}
@keyframes agShimmer{to{background-position:-120% 0}}
.ag-card.is-loaded::before{display:none}
.ag-card img{position:relative;z-index:1}
@media (prefers-reduced-motion:reduce){.ag-card::before{animation:none}}
.gallery-tabs{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--sp-3);margin-bottom:clamp(32px,4vw,52px)}
.gal-tab{padding:12px 24px;border-radius:100px;border:1px solid rgba(20,48,60,.14);background:#fff;color:var(--ink-body);font:500 15px/1 'Onest',sans-serif;cursor:pointer;transition:background .25s var(--ease-out),color .25s var(--ease-out),border-color .25s var(--ease-out)}
.gal-tab:hover{border-color:var(--cyan-2);color:var(--ink-cold)}
.gal-tab.is-active{background:var(--grad-cta);border-color:transparent;color:#fff}
@media (max-width:767px){
  /* классический мобильный таб-бар: ОДНА строка с горизонтальным скроллом, от края до края
     (негативные маргины выпускают ленту за контейнер), скроллбар скрыт */
  .gallery-tabs{flex-wrap:nowrap;justify-content:flex-start;gap:8px;overflow-x:auto;-webkit-overflow-scrolling:touch;scrollbar-width:none;margin-inline:calc(var(--bs-gutter-x)*-.5);padding-inline:calc(var(--bs-gutter-x)*.5);width:auto}
  .gallery-tabs::-webkit-scrollbar{display:none}
  .gal-tab{flex:none;white-space:nowrap;padding:9px 14px;font-size:13px}
}
.gal-section{margin-bottom:clamp(48px,6vw,84px)}
.gal-section:last-child{margin-bottom:0}
.gal-section[hidden]{display:none}
.gal-cat-title{text-align:center;margin:0 0 clamp(24px,3vw,40px);color:var(--ink-cold);font-size:clamp(26px,3vw,40px);font-weight:800;letter-spacing:-.02em}

/* — Лайтбокс галерей (.ag-card, about + gallery): просмотр фото по клику — */
.mkk-lightbox{position:fixed;inset:0;z-index:1300;display:flex;align-items:center;justify-content:center;padding:20px}
.mkk-lightbox[hidden]{display:none}
.mlb-scrim{position:absolute;inset:0;background:rgba(10,32,50,.78);backdrop-filter:blur(4px);-webkit-backdrop-filter:blur(4px)}
.mlb-img{position:relative;max-height:82vh;width:auto;height:auto;border-radius:var(--r-md);box-shadow:0 30px 80px -20px rgba(0,0,0,.55);animation:mlbIn .25s var(--ease-out)}
@keyframes mlbIn{from{opacity:0;transform:scale(.96)}to{opacity:1;transform:none}}
.mlb-x{position:absolute;top:18px;right:18px;z-index:2;width:40px;height:40px;display:flex;align-items:center;justify-content:center;border:0;border-radius:50%;background:rgba(255,255,255,.14);color:#fff;cursor:pointer;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);transition:background .2s}
.mlb-x:hover{background:rgba(255,255,255,.26)}
.mlb-nav{position:absolute;top:50%;transform:translateY(-50%);z-index:2;width:46px;height:46px;display:flex;align-items:center;justify-content:center;border:0;border-radius:50%;background:rgba(255,255,255,.14);color:#fff;cursor:pointer;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);transition:background .2s}
.mlb-nav:hover{background:rgba(255,255,255,.26)}
.mlb-prev{left:18px}
.mlb-next{right:18px}
@media (max-width:767px){
  .mlb-nav{width:40px;height:40px}
  .mlb-prev{left:10px}
  .mlb-next{right:10px}
  .mlb-img{max-height:74vh;border-radius:16px}
}
@media (prefers-reduced-motion:reduce){.mlb-img{animation:none}}

/* ═══════════════ КОНТАКТЫ И ЛОКАЦИЯ (contacts.html) ═══════════════ */
/* Hero — фирменная графика Романа (BG_contact_desk/mob.svg) на синем градиенте, не видео.
   Геометрия по Figma-1440: узор 973px = 67.6% ширины, якорь право-НИЗ; контент якорится СВЕРХУ
   (не по центру): тайтл ~82px → саб (гэп 8) → кнопка (гэп 48); высота героя 478. */
/* высота/якорь/типографика героя — из общего эталона .hero-page; здесь только фон-графика */
.hc-bg{position:absolute;pointer-events:none}
/* узор с выпуском ±14px за верх/низ: у SVG прозрачные поля по краям, и на деске они
   масштабируются вместе с растяжкой узора (1.24×) — ±6 не хватало, оставалось 2-3px */
.hc-bg-desk{right:0;top:-14px;height:calc(100% + 28px);width:auto}
.hc-bg-mob{display:none}
/* Живость героя: медленное «дыхание» глоу (standalone-scale — не конфликтует с transform) */
.hero-contacts.hero-blue::before{animation:hbGlowBreath 7s ease-in-out infinite}
@keyframes hbGlowBreath{0%,100%{scale:1}50%{scale:1.06}}
@media (prefers-reduced-motion:reduce){.hero-contacts.hero-blue::before{animation:none}}
.contacts-row{display:grid;grid-template-columns:1fr 1fr;gap:clamp(20px,2vw,32px);margin-bottom:clamp(20px,2vw,32px)}
.contact-card,.route-card{background:#fff;border:1px solid rgba(20,48,60,.08);border-radius:var(--r-lg);box-shadow:var(--shadow-sm),0 12px 28px -22px rgba(20,48,60,.16);padding:clamp(26px,3vw,40px)}  /* тень заметно легче (фидбэк: «навалил тяжело»; Figma вообще без) */
.cc-head{display:flex;align-items:flex-start;justify-content:space-between;gap:16px;margin-bottom:clamp(20px,2vw,26px)}
.cc-head h2{margin:0;color:var(--ink-cold);font-size:clamp(22px,2.2vw,30px);font-weight:800;letter-spacing:-.02em;line-height:1.15}
.cc-icon{flex:none;width:48px;height:48px}
.cc-links{display:flex;flex-wrap:wrap;gap:12px;margin-bottom:clamp(18px,2vw,22px)}
/* Контакты (не карты): на десктопе 3 кнопки СТОЛБЦОМ, повыше — как в Figma */
@media (min-width:992px){.cc-links:not(.cc-links-map){flex-direction:column;align-items:flex-start}}
.cc-pill{display:inline-flex;align-items:center;gap:9px;padding:14px 22px 12px;border-radius:100px;border:1px solid rgba(20,48,60,.14);background:#fff;color:var(--ink-cold);font:500 15px/1 'Onest',sans-serif;text-decoration:none;transition:border-color .25s var(--ease-out),background .25s var(--ease-out),transform .25s var(--ease-out)}
.cc-pill:hover{border-color:var(--cyan-2);background:var(--ice-1);transform:translateY(-1px)}
.cc-ic{flex:none;color:var(--cyan-2)}
.cc-map-ic{flex:none;width:auto;height:18px}
.cc-address{margin:0 0 clamp(16px,2vw,22px);color:var(--ink-cold);font-size:clamp(16px,1.2vw,18px);font-weight:600;line-height:1.45}
.cc-note{margin:0;color:var(--ink-body);font-size:15px;line-height:1.5;max-width:64ch}
.route-metro{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:0 0 clamp(22px,3vw,30px);color:var(--ink-cold);font-size:clamp(15px,1.15vw,17px);font-weight:600}
.metro-dot{width:14px;height:14px;border-radius:50%;background:#8E479C;flex:none}
.route-walk{display:inline-flex;align-items:center;gap:4px;color:var(--cyan-2)}
.route-metro-note{color:var(--ink-body);font-weight:400}
/* Маршрут — «тепловая» роадмэп (Figma): БЕЗ цифр (10 пунктов не акцентируем), точка каждого шага
   ярче предыдущей — имитация прогресса: старт почти прозрачный, финиш яркий. Кружок 36 (лёд) +
   точка 12 (циан, opacity по шагам), коннектор — 1px линия фоном li. */
.route-steps{list-style:none;margin:0 0 clamp(26px,3vw,38px);padding:0}
.route-steps li{position:relative;padding:8px 0 24px 52px;color:var(--ink-body);font-size:clamp(15px,1.1vw,16px);line-height:1.5;background:linear-gradient(rgba(11,170,236,.22),rgba(11,170,236,.22)) no-repeat 17.5px 38px;background-size:1px calc(100% - 40px)}
.route-steps li:last-child{padding-bottom:0;background:none}
.route-steps li::before{content:"";position:absolute;left:0;top:0;width:36px;height:36px;border-radius:50%;background:var(--ice-2)}
.route-steps li::after{content:"";position:absolute;left:12px;top:12px;width:12px;height:12px;border-radius:50%;background:var(--cyan-2);opacity:var(--dot,1)}
.route-steps li:nth-child(1){--dot:.14}
.route-steps li:nth-child(2){--dot:.24}
.route-steps li:nth-child(3){--dot:.34}
.route-steps li:nth-child(4){--dot:.45}
.route-steps li:nth-child(5){--dot:.56}
.route-steps li:nth-child(6){--dot:.67}
.route-steps li:nth-child(7){--dot:.78}
.route-steps li:nth-child(8){--dot:.89}
.route-steps li:nth-child(9){--dot:1}
/* Карта — отдельный блок ПОД карточкой (как в Figma), не внутри неё */
.route-map{margin-top:clamp(16px,3vw,40px);border-radius:var(--r-lg);overflow:hidden;border:1px solid rgba(20,48,60,.08);background:var(--ice-2)}
.route-map iframe{display:block;width:100%;height:460px;border:0}
@media (max-width:767px){
  /* Мобилка 1:1 по Figma 2119:4444: карточка 343/паддинг 16/гэп 16; заголовок 18 (2 строки у
     маршрута — 268px под иконку 32); иконки 24 (маршрут 32); кнопки-пилюли 32–34; карта 160 */
  .hc-bg-desk{display:none}
  /* Figma-мобилка: узор стоит НЕ по центру картинки, а сдвинут влево (x=-392@375 = -104.5vw) —
     так его КОЛЬЦО-мишень встаёт по центру экрана (в рисунке кольцо правее середины). Низ — с
     небольшим выпуском (у SVG прозрачное поле). */
  .hc-bg-mob{display:block;left:-104.5vw;bottom:-6px;width:220.8vw;max-width:none;height:auto}
  #hero.hero-contacts{min-height:100svh}  /* на всю высоту (как спец): без белого куска секции под героем */
  .hero-contacts .hero-in-page{margin-top:26px}  /* контент чуть ниже */
  /* глоу — под графикой, по центру (Figma: 471×420 на y=398 из 646) */
  .hero-contacts.hero-blue::before{left:50%;right:auto;top:61.6%;transform:translateX(-50%);width:125.6vw;height:112vw}
  /* сабтайтл узкий как в макете (245px → 2 строки, «перенос другой») */
  .hero-contacts .hero-page-sub{max-width:245px;margin-inline:auto}
  /* тайтл крупнее — строка «Контакты и» ≈ ширина кнопки (замерено: 14.2vw ≈ 259px против кнопки 264px) */
  .hero-contacts .hero-h1-page{font-size:clamp(46px,14.2vw,54px)}
  .contacts-row{grid-template-columns:1fr;gap:16px;margin-bottom:16px}
  .contact-card,.route-card{padding:16px}
  .cc-head{margin-bottom:var(--sp-5)}
  .route-card .cc-head{margin-bottom:16px}
  .cc-head h2{font-size:18px}
  .cc-icon{width:24px;height:24px}
  .cc-icon-route{width:32px;height:32px}
  .cc-links{gap:8px}
  .cc-pill{padding:9px 12px 7px;font-size:13px;gap:7px}
  .cc-map-ic{height:16px}
  .cc-address{font-size:13px}
  .cc-note{font-size:13px}
  .route-metro{font-size:13px;margin-bottom:var(--sp-5)}
  .metro-dot{width:12px;height:12px}
  .route-steps li{padding:2px 0 12px 48px;font-size:13px;line-height:1.35;background-position:17.5px 38px}
  .route-map{margin-top:16px}
  .route-map iframe{height:160px}
}

/* ═══════════════ ПОДАРОЧНЫЕ СЕРТИФИКАТЫ (gift-certificates.html) ═══════════════ */
/* Блоки 4/5 переиспользуют approved-компоненты: блок «Специально для вас» — .event-cards/
   .event-photo с about-leisure; блок цен — .price-card + .mkk-alert с реализованных страниц.
   Ниже — только точечное, всё на токенах (--sp-*/--text-*), без сырых значений. */

/* Блок «Почему именно мы?» — 6 пастельных карточек 3×2 (Figma 2197:14398).
   Точные числа Figma на шкале: паддинг --sp-6(32), гэп --sp-6(32), эмодзи 64 + до текста --sp-7(48).
   Заголовок→сетка = --head-gap приходит от базового .sec-head-c (см. выше) — патч не нужен. */
.gc-why-h2{color:var(--cyan-2)}
.gc-why-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:var(--sp-6)}
.gc-why-card{padding:var(--sp-6);border-radius:var(--radius-xl);background:var(--card-bg,var(--ice-2));transition:transform .3s var(--ease-out),box-shadow .3s var(--ease-out)}
.gc-why-card:hover{transform:translateY(-6px);box-shadow:0 20px 40px -22px rgba(20,48,60,.20)}
.gc-why-ic{display:block;width:64px;height:64px;margin-bottom:var(--sp-7);transition:transform .35s var(--ease-out)}
.gc-why-card:hover .gc-why-ic{transform:scale(1.1) rotate(-6deg)}
@media (prefers-reduced-motion:reduce){.gc-why-card:hover{transform:none}.gc-why-card:hover .gc-why-ic{transform:none}}
.gc-why-card h3{margin:0 0 var(--sp-2);color:var(--ink-cold);font-size:var(--text-h3);font-weight:var(--fw-bold);line-height:var(--lh-snug)}
.gc-why-card p{margin:0;color:var(--ink-mut);font-size:var(--text-sm);line-height:var(--lh-snug)}

/* Блок «Специально для вас» — лёгкий ice-1 фон секции (как about-leisure), без панели-прямоугольника.
   Иллюстрированные иконки из Figma показываем 60px без тинт-бокса (в Figma — прямо на карточке). */
.gc-special{background:var(--ice-1)}
.gc-special .ec-ic-box{width:60px;height:60px;padding:0;background:transparent}
.gc-special .ec-ic{width:60px;height:60px}

/* Блок цен: 2 белых .price-card (~432px) по центру; заголовок в 2 строки; дисклеймер = ширине карточек.
   .gc-price-wrap = ширина двух карточек+гэп → и ряд, и alert внутри неё центрированы одинаково. */
/* ═══ ШИРИНА БЛОКА ЦЕН = ШИРИНЕ РЯДА КАРТОЧЕК (правило Романа) ═══
   Обёртка .price-block считает ширину ИЗ ЧИСЛА КАРТОЧЕК, поэтому шапка и .mkk-alert садятся
   ровно по краям карточек сами — без хардкодов и без ручных <br> в заголовке.
   3 карточки → 3×432 + 2×32 = 1360 = внутренняя ширина .container-mkk, то есть на блоках
   с тремя карточками правило вырождается в no-op и ничего не меняет.
   2 карточки → 2×432 + 32 = 896.
   Счётчик сформулирован как «НЕ БОЛЕЕ N» (:not(:has(...:nth-child(N)))), а не «ровно N»:
   под одной шапкой может лежать несколько таб-панелей, и «ровно N» ложно срабатывало бы
   на любой короткой панели. */
.price-block{
  --card-w:432px;               /* де-факто константа блока цен */
  --card-gap:var(--sp-6);       /* 32 — гаттер рядов карточек */
  --cols:3;                     /* дефолт = ширина канваса */
  max-width:calc(var(--cols) * var(--card-w) + (var(--cols) - 1) * var(--card-gap));
  margin-inline:auto}
.price-block:not(:has(.price-row > :nth-child(3))){--cols:2}
.price-block:not(:has(.price-row > :nth-child(2))){--cols:1}
/* Правило Романа — про ШИРИНУ, не про переносы: где именно ломается строка, решает автор
   текста (утверждённая вёрстка сертификатов — 2 строки через <br>). balance выравнивает
   длины строк, если переноса нет, и не мешает авторскому <br>, если он есть. */
.price-block .prices-heading h2{text-wrap:balance}
.gc-price-row{display:flex;gap:var(--sp-6);margin-bottom:var(--sp-6)}
.gc-price-row .price-card{flex:1;min-width:0}

@media (max-width:767px){
  .gc-why-grid{grid-template-columns:1fr;gap:var(--sp-4)}
  .gc-why-ic{margin-bottom:var(--sp-4)}
  .gc-price-row{flex-direction:column}
}

/* ═══════════ ХЕРО GIFT: иллюстрация icon-simpleplay вместо percent.svg ═══════════
   Модификатор .hero-gift на секции — ИЗОЛЯЦИЯ от specials.html. Классы .hs-bg/.hs-bg-mob и
   правила .hero-specials шарятся со спецпредложениями, править их нельзя; поэтому у арта
   собственный класс, а всё новое висит на .hero-gift.

   Отличие от percent.svg принципиальное: там ВЕСЬ герой был одним файлом (фон+конфетти+свечение,
   фулл-блид cover). Здесь SVG — только фигуры, поэтому он не cover, а позиционированный элемент
   со своим аспектом (приём .hc-bg-desk на контактах и .bs-pct, mkk.css:577), а свечение снова
   рисует CSS.

   Геометрия от Figma 2172:17158 (херо 1440×498): арт 2172:17352 x=937 y=78 443×443 → правый край
   1380 (60 до края фрейма), низ 521 → свисает на 23 за нижнюю границу. Высота нашего херо ПЛАВАЕТ
   (478 при заголовке в 1 строку, 518 при двух), поэтому крепим ПРОПОРЦИЯМИ САМОЙ Figma к боксу,
   а не пикселями: высота 443/498 = 89%, свес 23/498 = 4.6%. Тогда при любой высоте блока арт
   садится в те же доли, что в макете (проверено: при 518 → 461 высоты, верх 15.6% — в Figma 15.7%).
   Правое поле 60 кладём на шкалу → --sp-8 (64). max-width — страховка,
   чтобы на ультрашироких арт не раздувался и не наезжал на текст.
   z-index 1: выше .hero-blue::before (auto) и ниже .hero-in (3). Явно, а не молча по DOM-порядку —
   переживёт перестановку строк в разметке. pointer-events:none — иначе арт перекроет CTA. */
.hero-gift .gc-hero-art{position:absolute;z-index:1;right:var(--sp-8);bottom:-4.6%;
  height:89%;width:auto;max-width:34%;pointer-events:none;
  /* Тень из Figma (нода 2172:17352): drop-shadow 0 -7px 4.9px, направлена ВВЕРХ.
     Через CSS, а НЕ запекая в SVG: там она резалась клипом и давала грязный контур.
     В CSS фильтр идёт по альфе контура, резать нечем.
     Интенсивность ВДВОЕ ниже макетной (.25 → .125) — по фидбэку Романа: на живом градиенте
     фигмовские 25% читались тяжелее, чем в макете. Геометрия тени не тронута. */
  filter:drop-shadow(0 -7px 4.9px rgba(0,0,0,.125))}

/* ── Конфетти: три слоя одного спрайта под разными углами ─────────────────────
   Figma отдаёт их как один растр 695.903×381.16, трижды повёрнутый: 108.79° / 116.94° / 72.91°
   (ноды 2172:17159 / 17196 / 17233). Отсюда и три файла — каждый слой автономен, подменяется
   отдельно, ничего не пересчитывая.
   Позиционируем по ЦЕНТРУ (как в Figma — там это translate(-50%,-50%) от точки), долями от бокса:
   ширина 695.903/1440 = 48.3%, центры — left/top в % от херо. height:auto, чтобы поворот не
   тянул спрайт: масштаб задаёт одна ось.
   z-index -1 — конфетти ПОД свечением, как в порядке слоёв Figma (Confetti → Rectangle 22022 →
   Title → icon). Секция стоит на isolation:isolate, поэтому -1 не проваливается под градиент. */
.hero-gift .gc-cf{position:absolute;z-index:-1;width:48.3%;height:auto;
  transform:translate(-50%,-50%) rotate(var(--cf-rot));pointer-events:none}
.hero-gift .gc-cf-1{--cf-rot:108.79deg;left:54.41%;top:97.15%}
.hero-gift .gc-cf-2{--cf-rot:116.94deg;left:101.22%;top:24.41%}
.hero-gift .gc-cf-3{--cf-rot:72.91deg;left:83.15%;top:41.08%}

@media (max-width:767px){
  /* Figma моб 2204:14396 (375×608): арт 2204:14559 x=49 y=324 265×265 → 70.6% ширины,
     центр 181.5 при центре кадра 187.5 — смещение 6px, оптически по центру → центрируем ровно.
     Нижний зазор 19 кладём на шкалу → --sp-5 (24); наш херо 100svh выше 608, зазор и должен
     дышать чуть больше. */
  .hero-gift .gc-hero-art{right:auto;left:50%;transform:translateX(-50%);bottom:var(--sp-5);
    width:70.6%;height:auto;max-width:none}
  /* Конфетти на мобилке — ТЕ ЖЕ три слоя под теми же углами (Figma 2204:14398/14435/14472 несут
     ровно те же 108.79/116.94/72.91), только спрайт мельче и центры другие. Отношение к десктопу
     ровно 0.5687 по всем трём — то есть это одна композиция, отмасштабированная.
     Ширина 695.903×0.5687 = 395.8 при кадре 375 → 105.5%. Центры — в % от мобильного херо. */
  .hero-gift .gc-cf{width:105.5%}
  .hero-gift .gc-cf-1{left:9.96%;top:88.74%}
  .hero-gift .gc-cf-2{left:112.19%;top:54.86%}
  .hero-gift .gc-cf-3{left:72.74%;top:62.62%}
  /* Возврат свечения. Правило .hero-specials.hero-blue::before гасит ::before на мобилке, потому
     что глоу был запечён внутри percentmob.svg. В hero-players.svg его нет — значит для gift
     свечение снова нужно CSS-ное. Специфичность (1,2,0) против (0,2,0) — выигрывает независимо
     от порядка. Кадр от Figma 2204:14509 (471×420 при 375×608): 125.6% × 69.1%, центр по x
     совпадает с центром экрана, низ 790 при 608 → свес −30%. */
  #hero.hero-gift.hero-blue::before{display:block;right:auto;left:50%;transform:translateX(-50%);
    top:auto;bottom:-30%;width:125.6%;height:69.1%}
}

/* ═══ Мобильные радиусы карточек — НАМЕРЕННО В САМОМ КОНЦЕ ФАЙЛА: базовые правила страничных
   блоков (contact-card, offer-card и т.д.) объявлены позже раннего списка в about-блоке и
   перебивали его каскадом (та же специфичность — выигрывает последний). Единая точка истины. */
@media (max-width:767px){
  .ab-stat,.ag-card,.ab-image img,.event-photo,.event-card,.offer-card,.offer-modal-card,.contact-card,.route-card,.route-map,.mlb-img{border-radius:16px}
}

/* ═══════════════════════════════════════════════════════════════════════════════════════
   ПЛАНШЕТНЫЙ СЛОЙ 768–991.98 — по макетам Figma-744 (фреймы 2113:3339, 2115:17099,
   2127:7968, 2197:13739; страница Design 0:1).

   ЗАЧЕМ ОН ВООБЩЕ НУЖЕН. До этого слоя в полосе не было почти ничего: 73% «планшетного» CSS
   приходилось на бургер-меню, а на весь контент — 17 правил. Мобильная компактификация сидит
   на 767.98 и в полосу не попадает, Bootstrap col-lg-* ниже 992 даёт 1-в-ряд. Итог — десктопный
   CSS в мобильной ширине: карточка цен, нарисованная под 432, растягивалась до 779.

   ГРАНИЦА 768, а не 744 (как во фреймах Figma) — сознательно: мобильный слой ≤767.98 уже одобрен,
   двигать его границу значит трогать ~192 правила. Полоса 744–767 остаётся мобильной — это
   просто широкая мобилка.

   Слой стоит В САМОМ КОНЦЕ ФАЙЛА намеренно: он перекрывает десктопные правила, объявленные
   выше, и при равной специфичности должен выигрывать порядком.
   ═══════════════════════════════════════════════════════════════════════════════════════ */
@media (min-width:768px) and (max-width:991.98px){
  /* ── Ритм и типографика ──
     Figma-744: паддинг секции 60/40, H2 24/700, лид 14/400/1.3, шапка→контент 32.
     Числа кладём НА 4pt-шкалу: 60 → --sp-8 (64), 32 → --sp-6. Симметрию паддинга сохраняем
     (см. §5 правил) — асимметрия 60/40 из макета не стоит слома ритма секций. */
  :root{--sec-pad:var(--sp-8);--head-gap:var(--sp-6)}
  h2{font-size:24px}
  .lead-txt{font-size:14px;font-weight:400;line-height:1.3;letter-spacing:0;text-wrap:pretty}

  /* ── Зазоры сеток: в макете 16 ВЕЗДЕ (и колонки, и ряды). У нас гаттер 40/32 — от десктопа. ── */
  .row{--bs-gutter-x:var(--sp-4);--bs-gutter-y:var(--sp-4)}
  .price-cards{--bs-gutter-x:var(--sp-4);--bs-gutter-y:var(--sp-4)}

  /* ── Шапка секции остаётся В РЯД (Figma: заголовок 300 + лид 360 при контейнере 704).
     Ниже 992 col-lg-* теряет ширину и падает в стек — возвращаем ряд.
     Пропорции из макета: 300/704 = 42.6%, 360/704 = 51%. Обрати внимание: на планшете лид
     ШИРЕ заголовка, то есть относительно десктопа (7/5) пропорция инвертирована. */
  .sec-head-split > [class*="col-lg-7"]{flex:0 0 auto;width:43%}
  .sec-head-split > [class*="col-lg-5"]{flex:0 0 auto;width:51%}
  .sec-head-split{justify-content:space-between}

  /* ── Карточки цен: 3 в ряд (Figma 224×296), а не 1 на всю ширину.
     Это и был главный источник «свалки»: .col-lg-4 объявлен внутри @media(min-width:992px),
     ниже действует только .row>*{width:100%} → карточка 779px вместо 432. ── */
  .price-cards > [class*="col-lg-4"]{flex:0 0 auto;width:33.3333%}

  /* ── «Почему именно мы»: 3 колонки → 2 (Figma: 2×3, карточка 344×161, эмодзи 40) ── */
  .gc-why-grid{grid-template-columns:repeat(2,1fr);gap:var(--sp-4)}
  .gc-why-ic{width:40px;height:40px;margin-bottom:var(--sp-4)}

  /* ── Контакты: в макете 744 двух колонок НЕТ, всё в стек на всю ширину, карта 704×270 ── */
  .contacts-row{grid-template-columns:1fr;gap:var(--sp-4)}
  .route-map,.route-map iframe{height:270px}

  /* ── Блок цен: правило §2.1 (шапка и дисклеймер по ширине карточек) — ТОЛЬКО ДЕСКТОПНОЕ.
     В макете 744 шапка и дисклеймер идут на всю ширину 704, а вот сами КАРТОЧКИ остаются
     группой 616 по центру (300 + 16 + 300). Решение Романа: на планшете следуем макету.
     Поэтому снимаем ограничение с блока (шапка и alert растекаются на всю ширину), но ряд
     карточек держим в 616 — иначе карточки раздувались до 341 вместо макетных 300. ── */
  /* ШАПКА на всю ширину, а РЯД КАРТОЧЕК и ДИСКЛЕЙМЕР — по одной ширине (правка Романа:
     «если две карточки, дисклеймер ровнять по ширине контейнера карточек»).
     Ширину держит ОДНА переменная, а не два независимых max-width: так ряд и алерт не могут
     разъехаться при правке. 616 = 2×300 + 16 из макета 744. */
  .price-block{max-width:none;--cards-w:616px}
  .price-block .gc-price-row,
  .price-block .mkk-alert{max-width:var(--cards-w);margin-inline:auto}

  /* ── rAF-канвас «морозной пыли» скрыт только ≤767.98 — на планшетах молотил впустую ── */
  #frostDust{display:none}

  /* ── БАННЕР СПЕЦПРЕДЛОЖЕНИЙ (Figma-744: баннер 704×162, ноды 2191:14559 / 14560 / 14561) ──
     Было: заголовок в ОДНУ строку доезжал до x=625, а глиф «%» начинался на x=606 — наложение
     19px, текст читался поверх процента (замер на 834).
     В макете заголовок в ДВЕ строки и до глифа не достаёт: текст стоит на x=40 (в координатах
     блока), глиф — на x=464, то есть на текст отведено 424 из 704 = 60%. Ограничиваем ширину
     этой долей — перенос получается сам, без ручного <br>, и держится при смене текста.
     Кегль 24 (высота ноды 62 на 2 строки при lh 1.3 → 23.8).
     Паддинг и зазор макета 20/24 кладём на шкалу → --sp-5. */
  .banner-specials{padding:var(--sp-5);gap:var(--sp-5)}
  /* Ширина текста — ФИКСИРОВАННЫЕ 424 (ровно поле от текста до глифа в макете), а не доля.
     С долей 60% на 991 контейнер вырастает, строка целиком влезает обратно в одну, баннер
     сплющивается до 6.16 при макетных 4.35. Фикс. 424 держит две строки во всей полосе. */
  .banner-specials h3{font-size:24px;max-width:424px}
  /* Кнопка 36 (Figma 245×36). Наша 51 — десктопная, именно она раздувала баннер до 181
     при макетных 162. Тач-цель 36 ниже гайдлайновых 44, но так в макете и так же сделаны
     кнопки хедера на планшете. */
  .banner-specials .btn-mkk{height:36px;padding-inline:var(--sp-5);font-size:14px}
  /* Глиф — ЦЕЛИКОМ ВНУТРИ баннера. В макете 744 он формально 255×255 при баннере 162, то есть
     вылезает и обрезается; я так и сделал — Роман забраковал: «раз мы везде его разместили
     внутри, то и тут внутри надо». Единообразие с десктопом и мобилкой важнее буквы макета.
     Высоту берём от баннера, ширину ограничиваем, чтобы не наезжал на текст. */
  .bs-pct{height:86%;max-width:32%;right:3.5%}

  /* ── КЛУБ-КАРТОЧКИ «Самый большой керлинг-клуб» (Figma-744: карточка 224×234) ──
     Мобильная компактификация (.club-card height 264, тайтл 18, текст 14) сидит на 767.98
     и в полосу не попадала — карточки шли с ДЕСКТОПНОЙ начинкой в планшетной ширине:
     тайтл 20 вместо 16, описание 15 вместо 12, иконка 34×32 вместо 28×26, паддинг панели
     16 вместо 12. Белая панель съедала 82% высоты карточки, фото почти не было видно.
     Аспект: у нас был 1.080 (от десктопных 432/400), в макете 224/234 = 0.957 — карточка
     ВЫШЕ, чем шире, и панель занимает низ, а не всю плашку. */
  .club-card{aspect-ratio:224/234}
  .club-card-body{padding:var(--sp-3);border-radius:14px}
  .club-card-title{margin-bottom:var(--sp-2)}
  .club-card-title h3{font-size:16px;line-height:1.1}
  .club-card-body p{font-size:12px;line-height:1.3}
  .club-card-ic{width:28px;height:26px}
  /* Зазор карточки→кнопки: было 48, в макете 24. Правило Романа: отступ до кнопок не может быть
     БОЛЬШЕ, чем отступ заголовок→контент (там 32). Иначе кнопки читаются как отдельный блок,
     а не как продолжение секции. */
  .club-actions{margin-top:var(--sp-5)}

  /* ── КАРТОЧКИ ЦЕН: начинка под ширину 224 (Figma-744, карточка 224×296, контент 192) ──
     Сетку я в полосу вывел (3 в ряд), а НАЧИНКУ проглядел: она осталась десктопной, рассчитанной
     на карточку 432. В карточке 227 всё рвалось на строки — бейджи «−30%» и «Февраль» вставали
     столбиком, цена ломалась на три строки («15 000₽» / «13 000₽» / «/ час»), пункты списка
     и текст кнопки — по две строки.
     Числа Figma: паддинг 16, бейдж h28, тайтл 23 по высоте, цена 26 (старая 21), список шаг 24,
     кнопка 192×40. Плюс nowrap на бейджах и цене — эти строки не должны переноситься в принципе.
     СЕЛЕКТОРЫ через .prices-ice: базовые правила блока объявлены как «.prices-ice .price-card»
     (0,2,0) и голый «.price-card» (0,1,0) их не перебивает — на этом я уже споткнулся, паддинг
     оставался 24 вместо 16. */
  .prices-ice .price-card{padding:var(--sp-4);gap:var(--sp-5)}
  .prices-ice .price-card-top{gap:var(--sp-3)}
  .prices-ice .price-card-badges{flex-wrap:nowrap;gap:var(--sp-2)}
  .prices-ice .price-badge{padding:4px var(--sp-3);font-size:12px;white-space:nowrap}
  .prices-ice .price-card h3{font-size:11px}
  .prices-ice .price-card-price{gap:var(--sp-2);white-space:nowrap}
  .prices-ice .price-old{font-size:16px}
  .prices-ice .price-now b{font-size:22px}
  .prices-ice .price-now i{font-size:11px}
  .prices-ice .price-card-list{gap:var(--sp-3)}
  .prices-ice .price-card-list li{font-size:12px;gap:var(--sp-1)}
  .prices-ice .price-card-list svg{width:14px;height:14px}
  /* Кнопка: текст «Забронировать дорожку» ≈150px при 13px. В карточке 227 (самая узкая точка
     полосы) контент 195, при паддинге 16+16 остаётся 163 — впритык. Кегль 12 и паддинг --sp-3
     дают 139 текста в 171 доступных: одна строка с запасом. */
  .prices-ice .price-card-cta{padding:var(--sp-3);font-size:12px}

  /* ── ЛЕДОВАЯ ДОРОЖКА: пересчёт под ширину полосы ──
     Высота оставалась ДЕСКТОПНОЙ (164) при сузившейся ширине — отсюда диспропорция: на 834
     полоса читалась как 834/164 = 5.1 против десктопных 1440/164 = 8.8, и камень с домом
     выглядели раздутыми. Мобильный пересчёт (78px и свой набор чисел) сидит на 767px и в полосу
     не попадал.
     Берём 100px: на середине полосы (880) это даёт 8.8 — ровно десктопную пропорцию.
     Разметка .lm-* — точные доли из Way.svg (viewBox 1835×242), поэтому ВСЕ её числа
     масштабируем тем же k = 100/164 = 0.61, иначе сегменты разъедутся.
     Камень отдельно трогать не нужно: stone.js берёт масштаб от высоты полосы
     (js/stone.js:299 — scale от r.height), то есть уменьшится сам. */
  .ice-lane{height:100px}
  .lm-back{width:7px}
  .lm-hog{width:4px}
  .lm-house{width:82px;height:82px}
  .lm-tee-t,.lm-tee-b{height:10px}
  .lm-c-mid{left:min(245px,44%);right:min(245px,44%)}
  [data-dir="l"] .lm-house{left:84px}
  [data-dir="l"] .lm-tee{left:84px}
  [data-dir="l"] .lm-hog-a{left:165px}
  [data-dir="l"] .lm-hog-b{right:165px}
  [data-dir="l"] .lm-c-fin{left:0;right:calc(100% - 44px)}
  [data-dir="l"] .lm-c-near{left:124px;right:calc(100% - 215px)}
  [data-dir="l"] .lm-c-far{right:124px;left:calc(100% - 215px)}
  [data-dir="l"] .lm-c-fe{right:0;left:calc(100% - 95px)}
  [data-dir="r"] .lm-house{right:84px}
  [data-dir="r"] .lm-tee{right:84px}
  [data-dir="r"] .lm-hog-a{right:165px}
  [data-dir="r"] .lm-hog-b{left:165px}
  [data-dir="r"] .lm-c-fin{right:0;left:calc(100% - 44px)}
  [data-dir="r"] .lm-c-near{right:124px;left:calc(100% - 215px)}
  [data-dir="r"] .lm-c-far{left:124px;right:calc(100% - 215px)}
  [data-dir="r"] .lm-c-fe{left:0;right:calc(100% - 95px)}
}

/* ═══ ПЛАНШЕТНОЕ БУРГЕР-МЕНЮ (Figma-744, нода «Меню открыто» 2127:8128) ═══
   Меню на 768–991 показывалось в МОБИЛЬНОМ формате: всё растянуто на всю ширину — гигантская
   CTA-кнопка во весь экран, бейджи контактов рядами по всей ширине, копирайт по центру.
   В макете планшета наоборот: типографика КРУПНЕЕ мобильной (пункты 30 против 24, подменю 18
   против 16, эмодзи 32 против 24), а CTA и бейджи — КОМПАКТНЫЕ и прижаты влево.
   То есть планшетное меню лево-центрично, а мобильное — низ по центру. Отсюда и было
   ощущение «плохо»: мы брали мобильные пропорции и растягивали их на вдвое более широкий экран. */
@media (min-width:768px) and (max-width:991.98px){
  /* Поля панели 20 (в макете padding 20, контент 704 из 744) */
  #site-nav .navbar-collapse{padding-inline:var(--sp-5)}

  /* Пункты верхнего уровня: 30/500, шаг 32 (шаг у нас уже --sp-6 = 32) */
  .nav-link{font-size:30px}

  /* Подменю: эмодзи 32, текст 18, зазор эмодзи↔текст 16, шаг между пунктами 16 */
  .has-dropdown .nav-dropdown{gap:var(--sp-4)}
  .nav-drop-item{font-size:18px;gap:var(--sp-4)}
  .ndi-ic{width:32px;font-size:32px}
  .ndi-ic img{max-width:100%;height:auto}

  /* CTA: в макете 282 по контенту и ПО ЛЕВОМУ КРАЮ, а не во всю ширину.
     Отступ от последнего пункта в макете 56 — кладём на шкалу как --sp-7 (48). */
  .nav-cta{align-self:flex-start;width:auto;margin-top:var(--sp-7)}

  /* Бейджи контактов: ВСЕ ТРИ В ОДИН РЯД по левому краю, h36, кегль 12, зазор 12.
     display:contents на .nmc-row поднимает её пилюли в один флекс-ряд с почтой — иначе
     разметка (ряд из двух + почта отдельно) не даёт собрать тройку без правки HTML. */
  .nav-mobile-contacts{align-items:flex-start}
  .nmc-buttons{flex-direction:row;flex-wrap:wrap;align-items:center;gap:var(--sp-3);width:auto}
  .nmc-row{display:contents}
  .nmc-pill{flex:none;width:auto;height:36px;padding-inline:var(--sp-5);font-size:12px}
  .nmc-pill-wide{width:auto;align-self:auto}
  /* Копирайт в макете 14/400 по левому краю (на мобилке 12 по центру) */
  .nav-mobile-contacts .nmc-copy{text-align:left;font-size:14px}
}

/* ═══ ПЛАНШЕТ: скругления карточек и дисклеймер ═══ (фидбэк Романа)
   1) СКРУГЛЕНИЯ. Взяв для бенто мобильный формат (паддинг 32 → 16), я оставил ДЕСКТОПНЫЙ радиус
   --r-lg = 28. На таком радиусе при паддинге 16 текст подходит к углу вплотную — кривая съедает
   как раз тот воздух, который отступ должен был дать.
   Из двух вариантов (уменьшить радиус либо добрать паддинг) беру радиус, потому что решение уже
   принято Романом для мобилки — «единое скругление карточек 16, бенто и цены были 24/28 → к 16» —
   и подтверждается макетом: у клуб-карточки в Figma-744 радиус 16. Правило консистентности
   выполняется: одна величина на весь набор карточек, тот же набор, что и на мобилке.
   2) ДИСКЛЕЙМЕР. Карточки цен ужались, а дисклеймер остался с десктопным кеглем 16 и на их фоне
   читался как главный объект блока. Кегль 11 — по Роману. */
@media (min-width:768px) and (max-width:991.98px){
  #events .eb-tile{border-radius:16px}
  #prices .price-card,#prices .price-card-teal,#prices .price-card-purple,#prices .price-card-blue-purple{border-radius:16px}
  .prices-ice .price-card{border-radius:16px}
  .ab-stat,.ag-card,.ab-image img,.event-photo,.event-card,.offer-card,.offer-modal-card,
  .contact-card,.route-card,.route-map,.mlb-img{border-radius:16px}
  .mkk-alert{border-radius:16px}
  .mkk-alert-txt p{font-size:11px}
}

/* ═══ ПЛАНШЕТ: шеврон вплотную к тексту пункта меню ═══ (фидбэк Романа)
   Было justify-content:space-between (наследство мобильной раскладки) — шеврон улетал к правому
   краю панели и с текстом визуально не связывался: на 744 между ними получалось больше 400px.
   В макете шеврон стоит сразу за текстом с зазором 6 (Figma-744, нода 2191:16948). 6 кладём
   на шкалу как --sp-2 (8). Ширина ссылки остаётся 100% — тач-зона на всю строку не сужается. */
@media (min-width:768px) and (max-width:991.98px){
  .nav-link{justify-content:flex-start;gap:var(--sp-2)}
}

/* ═══ ПЛАНШЕТ: страница «О клубе» (Figma-744, фрейм 2127:7424) ═══
   Три правки по фидбэку Романа. */
@media (min-width:768px) and (max-width:991.98px){

  /* 1. ХЕРО — ЗАГОЛОВОК КРУПНЕЕ.
     Было 55px (clamp 6.6vw). В макете 48 — но там херо всего 382 высотой, а у нас 100svh ≈ 1000.
     То есть по ШИРИНЕ мы в макет попадали (48 × 834/744 = 54), а по высоте кадр втрое выше,
     и заголовок в нём терялся. Поэтому равняем не на число из макета, а на пропорцию нашего херо:
     8.6vw даёт 66 на 768, 72 на 834, 85 на 991 — между планшетным 48 и десктопным 92.
     Проверено на nowrap: «КЕРЛИНГ-КЛУБ» при 85px = 647px в контейнере 951 — влезает. */
  .hero-h1-about{font-size:clamp(56px,8.6vw,84px)}

  /* 2. «НЕ ТОЛЬКО КЕРЛИНГ, НО И ОТДЫХ» — карточки СЛЕВА, фото СПРАВА (было в стопку).
     Ниже 992 col-lg-* теряет ширину и колонки падают друг под друга: карточки шли 382×184,
     а фото уезжало вниз на всю ширину 779×280. В макете это ряд: карточки 404 + фото 284, gap 16.
     Доли от контента 704: 404 → 57.4%, 284 → 40.3%, зазор 16 → 2.3%. Гаттер ряда обнуляю,
     зазор даёт gap — иначе бутстраповские паддинги колонок съедают проценты. */
  .events-row{--bs-gutter-x:0;--bs-gutter-y:0;gap:var(--sp-4);flex-wrap:nowrap}
  .events-row > [class*="col-lg-7"]{flex:0 0 auto;width:57.4%}
  .events-row > [class*="col-lg-5"]{flex:0 0 auto;width:40.3%}
  /* Карточки 2×2 по 196×116: зазор и паддинг 12, плашка иконки 44, эмодзи 24, текст 14 */
  .event-cards{gap:var(--sp-3)}
  .event-card{padding:var(--sp-3);gap:var(--sp-3);border-radius:16px}
  .ec-ic-box{width:44px;height:44px;padding:10px;border-radius:8px}
  .ec-ic{width:24px;height:24px}
  /* Текст карточки — это h3, а не span/p (первый заход промахнулся селектором и текст остался
     20px в ТРИ строки, из-за чего карточка была 158 вместо макетных 116). */
  .event-card h3,.event-card span,.event-card p{font-size:14px;line-height:1.3;font-weight:400}
  /* Фото: высоту тянет height:100% от ряда, поэтому НИКАКОГО aspect-ratio — с ним ширина
     считалась ОТ высоты (354 × 284/244 = 412) и фото вылезало из своей колонки на 98px,
     давая overflow-x 76 на всю страницу. Ширину держит колонка, высоту — ряд.
     В полосе также висел min-height:280 от правила на 991.98 — снимаем. */
  .event-photo{min-height:0;width:100%;border-radius:16px}
  .event-photo-thumbs{bottom:var(--sp-3);width:calc(100% - 32px);gap:var(--sp-1);padding:var(--sp-1)}
  /* Превью: высота у .ep-thumb прибита к 78px под ДЕСКТОПНУЮ ленту. Когда лента сузилась
     до 282, ширина превью упала до 66, а высота осталась 78 — кадры встали вертикально
     (аспект 0.84 вместо макетных 82.67/54 = 1.53) и фото в них резалось по бокам.
     Отдаём высоту аспекту: ширину диктует лента, высота считается от неё. */
  .ep-thumb{height:auto;aspect-ratio:82.67/54}

  /* 3. ГАЛЕРЕЯ — 4 фото в ряд и кнопка ОБРАТНО В ШАПКУ.
     Правило, уносящее кнопку под сетку и режущее сетку до 2 колонок, стоит на max-width:991.98
     (mkk.css:1655) — то есть оно же работало и на планшете. В макете шапка одним рядом:
     заголовок 300 слева + кнопка 214×48 справа, сетка 4×2 по 164×116, зазор 16, между рядами 24.
     (164 получается само: (704 − 3×16) / 4.) */
  .about-gallery .container-mkk{display:block}
  .about-gallery .sec-head-split{display:flex}
  .about-gallery .sec-head-split>div:first-child{margin-bottom:0}
  .about-gallery-cta{margin-top:0;justify-content:flex-end}
  .ag-grid{grid-template-columns:repeat(4,1fr);column-gap:var(--sp-4);row-gap:var(--sp-5)}
}

/* ═══ ПЛАНШЕТ: херо страницы «Фотки» (Figma-744, фрейм 2113:15750, херо 2191:18758) ═══
   Перекос, который заметил Роман: у нас было 105 сверху (хедер→заголовок) против 262 снизу
   (кнопка→низ). В макете на планшете отступы СИММЕТРИЧНЫ — 64/64 при высоте херо 362.
   ВАЖНО: на десктопе и мобилке перекос — НЕ баг, а замысел (1440 = 50:249, 375 = 124:316:
   текстовый блок намеренно прижат к верхней трети, снизу остаётся «окно» на фото).
   Поэтому правлю ТОЛЬКО полосу.
   Высота: 362 при 744 → 48.6vw, что даёт 373 / 405 / 481 на 768 / 834 / 991.
   Выравнивание переключаю с center на flex-start: при центрировании отступы задаются не
   паддингами, а свободным местом, и управлять ими нельзя. Верх = промо + нав + 64 − 10:
   десятка — та самая переоценка низа хедера (формула считает 103, реальный низ пилюли 93). */
@media (min-width:768px) and (max-width:991.98px){
  /* min-height СНЯТА намеренно (было clamp(360,48.6vw,480) под макетные 362).
     С жёсткой высотой любое изменение контента уходит в нижний зазор: как только подзаголовок
     подъехал к кнопке на 32 вместо 48, контент стал на 16 короче и низ вырос 69 → 85.
     Без min-height высоту держат сами паддинги — верх и низ остаются 64/64 при любом тексте.
     Это тот же принцип hug, что и в .hero-stack (§4.1 правил). */
  /* .hero-birthday идёт этим же набором: это второй фото-херо, дефект у него был тот же и хуже —
     десктопное align-items:center (min-width:768) доставало до планшета, а планшет тут же снимал
     min-height и обнулял верхний паддинг. Контент центрировался в коробке 265px, и заголовок
     уезжал ПОД хедер: замер давал зазор нав→H1 = −133 (перекрытие), при формально «нормальных»
     габаритах секции. Ровно тот случай, ради которого написан §12.1 — мерить контент, а не боксы. */
  #hero.hero-gallery,#hero.hero-birthday{min-height:0;align-items:flex-start}
  .hero-gallery .hero-in,.hero-birthday .hero-in{padding-top:calc(var(--promo-h) + var(--nav-h) + var(--sp-8) - 10px)}
  .hero-gallery .hero-in-page,.hero-birthday .hero-in-page{padding-bottom:var(--sp-8)}
  /* Подзаголовок → кнопка: 32 (Figma-744). Базовый margin — clamp(32,6vh,48), и на планшетной
     высоте вьюпорта 6vh упирается в потолок 48. Фиксируем токеном --sp-6. */
  .hero-gallery .hero-page-sub,.hero-birthday .hero-page-sub{margin-bottom:var(--sp-6)}
}

/* ═══ ПЛАНШЕТ: херо типа 3 (.hero-stack) — высота hug и верхний отступ 64 ═══
   Роман про контакты: «херо планшета сузим». Замер показал, что дефект одинаков у ВСЕХ ТРЁХ
   страниц с этим херо (контакты, спецпредложения, сертификаты): высота 478, отступы 49 сверху
   и 170 снизу, перекос 121. Класс общий, причина общая — правлю разом.

   1) min-height:478 в полосе просто раздувала блок: контент заканчивался на 308, а секция
      тянулась до 478, и вся разница уходила вниз. Снимаем — высоту держат паддинги .hero-stack,
      как в §4.1 (hug). В макете херо 362, у нас получается ~389 при том же контенте.
   2) --hero-optical-top:25px подбиралась под ДЕСКТОПНЫЙ хедер. На планшете хедер — пилюля,
      её реальный низ 93 (промо 33 + зазор 12 + пилюля 48), а формула --promo-h + --nav-h даёт 103,
      то есть переоценивает на 10. Из-за этого верхний отступ выходил 49 вместо макетных 64.
      Ставим компенсацию 10 — ровно ту переоценку, что и наблюдаем. */
@media (min-width:768px) and (max-width:991.98px){
  #hero.hero-page{min-height:0}
  .hero-stack{--hero-optical-top:10px}
  /* Иллюстрация сертификатов: height 89% и max-width 34% дрались между собой — высота просила
     ширину 352, max-width резал до 279, и квадратный SVG выходил СПЛЮЩЕННЫМ (279×352).
     На планшете это было и до правки высоты, просто не попадало в замеры.
     В макете 744 арт 338 при херо 410 = 82% высоты, ширина 338 = 45% контента. Ставим эти доли:
     max-width больше не режет, аспект сохраняется. */
  .hero-gift .gc-hero-art{height:82%;max-width:45%}
}

/* ═══ ПЛАНШЕТ: СПЕЦПРЕДЛОЖЕНИЯ (Figma-744, херо 2191:19555, карточки 2191:19815) ═══

   1. ВЕКТОР «%» — «уменьшенная версия десктопа» (формулировка Романа).
   Причина бага: percent.svg — это ВЕСЬ десктопный херо одним файлом 1440×478, прибитый через
   object-fit:cover. Cover масштабирует по большей стороне, и на узком экране он тянет картинку
   ПО ВЫСОТЕ — процент раздувается до 95.4% высоты херо вместо макетных 87.5%, съезжает влево
   и вверх.
   Считаю от долей макета, а не подбором:
   • процент занимает 456/478 = 95.4% высоты самого SVG. Нужно, чтобы он был 87.5% высоты херо
     → высота бокса картинки = 0.875/0.954 = 91.7%.
   • верх процента в SVG — 67/478 = 14.0% его высоты → при боксе 91.7% это 12.8% высоты херо,
     а нужно 18.7% → бокс сдвигаем вниз на 5.9%.
   • по горизонтали cover обрезает лишнее; левый край процента в SVG — 66.04% его ширины,
     а в макете он должен встать на 64.38% ширины херо. Решая относительно окна обрезки,
     получаем object-position по X = 71.6%.
   Числа проверяемые: после правки бокс процента должен встать в те же доли, что в макете. */
@media (min-width:768px) and (max-width:991.98px){
  .hs-bg{inset:5.9% 0 auto 0;height:91.7%;object-position:71.6% 0}

  /* 2. КАРТОЧКИ ОФФЕРОВ.
     Роман: «карточки такие же как в мобилке, но важно что они ВСЕ ПО ВЫСОТЕ ОДИНАКОВЫЕ, чтобы
     сетка была чёткой, и кнопка Условия прижата всегда к низу».
     Было: высоты 290 / 290 / 226 / 226 / 212 / 212 — три разных, сетка рваная, кнопка висела
     сразу под текстом.
     grid-auto-rows:1fr вместо фиксированных 186 из макета — намеренно: так высота берётся
     от самой «длинной» карточки и держится единой сама, без магического числа, которое
     развалится при смене текста. Кнопку к низу прижимает margin-top:auto в колонке контента —
     это ровно то, что в макете сделано через justify-content:space-between. */
  .offers-grid{grid-template-columns:1fr 1fr;gap:var(--sp-4);grid-auto-rows:1fr}
  .offer-card{min-height:0;padding:var(--sp-4);align-items:stretch;border-radius:16px}
  .oc-body{position:static;max-width:60%;display:flex;flex-direction:column;height:100%}
  .oc-head{gap:var(--sp-2);margin-bottom:var(--sp-3)}
  .oc-head h3{font-size:16px;font-weight:600}
  .oc-badge{padding:6px var(--sp-2);font-size:12px;border-radius:10px}
  .oc-desc{font-size:14px;line-height:1.3;margin-bottom:var(--sp-4)}
  .oc-btn{align-self:flex-start;margin-top:auto;padding:9px var(--sp-4);font-size:14px}
  /* Эмодзи 130 в правом-нижнем углу, углом ЗА карточку — она его обрезает (в макете overflow:clip
     и вылет 23–31 вправо, 15–31 вниз) */
  .oc-icon{right:-23px;bottom:-22px;top:auto;transform:none;width:130px}
}

/* Плавное раскрытие подменю уважает системную настройку «меньше движения»:
   переход снимаем, состояния остаются — меню просто открывается мгновенно, как раньше. */
@media (prefers-reduced-motion:reduce){
  .has-dropdown .nav-dropdown,.has-dropdown.is-open .nav-dropdown{transition:none}
}

/* ═══ ПЛАНШЕТ: заголовок херо сертификатов не заходит под вектор ═══
   Замер на 834: строка «сертификат в керлинг» доходила до x=467, а арт начинается на x=431 —
   перекрытие 36px, текст лез под иллюстрацию.
   Из двух вариантов (двигать вектор или ломать заголовок) выбран второй — так в макете:
   на планшете заголовок в ТРИ строки. Двигать вектор было нельзя: его правый край уже стоит
   на --sp-8 от края, а ширина задана долей высоты херо по Figma.
   46% — ширина текстовой колонки до вектора с запасом на всю полосу: на 768 остаётся 23px
   до арта, на 991 — 122. Ширину даём ДОЛЕЙ, а не пикселями: арт масштабируется от высоты херо,
   и фиксированное число разъехалось бы на краях полосы. */
@media (min-width:768px) and (max-width:991.98px){
  .hero-gift .hero-h1-2line{max-width:46%}
}


/* ═══════════════ ПРАВИЛА ИГРЫ (rules.html) ═══════════════
   ХЕРО «Оглавление ролика» — пятый тип херо в таксономии (§3.0).
   Верхний ряд: слева текст, справа видео. Под ними — лента из шести глав-превью.

   РАЗМЕТКА ВЕРХНЕГО РЯДА — ПО FIGMA (правка Романа): левый контейнер 630, правый 665.
   При контейнере 1360 это 630+665=1295, на зазор остаётся 65 — берём токен --sp-8 (64),
   и колонки задаём дробями 630fr/665fr: пропорция макета держится на любой ширине,
   а не только на 1440. */
#hero.hero-rules{min-height:0;align-items:flex-start;background:var(--background-bg);color:var(--ink-cold)}
/* Верхний зазор 80 — как на херо дня рождения, единый ритм под шапкой. */
.hero-rules .hero-in{padding-top:calc(var(--promo-h) + var(--nav-h) + 80px)}
.hero-in-rules{display:flex;flex-direction:column;gap:var(--sp-8);padding-bottom:var(--sp-8)}
/* Видео РАВНО по высоте левой колонке (правка Романа: иначе колонки заканчиваются на разной
   высоте и отступы «скачут»). Механика: строка тянется по левой колонке (align-items:stretch),
   видео берёт height:100%, а ширину ему считает aspect-ratio. Если получившаяся ширина меньше
   колонки — видео прижимается вправо, и просто растёт зазор между контейнерами. Это ровно то,
   что Роман и предложил: «сузить видео, отступ будет больше — это ок». */
.hr-top{display:grid;grid-template-columns:630fr 665fr;gap:var(--sp-8);align-items:stretch}
/* Мера строки лида — по колонке, а не по символам: колонка уже задана макетом (630). */
.hr-txt .hr-lead{max-width:none}
.hr-txt{display:flex;flex-direction:column;align-items:flex-start}
.hero-rules .hero-h1-page{font-size:clamp(34px,3.9vw,56px);line-height:1.06;color:var(--ink-cold);margin:0}
.hr-lead{margin:var(--sp-5) 0 0;color:var(--ink-body);font-size:clamp(15px,1.15vw,17px);line-height:1.5}
.hr-lead-2{margin-top:var(--sp-4)}
.hero-in-rules .hero-cta{margin:var(--sp-6) 0 0;justify-content:flex-start}

/* ЭКРАН ГЛАВЫ.
   Смена кадра — КРОССФЕЙД, а не подмена src: раньше картинка «скакала» (фидбэк Романа).
   Реализация: два слоя друг на друге, меняем opacity. Нижний слой держит текущий кадр,
   верхний — тот, что въезжает; после перехода они меняются ролями (js/rules.js). */
.hr-screen{position:relative;display:block;border-radius:var(--r-lg);overflow:hidden;isolation:isolate;
  background:var(--ink-cold);aspect-ratio:16/9;text-decoration:none;
  height:100%;width:auto;max-width:100%;margin-left:auto;   /* см. .hr-top: высота от левой колонки */
  box-shadow:0 28px 60px -30px rgba(20,48,60,.5)}
.hr-screen-img{position:absolute;inset:0;width:100%;height:100%;object-fit:cover;display:block}
.hr-screen-img.is-next{opacity:0;transition:opacity .38s var(--ease-out)}
.hr-screen-img.is-next.is-shown{opacity:1}
.hr-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:76px;height:76px;border-radius:50%;
  background:#fff;box-shadow:0 14px 34px -12px rgba(20,48,60,.55);z-index:3;
  transition:transform .3s var(--ease-out)}
.hr-play::after{content:"";position:absolute;left:52%;top:50%;transform:translate(-50%,-50%);
  border-left:20px solid var(--ink-cold);border-top:13px solid transparent;border-bottom:13px solid transparent}
.hr-screen:hover .hr-play{transform:translate(-50%,-50%) scale(1.07)}
/* НИЖНЯЯ ПОЛОСА ЭКРАНА. По умолчанию несёт САМ РОЛИК: слева его название, справа полный
   хронометраж. При наведении на главу подменяется её названием и таймкодом.
   Раньше тут стояла одна строка «00:14 · как держать камень» белым текстом — логика была
   сломана: большой экран показывал фрагмент вместо видео, да ещё в другом визуальном формате,
   чем плашки на превью (правка Романа). Теперь формат один — те же тёмные плашки, просто крупнее. */
.hr-screen-bar{position:absolute;left:var(--sp-4);right:var(--sp-4);bottom:var(--sp-4);z-index:3;
  display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);pointer-events:none;
  transition:opacity .22s var(--ease-out)}
.hr-screen-bar.is-fading{opacity:0}
/* РАДИУС ПЛАШКИ = РАДИУС ЭКРАНА − ОТСТУП (правило концентричности).
   Было 6 при экране 28 и отступе 16: плашка почти квадратная внутри круглого угла, и в углу
   зазор до края съедался — острый угол «протыкал» паддинг (правка Романа). 28 − 16 = 12:
   кривые идут параллельно, зазор одинаковый по всему углу.
   Шрифт 14 → 17: на экране 665px подпись почти не отличалась от 12px на превью 213px, хотя
   это главная подпись блока. Плашка выше за счёт паддинга — 17*1.3 + 20 ≈ 42px. */
.hr-screen-title,.hr-screen-time{color:#fff;background:rgba(6,26,38,.72);border-radius:var(--r-sm);
  padding:10px 16px;font:600 17px/1.3 var(--font-sans);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
.hr-screen-time{flex:none;font-variant-numeric:tabular-nums}
.hr-screen::after{content:"";position:absolute;inset:auto 0 0 0;height:38%;z-index:2;pointer-events:none;
  background:linear-gradient(transparent,rgba(6,26,38,.55))}

/* ЛЕНТА ГЛАВ — карточки с превью (правка Романа: текстовые строки читались слабо).
   Шесть штук: 6 в ряд на десктопе, 3+3 на планшете, 2 в ряд на мобилке. */
/* Растворение краёв ленты — ТОЛЬКО с той стороны, куда ещё можно скроллить.
   Раньше маска гасила левый край всегда, и первая карточка уходила в туман, хотя скроллить
   влево некуда, а она обязана быть чётко выровнена с левым контейнером (правка Романа).
   Прозрачность краёв держат --fl / --fr, их переключает js/rules.js по позиции скролла:
   в начале левый край непрозрачен, в конце — правый. */
.hr-chapters{list-style:none;margin:0;padding:0;display:grid;grid-template-columns:repeat(6,1fr);gap:var(--sp-4);
  --fl:0;--fr:0;
  --hr-fade:linear-gradient(90deg,
    rgba(0,0,0,var(--fl)) 0, #000 var(--hr-fade-w,16px),
    #000 calc(100% - var(--hr-fade-w,16px)), rgba(0,0,0,var(--fr)) 100%)}
.hr-chapters.at-start{--fl:1}
.hr-chapters.at-end{--fr:1}
.hr-ch a{display:block;text-decoration:none}
.hr-thumb{position:relative;display:block;border-radius:var(--r-sm);overflow:hidden;background:var(--ink-cold);
  aspect-ratio:16/9;box-shadow:0 6px 16px -10px rgba(20,48,60,.45);
  transition:box-shadow .3s var(--ease-out),transform .3s var(--ease-out)}
.hr-thumb img{width:100%;height:100%;object-fit:cover;display:block;
  transition:transform .45s var(--ease-out),filter .3s var(--ease-out)}
.hr-thumb::after{content:"";position:absolute;inset:0;background:rgba(6,26,38,.28);
  transition:background .3s var(--ease-out)}
.hr-ch.is-on .hr-thumb::after,.hr-ch a:hover .hr-thumb::after{background:rgba(6,26,38,.06)}
.hr-ch.is-on .hr-thumb,.hr-ch a:hover .hr-thumb{box-shadow:0 12px 26px -12px rgba(20,48,60,.5);transform:translateY(-2px)}
.hr-ch a:hover .hr-thumb img{transform:scale(1.05)}
/* Кнопка play на превью — маленькая, белая, без красного: красный тут был бы четвёртым
   акцентным цветом в блоке (§7.1). */
.hr-thumb-play{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);width:30px;height:30px;
  border-radius:50%;background:rgba(255,255,255,.92);z-index:2;
  transition:transform .3s var(--ease-out),background .3s var(--ease-out)}
.hr-thumb-play::after{content:"";position:absolute;left:53%;top:50%;transform:translate(-50%,-50%);
  border-left:9px solid var(--ink-cold);border-top:6px solid transparent;border-bottom:6px solid transparent}
.hr-ch.is-on .hr-thumb-play,.hr-ch a:hover .hr-thumb-play{transform:translate(-50%,-50%) scale(1.1);background:#fff}
.hr-thumb-tc{position:absolute;right:6px;bottom:6px;z-index:2;color:#fff;background:rgba(6,26,38,.72);
  border-radius:4px;padding:2px 6px;font:600 12px/1.25 var(--font-sans);font-variant-numeric:tabular-nums}
/* Подпись главы лежит ВНУТРИ превью, в такой же тёмной плашке, что и тайминг, но у левого края
   (правка Романа). Раньше она стояла текстом ПОД карточкой — и уезжала за сгиб, из-за чего
   человек видел просто кадры из видео, которые ему ничего не говорят. А весь смысл ленты в том,
   чтобы он сразу прочитал, какие его вопросы тут закрывают. */
/* Плашка по КОНТЕНТУ (hug), а не растянутая до тайминга: right:auto + max-width как страховка
   от наезда на тайминг. Раньше стояло right:52px — плашка тянулась во всю ширину и слипалась
   со временем в одну полосу, хотя места достаточно (правка Романа). */
.hr-name{position:absolute;left:6px;bottom:6px;right:auto;max-width:calc(100% - 58px);z-index:2;
  color:#fff;background:rgba(6,26,38,.72);
  border-radius:4px;padding:3px 7px;font:600 12px/1.3 var(--font-sans);
  overflow:hidden;text-overflow:ellipsis;white-space:nowrap;
  transition:background .25s var(--ease-out)}
.hr-ch.is-on .hr-name,.hr-ch a:hover .hr-name{background:var(--cyan-2)}

@media (prefers-reduced-motion:reduce){
  .hr-screen-img.is-next{transition:none}
  .hr-thumb,.hr-thumb img,.hr-thumb-play{transition:none}
  .hr-ch a:hover .hr-thumb{transform:none}
  .hr-ch a:hover .hr-thumb img{transform:none}
}

/* ── ПЛАНШЕТ: разметка ПО FIGMA (2196:11071, 744×372) ──
   Из макета: колонки 354 текст / 326 видео при контейнере 704, зазор 24; от низа шапки до H1 — 48;
   H1→абзац 16, абзац→абзац 12, абзац→кнопка 24. Видео по низу выровнено с кнопкой.
   Ленты глав в макете НЕТ — она наша добавка, поэтому её ритм задаём сами (3 в ряд). */
@media (min-width:768px) and (max-width:991.98px){
  /* 48 из макета + поправка -10: шапка здесь пилюля, её реальный низ 93 против формульных 103. */
  .hero-rules .hero-in{padding-top:calc(var(--promo-h) + var(--nav-h) + 48px - 10px)}
  .hero-in-rules{gap:var(--sp-6);padding-bottom:var(--sp-6)}
  /* align-items:end — в макете обе колонки заканчиваются на одной линии (низ видео = низ кнопки,
     оба на 308). При центрировании видео вставало на 7px выше. */
  .hr-top{grid-template-columns:354fr 326fr;gap:var(--sp-5);align-items:end}
  .hero-rules .hero-h1-page{font-size:30px}
  .hr-lead{font-size:14px;margin-top:var(--sp-4)}
  .hr-lead-2{margin-top:var(--sp-3)}
  .hero-in-rules .hero-cta{margin-top:var(--sp-5)}
  .hr-play{width:56px;height:56px}
  .hr-play::after{border-left-width:15px;border-top-width:10px;border-bottom-width:10px}
  .hr-screen{border-radius:16px}
  .hr-screen-bar{left:var(--sp-3);right:var(--sp-3);bottom:var(--sp-3);gap:var(--sp-3)}
  /* Строго концентрично тут вышло бы 16 − 12 = 4 — а это ещё квадратнее, чем было, и ровно
     против правки. Берём 10: КРУГЛЕЕ концентричного. Артефакт «протыкания» несимметричен —
     он появляется, только когда внутренний угол ОСТРЕЕ внешнего; круглее — безобидно. */
  .hr-screen-title,.hr-screen-time{font-size:13px;padding:7px 12px;border-radius:10px}
  /* Превью были почти как главное видео — читалось «галерея», а не навигация (Роман).
     Уменьшены примерно в полтора раза (249 → 166) и переведены в боковой скролл: шесть штук
     в ряд на 744 стали бы совсем мелкими, а подписи в них не поместились бы. */
  /* padding-block ОБЯЗАТЕЛЕН: overflow-x:auto делает контейнер клипающим и по вертикали тоже
     (спека: если одна ось не visible, вторая перестаёт быть visible). Активная карточка
     приподнята на 2px и её верхние скругления срезало — заметно и некрасиво (правка Романа).
     Компенсируем отрицательным margin, чтобы ритм блока не поехал. */
  .hr-chapters{display:flex;grid-template-columns:none;gap:var(--sp-4);
    overflow-x:auto;scrollbar-width:none;
    margin-inline:calc(var(--sp-5) * -1);padding-inline:var(--sp-5);
    padding-block:6px;margin-block:-6px;
    -webkit-mask-image:var(--hr-fade);mask-image:var(--hr-fade)}
  .hr-chapters::-webkit-scrollbar{display:none}
  /* 180, а не 166: на 166 самые длинные подписи («как держать камень», «как считаются очки»)
     не дотягивали 4–7px и уходили в многоточие. Замерено, а не подобрано на глаз. */
  .hr-ch{flex:0 0 180px}
  /* Карточка 180 против десктопных 213: подпись и тайминг в один ряд оставляли между собой
     3px и снова читались слипшимися — ровно то, что Роман забраковал. Тайминг уходит НАВЕРХ,
     подпись занимает весь низ и остаётся hug. То же решение, что на мобилке: как только
     карточка узкая, плашки разносим по вертикали, а не по горизонтали. */
  .hr-name{font-size:11px;padding:2px 6px;max-width:calc(100% - 12px)}
  .hr-thumb-tc{font-size:11px;padding:2px 5px;top:6px;bottom:auto}
  .hr-thumb-play{width:26px;height:26px}
  .hr-thumb-play::after{border-left-width:8px;border-top-width:5px;border-bottom-width:5px}
}

/* ── МОБИЛКА: разметка ПО FIGMA (2203:23168, 375×610) ──
   Ключевое отличие от планшета — ПОРЯДОК: H1 → абзац → абзац → ВИДЕО → кнопка.
   Видео стоит МЕЖДУ текстом и кнопкой, а не после неё, и оба абзаца на месте.
   Отступы макета: низ шапки → H1 48, H1→абзац 16, абзац→абзац 16, абзац→видео 24,
   видео→кнопка 24. Кнопка на всю ширину. Ленты глав в макете нет — ставим сами, 2 в ряд. */
@media (max-width:767px){
  /* Херо НЕ на всю высоту: лента глав обязана выглядывать из-под сгиба и звать скроллить. */
  #hero.hero-rules{min-height:0}
  .hero-rules .hero-in{padding-top:calc(var(--promo-h) + var(--nav-h) + 48px - 10px)}
  .hero-in-rules{gap:var(--sp-6);padding-bottom:var(--sp-6)}
  /* display:contents распускает текстовую колонку в сетку .hr-top — только так видео можно
     поставить МЕЖДУ абзацами и кнопкой, не трогая порядок в разметке (в HTML кнопка лежит
     внутри текстового блока, и для десктопа это правильно). */
  /* Оба контейнера распускаем в .hero-in-rules, чтобы кнопка встала ПОСЛЕ ленты превью
     (правка Романа), а лента — сразу за видео. В разметке кнопка лежит внутри текстового
     блока, и для десктопа это верно; порядок меняем только здесь. */
  /* gap:0 ОБЯЗАТЕЛЕН. Пока .hr-top был сеткой, зазор 32 у .hero-in-rules стоял между двумя
     блоками. Как только оба контейнера распустились в display:contents, тот же зазор встал
     между КАЖДОЙ парой элементов и сложился с моими margin — вертикальные отступы разъехались
     (баг, который Роман поймал на скрине). Теперь ритм держат только margin, по числам Figma. */
  .hr-top{display:contents}
  .hr-txt{display:contents}
  .hero-in-rules{gap:0}
  .hero-rules .hero-h1-page{font-size:30px;order:1;margin:0}
  .hr-lead{order:2;margin-top:var(--sp-4)}      /* 16 — Figma */
  .hr-lead-2{order:3;margin-top:var(--sp-4)}    /* 16 — Figma */
  .hr-screen{order:4;margin-top:var(--sp-5);height:auto;width:100%;margin-left:0}  /* 24 — Figma */
  .hr-chapters{order:5;margin-top:var(--sp-5)}  /* 24 — лента наша, ритм берём тот же */
  .hero-in-rules .hero-cta{order:6;width:100%;margin-top:var(--sp-5)}              /* 24 */
  .hero-in-rules .hero-cta .btn-mkk{width:100%;justify-content:center}
  .hr-play{width:54px;height:54px}
  .hr-play::after{border-left-width:15px;border-top-width:10px;border-bottom-width:10px}
  /* Скругление 16 — единый мобильный набор карточек (было забыто, стояло десктопное 28). */
  .hr-screen{border-radius:16px}
  .hr-screen-bar{left:var(--sp-3);right:var(--sp-3);bottom:var(--sp-3);gap:var(--sp-3)}
  /* См. планшет: концентрично было бы 4, берём 10 — круглее внешнего угла не «протыкает». */
  .hr-screen-title,.hr-screen-time{font-size:13px;padding:7px 11px;border-radius:10px}
  /* Тот же приём, что на планшете: мельче и боковой скролл с растворением по краям.
     Поля контейнера на мобилке 16 — на них и вешаем подрез. */
  /* padding-block — см. комментарий в планшетном блоке: горизонтальный скролл клипает
     и по вертикали, приподнятой карточке срезало верхние скругления. */
  /* margin-top ПОСЛЕ margin-block и с вычетом 6 — иначе отступ до видео пропадает совсем.
     Правило `.hr-chapters{margin-top:24}` стоит выше по файлу, а `margin-block:-6px` — это
     шорткат, он переписывает и margin-top тоже. Получалось не «24 минус 6», а −6, и вместе
     с 6px паддинга видимый зазор схлопывался в НОЛЬ (Роман: «отвалился отступ»).
     Видимый зазор = margin-top + padding-block, поэтому 18 + 6 = 24 из Figma.
     На планшете компенсация не нужна: там margin-top своего нет, ритм держит gap родителя,
     и −6 + 6 как раз возвращают его на место. */
  .hr-chapters{display:flex;grid-template-columns:none;gap:var(--sp-3);
    overflow-x:auto;scrollbar-width:none;
    margin-inline:-16px;padding-inline:16px;
    padding-block:6px;margin-block:-6px;margin-top:calc(var(--sp-5) - 6px);
    -webkit-mask-image:var(--hr-fade);mask-image:var(--hr-fade)}
  .hr-chapters::-webkit-scrollbar{display:none}
  .hr-ch{flex:0 0 150px}
  /* На карточке 150px две плашки в один ряд не помещаются — подписи уходили в многоточие
     (замер: четыре из шести). А подпись тут и есть смысл ленты: без неё человек видит просто
     кадры, которые ему ничего не говорят. Поэтому тайминг переезжает НАВЕРХ, а подпись
     занимает весь низ. Оба элемента на месте, просто разнесены по вертикали. */
  .hr-name{font-size:11px;padding:2px 6px;max-width:calc(100% - 12px)}
  .hr-thumb-tc{top:6px;bottom:auto}
  .hr-thumb-play{width:24px;height:24px}
  .hr-thumb-play::after{border-left-width:7px;border-top-width:5px;border-bottom-width:5px}
  .hr-thumb-tc{font-size:11px;padding:2px 5px}
}

/* ═══════════════════════ ХОД ИГРЫ — РОАДМЭП + МИНИ-ФИЛЬМ ═══════════════════════
   Роадмэп слева едет обычным потоком и ДАЁТ ВЫСОТУ, экран справа липнет и играет.
   Оба липкими быть не могут — тогда прокручивать станет нечего и фильм не тронется.

   Высота экрана задана числом, а не aspect-ratio: при height:100% в колонке aspect-ratio
   считает ширину ОТ высоты и вылезает за колонку (ошибка №13 журнала).

   Липкость — CSS sticky по образцу .cta-pin. ScrollTrigger pin:true в проекте не используется
   ни разу, и заводить его здесь не будем. */
.flow-head-cta{display:flex;align-items:end;justify-content:flex-end;gap:var(--sp-4);flex-wrap:wrap}
/* align-items тут НЕ ТРОГАТЬ. Стояло align-items:start — и колонки перестали растягиваться
   на высоту ряда, из-за чего .flow-film{height:100%} схлопывался до высоты экрана, запас для
   sticky становился нулевым и экран уезжал вверх вместе со страницей. Замер: top уходил
   до −1080 вместо того, чтобы замереть на 94. Растяжение по умолчанию — и есть то, что нужно. */

/* Пунктирная связка между шагами — как в макете, только соединяет камни, а не цифры.
   Три переменные на адаптив: ширина камня (по ней ищем центр линии), его высота вместе с
   margin-top и вертикальный паддинг шага. Отрицательный bottom протягивает пунктир в следующий
   шаг до его камня — иначе на каждом стыке зияла бы дыра в полсотни пикселей. */
.flow-road{list-style:none;margin:0;padding:0;--st-w:44px;--st-h:31px;--st-pad:var(--sp-4)}
.flow-step:not(:last-child)::after{content:'';position:absolute;z-index:0;
  left:calc(var(--st-w) / 2 - 1px);
  top:calc(var(--st-pad) + var(--st-h) + 6px);
  bottom:calc(-1 * (var(--st-pad) + 6px));
  width:2px;opacity:.3;
  background:repeating-linear-gradient(to bottom,var(--cyan-2) 0 4px,transparent 4px 11px)}
/* min-height даёт прокрутке дистанцию, а align-content:center держит текст в середине своей
   зоны — шаг подсвечивается ровно тогда, когда доезжает до центра экрана рядом с кадром. */
.flow-step{position:relative;display:grid;grid-template-columns:auto 1fr;gap:var(--sp-5);align-content:center;
  min-height:30vh;padding-block:var(--st-pad)}
.flow-step-tx h3{margin:0 0 var(--sp-3);color:var(--ink-cold);font:600 clamp(19px,2.3vw,24px)/1.25 var(--font-sans);
  transition:color .3s var(--ease-out)}
.flow-step-tx p{margin:0;color:var(--ink-body);font:400 17px/1.55 var(--font-sans)}
/* Гасим ТЕКСТ, а не шаг целиком. Когда прозрачность висела на всём <li>, камни неактивных шагов
   превращались в бесформенные серые кляксы и колонка теряла свой хребет. Камень остаётся почти
   в полную силу — он тут навигация, а не украшение; приглушение несёт только текст.
   Приглушение мягкое (.45): все четыре шага обязаны читаться без прокрутки назад. */
.flow-step-tx{opacity:.45;transition:opacity .35s var(--ease-out)}
.flow-step.is-on .flow-step-tx{opacity:1}
.flow-step.is-on .flow-step-tx h3{color:var(--cyan-2)}

/* Камень-маркер вместо номера. CSS, не Three.js: пятый WebGL-контекст на странице ради четырёх
   иконок не оправдан. Рецепт — уменьшенный фолбэк-камень #house.stone-css (120×74 → 44×27). */
.flow-stone{position:relative;z-index:1;flex:none;width:var(--st-w);height:27px;margin-top:4px;border-radius:50%;
  background:var(--stone);opacity:.8;
  box-shadow:inset 0 -4px 8px rgba(0,0,0,.25),0 6px 12px -5px rgba(20,48,60,.35);
  transition:box-shadow .35s var(--ease-out),opacity .35s var(--ease-out)}
.flow-step.is-on .flow-stone{opacity:1}
.flow-stone::after{content:'';position:absolute;left:50%;top:50%;width:18px;height:6px;border-radius:100px;
  background:var(--stone-red);transform:translate(-50%,calc(-50% - 7px))}
.flow-step.is-on .flow-stone{box-shadow:inset 0 -4px 8px rgba(0,0,0,.25),0 6px 12px -5px rgba(20,48,60,.35),
  0 0 26px 5px rgba(24,172,238,.58)}

/* ── ЭКРАН ── */
.flow-film{height:100%}
.flow-stage{position:sticky;top:calc(var(--nav-h) + var(--sp-5));height:min(62vh,430px);
  border-radius:var(--r-lg);overflow:hidden;isolation:isolate;
  background:var(--ice-2);
  box-shadow:inset 0 11px 24px -6px rgba(14,139,255,.18),inset 0 -11px 24px -6px rgba(14,139,255,.18),
    0 28px 60px -34px rgba(20,48,60,.45)}
.flow-svg{position:absolute;inset:0;width:100%;height:100%;display:block}
/* Камень внутри <use> красится переменной, а не классом: пользовательские свойства наследуются
   в теневое дерево <use>, а классы туда не достают. */
.flow-svg{--st-h:#d83a34}
.fs-l{stroke-linecap:butt}
.fs-l-c{stroke:rgba(6,187,255,.34);stroke-width:2}
.fs-l-tee{stroke:rgba(6,187,255,.5);stroke-width:2.5}
.fs-l-back{stroke:#149FD5;stroke-width:3.5}
.fs-l-hog{stroke:#FF544E;stroke-width:5}
.fs-l-tr{stroke:rgba(20,48,60,.16);stroke-width:2.5;stroke-linecap:round;stroke-dasharray:14 12}
.fs-count{fill:none;stroke:var(--cyan-2);stroke-width:3}

/* Кадры 2–3 спрятаны в базовом CSS, кадр 1 виден: это и есть состояние без JS —
   весь лист, разметка, дом и 16 камней на старте. Осмысленная статика, а не пустой прямоугольник.
   Класс is-live вешает JS: только после него кадрами начинает распоряжаться скролл. */
.fs-f{transition:opacity .38s var(--ease-out)}
.fs-f2,.fs-f3{opacity:0}
.flow-stage.is-live .fs-f{opacity:0}
.flow-stage.is-live .fs-f.is-on{opacity:1}

.flow-cap{position:absolute;z-index:2;transition:opacity .38s var(--ease-out)}
.flow-cap-1{left:var(--sp-5);bottom:var(--sp-5);display:flex;flex-wrap:wrap;gap:var(--sp-3)}
/* Табло вверху, а не по центру: на четвёртом плане камера отъезжает, лист становится тонкой
   полосой посередине — по центру табло легло бы прямо на него и закрыло весь смысл отъезда. */
.flow-cap-4{inset:var(--sp-5);display:flex;align-items:flex-start;justify-content:center;opacity:0}
.flow-stage.is-live .flow-cap{opacity:0}
.flow-stage.is-live .flow-cap.is-on{opacity:1}
.flow-tag{display:inline-flex;align-items:center;gap:var(--sp-2);
  background:rgba(255,255,255,.9);border:1px solid var(--border-blue);border-radius:100px;
  padding:7px 13px;color:var(--ink-cold);font:600 13px/1 var(--font-sans)}
.flow-dot{width:9px;height:9px;border-radius:50%;flex:none}
.flow-dot-r{background:#d83a34}
.flow-dot-b{background:#149FD5}

/* Табло. Сдержанное: третьего акцентного цвета в блоке быть не должно (§7.1) — выигравшая
   строка отмечена тем же брендовым цианом, а не новым «победным» цветом. */
.flow-board{width:100%;max-width:520px;background:#fff;border:1px solid var(--border-blue);
  border-radius:var(--r-sm);padding:var(--sp-4);box-shadow:0 18px 40px -22px rgba(20,48,60,.45)}
.flow-board-row{display:grid;grid-template-columns:auto repeat(10,1fr) auto;align-items:center;gap:2px;
  font:600 13px/1 var(--font-sans);color:var(--ink-cold)}
.flow-board-row+.flow-board-row{margin-top:6px;padding-top:6px;border-top:1px solid rgba(199,211,255,.5)}
.flow-board-row>span{text-align:center;font-variant-numeric:tabular-nums}
.flow-board-name{display:inline-flex;align-items:center;gap:6px;justify-content:flex-start;
  min-width:104px;text-align:left;font-weight:500;color:var(--ink-body)}
.flow-board-sum{min-width:30px;font-weight:700;color:var(--ink-cold)}
.flow-board-win{color:var(--cyan-2)}
.flow-board-win .flow-board-sum,.flow-board-win .flow-board-name{color:var(--cyan-2);font-weight:700}

@media (prefers-reduced-motion:reduce){
  .fs-f,.flow-cap,.flow-step,.flow-step-tx h3,.flow-stone{transition:none}
}

/* ── ПЛАНШЕТ 768–991.98 ── две колонки не помещаются: экран уезжает наверх, роадмэп под ним. */
@media (min-width:768px) and (max-width:991.98px){
  /* Кнопки уезжают ПОД анимацию: пока сцена липнет вверху, под ней всё равно пусто до самого
     конца прокрутки блока — там им и место.
     display:contents распускает шапку в колонку контейнера, иначе кнопки нельзя вынести за
     пределы её строки, не трогая разметку (на десктопе они обязаны остаться справа от H2).
     Вместе с боксом шапки пропадает и её margin-bottom — возвращаем его текстовой колонке,
     ровно на этом я уже обжигался в херо. */
  .flow-c .container-mkk{display:flex;flex-direction:column}
  .flow-c .flow-head{display:contents}
  .flow-c .flow-head>*{width:100%;max-width:none;padding-inline:0}
  .flow-c .flow-head>.col-lg-7{order:1;margin-bottom:var(--head-gap)}
  .flow-c .flow-body{order:2}
  /* sticky снизу: кнопка всплывает в пустоте под сценой и держится там всю прокрутку блока,
     а не появляется в самом конце. Отдельной липкой кнопки бронирования на этой странице нет,
     так что двух конкурирующих CTA не возникает — проверено. */
  .flow-c .flow-head-cta{order:3;position:sticky;bottom:var(--sp-5);z-index:4;margin-top:var(--sp-5)}
  /* Два в ряд: на 779px они спокойно помещаются, и растягивать их по одной было незачем. */
  .flow-c .flow-head-cta{flex-direction:row;justify-content:center;gap:var(--sp-4)}
  .flow-head-cta{margin-top:var(--sp-5);justify-content:flex-start}
  /* Липнет КОЛОНКА, а не экран внутри неё. Замер показал ровно 0 запаса: колонка ростом с экран,
     и sticky внутри неё ехать некуда — фильм уехал бы вверх, не начав играть. Ряду же высоту
     даёт роадмэп, поэтому липкой должна быть сама колонка. Фон обязателен: текст шагов проезжает
     ПОД экраном, и без него он просвечивал бы сквозь. */
  .flow-col-film{order:-1;position:sticky;top:calc(var(--nav-h) + var(--sp-2));z-index:3;
    background:#fff;padding-block:var(--sp-3);margin-bottom:var(--sp-4)}
  .flow-stage{position:static;height:min(46vh,320px);border-radius:16px}
  .flow-road{--st-w:38px;--st-h:27px;--st-pad:var(--sp-4)}
  .flow-step{min-height:26vh;gap:var(--sp-4)}
  .flow-step-tx p{font-size:15px}
  .flow-stone{height:23px}
  .flow-stone::after{width:15px;height:5px;transform:translate(-50%,calc(-50% - 6px))}
  .flow-cap-1,.flow-cap-4{left:var(--sp-4);right:var(--sp-4);bottom:var(--sp-4)}
  .flow-cap-4{top:var(--sp-4)}
}

/* ── МОБИЛКА ≤767.98 ── экран липнет под шапкой и остаётся тонким: он тут спутник текста,
   а не главный герой. Больше четверти экрана под него отдавать нельзя. */
@media (max-width:767.98px){
  /* Кнопки уезжают ПОД анимацию: пока сцена липнет вверху, под ней всё равно пусто до самого
     конца прокрутки блока — там им и место.
     display:contents распускает шапку в колонку контейнера, иначе кнопки нельзя вынести за
     пределы её строки, не трогая разметку (на десктопе они обязаны остаться справа от H2).
     Вместе с боксом шапки пропадает и её margin-bottom — возвращаем его текстовой колонке,
     ровно на этом я уже обжигался в херо. */
  .flow-c .container-mkk{display:flex;flex-direction:column}
  .flow-c .flow-head{display:contents}
  .flow-c .flow-head>*{width:100%;max-width:none;padding-inline:0}
  .flow-c .flow-head>.col-lg-7{order:1;margin-bottom:var(--head-gap)}
  .flow-c .flow-body{order:2}
  /* sticky снизу: кнопка всплывает в пустоте под сценой и держится там всю прокрутку блока,
     а не появляется в самом конце. Отдельной липкой кнопки бронирования на этой странице нет,
     так что двух конкурирующих CTA не возникает — проверено. */
  .flow-c .flow-head-cta{order:3;position:sticky;bottom:var(--sp-5);z-index:4;margin-top:var(--sp-5)}
  /* В столбик, а не в ряд: «Забронировать дорожку» в 165px просто не помещается. */
  .flow-c .flow-head-cta{flex-direction:column}
  .flow-head-cta{margin-top:var(--sp-5);justify-content:stretch;flex-direction:column}
  .flow-head-cta .btn-mkk{width:100%;justify-content:center}
  /* См. планшет: липкой делаем колонку, а не экран внутри неё. */
  .flow-col-film{order:-1;position:sticky;top:calc(var(--nav-h) + var(--sp-1));z-index:3;
    background:#fff;padding-block:var(--sp-2);margin-bottom:var(--sp-4)}
  .flow-stage{position:static;height:min(30vh,210px);border-radius:16px}
  .flow-road{--st-w:34px;--st-h:23px;--st-pad:var(--sp-5)}
  .flow-step{min-height:0;gap:var(--sp-4)}
  .flow-step-tx h3{font-size:19px;margin-bottom:var(--sp-2)}
  .flow-step-tx p{font-size:14px;line-height:1.5}
  .flow-stone{height:21px;margin-top:2px}
  .flow-stone::after{width:14px;height:5px;transform:translate(-50%,calc(-50% - 5px))}
  .flow-cap-1{left:var(--sp-3);bottom:var(--sp-3);gap:6px}
  .flow-tag{font-size:11px;padding:5px 9px}
  .flow-cap-4{inset:var(--sp-3)}
  .flow-board{padding:var(--sp-3)}
  /* Десять колонок эндов на 375 превращаются в кашу из двухпиксельных цифр — оставляем
     команды и сумму. Смысл кадра («счёт по сумме эндов») держится, читаемость не страдает. */
  /* Селекторы-показывалки ОБЯЗАНЫ быть не легче скрывалки: `.flow-board-row>span` весит (0,1,1),
     а голый `.flow-board-name` — (0,1,0), и названия команд остались бы скрытыми (ошибка №15
     журнала — вес, а не порядок). Поэтому оба возврата пишем через тот же комбинатор. */
  .flow-board-row{grid-template-columns:1fr auto}
  .flow-board-row>span{display:none}
  .flow-board-row>span.flow-board-name{display:inline-flex;min-width:0;font-size:13px}
  .flow-board-row>span.flow-board-sum{display:inline-flex;justify-content:flex-end}
}

/* ══════════ ХОД ИГРЫ — ВАРИАНТ C: одна непрерывная сцена (сравнительный, flow-c.html) ══════════
   Роадмэпа нет: сцена во всю ширину, текст живёт ПОВЕРХ неё нижней полосой и сменяется вместе
   с планом. Крупный номер вместо списка.
   Разметка та же, что в B, — расходится только CSS. Так сравнение получается про подачу,
   а не про то, что где-то сцена нарисована аккуратнее.
   Высоту прокрутке в B давал роадмэп; тут его нет, поэтому её задаёт сама плёнка. */
/* Высота плёнки = ДЛИНА ПРОКРУТКИ фильма: чем она больше, тем медленнее идёт сцена.
   340vh местами пролетало слишком стремительно (фидбэк Романа) — растянули до 460. */
.flow-c .flow-film{height:620vh}
/* --flow-reserve читает js/flow.js: столько внизу занимает полоса с текстом, и на столько же
   он поднимает сцену. Меняешь высоту полосы — меняй и это число. */
.flow-c .flow-stage{position:sticky;top:calc(var(--nav-h) + var(--sp-5));height:min(72vh,560px);--flow-reserve:186px}
/* Подложка под текстом. Без неё тёмный текст ложится прямо на лёд и на светлых участках
   разваливается — а лёд тут светлый почти везде. */
/* Высота подложки привязана к --flow-reserve, а не задана процентом. При 56% она поднималась
   на 314px и размывала нижний ряд камней — камера-то ставит лист ровно НАД полосой, а подложка
   про это не знала. Теперь это полоса плюс 40px растушёвки: замыливается только пустая кромка. */
.flow-c .flow-stage::after{content:'';position:absolute;left:0;right:0;bottom:0;z-index:1;
  height:calc(var(--flow-reserve) + 40px);
  pointer-events:none;background:linear-gradient(transparent,#fff 40%,#fff)}
.flow-c .flow-road{position:absolute;inset:auto 0 0 0;z-index:2;min-height:180px}
.flow-c .flow-step{position:absolute;left:var(--sp-7);right:var(--sp-7);bottom:var(--sp-6);
  min-height:0;padding-block:0;gap:var(--sp-6);align-items:center;
  opacity:0;transition:opacity .4s var(--ease-out)}
.flow-c .flow-step.is-on{opacity:1}
.flow-c .flow-step::after{display:none}   /* пунктирной связки тут нет: связывать нечего */
.flow-c .flow-stone{display:none}          /* его место занял номер */
.flow-c .flow-step-tx{opacity:1}
.flow-c .flow-step-tx h3{font-size:clamp(22px,2.6vw,30px)}
.flow-c .flow-step-tx p{max-width:660px}
.flow-num{font:800 clamp(54px,7vw,104px)/.82 var(--font-sans);color:var(--cyan-2);
  letter-spacing:-.04em;font-variant-numeric:tabular-nums}
/* Легенда команд уезжает вправо-вверх. Табло — в ПРАВУЮ ЧАСТЬ НИЖНЕЙ ПОЛОСЫ, рядом с текстом:
   сверху оно перекрывало бы дом, то есть самое содержательное место четвёртого плана.
   Внизу текст слева и счёт справа читаются как одна мысль, а лист остаётся чистым. */
.flow-c .flow-cap-1{left:auto;right:var(--sp-5);top:var(--sp-5);bottom:auto}
/* Табло по центру СЦЕНЫ, а не всего экрана: bottom отрезает полосу текста, иначе центр
   уехал бы вниз, в подпись. На четвёртом плане виден весь лист, дом стоит у правого края,
   а середина кадра — пустой лёд между хог-линиями: табло там ничего не перекрывает. */
.flow-c .flow-cap-4{inset:0 0 var(--flow-reserve) 0;align-items:center;justify-content:center}
/* 440, а не 520: слева стоит номер (104) плюс текст (660) плюс отступы — на 1264 свободных
   двум блокам иначе не разойтись. Замер, а не подбор. */
.flow-c .flow-cap-4 .flow-board{max-width:min(520px,calc(100% - var(--sp-7) * 2))}
/* Четвёртому шагу УРЕЗАЕМ ширину на размер табло. Само по себе сжатие табло накладку не сняло:
   текстовый блок растянут во всю полосу, и абзац доезжал до правого края под самый счёт —
   замер показал −166 вместо зазора. Место надо именно резервировать. */

/* Индикатор — в нижний левый угол СЦЕНЫ, то есть над полосой текста, а не в самом низу
   экрана: там уже стоит крупный номер шага. */
.flow-ticks{position:absolute;left:var(--sp-7);top:auto;bottom:calc(var(--flow-reserve) + var(--sp-3));
  z-index:2;display:flex;gap:6px}
.flow-tick{width:26px;height:3px;border-radius:2px;background:rgba(20,48,60,.18);
  transition:background .3s var(--ease-out)}
.flow-tick.is-on{background:var(--cyan-2)}

@media (min-width:768px) and (max-width:991.98px){
  .flow-c .flow-stage{height:min(62vh,440px);border-radius:16px;--flow-reserve:168px}
  .flow-c .flow-step{left:var(--sp-6);right:var(--sp-6);gap:var(--sp-5)}
  .flow-ticks{left:var(--sp-6);bottom:calc(var(--flow-reserve) + var(--sp-2))}
  /* Сжатие табло до «команда + сумма» СНЯТО: оно понадобилось, когда табло теснилось
     рядом с текстом в 779px. Теперь оно в центре сцены, под него 683px — все десять эндов
     помещаются, а именно они и объясняют «сумму очков во всех 10 эндах». */
}
/* На мобилке базовые правила .flow-c перебивают мобильные .flow-stage по весу (0,2,0 против
   0,1,0), поэтому высоту и поля тут задаём заново явно — иначе экран остался бы десктопным. */
@media (max-width:767.98px){
  .flow-c .flow-film{height:520vh}
  .flow-c .flow-stage{position:sticky;top:calc(var(--nav-h) + var(--sp-2));height:min(64vh,420px);border-radius:16px;--flow-reserve:172px}
  .flow-c .flow-road{min-height:0}
  .flow-c .flow-step{left:var(--sp-4);right:var(--sp-4);bottom:var(--sp-4);gap:var(--sp-4);
    grid-template-columns:auto 1fr;align-items:start}
  .flow-num{font-size:40px}
  .flow-c .flow-step-tx h3{font-size:19px}
  .flow-c .flow-cap-1{right:var(--sp-3);top:var(--sp-3)}
  /* На мобилке табло возвращается НАВЕРХ: в полосе оно не разойдётся с текстом по ширине,
     а само оно тут компактное — только команды и сумма. */
  .flow-ticks{left:var(--sp-4);bottom:calc(var(--flow-reserve) + var(--sp-2))}
  .flow-tick{width:18px}
}

/* ═══════════════ ТРЕТИЙ ВАРИАНТ ХЕДЕРА: СВЕТЛЫЙ ХЕРО (.light-hero) ═══════════════
   Было два состояния: над тёмным/цветным херо — белый лого и белые пункты; .scrolled —
   светлая шапка с тёмными пунктами и цветным лого. Страница «Правила игры» принесла третье:
   херо СВЕТЛЫЙ (#F8FAFF) с самого верха, и белая шапка на нём просто не читается.

   Решение: класс .light-hero на <body>. Шапка сразу выглядит как в .scrolled — цветной лого,
   тёмные пункты, синяя кнопка, — но БЕЗ заливки и тени: фон херо и так светлый, а плашка
   над ним читалась бы как лишний слой. Как только страница проскроллена, включается обычная
   .scrolled-логика и шапка получает свой фон — здесь ничего переопределять не нужно.

   Кнопка остаётся градиентной по умолчанию: правило «белая кнопка» висит на .hero-blue
   и .hero-birthday, светлого херо оно не касается. */
.light-hero #site-nav:not(.scrolled) .logo-on-dark{display:none}
.light-hero #site-nav:not(.scrolled) .logo-on-light{display:block}
.light-hero #site-nav:not(.scrolled) .nav-link{color:var(--ink-cold)}
.light-hero #site-nav:not(.scrolled) .nav-link:hover,
.light-hero #site-nav:not(.scrolled) .nav-link:focus{color:var(--cyan-2)}
.light-hero #site-nav:not(.scrolled) .nav-chev{color:var(--ink-cold)}

@media (max-width:991.98px){
  /* Мобилка и планшет: меняется ТОЛЬКО сама пилюля (Роман). Открытое бургер-меню —
     самостоятельное, всегда светлое, его логика уже есть и здесь не трогается. */
  .light-hero #site-nav:not(.scrolled):not(:has(.navbar-collapse.show)){
    background:rgba(255,255,255,.82);
    box-shadow:0 8px 22px -14px rgba(20,48,60,.3)}
  .light-hero #site-nav:not(.scrolled):not(:has(.navbar-collapse.show)) .burger span{background:var(--ink-cold)}
}

/* ═══════════ «ПОПРОБУЙТЕ САМИ» — бросок камня по настоящей дорожке ═══════════
   Вся геометрия разметки выведена из ЧЕТЫРЁХ переменных: высота дорожки, диаметр дома,
   отступ центра дома от края и отступ линии броска. На другом адаптиве меняются только они —
   ни одного повторно посчитанного вручную числа.
   Дорожка ЗЕРКАЛЬНАЯ: дом с обеих сторон, как на настоящем листе. У декоративных дорожек сайта
   дом один — там он украшение, здесь мы объясняем правила, и врать геометрией нельзя. */
.sec-try .container-mkk{position:relative}
/* Баннер скидок перенесён с главной, где он стоит ВНУТРИ секции и его собственный
   margin-bottom:140 отбивает идущую следом шапку. Здесь он сам себе секция, и эти 140 легли
   ПОВЕРХ двух секционных паддингов — замер дал 332px до отзывов. Гасим и margin, и паддинги
   обёртки: ритм должны задавать соседние секции, а не остатки чужого контекста. */
/* Эталон, названный Романом: отступ от дисклеймера цен до конца блока — это ровно --sec-pad.
   Такой же зазор нужен и до баннера, и после него.
   Сверху даём его сами; снизу основной зазор приходит паддингом секции отзывов, а собственный
   margin баннера погашен (он настроен под главную, где баннер стоит внутри секции).

   ОПТИЧЕСКАЯ ПОПРАВКА снизу +24. Геометрически оба зазора были ровно по 96 — замер это
   подтверждал, — но читались они по-разному, и Роман увидел разницу примерно в 20px.
   Причина в том, ЧЕМ ограничен зазор: сверху это жёсткий край цветного блока цен, снизу —
   маленькая бледная пилюля кикера, вокруг которой белое продолжается влево и вправо.
   Равные числа при неравной визуальной опоре равными не выглядят. 24, а не 20, — ближайший
   шаг нашей шкалы отступов: держим блок на системе, а не на случайном числе. */
.sec-discounts{padding-top:var(--sec-pad);padding-bottom:var(--sp-5)}
.sec-discounts .banner-specials{margin-bottom:0}
.tt-head-tx{min-width:0}
.tt-head-tx h2{margin:0}
.tt-lead{margin:var(--sp-4) 0 0;max-width:566px;color:var(--ink-body);font:400 18px/1.3 var(--font-sans)}

/* Панель силы — серая пилюля. Кнопка «Бросить» остаётся тут: это путь для тех, кто не тащит
   камень мышью, и заодно клавиатурный. Кнопка «Перебросить» живёт отдельно, на дорожке. */
.tt-panel{display:flex;align-items:center;gap:var(--sp-5);
  background:#f9f9f9;border-radius:200px;padding:16px 24px}
.tt-panel-lb{color:var(--ink-body);font:400 18px/1.3 var(--font-sans);white-space:nowrap;cursor:pointer}
.tt-panel .btn-mkk{height:48px;padding-block:0}

.tt-power-rail{position:relative;flex:none;width:257px;height:8px;border-radius:100px;
  background:#e6edf3}
/* Чем сильнее бросок, тем ТЕМНЕЕ полоса: цвет и есть индикатор, отдельная цифра не нужна. */
.tt-power-fill{position:absolute;left:0;top:0;bottom:0;width:calc(var(--pw,.5) * 100%);
  border-radius:100px;background:hsl(198 92% calc(62% - var(--pw,.5) * 20%))}
/* Кружок на конце — привычная ручка ползунка: без неё непонятно, что полосу можно тянуть. */
.tt-power-knob{position:absolute;top:50%;left:calc(var(--pw,.5) * 100%);width:20px;height:20px;
  margin:-10px 0 0 -10px;border-radius:50%;background:#fff;
  box-shadow:0 2px 8px rgba(20,48,60,.28),0 0 0 1px rgba(20,48,60,.08);pointer-events:none}
/* Невидимая область ползунка выше самой полосы: тянуть 8px пальцем невозможно. 44 — тот же
   минимум тач-цели, что и у кнопок. */
.tt-power{position:absolute;inset:-18px 0;width:100%;height:44px;margin:0;opacity:0;cursor:pointer}
.tt-power:focus-visible~.tt-power-knob{box-shadow:0 0 0 3px var(--cyan-2)}

/* ── ДОРОЖКА ── */
.sec-try{--pw:.5}
/* Контейнер — сетка. Пульт стоит справа от заголовка на десктопе и уезжает под дорожку
   на мобилке, а разметка при этом одна: меняются только области. */
.tt-grid{display:grid;grid-template-columns:minmax(0,1fr) auto;
  grid-template-areas:"tx panel" "stage stage" "status colors";
  align-items:end;column-gap:var(--sp-7)}
.tt-head-tx{grid-area:tx}
/* Прижимаем по содержимому: в сетке элемент по умолчанию тянется на всю колонку, и обе
   пилюли раздувались до 625px вместо своей ширины. */
.tt-panel{grid-area:panel;justify-self:end}
.tt-stage{grid-area:stage}
.tt-status{grid-area:status}
.tt-colors{grid-area:colors;justify-self:end}
/* Зазоры держим маргинами, а не row-gap: между шапкой и дорожкой он больше, чем под дорожкой. */
/* Верхний отступ — тот же --head-gap, что у всех секций сайта. Здесь стояло своё число,
   и «Практика» единственная выбивалась из общего ритма на мобилке. */
.tt-stage{position:relative;margin-block:var(--head-gap) var(--sp-6);
  --lane-h:180px;--house:148px;--hx:151px;--edge:12px;--hogw:6px;--start-x:var(--hx);
  --gap:calc(var(--hx) - var(--house) / 2 - var(--edge));
  --hog:calc(var(--hx) + var(--house) / 2 + var(--gap));
  --bx:calc(var(--house) / 2 + 26px)}
.tt-lane{position:relative;height:var(--lane-h);overflow:hidden;cursor:grab;touch-action:pan-y;
  user-select:none;isolation:isolate}
.sec-try.is-dragging .tt-lane{cursor:grabbing}
.tl{position:absolute;display:block}
/* Невидимая точка старта. Ширина 0 — JS берёт её центр; CSS двигает её по адаптивам,
   и логика броска про адаптивы ничего не знает. */
.tl-start{top:50%;left:var(--start-x);width:0;height:0}
.tl-edge{top:0;bottom:0;width:var(--edge);background:#149FD5;z-index:3}
.tl-edge-l{left:0}
.tl-edge-r{right:0}
.tl-c{left:0;right:0;top:50%;height:4px;transform:translateY(-50%);background:rgba(6,187,255,.38)}
/* Красная линия стоит от дома на том же расстоянии, что и синяя кромка с другой стороны,
   поэтому её положение ВЫВОДИТСЯ из дома, а не задаётся числом: подвинется дом — подвинется
   и она. Сам зазор тоже считается (--gap), а не подбирается: равенство двух расстояний
   становится свойством формулы, а не совпадением чисел, которое легко разъедется при правке. Толщина меньше синей: красная тут вспомогательная. */
.tl-hog{top:0;bottom:0;width:var(--hogw);background:#FF544E;z-index:2}
.tl-hog-l{left:var(--hog)}
.tl-hog-r{right:var(--hog)}
.tl-tee{top:0;bottom:0;width:4px;background:rgba(6,187,255,.38)}
.tl-tee-l{left:var(--hx);transform:translateX(-50%)}
.tl-tee-r{right:var(--hx);transform:translateX(50%)}
.tl-house{top:50%;width:var(--house);height:var(--house);
  background:url(../design/img/house.svg) center/contain no-repeat}
.tl-house-l{left:var(--hx);transform:translate(-50%,-50%)}
.tl-house-r{right:var(--hx);transform:translate(50%,-50%)}

/* Бейджи привязаны к ПРАВОМУ дому, а не к краю дорожки: сдвинется дом — сдвинутся и они. */
.tt-badge{position:absolute;top:78%;z-index:4;white-space:nowrap;
  background:rgba(255,255,255,.78);border-radius:200px;padding:2px 8px;
  font:500 14px/1.3 var(--font-sans)}
.tt-badge-miss{color:#F70400}
.tt-badge-home{color:#09A13E}
.tt-badge-short{right:calc(var(--hx) + var(--bx));transform:translateX(50%)}
.tt-badge-home{right:var(--hx);transform:translateX(50%)}
.tt-badge-long{right:calc(var(--hx) - var(--bx));transform:translateX(50%)}

.tt-canvas{position:absolute;inset:0;width:100%;height:100%;display:block;pointer-events:none;z-index:5}

/* Подсказка висит НАД дорожкой, поэтому живёт в .tt-stage: у самой дорожки overflow:hidden,
   внутри неё её бы срезало. Гаснет, как только человек взялся за камень. */
/* Указатель у ЛЕВОГО края подсказки, а не по центру. С центральным указателем подсказку
   нельзя было довести до камня, не упершись в край экрана: камень стоит почти у кромки,
   и половина её ширины уходила за границу. Со сдвинутым указателем сама плашка спокойно
   отходит вправо, а её носик по-прежнему смотрит ровно в центр камня.
   Привязка к --start-x, а не к --hx: на мобилке камень стартует не из дома. */
.tt-tip{position:absolute;bottom:calc(100% - 46px);left:calc(var(--start-x) - 24px);
  z-index:6;max-width:150px;text-align:center;
  background:#fff;border:1px solid rgba(42,176,236,.34);border-radius:18px;padding:9px 12px;
  color:#0958A1;font:500 14px/1.3 var(--font-sans);box-shadow:0 10px 24px -14px rgba(20,48,60,.5);
  transition:opacity .28s var(--ease-out),transform .28s var(--ease-out)}
.tt-tip::after{content:"";position:absolute;left:24px;top:100%;width:14px;height:9px;
  margin-left:-7px;background:#fff;clip-path:polygon(0 0,100% 0,50% 100%);
  filter:drop-shadow(0 1px 0 rgba(42,176,236,.34))}
.sec-try.is-touched .tt-tip{opacity:0;transform:translateY(-6px);pointer-events:none}

/* Появляется только когда камень встал: до броска перебрасывать нечего.
   Слово вердикта продублировано ЗДЕСЬ же, над кнопкой: глаз в этот момент на дорожке, а не
   на статусе под ней. Плашка та же, что у бейджей на льду, — один визуальный язык. */
.tt-end{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%) scale(.94);z-index:7;
  display:flex;flex-direction:column;align-items:center;gap:var(--sp-2);
  opacity:0;pointer-events:none;
  transition:opacity .3s var(--ease-out),transform .3s var(--ease-out)}
.sec-try.is-done .tt-end{opacity:1;transform:translate(-50%,-50%) scale(1);pointer-events:auto}
.tt-end-word{background:rgba(255,255,255,.86);border-radius:200px;padding:2px 10px;
  font:500 14px/1.3 var(--font-sans);white-space:nowrap}
[data-zone="short"] .tt-end-word,[data-zone="long"] .tt-end-word{color:#F70400}
[data-zone="house"] .tt-end-word{color:#09A13E}

/* ── ПОДВАЛ БЛОКА: статус слева, цвета справа ── */
/* Высота зафиксирована, подпись всегда в две строки — иначе смена вердикта дёргала бы вёрстку. */
.tt-status{min-width:0;min-height:93px}
.tt-verdict{margin:0;color:#1A1A1A;font:500 40px/32px var(--font-sans);letter-spacing:-.8px}
/* Цвет вердикта — тот же язык, что у бейджей на льду: промах красный, попадание зелёное.
   Раньше «в доме» было циановым, то есть просто «акцентным», и не читалось как «получилось». */
[data-zone="short"] .tt-verdict,[data-zone="long"] .tt-verdict{color:#F70400}
[data-zone="house"] .tt-verdict{color:#09A13E}
.tt-sub{margin:var(--sp-4) 0 0;color:var(--ink-body);font:400 18px/1.3 var(--font-sans)}
.tt-sub span{display:block}

.tt-colors{display:flex;align-items:center;gap:var(--sp-5);
  background:#f9f9f9;border-radius:200px;padding:16px 24px}
.tt-colors-lb{color:var(--ink-body);font:400 18px/1.3 var(--font-sans);white-space:nowrap}
.tt-colors-set{display:flex;align-items:center;gap:var(--sp-4)}
/* Невыбранные приглушены, но НЕ спрятаны: видно, что цветов четыре и их можно менять. */
.tt-color{width:60px;height:60px;padding:0;border:0;background:none;cursor:pointer;
  border-radius:50%;opacity:.42;transition:opacity .25s var(--ease-out),transform .25s var(--ease-out)}
.tt-color:hover{opacity:.75}
.tt-color.is-on{opacity:1;transform:scale(1.04)}
.tt-color:focus-visible{outline:2px solid var(--cyan-2);outline-offset:3px}
/* Кружок-камень сверху: гранит + цветная ручка — та же азбука, что на дорожке. */
.tt-color-st{display:block;width:100%;height:100%;border-radius:50%;position:relative;
  background:radial-gradient(circle at 38% 32%,#5b6873,#2c353d);
  box-shadow:inset 0 -3px 7px rgba(0,0,0,.3)}
.tt-color.is-on .tt-color-st{box-shadow:inset 0 -3px 7px rgba(0,0,0,.3),0 0 0 3px var(--cyan-2)}
.tt-color-st::after{content:"";position:absolute;left:50%;top:50%;width:22%;height:56%;
  border-radius:100px;background:var(--h);transform:translate(-50%,-50%)}

@media (prefers-reduced-motion:reduce){
  .tt-tip,.tt-replay,.tt-color{transition:none}
}

@media (min-width:768px) and (max-width:991.98px){
  /* Цвета и панель в ОДИН СТОЛБЕЦ, а не в ряд: вместе они требуют 938px при 819 доступных,
     и прижатая вправо пилюля цветов вылезала за левый край на 139px. Слева переполнение
     не даёт горизонтальной прокрутки, поэтому в общей проверке оно и не всплывало. */
  .tt-grid{grid-template-columns:minmax(0,1fr);
    grid-template-areas:"tx" "stage" "colors" "panel" "status"}
  .tt-panel,.tt-colors{justify-self:center}
  .tt-stage{margin-block:var(--head-gap) var(--sp-5)}
  .tt-panel{gap:var(--sp-4);padding:12px 20px}
  .tt-colors{margin-bottom:var(--sp-5)}
  .tt-panel{margin-bottom:var(--sp-5)}
  .tt-panel-lb,.tt-colors-lb{font-size:16px}
  .tt-power-rail{width:180px}
  .tt-lead{font-size:16px}
  .tt-stage{--lane-h:140px;--house:115px;--hx:118px;--edge:9px;--hogw:5px}
  .tt-verdict{font-size:32px;line-height:28px}
  .tt-sub{font-size:16px;margin-top:var(--sp-3)}
  /* Пояснение под пультом убрано и на планшете (было только на мобилке): короткий вердикт
     появляется на самой дорожке после броска, второй индикатор рядом его дублирует. */
  .tt-status{display:none}
  .tt-foot{gap:var(--sp-5)}
  .tt-colors{gap:var(--sp-4);padding:12px 20px}
  .tt-color{width:48px;height:48px}
}

@media (max-width:767.98px){
  /* D — ПУЛЬТ ПОД ДОРОЖКОЙ. Порядок: заголовок → дорожка → цвет камня → сила с кнопкой →
     результат. Сначала выбираешь камень, потом бросаешь, потом читаешь, что вышло; всё три
     органа управления идут подряд в зоне пальца, а не разбросаны по блоку. */
  .tt-grid{grid-template-columns:1fr;
    grid-template-areas:"tx" "stage" "panel" "colors";
    column-gap:0}
  /* Пояснение внизу скрыто: короткий вердикт уже появляется на самой дорожке после каждого
     броска, и второй индикатор рядом только дублирует. На мобилке место дороже. */
  .tt-status{display:none}
  .tt-stage{margin-block:var(--head-gap) var(--sp-4)}
  .tt-panel,.tt-colors{justify-self:stretch}
  .tt-panel{margin-bottom:var(--sp-3)}
  .tt-colors{margin-bottom:var(--sp-5)}
  .tt-lead{font-size:15px;margin-top:var(--sp-3)}
  /* Подпись НАД ползунком, кнопка справа во всю высоту получившейся колонки — сетка держит
     это без вложенных обёрток. */
  .tt-panel{display:grid;grid-template-columns:minmax(0,1fr) auto;
    grid-template-areas:"lb btn" "rail btn";align-items:center;
    gap:8px var(--sp-4);padding:12px 12px 12px 20px;border-radius:var(--radius-lg)}
  .tt-panel-lb{grid-area:lb;font-size:12px}
  .tt-power-rail{grid-area:rail;width:auto;min-width:0}
  /* min-height обязателен: подпись 12px плюс ползунок дают колонку всего в 32px, и кнопка,
     растянутая по ней, оказывалась ниже минимальной тач-цели в 44. Растягивая кнопку, она
     же поднимает и строки сетки — пульт просто становится нужной высоты. */
  .tt-panel .btn-mkk{grid-area:btn;align-self:stretch;height:auto;min-height:44px;
    padding-inline:var(--sp-6)}
  /* B — БЛИЖНЕГО ДОМА НЕТ. Два дома съедали 48% ширины, и камню оставалось 219px пути.
     Убираем ближний и стартуем от края, как от хака. Дальний дом заодно чуть меньше и ближе
     к краю — каждый выигранный пиксель здесь идёт в длину броска.
     Замер: путь 219 → 267px, это +22%. Больше на 343px по горизонтали не выжать: потолок
     343 − 37 (полдома) − 25 (радиус камня) = 281. Ради большего надо было бы разворачивать
     дорожку вертикально, но это вариант A, и мы его не выбрали. */
  .tt-stage{--lane-h:112px;--house:74px;--hx:48px;--edge:7px;--hogw:4px;--start-x:36px;
    --bx:calc(var(--house) / 2 + 14px)}
  .tl-house-l,.tl-tee-l{display:none}
  /* На 343px три бейджа в ряд не встают — оставляем «дом». Он и есть действие: куда толкать.
     Промахи человек и так увидит по статусу под дорожкой. */
  .tt-badge-short,.tt-badge-long{display:none}
  .tt-badge{font-size:12px;top:74%}
  .tt-tip{font-size:12px;padding:7px 10px;max-width:128px;bottom:calc(100% - 34px)}
  .tt-foot{flex-direction:column;align-items:stretch;gap:var(--sp-4);margin-top:var(--sp-5)}
  .tt-status{min-height:74px}
  .tt-verdict{font-size:28px;line-height:26px;letter-spacing:-.4px}
  .tt-sub{font-size:15px;margin-top:var(--sp-3)}
  .tt-colors{justify-content:space-between;gap:var(--sp-3);padding:12px 16px;
    border-radius:var(--radius-lg)}
  .tt-colors-lb{font-size:15px}
  .tt-color{width:44px;height:44px}
}


/* ═══════════ НЕОБХОДИМО ЗНАТЬ — аккордеон терминов ═══════════
   Нативные <details>: раскрытие, клавиатура и поиск по странице достаются даром, JS не нужен.
   Плавной высоты у <details> нет и городить её не будем — вместо неё мягко проявляется
   содержимое. Это честнее, чем имитировать раскрытие скриптом и потерять работу без JS. */
.nz-list{display:flex;flex-direction:column;gap:var(--sp-4)}
.nz-item{background:#fff;border:1px solid var(--border-blue);border-radius:var(--radius-md);
  transition:border-color .25s var(--ease-out),box-shadow .25s var(--ease-out)}
.nz-item[open]{border-color:rgba(11,170,236,.45);box-shadow:0 14px 34px -22px rgba(20,48,60,.4)}
/* Убираем нативный треугольник в обоих движках: свой шеврон справа. */
.nz-head{list-style:none;cursor:pointer;display:flex;align-items:center;gap:var(--sp-4);
  padding:var(--sp-5) var(--sp-6);user-select:none}
.nz-head::-webkit-details-marker{display:none}
.nz-head::marker{content:''}
.nz-title{flex:1 1 auto;color:var(--ink-cold);font:600 clamp(17px,1.9vw,21px)/1.3 var(--font-sans);
  transition:color .25s var(--ease-out)}
.nz-item[open] .nz-title{color:var(--cyan-2)}
.nz-head:hover .nz-title{color:var(--cyan-2)}
.nz-chev{flex:none;width:12px;height:12px;border-right:2px solid var(--ink-cold);
  border-bottom:2px solid var(--ink-cold);transform:rotate(45deg);margin-bottom:4px;
  transition:transform .3s var(--ease-out),border-color .25s var(--ease-out)}
.nz-item[open] .nz-chev{transform:rotate(-135deg);margin:4px 0 0;border-color:var(--cyan-2)}
.nz-head:focus-visible{outline:2px solid var(--cyan-2);outline-offset:-2px;border-radius:var(--radius-md)}

/* Текст слева, схема справа фиксированной колонкой: она поясняет, а не спорит с текстом. */
/* Текст НАМЕРЕННО узкий, а не во всю ширину: схема справа высокая, а текста в большинстве
   карточек мало — при широкой колонке под ним зияла пустота в половину картинки. Узкая колонка
   даёт больше строк и съедает эту дыру. space-between прижимает схему к правому краю. */
.nz-body{display:grid;grid-template-columns:minmax(0,620px) 280px;gap:var(--sp-6);align-items:start;
  justify-content:space-between;padding:0 var(--sp-6) var(--sp-6)}
.nz-txt{margin:0;color:var(--ink-body);font:400 16px/1.6 var(--font-sans)}
.nz-fig{align-self:start}
.nz-svg{display:block;width:100%;height:auto}
@media (prefers-reduced-motion:no-preference){
  .nz-item[open] .nz-body{animation:nzIn .32s var(--ease-out) both}
  @keyframes nzIn{from{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:none}}
}
@media (prefers-reduced-motion:reduce){
  .nz-item,.nz-title,.nz-chev{transition:none}
}

@media (min-width:768px) and (max-width:991.98px){
  .nz-head{padding:var(--sp-4) var(--sp-5)}
  .nz-body{grid-template-columns:minmax(0,1fr) 220px;gap:var(--sp-5);padding:0 var(--sp-5) var(--sp-5)}
  .nz-txt{font-size:15px}
}
@media (max-width:767.98px){
  .nz-list{gap:var(--sp-3)}
  .nz-head{padding:var(--sp-4);gap:var(--sp-3)}
  .nz-title{font-size:16px}
  /* Схема уходит ПОД текст и ужимается: рядом с текстом на 375 обе колонки станут нечитаемы. */
  .nz-body{grid-template-columns:1fr;gap:var(--sp-4);padding:0 var(--sp-4) var(--sp-4)}
  .nz-txt{font-size:14px;line-height:1.55}
  .nz-fig{max-width:260px}
}


/* ═══════════════ РЕСТОРАН (restaurant.html) ═══════════════
   Figma 2127:2556. Из четырёх блоков макета три взяты как есть, «Что в меню» пересобран
   (см. комментарий в разметке). Числа макета положены на 4pt-шкалу токенов. */

/* ── Херо: имя ресторана вместо длинного заголовка ──
   Кегль тот же, что у остальных фото-херо; одно слово при 82px и так занимает пол-экрана,
   увеличивать нечего. Кадр не сдвигаем вверх, как на общем правиле: тут интерьер, а не люди,
   и центр кадра — то, что нужно показать. */
.hero-resto .hero-photo{object-position:center}
/* ПРАВИЛО ХЕРО (действует на всех страницах и всех размерах): видимый отступ от шапки до
   заголовка равен отступу от кнопки до низа блока. Сверху расстояние отсчитывается до
   КЕГЕЛЬНОЙ площадки строки, а заглавные буквы начинаются ниже неё — поэтому равные числа
   в CSS дают НЕравные отступы на глаз.
   Поэтому отступ собирается из двух слагаемых:
     --hero-gap  — видимый зазор, ОДИН И ТОТ ЖЕ сверху и снизу;
     --hero-head — сколько над контентом занимает шапка (у неё свои высоты на каждом
                   размере, на мобилке это вообще пилюля), минус пустота над заглавной.
   Пустота у Onest мелкая — замер по пикселям канваса дал 5px при кегле 82, ~2px при 40, —
   поэтому она сидит внутри --hero-head, а не компенсируется отдельно. */
.hero-resto .hero-in-page{padding-top:calc(var(--hero-gap) + var(--hero-head));
  padding-bottom:var(--hero-gap)}
.hero-resto{--hero-gap:var(--sp-9);--hero-head:79px}

/* ── О ресторане: карточка в центре, фото по углам ──
   Колонки 1fr / фикс / 1fr: карточка держит читаемую строку, фото добирают остаток. */
/* Колонки и зазоры — из Figma 2127:5495: 348 / 40 / 585 / 40 / 347. Центр фиксирован (585),
   фото делят остаток поровну и ТЯНУТСЯ ПО ВЫСОТЕ карточки: их пропорция подчиняется тексту,
   а не наоборот (правка Романа — фото fill container). */
.rs-about{display:grid;grid-template-columns:minmax(0,1fr) 585px minmax(0,1fr);
  grid-template-areas:"p1 card p3" "p2 card p4";
  gap:40px}
.rs-ph-1{grid-area:p1} .rs-ph-2{grid-area:p2} .rs-ph-3{grid-area:p3} .rs-ph-4{grid-area:p4}
.rs-card{grid-area:card}
/* Высоту задаёт карточка с текстом, фото подстраиваются: min-height:0 нужен, чтобы
   grid-элемент не распирало содержимым, иначе строка тянется по картинке. */
.rs-ph{border-radius:var(--r-lg);overflow:hidden;min-height:0}
.rs-ph img{display:block;width:100%;height:100%;object-fit:cover}

/* Паддинги из макета: верхний 56, боковой 40. При ширине 585 − 80 = 505 подзаголовок
   ложится ровно в 4 строки — это и было условием правки. */
/* Зазор 44 — из макета (лого кончается на 188.8, текст начинается на 232.8; текст кончается
   на 340.8, кнопка на 384.8). Стояло 24, и логотип с текстом и кнопкой слипались. */
.rs-card{display:flex;flex-direction:column;align-items:center;justify-content:center;
  text-align:center;gap:44px;padding:56px 40px;
  background:#F4F8FA;border-radius:var(--r-lg)}
/* Логотип ресторана — растр из макета (нода 2127:5765, 202×132.82). Взят исходник
   с прозрачностью и перекрашен в #2E2E2E: экспорт ноды приходит с впечённым фоном #F8FAFF,
   который лёг бы на карточку заметным прямоугольником. Файл @2x под ретину. */
.rs-brand{display:block;width:202px;height:auto;margin:0}
.rs-txt{margin:0;color:var(--stone);font-size:16px;line-height:1.55}

/* ── Что в меню ──
   Слева меню, справа фото. Обе колонки равны: список из пятнадцати позиций и четыре кадра
   занимают примерно одинаковую высоту, и блок не заваливается на один бок. */
.rs-menu{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-5);
  align-items:start}

.rs-menu-card{padding:var(--sp-7);background:#F4F8FA;border-radius:var(--r-lg)}
/* Кухни — пилюлями: это перечисление, а не список чтения, и в строку оно честнее. */
.rs-cuisines{display:flex;flex-wrap:wrap;gap:var(--sp-2);margin:0 0 var(--sp-6);padding:0;
  list-style:none}
.rs-cuisines li{padding:6px 14px;border-radius:999px;background:#fff;
  color:var(--ink-cold);font-size:14px;font-weight:600;white-space:nowrap}

.rs-menu-cols{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-6)}
/* Колонка меню — <details>, но на десктопе это просто заголовок: маркер снят, шеврон скрыт,
   клик отключён. Разворачивать нечего — блок и так раскрыт. */
.rs-menu-head{display:block;list-style:none;cursor:default}
.rs-menu-head::-webkit-details-marker{display:none}
.rs-menu-chev{display:none}
.rs-menu-col h3{margin:0 0 var(--sp-4);font-size:13px;font-weight:700;letter-spacing:.08em;
  text-transform:uppercase;color:var(--cyan-2)}
.rs-menu-col ul{margin:0;padding:0;list-style:none}
.rs-menu-col li{padding:9px 0;border-top:1px solid rgba(20,48,60,.10);
  color:var(--ink-cold);font-size:15px;line-height:1.35}
.rs-menu-col li:first-child{border-top:0;padding-top:0}

.rs-dishes{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-5)}
.rs-dish{position:relative;margin:0;border-radius:var(--r-lg);overflow:hidden}
/* 3:2, а не 16:9: так колонка кадров ближе по высоте к списку блюд. Растягивать кадры до
   его высоты нельзя — вышло бы 1.17:1, а это срезает треть ширины исходника, и у широких
   композиций (каре с ложкой слева) уезжает половина блюда. 3:2 режет 16%. */
.rs-dish img{display:block;width:100%;height:100%;object-fit:cover;aspect-ratio:3/2}
/* Подпись — бейдж по содержимому в правом верхнем углу (правка Романа). Раньше плашка
   растягивалась во всю ширину кадра и читалась как подложка, а не как ярлык.
   left:auto обязателен: без него right не даёт схлопнуться по содержимому.
   Радиус по закону §4.4: внутренний = внешний − отступ = 28 − 12 = 16. */
.rs-dish figcaption{position:absolute;left:auto;right:12px;top:12px;bottom:auto;
  padding:8px 14px;border-radius:var(--r-md);background:rgba(6,26,38,.72);
  color:#fff;font-size:14px;font-weight:600;line-height:1.3}

/* ── Специально для вас мы проводим: бенто ──
   Ширины макета (318/528/454 и 549/375/375 из 1360) переведены в доли 24-колоночной сетки:
   6+10+8 и 10+7+7. Это те же пропорции с точностью до пары процентов, но без магических
   пикселей — блок тянется вместе с контейнером. */
/* Ряды бенто — точные пропорции Figma (2167:7635): 318/528/454 и 549/375.5/375.5.
   Записаны во fr, а не в процентах: fr делит остаток ПОСЛЕ вычета зазоров, то есть ровно ту
   сумму, от которой пропорции и считались в макете. Поэтому доли совпадают на любой ширине,
   а не только на 1360. Раньше тут была 24-колоночная сетка со спанами — она ошибалась
   до 1.6% (≈20px на 1360). */
.rs-bento{display:flex;flex-direction:column;gap:var(--sp-5)}
.rs-bt-row{display:grid;gap:var(--sp-5)}
.rs-bt-row-1{grid-template-columns:318fr 528fr 454fr}
.rs-bt-row-2{grid-template-columns:549fr 375.5fr 375.5fr}
/* Карточка бенто — числа из ноды 2167:7637, кроме РАДИУСА: его диктует дизайн-система,
   а не макет (правка Романа — система главнее Figma). У плиток такого размера на десктопе
   и планшете радиус --r-lg (28), как у .eb-tile и .price-card; 14/16 — мобильные значения,
   на большом экране они смотрятся чужеродно. Мобильный переопределяется ниже. */
.rs-bento{--bt-r:var(--r-lg)}
/* Карточки — ссылки: три ведут на разделы сайта ресторана, фото — на мастер-классы
   (на обоих кадрах занятие). Раньше это были div, и ховер-подъём обещал клик, которого нет. */
.rs-bt{display:flex;flex-direction:column;justify-content:space-between;gap:var(--sp-5);
  min-height:196px;padding:var(--sp-5);border:1px solid rgba(57,28,3,.1);
  border-radius:var(--bt-r);overflow:hidden;text-decoration:none;color:inherit}
.rs-bt:focus-visible{outline:3px solid var(--cyan-2);outline-offset:2px}
.rs-bt p{margin:0;font-size:20px;font-weight:500;line-height:1.3;color:var(--ink-cold)}
/* Эмодзи сидит на светлой подложке (#F8FAFF, 60×60, радиус 12) — в макете она есть
   у всех карточек, я её пропустил. Размер задан жёстко, а не паддингом: составной глиф
   👨‍🍳 шире своего кегля, и от паддинга подложка выходила прямоугольной (72×60 вместо 60×60).
   isolation нужен, чтобы шрифт страницы не перекрашивал цветные глифы. */
.rs-bt-ic{display:inline-flex;align-items:center;justify-content:center;align-self:flex-start;
  width:60px;height:60px;background:var(--background-bg);border-radius:12px;
  font-size:32px;line-height:1;font-style:normal;isolation:isolate;overflow:hidden}

/* Синяя карточка — полупрозрачная поверх фона, как в макете (rgba(0,123,255,.7) + блюр). */
.rs-bt-cy{background:rgba(0,123,255,.7);backdrop-filter:blur(6px);-webkit-backdrop-filter:blur(6px)}
.rs-bt-cy p{color:#fff}
.rs-bt-lv{background:#EDEAF9}
.rs-bt-pk{background:#FCEAF0}
.rs-bt-mt{background:#E4F3EF}

/* Фото — та же карточка, только без паддинга. Радиус наследуется от .rs-bt; картинке он
   задаётся ЕЩЁ РАЗ, потому что overflow:hidden на флекс-контейнере не режет угол картинки
   в Safari, когда у неё height:100%. */
.rs-bt-ph{padding:0;border:0}
.rs-bt-ph img{display:block;width:100%;height:100%;object-fit:cover;border-radius:var(--bt-r);
  transition:transform .5s var(--ease-out)}

/* Ховер — тем же языком, что у плиток .eb-tile и .price-card на главной: карточка
   приподнимается с тенью, фото внутри чуть наезжает. Ничего нового не придумываем.
   Только для мыши: на тач-экранах ховер залипает после тапа. */
@media (hover:hover){
  .rs-bt{transition:transform .3s var(--ease-out),box-shadow .3s var(--ease-out)}
  .rs-bt:hover{transform:translateY(-6px);box-shadow:0 22px 44px -22px rgba(20,48,60,.3)}
  .rs-bt-ph:hover img{transform:scale(1.05)}
}
@media (prefers-reduced-motion:reduce){
  .rs-bt,.rs-bt-ph img{transition:none}
  .rs-bt:hover{transform:none}
  .rs-bt-ph:hover img{transform:none}
}

/* ═══ ПЛАНШЕТ: ресторан ═══ */
@media (min-width:768px) and (max-width:991.98px){
  /* ХЕРО. Кегль 56 и зазор до кнопки 32 — из макета 2192:8595. Раньше кегль считался
     формулой от ширины и на планшете выходил заметно крупнее. */
  .hero-resto .hero-h1-page{font-size:56px}
  .hero-resto .hero-page-sub{margin-bottom:var(--sp-6)}
  .hero-resto{--hero-gap:var(--sp-8);--hero-head:64px}   /* шапка на планшете ниже, отсюда своё число */

  /* «О РЕСТОРАНЕ»: сетка та же, что на десктопе (правка Романа), пропорции из 2192:9019 —
     155.5 / 16 / 361 / 16 / 155.5. Центр здесь резиновый, а не фиксированный: 361px на
     768-ми не оставили бы фото ничего. */
  .rs-about{grid-template-columns:minmax(0,155.5fr) minmax(0,361fr) minmax(0,155.5fr);
    grid-template-areas:"p1 card p3" "p2 card p4";gap:var(--sp-4)}
  /* Паддинг карточки БОЛЬШЕ зазора между элементами — закон «внешнее ≥ внутреннее».
     В макете тут 16 при зазоре 24, то есть макет закон нарушает; берём 32/24.
     (На десктопе зазор 44 наследовался сюда при паддинге 16 — вот это и бросалось в глаза.) */
  .rs-card{gap:var(--sp-5);padding:var(--sp-6)}
  .rs-brand{width:67px}   /* планшетный макет 2192:9104 */
  .rs-txt{font-size:14px}

  /* Меню — две колонки, как в макете 2192:9203 (349 / 16 / 339). */
  .rs-menu{grid-template-columns:minmax(0,349fr) minmax(0,339fr);gap:var(--sp-4)}
  .rs-menu-card{padding:var(--sp-5)}
  .rs-menu-cols{gap:var(--sp-4)}
  .rs-menu-col li{font-size:14px;padding:7px 0}
  /* Все четыре кадра столбцом, меню — по своей высоте (hug) и ЛИПКОЕ: колонка фото выше,
     и при скролле меню едет вместе с ней, пока кадры не кончатся.
     Так решается исходная проблема — раньше кадров было три «под высоту меню», и полстраницы
     меню пустовало, будто в ресторане нечего подать (правка Романа).
     align-items:start обязателен: при stretch карточка растягивается на всю строку грида,
     и sticky внутри неё не сдвигается — прилипать становится нечему. */
  .rs-menu{align-items:start}
  .rs-menu-card{position:sticky;top:calc(var(--promo-h) + var(--nav-h) + var(--sp-4))}
  .rs-dishes{grid-template-columns:1fr;gap:var(--sp-4)}
  .rs-dish img{aspect-ratio:163.5/100}

  /* Бенто сохраняется, пропорции из планшетного макета (2192:9767): 196/280/196 и 304/184/184
     при зазоре 16 (правка Романа — «бенто сохраняем»). */
  .rs-bento,.rs-bt-row{gap:var(--sp-4)}
  .rs-bt-row-1{grid-template-columns:196fr 280fr 196fr}
  .rs-bt-row-2{grid-template-columns:304fr 184fr 184fr}
  /* Нода 2192:9769: паддинг 12, текст 16/500, эмодзи 24.
     Радиус 20 (--radius-lg), а не десктопные 28: на планшете такое скругление съедает угол
     (правка Романа). Подложка эмодзи тогда 8 — ровно по закону концентричности §4.4:
     внутренний = внешний − отступ = 20 − 12 = 8. При карточке 28 подложка выходила острее
     концентрической, а это как раз тот артефакт, который закон запрещает. */
  .rs-bento{--bt-r:var(--radius-lg)}
  .rs-bt{min-height:151px;padding:12px;gap:var(--sp-5)}
  /* Фото-карточка обнуляет паддинг ЗДЕСЬ: базовое .rs-bt-ph{padding:0} имеет ту же
     специфичность, что и .rs-bt{padding:12px}, а медиазапрос идёт ниже по файлу — и
     побеждал он. Из-за этого картинка сидела с полями 12px и была на 24px меньше своей
     карточки: карточки-то были ровные, а фото визуально не дотягивалось (правка Романа,
     третий заход — я мерил карточки, а не картинку внутри). */
  .rs-bt-ph{height:100%;padding:0}
  .rs-bt-ph img{height:100%}
  .rs-bt p{font-size:16px;font-weight:500}
  .rs-bt-ic{width:40px;height:40px;border-radius:8px;font-size:24px}
}

/* ═══ МОБИЛКА: ресторан ═══ */
@media (max-width:767.98px){
  /* ХЕРО. Раньше он занимал 100svh и под кнопкой оставалась пустая треть экрана.
     В макете 2203:10995 высота 341 — столько и берём: заголовок во всю ширину (335 из 343),
     контент опущен ниже (правка Романа). */
  .hero-resto.hero-page,#hero.hero-resto.hero-page{min-height:341px}
  /* Отступы подобраны по замеру так, чтобы от низа шапки до заголовка было 48, а под
     кнопкой 80 — пропорции макета 2203:10998. Считать их формулой от --nav-h нельзя:
     на мобилке шапка превращается в пилюлю другой высоты. */
  /* Зазор 60 вместо 96: при нём высота херо выходит ровно 341 из макета И правило
     равенства соблюдено. Шапка тут пилюля другой высоты, отсюда своё --hero-head. */
  .hero-resto .hero-in-page{text-align:center;margin-top:0}
  .hero-resto{--hero-gap:60px;--hero-head:65px}
  .hero-resto .hero-h1-page{font-size:40px;margin-bottom:var(--sp-2)}
  .hero-resto .hero-page-sub{margin-bottom:var(--sp-6)}

  .rs-about{grid-template-columns:repeat(2,minmax(0,1fr));
    grid-template-areas:"card card" "p1 p2" "p3 p4";gap:var(--sp-4)}
  /* Зазор 24 — из макета 2203:11298 (лого кончается на 68, текст на 92; текст на 200,
     кнопка на 224). Стояло 16, и блок читался слипшимся. */
  .rs-card{gap:var(--sp-5);padding:var(--sp-5) var(--sp-4)}
  .rs-brand{width:67px}   /* мобильный макет 2203:11299 */
  /* По центру — сознательно вопреки правилу «длиннее четырёх строк выключаем влево»:
     так в макете, и это осознанный выбор Романа, а не недосмотр. */
  .rs-txt{font-size:14px}
  /* Единый радиус у карточки и фото: были 28 и 16 и не сходились на глаз (правка Романа).
     Взят меньший — 28 на кадре 163×100 превращает его в таблетку. */
  .rs-card,.rs-ph{border-radius:var(--r-md)}

  .rs-menu{grid-template-columns:1fr;gap:var(--sp-4)}
  .rs-menu-card{padding:var(--sp-5)}
  /* Два столбца блюд на 320px дают по слову в строку — разворачиваем в один. */
  .rs-menu-cols{grid-template-columns:1fr;gap:var(--sp-4)}

  /* АККОРДЕОН. На десктопе меню — это блок, на мобилке оно превращалось в несколько экранов
     скролла, которые приходится проматывать даже тем, кто читать меню не собирался.
     Поэтому разделы сворачиваются: содержимое то же, шеврон у заголовка (правка Романа). */
  .rs-menu-col{border-top:1px solid rgba(20,48,60,.10)}
  .rs-menu-col:first-child{border-top:0}
  .rs-menu-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4);
    cursor:pointer;padding:14px 0;min-height:44px}
  .rs-menu-col h3{margin:0}
  /* Шеврон той же геометрии, что в аккордеоне «Необходимо знать», — чтобы жест по сайту
     читался одинаково. */
  .rs-menu-chev{display:block;flex:none;width:9px;height:9px;margin:-4px 0 0;
    border:2px solid var(--cyan-2);border-left:0;border-top:0;transform:rotate(45deg);
    transition:transform .28s var(--ease-out),margin .28s var(--ease-out)}
  .rs-menu-col[open] .rs-menu-chev{transform:rotate(-135deg);margin:4px 0 0}
  .rs-menu-col ul{padding-bottom:var(--sp-4)}
  .rs-menu-col li:first-child{border-top:0;padding-top:0}

  /* Фото 2×2, как в макете 2203:11511 (163.5×100), а не в столбик: четыре кадра подряд
     на всю ширину — это ещё экран скролла. */
  .rs-dishes{grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-4)}
  .rs-dish{border-radius:var(--r-md)}
  .rs-dish img{aspect-ratio:163.5/100}
  /* Бейджи на мобилке скрыты: на кадре 164px название занимало две строки и половину
     кадра — затея не сработала (правка Романа). Названия блюд остаются в списке рядом,
     подпись под каждым кадром тут не нужна. alt у картинок сохраняет их для скринридеров. */
  .rs-dish figcaption{display:none}
  /* Радиус кадра стал 16 — подпись по тому же закону: 16 − 8 = 8. */
  .rs-dish figcaption{left:auto;right:8px;top:8px;bottom:auto;padding:7px 12px;
    border-radius:8px;font-size:13px}

  /* Мобильная сетка бенто — из макета 2203:11683: две карточки во всю ширину, затем два
     зеркальных ряда «карточка 201 + фото 126» и «фото 126 + карточка 201».
     Группировка тут ДРУГАЯ, чем на десктопе (доставка уезжает к первому фото), поэтому
     ряды-обёртки распускаются через display:contents, и раскладку задают areas.
     Три колонки вместо двух — потому что ряды зеркальны: 126 + 59 + 126 даёт и 201 слева
     (126+16+59), и 201 справа (59+16+126) без второй сетки. */
  .rs-bento{display:grid;grid-template-columns:126fr 59fr 126fr;gap:var(--sp-4);
    grid-template-areas:"cy cy cy" "lv lv lv" "pk pk b1" "b2 mt mt"}
  .rs-bt-row{display:contents}
  .rs-bt-cy{grid-area:cy} .rs-bt-lv{grid-area:lv}
  .rs-bt-pk{grid-area:pk} .rs-bt-mt{grid-area:mt}
  .rs-bt-row-1 .rs-bt-ph{grid-area:b1}
  .rs-bt-row-2 .rs-bt-ph{grid-area:b2}
  /* Нода 2203:12089: паддинг 12, текст 14/400 (НЕ полужирный — на карточке это обычный
     текст, а не заголовок), подложка 8/8, эмодзи 24.
     Высоты — из макета 2203:11683: 106 у карточек и 105 у фото. Общий min-height:126
     тут стоять не может: он растягивал и ФОТО, и пропорция кадра уезжала с 1.20 на 1.00
     (правка Романа). Ровными должны быть плитки В ОДНОМ РЯДУ — это даёт сама сетка,
     а не одинаковое число на всех.
     Радиус на мобилке — системные 16 (--r-md), как у .eb-tile; 14 из макета в систему
     не входит. */
  .rs-bento{--bt-r:var(--r-md)}
  .rs-bt{min-height:106px;gap:var(--sp-5);padding:12px}
  .rs-bt p{font-size:14px;font-weight:400}
  .rs-bt-ic{width:40px;height:40px;border-radius:8px;font-size:24px}
  .rs-bt-ph{padding:0}
  .rs-bt-ph img{height:100%;aspect-ratio:auto}
}


/* Иконка гостя рядом с числом — из ноды 2192:11728. Без неё каунтер читался как
   «300 · Банкет» и не отвечал на вопрос «300 чего» (правка Романа). У «Площади» иконки
   нет: там единица измерения уже стоит в самом числе.
   Число и иконка выравниваются по ОПТИЧЕСКОМУ центру цифр, а не по строке: у кегля 76
   базовая линия ниже середины иконки, и по baseline человечек «тонул». */
.ab-stat-num{display:inline-flex;align-items:center;justify-content:center;gap:6px}
/* Размер привязан к кеглю числа, но с границами: на мобилке кегль 24 давал иконку
   в 10px — человечек превращался в точку. В макете планшета иконка 24 при кегле 44,
   то есть примерно половина; clamp держит эту пропорцию и не даёт уйти в крайности. */
.ab-stat-ic{flex:none;width:clamp(16px,.5em,32px);height:clamp(16px,.5em,32px);
  opacity:.9;transform:translateY(-.04em)}

/* ═══════════════ БАНКЕТНЫЕ ЗАЛЫ (halls.html) ═══════════════
   Figma 2127:6439 / 2127:6143 / 2203:12327. Числа из нод, радиусы — по дизайн-системе. */

/* ── Херо ──
   Поля по закону §3.0-A: видимый отступ «шапка → заголовок» равен «кнопка → низ блока».
   --hero-head здесь тот же, что на ресторане: шапка одна и та же. */
.hero-halls .hero-in-page{padding-top:calc(var(--hero-gap) + var(--hero-head));
  padding-bottom:var(--hero-gap)}
.hero-halls{--hero-gap:var(--sp-9);--hero-head:79px}

/* ── Сетка залов ──
   Три колонки на десктопе, зазор 32 (в макете 30 — кладём на 4pt-шкалу). */
.hl-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--sp-6)}

/* ── Карточка ──
   Радиус --radius-lg (20), как у .prices-ice .price-card: это такая же белая карточка
   с контентом. В макете 16, но 16 в системе — мобильное значение (правка Романа
   по бенто ресторана: система главнее макета). */
.hl-card{display:flex;flex-direction:column;gap:var(--sp-5);padding:var(--sp-5);
  background:#fff;border:1px solid var(--border-blue);border-radius:var(--radius-lg);
  overflow:hidden}
/* Полоса цвета зала над фото. Раньше цвет жил только в точке у названия — залы
   различались лишь после чтения имени. Теперь «Коралловый» и «Синий» видно боковым
   зрением, а карточки перестали быть одинаковыми белыми прямоугольниками. */
.hl-photo{position:relative;border-radius:8px;overflow:hidden}
.hl-photo::after{content:"";position:absolute;top:0;left:0;right:0;height:3px;
  background:var(--hall-ln);z-index:1}
.hl-photo img{display:block;width:100%;height:223px;object-fit:cover}

.hl-body{display:flex;flex-direction:column;gap:var(--sp-5);flex:1 1 auto}

/* Шапка карточки: имя с цветной меткой слева, площадь прижата вправо. */
.hl-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4)}
.hl-name{display:flex;align-items:center;gap:var(--sp-3);margin:0;
  font-size:24px;font-weight:600;line-height:1.3;color:#3F3F3F}
/* Метка — цвет зала из макета; у Кёрлинг-зала вместо заливки иконка камня. */
/* Заливка берётся из переменной карточки: у четырёх залов это сплошной цвет, у двух —
   градиент, поэтому --hall отдельно от --hall-ln (линии градиентом быть не могут). */
.hl-dot{flex:none;width:26px;height:26px;border-radius:12px;background:var(--hall,var(--hall-ln))}
.hl-dot-stone{background:var(--cyan-2);
  -webkit-mask:radial-gradient(circle at 50% 62%,#000 46%,transparent 47%) center/100% 100% no-repeat;
  mask:radial-gradient(circle at 50% 62%,#000 46%,transparent 47%) center/100% 100% no-repeat}
.hl-area{margin:0;font-size:18px;font-weight:400;line-height:1.3;color:rgba(63,63,63,.8);
  white-space:nowrap}

/* Характеристики: две плитки в ряд + строка «Рекомендуем для» под ними. */
.hl-stats{display:flex;flex-direction:column;gap:var(--sp-3)}
.hl-stats-row{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-3)}
/* Зазоры из макета 2142:3515: эмодзи отбит на 16, а подпись от числа — на 8.
   Раньше стоял один зазор 16 на всё, и подпись «Банкет» отрывалась от своей цифры. */
.hl-stat{display:flex;flex-direction:column;align-items:center;gap:var(--sp-2);
  padding:12px;background:var(--background-bg);border-radius:8px;text-align:center}
.hl-stat-ic{margin-bottom:var(--sp-2)}
/* Эмодзи изолирован, иначе шрифт страницы ломает цветные глифы. */
.hl-stat-ic{font-size:32px;line-height:1;font-style:normal;isolation:isolate}
.hl-stat-lb{font-size:14px;font-weight:400;line-height:1.3;color:rgba(63,63,63,.8)}
.hl-stat-v{font-size:20px;font-weight:600;line-height:1.3;color:#3F3F3F}
/* Шкала вместимости: длина = доля от самого большого зала (фуршет 350), масштаб единый
   для банкета и фуршета — иначе полоски в соседних колонках несравнимы.
   Смысл: шесть залов сортируются взглядом, без чтения цифр — ровно за этим на страницу
   и приходят. Минимум 6% — иначе самые маленькие залы показывали бы пустую полоску. */
.hl-bar{display:block;align-self:stretch;height:4px;margin-top:2px;border-radius:2px;
  background:rgba(63,63,63,.12);overflow:hidden}
.hl-bar i{display:block;height:100%;border-radius:inherit;background:var(--hall-ln)}

.hl-for{margin:0;padding:12px;background:var(--background-bg);border-radius:8px;
  font-size:14px;font-weight:400;line-height:1.3;color:rgba(63,63,63,.8);text-align:center}

/* Ховер тем же языком, что у .price-card: подъём с тенью. Рамка при этом окрашивается
   в цвет зала — карточка «представляется» до того, как прочитано название.
   Только для мыши: на тач-экранах ховер залипает после тапа. */
@media (hover:hover){
  .hl-card{transition:transform .3s var(--ease-out),box-shadow .3s var(--ease-out),
    border-color .3s var(--ease-out)}
  .hl-card:hover{transform:translateY(-6px);border-color:var(--hall-ln);
    box-shadow:0 22px 44px -22px rgba(20,48,60,.3)}
}
@media (prefers-reduced-motion:reduce){
  .hl-card{transition:none}
  .hl-card:hover{transform:none}
}

/* Кнопки: бронь и переход на страницу зала — поровну, всегда прижаты к низу карточки. */
.hl-cta{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-3);
  margin-top:auto}
.hl-cta .btn-mkk{width:100%;height:56px;padding-inline:var(--sp-5)}
/* Вторая кнопка — обводка на светлом. Готовый .btn-mkk-ghost не подошёл: он белый,
   рассчитан на тёмный фон. */
.hl-cta .btn-mkk-ghost{background:transparent;color:rgba(63,63,63,.8);
  border:1px solid rgba(63,63,63,.8)}
.hl-cta .btn-mkk-ghost:hover{background:rgba(63,63,63,.06);color:#3F3F3F}

/* ═══ ПЛАНШЕТ: залы ═══ */
@media (min-width:768px) and (max-width:991.98px){
  /* Две колонки, зазор 16 — макет 2192:10640. */
  .hl-grid{grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-4)}
  .hl-card,.hl-body{gap:var(--sp-4)}
  .hl-card{padding:var(--sp-4)}
  .hl-name{font-size:20px}
  .hl-dot{width:22px;height:22px}
  .hl-area{font-size:16px}
  .hl-stat{gap:var(--sp-3)}
  .hl-stat-v{font-size:18px}
  .hero-halls{--hero-gap:var(--sp-8);--hero-head:63px}
}

/* ═══ МОБИЛКА: залы ═══ */
@media (max-width:767.98px){
  /* Один столбец, зазор 20 — макет 2203:12344 (562 − 542). */
  .hl-grid{grid-template-columns:1fr;gap:20px}
  .hl-card{padding:var(--sp-4);border-radius:var(--r-md)}
  .hl-card,.hl-body{gap:var(--sp-4)}
  .hl-name{font-size:20px}
  .hl-dot{width:22px;height:22px}
  .hl-area{font-size:16px}
  .hl-stat{gap:var(--sp-3);padding:10px}
  .hl-stat-v{font-size:17px}
  .hl-for{font-size:13px}
  /* Кнопки ниже, но не ниже 44 — это порог касания. В макете 36, что мельче предела. */
  .hl-cta .btn-mkk{height:44px;padding-inline:var(--sp-4);font-size:15px}
  /* Высота из макета 2203:12335 (341). Без этого действует общее правило .hero-page
     на 100svh, и под кнопкой остаётся пустая половина экрана. */
  .hero-halls.hero-page,#hero.hero-halls.hero-page{min-height:341px}
  .hero-halls .hero-in-page{text-align:center;margin-top:0}
  .hero-halls .hero-h1-page{font-size:40px;margin-bottom:var(--sp-2)}
  /* 16 — прямо из ноды 2203:12341 (Body/16/Medium). */
  .hero-halls .hero-page-sub{margin-bottom:var(--sp-6);font-size:16px}
  .hero-halls{--hero-gap:60px;--hero-head:65px}
}


/* ═══════════════ СТРАНИЦА ЗАЛА (halls/<slug>.html) ═══════════════
   Figma 2143:7214 / 2143:6749 / 2203:14108.
   Херо тут ПЯТЫЙ тип по таксономии §3: не полноэкранный медиа-блок, а светлая полоса —
   текст слева, фото справа. Отсюда и шапка в светлом варианте (.light-hero). */

/* Фон --background-bg (#F8FAFF) — тот же токен, что в макете называется background/bg.
   Стоял --ice-0, а это чистый белый: взял по названию, не сверив с нодой.
   Отступы из макета 2143:7226: от низа шапки до заголовка 60 и от кнопки до низа блока 60
   (закон §3.0-A соблюдён и в самом макете). Сверху задано 54, а не 60: над заглавной буквой
   у Onest остаётся ~6px пустой кегельной площадки, и по ВИДИМОМУ краю выходит ровно 60. */
.hp-hero,#hero.hp-hero{position:relative;display:block;min-height:0;
  background:var(--background-bg);
  padding-top:calc(var(--promo-h) + var(--nav-h) + 54px);padding-bottom:60px}
/* #hero.hp-hero обязателен: базовое #hero — это ТОП-херо главной, он несёт
   min-height:100svh и align-items:flex-end. Здесь секция обычной высоты, и без сброса
   она растягивалась на весь экран, отодвигая заголовок на 410 вместо 60. */
/* Текст выровнен по ВЕРХУ, а не по центру: в макете 2143:8334 колонка текста (329)
   и фото (341) начинаются с одной линии. При центрировании заголовок опускался на 32px,
   и отступ от шапки переставал совпадать с нижним (закон §3.0-A). */
.hp-hero-in{display:grid;grid-template-columns:630fr 650fr;gap:80px;align-items:start}
.hp-hero-tx{display:flex;flex-direction:column;align-items:flex-start;gap:var(--sp-6)}

/* Заголовок с цветной меткой зала — та же связка, что на карточках в /halls.html:
   зал узнаётся по цвету раньше, чем прочитано имя. */
.hp-h1{margin:0;
  font-size:clamp(34px,4vw,56px);font-weight:700;line-height:1.1;letter-spacing:-.02em;
  color:var(--ink-cold)}
/* Десктоп не трогаем — он согласован. Кегли планшета и мобилки взяты из нод
   2192:11653 и 2203:14227 (оба 14), а не посчитаны из высоты строки. */
.hp-lead{margin:0;max-width:630px;color:var(--stone);font-size:18px;line-height:1.5}
.hp-hero-cta{margin-top:var(--sp-2)}
.hp-hero-cta .btn-mkk{height:56px;padding-inline:var(--sp-6)}

.hp-hero-ph{border-radius:var(--radius-lg);overflow:hidden}
.hp-hero-ph img{display:block;width:100%;height:341px;object-fit:cover}

/* ── Галерея зала ── */
.hp-shots{display:grid;grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--sp-5);
  margin-top:var(--sp-7)}
.hp-shot{display:block;border-radius:var(--radius-lg);overflow:hidden;
  background:var(--ice-1);cursor:zoom-in}
.hp-shot img{display:block;width:100%;height:239px;object-fit:cover;
  transition:transform .5s var(--ease-out)}
@media (hover:hover){
  .hp-shot:hover img{transform:scale(1.05)}
}
.hp-shot:focus-visible{outline:3px solid var(--cyan-2);outline-offset:2px}
@media (prefers-reduced-motion:reduce){
  .hp-shot img{transition:none}
  .hp-shot:hover img{transform:none}
}

/* ═══ ПЛАНШЕТ: страница зала ═══ */
@media (min-width:768px) and (max-width:991.98px){
  /* Числа планшетного макета 2192:11482: зазоры 64/64, две колонки 404/276 с gap 24,
     галерея в ЧЕТЫРЕ столбца по 164, цифры по 224. Я сначала свернул херо в одну колонку
     и галерею в три — обоего в макете нет. Сверху 58, а не 64: вычтена пустота
     над заглавной. */
  .hp-hero,#hero.hp-hero{padding-top:calc(var(--promo-h) + var(--nav-h) + 51px);padding-bottom:64px}
  /* Зазоры внутри текстовой колонки — из макета 2192:11650: заголовок → описание 12,
     описание → кнопка 32. Наследовались десктопные 32 и 40, и колонка выходила на 34px
     выше макетной: та же ширина, но заметно рыхлее (правка Романа). */
  .hp-hero-in{grid-template-columns:404fr 276fr;gap:var(--sp-5);align-items:stretch}
  .hp-hero-tx{gap:var(--sp-3)}
  .hp-hero-cta{margin-top:20px}
  /* Фото тянется до низа текста: в макете обе колонки по 238, но там описание умещается
     в 6 строк, а в вёрстке при том же кегле выходит 8 — фиксированная высота оставляла бы
     под фото дыру. Кадр обрезается по cover, композиция не страдает. */
  .hp-hero-ph{height:100%}
  .hp-hero-ph img{height:100%;min-height:238px}
  .hp-h1{font-size:32px}
  .hp-lead{font-size:14px;font-weight:500;line-height:1.3;letter-spacing:0;
    color:rgba(63,63,63,.8)}
  .hp-shots{grid-template-columns:repeat(4,minmax(0,1fr));gap:var(--sp-4);margin-top:var(--sp-6)}
  .hp-shot img{height:116px}
}

/* ═══ МОБИЛКА: страница зала ═══ */
@media (max-width:767.98px){
  /* Порядок из макета 2203:14224: заголовок → описание → ФОТО → кнопка. Кнопка живёт
     внутри текстовой колонки, поэтому на мобилке колонка распускается display:contents,
     и порядок задаётся order у прямых детей грида. Раньше кнопка шла до фото — не по макету,
     и правило равных полей считалось не от того элемента. */
  .hp-hero,#hero.hp-hero{padding-top:calc(var(--promo-h) + var(--nav-h) + 30px);padding-bottom:42px}
  /* Зазоры из макета 2203:14224: заголовок → описание 16, описание → фото 32,
     фото → кнопка 32. Колонка распущена display:contents, поэтому базовый зазор 16 задаёт
     сетка, а два места, где нужно 32, добираются margin-top. */
  .hp-hero-in{grid-template-columns:1fr;gap:var(--sp-4)}
  .hp-hero-tx{display:contents}
  .hp-hero-ph,.hp-hero-cta{margin-top:var(--sp-4)}
  .hp-h1{order:1}
  .hp-lead{order:2}
  .hp-hero-ph{order:3}
  .hp-hero-cta{order:4}
  .hp-h1{font-size:28px}
  .hp-lead{font-size:14px;font-weight:400;line-height:1.3;letter-spacing:0;
    color:rgba(63,63,63,.8)}
  .hp-hero-cta{width:100%}
  .hp-hero-cta .btn-mkk{width:100%;height:48px}
  .hp-hero-ph img{height:173px}

  /* Каунтеры на странице зала остаются ТРОЙКОЙ в ряд (макет 2203:14848): они короткие,
     а столбиком заняли бы пол-экрана. На «О клубе» подписи длинные («дорожек для керлинга»),
     поэтому там столбик — оттуда правило и наследовалось. Скоуп #hall, чтобы клуб не трогать. */
  #hall .ab-stats{grid-template-columns:repeat(3,minmax(0,1fr));gap:var(--sp-3)}
  #hall .ab-stat{padding:var(--sp-5) var(--sp-2);gap:4px}
  #hall .ab-stat-num{font-size:24px;letter-spacing:-.02em}
  #hall .ab-stat-label{font-size:14px;max-width:none}

  .hp-shots{grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-4);margin-top:var(--sp-5)}
  .hp-shot{border-radius:var(--r-md)}
  .hp-shot img{height:116px}
}


/* ═══════════════ ПРОСТО ПОИГРАТЬ (play.html) ═══════════════
   Figma 2159:9125 / 2159:9122 / 2203:18465. Херо, цены, скидки, отзывы и сцена — готовые
   блоки с других страниц. Здесь только новая фото-сетка. */

/* ── Херо: фото на всю ширину, поля по §3.0-A ── */
.hero-play .hero-photo{object-position:center 40%}
.hero-play .hero-in-page{padding-top:calc(var(--hero-gap) + var(--hero-head));
  padding-bottom:var(--hero-gap)}
/* --hero-head учитывает ДВА невидимых слагаемых, иначе сверху всегда просторнее:
   1) бокс заголовка выше видимой буквы на half-leading + (ascent − cap-height) — ~14px при 90px;
   2) на десктопе шапка ПРОЗРАЧНАЯ: её контейнер кончается на 110, а глаз видит низ кнопки
      на 100.5. Мерить надо от нижней «краски» шапки, а не от границы контейнера.
   На планшете и мобилке шапка — пилюля с фоном, там край контейнера и есть видимый край. */
.hero-play{--hero-gap:var(--sp-9);--hero-head:85px}
/* Десктоп: нижнее поле на 32px больше расчётного — правка Романа по факту на экране. */
@media (min-width:992px){
  .hero-play .hero-in-page{padding-bottom:calc(var(--hero-gap) + var(--sp-6))}
}
/* Скрим по макету 2159:9127: нейтрально-чёрный и СВЕТЛЕЕТ книзу — низ кадра должен
   оставаться фотографией, а не уходить в почти сплошную заливку. */
.hero-play .hero-scrim{background:linear-gradient(180deg,rgba(0,0,0,.55),rgba(0,0,0,.35))}
.hero-play .hero-h1-page{font-size:90px;line-height:1.1;font-weight:700;letter-spacing:0}
.hero-play .hero-page-sub{font-size:24px;line-height:1.3}
/* Кнопки херо: высоты из макета держим через height + flex, а не через паддинги —
   у .btn-mkk паддинги асимметричные, точную высоту на них не собрать. */
.hero-play .hero-cta{gap:var(--sp-5)}
.hero-play .hero-cta .btn-mkk{display:inline-flex;align-items:center;justify-content:center;
  height:56px;padding:0 var(--sp-6);font-size:16px;line-height:1.3}
/* Заливная кнопка в макете без обводки и с тёплым тёмным текстом. */
.hero-play .btn-mkk-light{border-color:transparent;color:var(--ink-body)}
/* Вторая кнопка — полностью прозрачная с чисто белой обводкой (макет). Базовый ghost
   даёт обводку в 25% белого — на фотофоне она почти пропадает. */
.hero-play .btn-mkk-ghost{background:transparent;color:#fff;border:1px solid #fff}
.hero-play .btn-mkk-ghost:hover{background:rgba(255,255,255,.14)}

/* ── Фото-сетка 4+1 ──
   Пропорции из макета: слева блок 781, справа 549 при зазоре 30 (кладём на шкалу — 32).
   Мелкие кадры 375.5×168, крупный 549×366. */
.pr-grid{display:grid;grid-template-columns:781fr 549fr;gap:var(--sp-6);align-items:stretch}
.pr-small{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-6)}
.pr-ph,.pr-big{position:relative;margin:0;border-radius:var(--r-md);overflow:hidden}
.pr-ph img,.pr-big img{display:block;width:100%;height:100%;object-fit:cover}
.pr-ph img{aspect-ratio:375.5/168}
/* Мелкие кадры в макете обведены светлой линией, у крупного её нет. Через inset-тень —
   чтобы обводка не меняла габарит внутри жёсткой сетки. */
.pr-ph{box-shadow:inset 0 0 0 1px rgba(255,255,255,.25)}

/* Плашки-условия поверх крупного кадра. Прижаты к левому нижнему углу, ширина по
   содержимому — в макете они разной длины и не тянутся на всю карточку. */
.pr-tags{position:absolute;left:var(--sp-5);bottom:var(--sp-5);
  display:flex;flex-direction:column;align-items:flex-start;gap:9px}
.pr-tag{display:inline-flex;align-items:center;gap:var(--sp-3);
  padding:12px;border-radius:var(--r-md);background:#fff;border:1px solid var(--border-blue);
  color:var(--ink-body);font-size:18px;font-weight:500;line-height:1.3}
.pr-tag-ic{flex:none;display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;border-radius:12px;background:var(--background-bg)}
/* Иконка в макете залита брендовым градиентом, а не плоским цианом. Через <img> внешний CSS
   в SVG не проникает и currentColor резолвится в чёрный — поэтому маска. */
.pr-ic{display:block;width:18px;height:18px;background:var(--grad-cta);
  -webkit-mask:var(--ic) center/contain no-repeat;mask:var(--ic) center/contain no-repeat}
.pr-ic-company{--ic:url(../assets/img/icon-company.svg)}
.pr-ic-level{--ic:url(../assets/img/icon-level.svg)}

/* Кнопки под сеткой — по центру, как в макете. */
.pr-cta{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--sp-5);margin-top:var(--sp-7)}

/* ── Финальная сцена: белый провал над льдом ──
   .cta-pin всегда 100vh, а высота сцены — функция ШИРИНЫ (svg viewBox 1007×432, height:auto).
   Значит чем уже окно, тем больше белого над льдом: на 1440 это 289px, а на 1220 уже 383px —
   ровно та «дыра», которую видно на промежуточных ширинах. Для ≤991.98px это уже вылечено
   выше (высота от вьюпорта); здесь тот же приём для десктопа, но пока только на этой
   странице — на остальных сцена в этом же состоянии и трогать их без спроса нельзя. */
/* Белое поле над сценой = высота экрана − высота сцены, а сцена растёт только от ШИРИНЫ
   (svg viewBox 1007×432). На 992–1439 она выходит низкой, и в пине высотой 100vh над ней
   зияет до 383px. Перебрали три пути:
   — короче пин: белое просто переезжает ПОД сцену (пин липнет к верху экрана);
   — растянуть сцену: slice режет бока, сцена «зумится», и камни финала мельчают относительно
     дома — они позиционируются в долях canvas (finale-stones.js), а зум их не масштабирует;
   — снять пин: сцена идёт своей натуральной высотой сразу за отзывами, белого нет вообще.
   Берём третий — ровно тот режим, что уже принят на планшете (ветка ≤991.98 ниже).
   ВАЖНО: у непин-раскладки своя шкала прогресса, поэтому граница обязана совпадать с
   условием MOB в finale-stones.js — иначе камни поедут по чужой шкале. */
@media (min-width:992px) and (max-width:1439.98px){
  .cta-scene-sec{height:auto;padding-block:0}
  .cta-pin{position:static;height:auto;display:block;overflow:hidden}
  .dom-scene,.dom-scene-svg{height:auto}
}
/* Отзывы → сцена: срезаем 40px (правка Романа по факту). Тянем сцену вверх, а не режем
   padding у #reviews: блок отзывов стоит и на страницах без сцены, а .cta-scene-sec —
   только там, где сцена есть. Работает в обоих режимах — и в непин-раскладке 992–1439,
   и в пине с 1440. */
@media (min-width:992px){
  .cta-scene-sec{margin-top:-40px}
}

/* Планшет: общая ветка ≤991.98 задаёт ленте фиксированные 240–320px. На мобилке это сцену
   УВЕЛИЧИВАЕТ (при 375px её натуральный рост всего ~161) и slice режет только бока — там всё
   верно. Но с 768px натуральная высота уже 380–425, то есть лента сцену СЖИМАЕТ, и slice
   срезает по 30px сверху и снизу — сверху как раз уходит растушёвка, вход в сцену становится
   резким порогом. Отдаём планшету натуральную высоту. */
@media (min-width:768px) and (max-width:991.98px){
  .dom-scene,.dom-scene-svg{height:auto}
}

/* ═══ ПЛАНШЕТ: просто поиграть ═══ */
@media (min-width:768px) and (max-width:991.98px){
  /* Пропорции из планшетного макета 2196:10081: слева 320, справа 360, зазор 24.
     Крупный кадр тут ШИРЕ мелкого блока — сетка не просто ужимается. */
  .pr-grid{grid-template-columns:320fr 360fr;gap:var(--sp-5)}
  .pr-small{gap:var(--sp-4)}
  .pr-tags{left:10px;bottom:10px;gap:9px}
  /* Радиус плашки 12, а не 8: карточка остаётся 16, отступ 10 — концентрично выходит 6,
     а по §4.4 берём БОЛЬШЕ формулы. 8 читались как «угол острее карточки». */
  .pr-tag{padding:var(--sp-2);border-radius:var(--r-sm);font-size:14px;gap:var(--sp-2)}
  .pr-tag-ic{width:24px;height:24px;border-radius:6px}
  .pr-ic{width:14px;height:14px}
  .pr-cta{margin-top:var(--sp-6);gap:var(--sp-3)}
  .hero-play .hero-h1-page{font-size:44px}
  /* Зазор подзаголовок→кнопки: 48 − 16 = 32 (правка Романа по факту на экране). */
  .hero-play .hero-page-sub{font-size:20px;margin-bottom:var(--sp-6)}
  .hero-play .hero-cta{gap:var(--sp-4)}
  .hero-play .hero-cta .btn-mkk{height:48px;padding:0 28px;font-size:14px}
  .hero-play{--hero-gap:var(--sp-7);--hero-head:86px}
  /* Нижнее поле на 32px больше расчётного — как на десктопе, правка Романа по факту. */
  .hero-play .hero-in-page{padding-bottom:calc(var(--hero-gap) + var(--sp-6))}
}

/* ═══ МОБИЛКА: просто поиграть ═══ */
@media (max-width:767.98px){
  /* Крупный кадр наверх — он и есть главный аргумент блока, а мелкие идут под ним
     парами. В одну колонку всё вытянулось бы на два экрана. */
  .pr-grid{grid-template-columns:1fr;gap:var(--sp-4)}
  .pr-big{order:-1;aspect-ratio:16/10}
  .pr-small{gap:var(--sp-3)}
  .pr-tags{left:10px;bottom:10px;gap:9px}
  /* Тот же расчёт, что на планшете: карточка 16, отступ 10 → формула 6, берём 12.
     Паддинг симметричный 8 (в макете 8 по кругу, высота плашки 40). */
  .pr-tag{padding:var(--sp-2);border-radius:var(--r-sm);font-size:12px;gap:var(--sp-2)}
  .pr-tag-ic{width:24px;height:24px;border-radius:6px}
  .pr-ic{width:14px;height:14px}
  /* Кнопки по содержимому и в одну строку, как в макете: растянутые во всю ширину
     читаются как форма, а не как выбор из двух действий. Размеры — те же мобильные,
     что у пары в херо, иначе «Забронировать дорожку» + «Скидки и акции» не помещаются. */
  .pr-cta{margin-top:var(--sp-5);gap:var(--sp-3)}
  .pr-cta .btn-mkk{display:inline-flex;align-items:center;justify-content:center;
    height:48px;padding:0 var(--sp-3);font-size:14px;line-height:1.3}
  .hero-play.hero-page,#hero.hero-play.hero-page{min-height:348px}
  .hero-play .hero-in-page{text-align:center;margin-top:0}
  /* 32px — из макета (там ширина 375), и ровно на этом кегле заголовок держится в ОДНУ
     строку. На 40px он ломался надвое. Ниже 375 (массовые 360) 32px уже не помещается,
     поэтому нижняя граница clamp — кегль слегка уступает, но строка остаётся одна. */
  .hero-play .hero-h1-page{font-size:clamp(28px,8.55vw,32px);margin-bottom:var(--sp-2)}
  .hero-play .hero-page-sub{font-size:16px}
  .hero-play .hero-cta{flex-direction:row;flex-wrap:wrap;justify-content:center;gap:var(--sp-3)}
  /* Паддинг 20 вместо базовых 28: только так обе кнопки (145 + 12 + 149) влезают
     в строку на 343px, как в макете. */
  .hero-play .hero-cta .btn-mkk{width:auto;height:48px;padding:0 20px;font-size:14px}
  /* --hero-head = 88 подобран так, что равенство полей держится при ЛЮБОМ зазоре
     (88 + оптсдвиг 5.5 ≈ высота шапки 93). Но зазор нельзя опускать ниже ~60: при меньшем
     высота блока падает под min-height:348, низ начинает держать распорка, а не паддинг,
     и поля разъезжаются (на 32 было 32 сверху против 84 снизу). */
  /* Правка Романа по факту: низ +18, верх −18. Сумма паддингов не изменилась, поэтому
     высота остаётся 352 и min-height:348 по-прежнему не вмешивается. */
  .hero-play{--hero-gap:60px;--hero-head:70px}
  .hero-play .hero-in-page{padding-bottom:calc(var(--hero-gap) + 18px)}
}


/* ═══════════════ ШКОЛА КЕРЛИНГА (school.html) ═══════════════
   Figma 2151:4104 / 2151:4101 / 2203:15024. Херо, цены, отзывы, сцена и «Практика» — готовые
   блоки, здесь только три новые сущности: полоса преимуществ, сетка «Почему керлинг»
   и раскладка «Тренерского состава». */

/* ── Полоса преимуществ (2159:8504) ──
   По макету: голубая подложка секции, белые карточки с рамкой --border-blue и радиусом 16,
   внутри плашка 40×40 радиусом 12 на том же голубом, в ней глиф 18×18. */
.sc-adv-sec{padding-block:var(--sp-7);background:var(--background-bg)}
.sc-adv{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:1fr;
  gap:var(--sp-6);margin:0;padding:0;list-style:none}
/* Четыре в ряд — только на макетной ширине. Между 992 и 1439 колонка ужимается настолько,
   что каждый пункт ломается на своё число строк, и карточки перестают быть одной высоты.
   grid-auto-rows:1fr держит ряд равным по высоте на любом брейкпойнте. */
@media (min-width:1440px){
  .sc-adv{grid-template-columns:repeat(4,minmax(0,1fr))}
}
.sc-adv-i{display:flex;align-items:center;gap:var(--sp-4);padding:var(--sp-5);
  background:var(--ice-0);border:1px solid var(--border-blue);border-radius:var(--r-md);
  color:var(--ink-body);font-size:18px;font-weight:500;line-height:1.3}
.sc-adv-ic{flex:none;display:inline-flex;align-items:center;justify-content:center;
  width:40px;height:40px;border-radius:12px;background:var(--background-bg)}
/* Глиф залит брендовым градиентом через маску — тем же приёмом, что .pr-ic: сквозь <img>
   внешний CSS в SVG не проходит и currentColor резолвится в чёрный. */
.sc-adv-gl{width:18px;height:18px;background:var(--grad-cta);
  -webkit-mask:var(--ic) center/18px 18px no-repeat;mask:var(--ic) center/18px 18px no-repeat}
.sc-adv-gl-program{--ic:url(../assets/img/icon-program.svg)}
.sc-adv-gl-cup{--ic:url(../assets/img/icon-cup.svg)}
.sc-adv-gl-camp{--ic:url(../assets/img/icon-camp.svg)}
.sc-adv-gl-person{--ic:url(../assets/img/icon-person.svg)}

/* ── Почему керлинг (2160:10535) ──
   Сетка 2×2 равных кадров во всю ширину. Аспект 3:2 обязателен: базовый .pr-ph несёт
   панорамный 375.5/168, в нём плашка занимает пол-кадра. */
.sc-why-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-6)}
.sc-why-ph img{aspect-ratio:3/2}
/* Белая плашка на светлом льду теряет нижний край — притеняем низ кадра. */
.sc-why-ph::after{content:'';position:absolute;inset:auto 0 0;height:45%;
  background:linear-gradient(transparent,rgba(20,48,60,.3));pointer-events:none}
.sc-why-ph .pr-tags{z-index:1}
.sc-why-ph .pr-tag{font-size:17px}
#why .pr-cta{margin-top:var(--sp-7)}

/* ── Тренерский состав (2151:4287) ──
   Кадр слева, текст справа — зеркально к соседнему блоку, чтобы два фото-блока подряд
   не читались одинаково. */
.sc-coaches-sec{background:var(--background-bg)}
.sc-coach-grid{display:grid;grid-template-columns:665fr 630fr;gap:var(--sp-6);align-items:stretch}
.sc-coach-shot{position:relative;margin:0;border-radius:var(--r-lg);overflow:hidden}
.sc-coach-shot img{display:block;width:100%;height:100%;object-fit:cover}
/* Три группы: бейджи, текст (герой+хвост) и кнопка. Общий gap делал все зазоры равными,
   и группы читались одним потоком — закон «внешнее ≥ внутреннее». Разводим поэлементно. */
.sc-coach-tx{display:flex;flex-direction:column;gap:0}
/* Регалии вынесены из сплошного абзаца пилюлями — приём с «Кухни» ресторана. */
.sc-regalia{display:flex;flex-wrap:wrap;gap:var(--sp-3);margin:0;padding:0;list-style:none}
.sc-regalia li{padding:6px var(--sp-4);border:1px solid var(--border-blue);border-radius:100px;
  background:var(--ice-0);color:var(--ink-cold);font-size:14px;font-weight:500;line-height:1.4}
.sc-coach-hero{margin:var(--sp-6) 0 0;color:var(--ink-cold);font-size:clamp(24px,2.4vw,32px);
  font-weight:600;line-height:1.25;text-wrap:balance}
.sc-coach-tail{margin:var(--sp-4) 0 0;color:var(--ink-body);font-size:16px;line-height:1.6;max-width:56ch}
.sc-coach-cta{align-self:flex-start;margin-top:auto}

/* ═══ ПЛАНШЕТ: школа ═══ */
@media (min-width:768px) and (max-width:991.98px){
  /* Преимущества 2×2 (2195:8715), сетка кадров остаётся 2×2, тренеры стакаются. */
  .sc-adv{grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-4)}
  .sc-adv-i{padding:var(--sp-3);gap:var(--sp-3);font-size:16px}
  .sc-why-grid{gap:var(--sp-4)}
  .sc-why-ph .pr-tag{font-size:14px}
  .sc-coach-grid{grid-template-columns:1fr;gap:var(--sp-5)}
  .sc-coach-shot{aspect-ratio:16/9;border-radius:var(--r-md)}
  .sc-coach-hero{margin-top:var(--sp-5);font-size:22px}
  .sc-coach-tail{margin-top:var(--sp-3)}
  .sc-coach-tail{font-size:14px;line-height:1.45}
  .sc-coach-cta{margin-top:var(--sp-5)}
  /* §2.1: на планшете .price-block зажимает карточки и дисклеймер в --cards-w и центрирует их,
     а шапку оставляет на всю ширину — края блока разъезжаются (шапка 845 против карточек 616).
     Сажаем шапку на ту же ширину. Скоуп страницы: на других страницах блок уже принят. */
  .page-school #prices .prices-heading{max-width:var(--cards-w);margin-inline:auto}
}

/* Карточки цен: равная высота + кнопка по нижнему краю.
   База даёт .price-card{height:100%} — процент от родителя с авто-высотой не резолвится,
   но height формально задан и ОТМЕНЯЕТ align-items:stretch, поэтому короткая карточка
   оставалась на 39px ниже. Возвращаем auto, и flex растягивает обе. Кнопку прижимаем
   margin-top:auto, чтобы лишняя высота уходила в промежуток, а не под кнопку. */
/* Карточки цен равной высоты, кнопка прижата к низу — договорённость Романа, общее для
   всех страниц с .gc-price-row (school / gift / corporate / night). height:auto снимает
   .price-card{height:100%}, который во flex-ряду отменяет растягивание. */
.gc-price-row .price-card{height:auto}
.gc-price-row .price-card-cta,
.gc-price-row .price-card-btns{margin-top:auto}
/* night/corporate/birthday: карточки цен лежат в Bootstrap-ряду .price-cards (col-lg-4),
   а не в .gc-price-row. height:100% (базовый) даёт равную высоту через stretch колонок,
   margin-top:auto прижимает кнопку к низу более короткой карточки. */
.price-cards .price-card-cta,
.price-cards .price-card-btns{margin-top:auto}

/* ═══ МОБИЛКА: школа ═══ */
@media (max-width:767.98px){
  /* Преимущества столбиком (2203:15733), кадры «Почему» — по одному в ряд. */
  .sc-adv{grid-template-columns:1fr;gap:var(--sp-3)}
  .sc-adv-i{padding:var(--sp-3);gap:var(--sp-3);font-size:16px}
  .sc-adv-ic{width:32px;height:32px;border-radius:10px}
  .sc-adv-gl{width:16px;height:16px;-webkit-mask-size:16px 16px;mask-size:16px 16px}
  .sc-why-grid{grid-template-columns:1fr;gap:var(--sp-4)}
  .sc-why-ph img{aspect-ratio:16/10}
  .sc-why-ph .pr-tag{font-size:13px}
  #why .pr-cta{margin-top:var(--sp-5)}
  .sc-coach-grid{grid-template-columns:1fr;gap:var(--sp-4)}
  .sc-coach-shot{aspect-ratio:16/10;border-radius:var(--r-md)}
  .sc-regalia{gap:var(--sp-2)}
  .sc-coach-hero{margin-top:var(--sp-6);font-size:20px}
  .sc-coach-tail{margin-top:var(--sp-3)}
  .sc-coach-tail{font-size:14px;line-height:1.5}
  .sc-coach-cta{margin-top:var(--sp-6);align-self:stretch;text-align:center}
  /* «Записаться на тренировку» длиннее play-овского «Забронировать»: при паддинге 20 паре
     не хватало 8px до строки. Скоуп .hero-school — геометрия play остаётся нетронутой
     (селекторы равной силы, этот раздел ниже в файле). */
  .hero-school .hero-cta .btn-mkk{padding:0 var(--sp-4)}
}


/* ═══════════════ ВЫПУСКНЫЕ (graduation.html) ═══════════════
   Figma 2167:10172 / 2197:9644 / 2203:28066. Херо, блок о клубе, «почему именно мы», отзывы
   и сцена — блоки шаблона «День рождения». Новое здесь: блок программ и модалка «Подробнее». */

/* Мобильный перенос заголовка херо: в макете H1 на мобилке разбит на ТРИ строки, на десктопе
   и планшете — на две. */
.hero-grad .br-mob{display:none}
/* Херо 1 в 1 по макету 2167:10174: кегль 72, кнопка 56 высотой, поле под кнопкой 130.
   Шаблонный .hero-birthday несёт 64/51/120 — на этой странице переопределяем. */
.hero-grad .hero-h1-page{font-size:72px;line-height:1.1}
.hero-grad .hero-page-sub{font-size:24px;line-height:1.3}
.hero-grad .hero-cta .btn-mkk{height:56px;padding:0 var(--sp-6);font-size:16px}
.hero-grad .hero-in-page{padding-bottom:130px}
/* Ночные: подзаголовок длинный, при 800px ломается на 4 строки — расширяем до 3 (Роман).
   На планшете/мобилке контейнер уже 880, поэтому правило влияет только на десктопе. */
.hero-night .hero-page-sub{max-width:880px}

/* ── Программы для выпускного (2167:10252) ── */
.pg-sec{background:#F7FBFF;border-radius:32px;padding-block:100px}
.pg-head{margin-bottom:56px;text-align:center}
.pg-head h2{margin:0;color:var(--ink-body);font:700 48px/1.2 'Onest',sans-serif}
.pg-grid{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:1fr;gap:30px}
/* Карточка по макету: белая, тонкая голубая рамка, радиус 16, паддинг 24, содержимое по центру. */
.pg-card{display:flex;flex-direction:column;align-items:center;gap:var(--sp-6);
  padding:var(--sp-5);background:var(--ice-0);border:1px solid var(--border-blue);
  border-radius:var(--r-md);overflow:hidden;text-align:center}
.pg-ic{flex:none;width:100px;height:100px;object-fit:contain}
.pg-name{margin:0;color:var(--ink-body);font:600 30px/1.3 'Onest',sans-serif}
.pg-desc{margin:0;max-width:34ch;color:rgba(63,63,63,.8);font:400 16px/1.4 'Onest',sans-serif}
.pg-cta{display:flex;flex-wrap:wrap;justify-content:center;gap:var(--sp-4);margin-top:auto}
/* «Подробнее» — прозрачная с обводкой; в проекте такого варианта не было, поэтому описываем
   его здесь, а не изобретаем новый btn-mkk-*. */
.pg-more{background:none;border:1px solid rgba(63,63,63,.8);color:rgba(63,63,63,.8)}
.pg-more:hover{background:rgba(63,63,63,.06);color:var(--ink-body)}

/* ── Модалка «Подробнее» (2172:14337) ── */
.pg-modal{position:fixed;inset:0;z-index:1100;display:flex;align-items:center;justify-content:center;
  padding:var(--sp-6)}
.pg-modal[hidden]{display:none}
.pg-modal-scrim{position:absolute;inset:0;background:rgba(0,0,0,.1);
  backdrop-filter:blur(2.5px);-webkit-backdrop-filter:blur(2.5px)}
.pg-modal-card{position:relative;display:flex;flex-direction:column;gap:var(--sp-5);
  width:min(800px,100%);max-height:calc(100vh - 64px);padding:var(--sp-5);
  background:var(--ice-0);border-radius:24px;overflow:hidden;
  animation:pgModalIn .28s var(--ease-out) both}
@keyframes pgModalIn{from{opacity:0;transform:translateY(12px) scale(.98)}to{opacity:1;transform:none}}
.pgm-top{display:flex;flex-direction:column;gap:var(--sp-4);flex:none}
.pgm-head{display:flex;align-items:center;justify-content:space-between;gap:var(--sp-4)}
.pgm-head h2{margin:0;flex:1;color:var(--ink-body);font:600 24px/1.3 'Onest',sans-serif}
.pgm-close{flex:none;display:inline-flex;align-items:center;justify-content:center;
  width:32px;height:32px;padding:8px;border:0;border-radius:1000px;
  background:var(--background-bg);color:var(--ink-body);cursor:pointer}
.pgm-close:hover{background:var(--ice-2)}
.pgm-badges{display:flex;gap:var(--sp-3)}
.pgm-badge{flex:1;display:flex;flex-direction:column;align-items:center;gap:var(--sp-1);
  padding:var(--sp-3);background:var(--background-bg);border-radius:8px;text-align:center}
.pgm-badge span{color:rgba(63,63,63,.8);font:400 14px/1.3 'Onest',sans-serif}
.pgm-badge b{color:var(--ink-body);font:600 20px/1.3 'Onest',sans-serif}
.pgm-div{height:1px;background:var(--border-blue)}
/* Тело прокручивается само: описание разных программ разной длины, а окно не должно
   выпрыгивать за экран. */
.pgm-body{display:flex;flex-direction:column;gap:var(--sp-6);overflow-y:auto;overscroll-behavior:contain}
.pgm-sec{display:flex;flex-direction:column;gap:20px}
.pgm-sec h3{margin:0;color:var(--ink-body);font:500 18px/1.3 'Onest',sans-serif}
.pgm-text{display:flex;flex-direction:column;gap:var(--sp-4)}
.pgm-text p{margin:0;color:rgba(63,63,63,.8);font:400 16px/1.4 'Onest',sans-serif}
.pgm-text b{color:var(--ink-body);font-weight:600}
.pgm-menu{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:var(--sp-3);
  margin:0;padding:0;list-style:none}
.pgm-menu-card{padding:var(--sp-4);background:var(--background-bg);border-radius:12px}
.pgm-menu-n{display:block;margin-bottom:var(--sp-3);color:var(--ink-body);
  font:600 16px/1.3 'Onest',sans-serif}
.pgm-menu-card ul{display:flex;flex-direction:column;gap:6px;margin:0;padding:0;list-style:none}
.pgm-menu-card li{display:flex;align-items:baseline;justify-content:space-between;gap:var(--sp-3);
  color:rgba(63,63,63,.8);font:400 14px/1.35 'Onest',sans-serif}
.pgm-menu-card li b{flex:none;color:var(--ink-body);font-weight:500}
.pgm-menu-total{padding-top:6px;border-top:1px solid var(--border-blue)}
.pgm-actions{display:flex;flex-wrap:wrap;gap:var(--sp-3);flex:none}

/* ═══ ПЛАНШЕТ: выпускные ═══ */
@media (min-width:768px) and (max-width:991.98px){
  .pg-sec{padding-block:var(--sp-8);border-radius:24px}
  .pg-head{margin-bottom:var(--sp-6)}
  .pg-head h2{font-size:24px;line-height:1.3}
  .pg-grid{gap:var(--sp-3)}
  .pg-card{gap:var(--sp-4);padding:var(--sp-5)}
  .pg-ic{width:54px;height:54px}
  .pg-name{font-size:20px}
  .pg-desc{font-size:14px}
  .pg-cta{gap:var(--sp-3)}
  /* Херо планшета по макету 2197:9645: 44/18, кнопка 48, поле под кнопкой 64. */
  .hero-grad .hero-h1-page{font-size:44px;line-height:1.2;letter-spacing:-.02em}
  .hero-grad .hero-page-sub{font-size:18px}
  .hero-grad .hero-cta .btn-mkk{height:48px;padding:0 var(--sp-5);font-size:14px}
  .hero-grad .hero-in-page{padding-bottom:var(--sp-8)}
  .pg-modal{padding:var(--sp-5)}
  .pg-modal-card{width:min(664px,100%);max-height:calc(100vh - 48px);padding:var(--sp-4);gap:var(--sp-4)}
  .pgm-head h2{font-size:20px}
  .pgm-badge b{font-size:18px}
  .pgm-body{gap:var(--sp-5)}
  .pgm-sec{gap:var(--sp-4)}
  .pgm-menu{gap:var(--sp-3)}
}

/* ═══ МОБИЛКА: выпускные ═══ */
@media (max-width:767.98px){
  .hero-grad .br-mob{display:inline}
  .pg-sec{padding-block:var(--sp-7);border-radius:20px}
  .pg-head{margin-bottom:var(--sp-6)}
  .pg-head h2{font-size:24px;line-height:1.3}
  .pg-grid{grid-template-columns:1fr;gap:var(--sp-4)}
  .pg-card{gap:var(--sp-4);padding:var(--sp-5)}
  .pg-ic{width:54px;height:54px}
  .pg-name{font-size:20px}
  .pg-desc{font-size:14px}
  .pg-cta{flex-direction:column;align-items:stretch;gap:var(--sp-3);width:100%}
  /* Херо мобилки по макету 2203:28074: 32/16, три строки заголовка. */
  .hero-grad .hero-h1-page{font-size:32px;line-height:1.1}
  .hero-grad .hero-page-sub{font-size:16px}
  .hero-grad .hero-cta .btn-mkk{height:48px;padding:0 var(--sp-5);font-size:14px}
  /* Нижнее поле херо +24 на всех страницах шаблона (Роман: выпускной/корп/ночной). */
  .hero-grad .hero-in-page{padding-bottom:calc(var(--sp-7) + 24px)}
  .pg-modal{padding:var(--sp-4)}
  .pg-modal-card{width:100%;max-height:calc(100vh - 32px);padding:var(--sp-4);gap:var(--sp-4);
    border-radius:var(--r-md)}
  .pgm-head h2{font-size:18px}
  .pgm-badges{gap:var(--sp-2)}
  .pgm-badge{padding:var(--sp-3) var(--sp-2)}
  .pgm-badge span{font-size:12px}
  .pgm-badge b{font-size:16px}
  .pgm-body{gap:var(--sp-5)}
  .pgm-sec{gap:var(--sp-3)}
  .pgm-sec h3{font-size:16px}
  .pgm-text p{font-size:14px}
  .pgm-menu{grid-template-columns:1fr;gap:var(--sp-3)}
  .pgm-actions{flex-direction:column;align-items:stretch}
}


/* ═══════════════ КОРПОРАТИВЫ + НОЧНЫЕ (corporate.html / night.html) ═══════════════
   Обе — шаблон birthday. Новое: блок услуг корпоративов (3 карточки с PDF) и раскладка 3+2
   «Практических преимуществ» ночных. Херо обеих — класс hero-grad (утверждён на выпускных). */

/* ── Не только керлинг (корпоративы, 2169:13230): три карточки-услуги ── */
.co-sec{background:#F7FBFF;border-radius:32px;padding-block:100px}
.co-head{margin-bottom:56px;text-align:center}
.co-head h2{margin:0;color:var(--ink-body);font:700 48px/1.2 'Onest',sans-serif}
.co-grid{display:grid;grid-template-columns:repeat(3,minmax(0,1fr));grid-auto-rows:1fr;gap:30px}
.co-card{display:flex;flex-direction:column;align-items:center;gap:var(--sp-6);
  padding:var(--sp-5);background:var(--ice-0);border:1px solid var(--border-blue);
  border-radius:var(--r-lg);overflow:hidden;text-align:center}
.co-ic{flex:none;width:80px;height:80px;object-fit:contain}
.co-card-tx{display:flex;flex-direction:column;gap:var(--sp-3)}
.co-card-tx h3{margin:0;color:var(--ink-body);font:600 24px/1.3 'Onest',sans-serif}
.co-card-tx p{margin:0;color:rgba(63,63,63,.8);font:400 16px/1.4 'Onest',sans-serif}
.co-pdf{margin-top:auto;align-self:stretch}

/* ── Практические преимущества (ночные, 2172:15298): сетка 3+2 ──
   Верхний ряд — 3 карточки, нижний — 2 широкие. Каркас .gc-why-card переиспользован. */
.gc-why-3-2{grid-template-columns:repeat(6,1fr)}
.gc-why-3-2 .gc-why-card{grid-column:span 2}
.gc-why-3-2 .gc-why-card.nc-wide{grid-column:span 3}

/* ═══ ПЛАНШЕТ ═══ */
@media (min-width:768px) and (max-width:991.98px){
  .co-sec{padding-block:var(--sp-8);border-radius:24px}
  .co-head{margin-bottom:var(--sp-6)}
  .co-head h2{font-size:24px;line-height:1.3}
  /* На планшете три карточки в столбик: иконка+кнопка в верхнем ряду, ниже текст. */
  .co-grid{grid-template-columns:1fr;grid-auto-rows:auto;gap:var(--sp-3)}
  /* Верхний ряд: иконка слева + кнопка «Презентация» справа (по макету), текст на всю ширину ниже. */
  .co-card{display:grid;grid-template-columns:60px 1fr auto;grid-template-areas:'ic . btn' 'tx tx tx';
    align-items:center;gap:var(--sp-4);padding:var(--sp-5);border-radius:var(--r-md);text-align:left}
  .co-ic{width:60px;height:60px;grid-area:ic}
  .co-card-tx{grid-area:tx}
  .co-card-tx h3{font-size:20px}
  .co-card-tx p{font-size:14px}
  .co-pdf{grid-area:btn;margin-top:0;align-self:center;justify-self:end}
  /* Преимущества: 3+2 схлопывается в 2 колонки, широкие тянутся на всю ширину. */
  /* По макету планшета все 5 карточек — одна колонка на всю ширину. В 2 колонки нечётная
     короткая карточка висела одна рядом с пустотой (фидбэк Романа). */
  .gc-why-3-2{grid-template-columns:1fr}
  .gc-why-3-2 .gc-why-card,.gc-why-3-2 .gc-why-card.nc-wide{grid-column:auto}
  /* Планшет+корп: нижнее поле херо +24 (Роман). */
  .hero-cn .hero-in-page{padding-bottom:calc(var(--sp-8) + 24px)}
}

/* ═══ МОБИЛКА ═══ */
@media (max-width:767.98px){
  .co-sec{padding-block:var(--sp-7);border-radius:20px}
  .co-head{margin-bottom:var(--sp-6)}
  .co-head h2{font-size:24px;line-height:1.3}
  .co-grid{grid-template-columns:1fr;grid-auto-rows:auto;gap:var(--sp-4)}
  .co-card{gap:var(--sp-4);padding:var(--sp-5);border-radius:var(--r-md)}
  .co-ic{width:60px;height:60px}
  .co-card-tx h3{font-size:20px}
  .co-card-tx p{font-size:14px}
  /* Преимущества: всё в одну колонку, широкие ничем не отличаются. */
  .gc-why-3-2{grid-template-columns:1fr}
  .gc-why-3-2 .gc-why-card,.gc-why-3-2 .gc-why-card.nc-wide{grid-column:auto}
}

/* ── Заглушка праздников (holiday-soon.html) ── */
.holiday-soon .hs-emoji{width:96px;height:96px;object-fit:contain;margin-bottom:var(--sp-2)}
@media (max-width:767.98px){.holiday-soon .hs-emoji{width:72px;height:72px}}

/* Служебный светлый футер (404): без фото-фона и формы — только белая карточка навигации
   на светлом фоне. Растянут во всю ширину, фон страницы. */
.footer-plain{position:relative;background:var(--background-bg);color:var(--ink-body)}
.footer-plain .footer-in{padding-block:var(--sp-7)}
