/* Mobile owner: sigma.css */
@media (width < 1024px) {/* Manrope хранится на своём домене: variable-файл покрывает реальные веса
   400–700, а metric-compatible fallback резервирует близкую геометрию до
   загрузки 54-КБ WOFF2. Это сохраняет фирменный шрифт без внешнего Google
   Fonts и убирает позднюю перекомпоновку текста на мобильных устройствах. */
@font-face{
  font-family:'Manrope';
  src:url('/assets/fonts/manrope-var-69912a93.woff2') format('woff2-variations');
  font-style:normal;
  font-weight:400 700;
  font-display:swap;
}
@font-face{
  font-family:'Manrope Fallback';
  src:local('Arial');
  size-adjust:104.13%;
  ascent-override:106.6%;
  descent-override:30%;
  line-gap-override:0%;
}
/* ===== SIGMA CLUB — дизайн-система =====
   Единая гарнитура Manrope. Один золотой акцент на всех страницах и
   направлениях — ничего (кнопки, рамки, бейджи, цены, SubbrandMark)
   больше не красится по-разному в зависимости от направления. */

.skip-link{position:fixed;z-index:10000;top:8px;left:8px;max-width:calc(100vw - 16px);
  padding:12px 16px;border:2px solid var(--accent);border-radius:var(--r-sm);
  background:var(--bg);color:var(--text);font-weight:600;text-decoration:none;
  transform:translateY(calc(-100% - 16px));transition:transform var(--t-micro)}
.skip-link:focus,.skip-link:focus-visible{transform:translateY(0);outline:2px solid var(--text);outline-offset:2px}


:root{
  /* V9 Пакет 1, §1.7: согласованное владельцем визуальное улучшение (не
     регрессия — --bg/--card/--card2 не изменены со времени введения,
     проверено по истории). Минимальный шаг только на --line: обычная
     карточка чуть увереннее отделяется от чёрного фона. --bg, --card,
     --card2, opacity, золотые рамки (--border-emphasis, --gold-dim) не
     трогать — если рамки станут заметно ярче или сайт начнёт напоминать
     панель управления, откатить именно этот один токен. */
  /* Аудит при ярком внешнем свете 26.08.2026: второй осторожный шаг
     #25211D → #2B2722; меняется только обычная системная линия. */
  --bg:#0A0A0A; --card:#151310; --card2:#1b1613; --line:#2B2722;
  --text:#F0EDE8; --muted:#B0ABA2;
  --accent:#CF8A52; --accent-text:#E4A971; --accent-dim:#8D5E38; --on-accent:#1A1208;
  --subbrand-color:var(--accent-text);
  /* обратная совместимость со старыми именами токенов в шаблонах — тоже единые */
  --panel:var(--card); --panel2:var(--card2); --gold:var(--accent); --gold-dim:var(--accent-dim);
  --r:22px;
  /* Visual system 17.08.2026, батч 2: small/large/pill из шкалы аудита —
     добавлены только там, где значение уже дословно повторяется в файле
     (8px — фокус-рамка disclosure, 14px — поля форм и компактные карточки,
     28px — большие панели, 999px — таблетки). Единичные соседние значения
     (12/16/18/20/24px у отдельных компонентов) не сведены к этой шкале —
     задача убрать дрейф там, где он есть, а не сжать всё в 5 чисел. */
  --r-sm:8px;
  --r-md:14px;
  --r-lg:28px;
  --r-pill:999px;
  /* Семантические имена сохраняют уже согласованную геометрию, но больше
     не заставляют компоненты угадывать роль по абстрактному sm/md/lg. */
  --r-focus:var(--r-sm);
  --r-control:var(--r-md);
  --r-compact:16px;
  --r-card:var(--r);
  --r-feature:var(--r-lg);
  --control-primary-h:50px;
  --control-secondary-h:46px;
  --control-tertiary-h:44px;
  /* Visual system 17.08.2026, батч 2: durations сведены к 4 ролям вместо
     6 разных чисел (.12/.18/.2/.22/.25/.26/.5s), без добавления новых
     анимаций. --t-micro — мгновенные hover-цвета/подчёркивания, --t-base —
     наведение на карточки и поворот шеврона, --t-reveal — появление
     полноэкранных панелей (модалка связи), --t-ambient — вращение
     GoldMedallion (9s, значение не меняется, только именуется). --ease —
     существующая фирменная кривая .route (карточки направлений на
     главной), сохранена как токен для будущего переиспользования, но НЕ
     подставлена в сам .route — тот блок явно не трогается в этой задаче. */
  --t-micro:.18s;
  --t-base:.2s;
  --t-reveal:.28s;
  --t-ambient:9s;
  --ease:cubic-bezier(.2,.7,.3,1);
  /* Visual system 17.08.2026, батч 2: единый semantic-токен вместо двух
     вариантов акцентной рамки (var(--gold-dim) 1px и var(--accent-dim)
     1.4px — по факту один и тот же цвет, т.к. --gold-dim это алиас
     --accent-dim, разница была только в ширине 0.4px). Третий вариант из
     аудита, rgba(207,138,82,.28) на .hb-badge (GoldMedallion), сюда
     сознательно НЕ включён — по соседнему комментарию его цвет откалиброван
     с заказчиком и заморожен, сведение к другому значению было бы визуальным
     изменением, а не устранением дрейфа. */
  --border-emphasis:1px solid var(--accent-dim);
  /* Градиентная система 27.08.2026. У интерфейсных поверхностей остаются
     только две роли: единая мягкая акцентная поверхность для действительно
     выделенных предложений и отдельная поверхность фирменного медальона.
     Фотооверлеи, подсказка горизонтального скролла и нейтральный media-slot
     ниже остаются локальными функциональными градиентами. */
  --surface-accent:linear-gradient(155deg,rgba(207,138,82,.07),var(--panel) 62%);
  --surface-medallion:linear-gradient(155deg,rgba(207,138,82,.10),var(--card2) 70%);
  /* Высота шапки — единая точка правды. От неё считаются top мобильного меню
     (#nav) и верх top-sheet связи (.cp-overlay): раньше 52px (51px + рамка)
     были вбиты числом в трёх местах и при любой правке расходились. */
  --hdr-h:60px;
  /* --- desktop-сетка + типографика (ТЗ 11.08.2026 «восстановление UI-системы») —
     заменяет батч 10.08.2026 §4: тот впервые ввёл spacing-токены поверх старых
     локальных inline-отступов/page-CSS, не убрав их — из-за этого страницы
     получали двойной ритм. Контейнер 1760px и section-gap до 88px там же
     оказались шире целевых границ (см. PLAN_SIGMA_UI_RESTORE.md §2–4). */
  --gutter:clamp(20px,3vw,56px);
  --wrap-max:1440px;
  --measure:min(72ch,720px);
  /* ===== СЕМАНТИЧЕСКИЙ РИТМ (M09, R-6) =====================================
     Раньше значения отступов не имели ролей: gap/padding/margin разного
     масштаба выглядели одним «долгом», и сравнение любых gap с одним списком
     токенов давало ложную цель. Ритм объявлен по четырём смысловым уровням,
     и отклонение считается только внутри своего уровня:

       section    между модулями страницы верхнего уровня
       cluster    между блоками внутри одного модуля
       component  внутри коробки компонента
       inline     между соседними элементами одной строки

     Дальше — роли внутри семейства: границу держит имя роли, а не число в
     месте применения. Значение, сознательно уходящее от шага своего уровня,
     объявляется именованным исключением с владельцем, а не остаётся магическим
     числом; реестр исключений с эталонными снимками лежит в
     scripts/fixtures/v4-rhythm-exceptions.json и проверяется
     scripts/test-v4-rhythm-contract.js.

     Прежние имена (--sp-*, --card-pad*, --grid-gap) сохранены как псевдонимы:
     они остаются точкой чтения для всех существующих правил, но перестали быть
     точкой объявления — у каждого уровня она теперь ровно одна на режим. */
  --rhythm-section:36px;
  /* Visual system 17.08.2026, батч 3, §3 ТЗ владельца: было 18px — по аудиту
     /pro целиком шёл на этом шаге вместо системных переходов (см. также
     локальные margin-top:18px в pro.html/massage.html/contacts.html,
     переведённые на этот токен в том же батче). 24px выравнивает mobile с
     desktop — с M09 это одно объявление на все три режима, а не три
     одинаковых. */
  --rhythm-cluster:24px;
  --rhythm-component:18px;
  --rhythm-inline:14px;
  /* Роли внутри семейств. */
  --rhythm-cluster-grid:14px;   /* cluster: щель сетки между блоками модуля */
  --rhythm-heading-body:16px;   /* cluster: заголовок → текст */
  --rhythm-proof:14px;          /* cluster: текст → блок доказательства */
  --rhythm-action:24px;         /* cluster: доказательство → действие */
  --rhythm-component-lg:24px;   /* component: крупная коробка */
  --rhythm-card-row:10px;       /* component: строка карточки → строка */
  --rhythm-card-action:4px;     /* component: последняя строка → действие */
  /* Именованные исключения уровня section. Оба сознательно уходят от шага
     --rhythm-section и потому названы, а не вписаны числом по месту:
     --rhythm-section-wide — широкий шаг Desktop V4 у /space и у карточки
     «другие мастера» (владелец: композиция /space, M07);
     --rhythm-module-footer — переход «последний модуль → футер», сознательно
     теснее шага секции (владелец: откат ритма футера 16.08.2026 ниже). */
  --rhythm-section-wide:clamp(44px,5vw,80px);
  --rhythm-module-footer:22px;
  /* Плотный шаг секции: маршруты со стопкой коротких модулей (/pro, /school,
     /blog, /massage, профиль мастера, мост «дальше») ставят их ближе, чем шаг
     страницы. До M09 это читалось как «секция взяла кластерный токен» — то же
     число на другом уровне. Уровень теперь свой: значение совпадает с
     --rhythm-cluster сегодня, но объявлено отдельно, потому что это отдельная
     смысловая роль и менять их вместе нельзя. */
  --rhythm-section-dense:24px;
  /* Псевдонимы прежних имён. */
  --grid-gap:var(--rhythm-cluster-grid);
  --sp-section:var(--rhythm-section);
  --sp-block:var(--rhythm-cluster);
  --sp-eyebrow:var(--rhythm-inline);
  --sp-headlead:var(--rhythm-heading-body);
  --card-pad:var(--rhythm-component);
  --card-pad-lg:var(--rhythm-component-lg);

  /* Единая типографическая шкала — один h1-токен на весь сайт (максимум 38px:
     решение 11.08.2026, заменяет прежнее разделение base/service H1). */
  --fs-h1:clamp(29px,4.5vw,38px);
  --fs-h2:clamp(24px,3vw,30px);
  --fs-h3:clamp(19px,2vw,22px);
  --fs-lead:clamp(15px,1.6vw,17px);
  --fs-body:16px;
  /* Батч 0 (15.08.2026): display-уровень — крупнее H1, но это не заголовок
     (цитата миссии /about, цифра рейтинга в trust-карточке). Раньше это были
     два разных «магических» clamp() без общей точки — теперь один токен,
     см. docs/SIGMA_IMPLEMENTATION_PLAN.md §0.2. */
  --fs-display:clamp(26px,4.4vw,42px);
  /* Visual system 17.08.2026, батч 2: три недостающие роли из типографической
     шкалы аудита. Из 95 объявлений font-size в файле только 7 шли через
     токен — остальное было хардкодом, в том числе 9 почти неразличимых
     размеров 11–15px. Добавляем роли, а не меняем все 88 объявлений сразу:
     заменяем только там, где значение совпадает с ролью (±0.5px) и это
     точно не глиф иконки / не компонент с собственной подобранной
     responsive-кривой (см. комментарии по месту применения ниже). */
  --fs-body-sm:14.5px;
  --fs-meta:12.5px;
  --fs-eyebrow:11.5px;

  /* Батч 1.1 (16.08.2026, visual-density pass) — плотность строк-аккордеонов.
     Раньше вертикальный ритм жил на <details> (padding:18px 4px) — это
     ЕЩЁ ОДИН слой поверх min-height:44px на <summary>, поэтому закрытая
     строка из одной короткой фразы занимала 81px вместо ожидаемых ~56.
     Ритм переносится на <summary> (border-box: padding входит в min-height,
     поэтому однострочный текст просто получает высоту --row-min-h, а более
     длинный — растёт естественно). У <details> остаётся только рамка и
     воздух ПОСЛЕ раскрытого ответа (--row-pad-open, через margin-bottom
     у details p — не рендерится, пока <details> закрыт, так что на закрытую
     высоту не влияет вовсе). См. docs/SIGMA_OPUS_CONSOLIDATED_FIX_PLAN_20260816.md
     §A/§1.1 — там же таблица selector scope/exceptions: локальные компоненты
     со своим padding (.card-acc-cat, .p-cat, .p-prog, .pro-item, .mp-flat)
     продолжают выигрывать по специфичности и этот блок не трогает их. */
  /* V11 корректирующее ТЗ, пакет 3 (продолжение): 56px — плотность из
     visual-density pass 16.08.2026 — на реальном Manrope дала разброс
     56/63,1/88,7px на разных FAQ (однострочные упирались в 56px-пол,
     двустрочные росли естественно до ~63,1px, минуя его). Цель по ТЗ —
     коридор 64-72px. 68px (середина коридора) поднимает и однострочные
     (=68, пол теперь выше их естественной высоты), и двустрочные (тоже =68,
     68 > естественных 63,1 — пол снова побеждает) к одному числу без
     JS-выравнивания: не подпадают только карточки-раскрытия со своей
     normой (.pro-acc и т.п., §2.3 плана — трёхстрочные 88,7px там не
     "bare"-summary, а другой компонент со своим селектором). */
  --row-min-h:68px;        /* цель для одностроч. закрытой bare-строки (FAQ и т.п.) */
  --row-min-h-card:64px;   /* тот же паттерн внутри карточки с рамкой (.inc-col и т.п.) */
  --row-pad-y:6px;         /* доп. воздух bare-строки при многострочном тексте */
  --row-pad-y-card:10px;   /* то же для карточного варианта */
  --row-pad-open:16px;     /* воздух между текстом ответа и нижней границей открытого <details> */
}
@media(max-width:359px){:root{--gutter:16px}}
/* Режимы переобъявляют только сами семейства и роли; псевдонимы читают их
   один раз. --rhythm-cluster (24px) и --rhythm-component-lg (24px в планшете)
   раньше повторялись здесь тем же числом — это была дублирующая политика
   внутри одного владельца, а не отдельный шаг режима. */
@media(min-width:768px) and (max-width:1023px){
  :root{--rhythm-section:48px;--rhythm-cluster-grid:20px;--rhythm-component:20px}
}
*{margin:0;padding:0;box-sizing:border-box}
/* Regression-delta 16.08.2026 §2: точечно -webkit-tap-highlight-color:transparent
   уже стоял на .hs-arrow/.ctap/summary и части кнопок (снимает системную
   синевато-бирюзовую подсветку тапа Android WebView/Chrome, которая на части
   устройств визуально «залипает» после жеста, особенно на карточках со своим
   transform/overflow — GPU-слой не всегда корректно инвалидируется). Здесь —
   тот же принцип sitewide, одной строкой, а не костылём на каждую карточку:
   закрывает Home direction cards (.mst-i), карточки каталога /massage (.card),
   .loft на /space, .dir-card на /about, .pt-i/.pro-item на /pro, .pil/.fmt-c
   на /school, .rel-card, .mp-other и любые другие кликабельные карточки —
   без исключений и без правки каждой по отдельности. */
*{-webkit-tap-highlight-color:transparent}
/* Батч 8 §8.3 (финальный кросс-QA): базовый видимый фокус для ссылок/кнопок,
   у которых нет собственного :focus-visible (карточки .rel-card/.b-card/
   .mp-other, обычные ссылки шапки/футера) — раньше только браузерный
   дефолт (функционально видимый, но не в фирменном золотом языке сайта).
   Компонентные правила ниже (.btn/.ic-card/.route/summary/.hs-arrow и т.д.)
   специфичнее этого селектора и продолжают побеждать там, где заданы
   отдельно — этот блок только закрывает то, что раньше не было
   переопределено вовсе. */
a:focus-visible,button:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
/* overflow-x (любое значение, кроме visible — hidden, clip, auto...) на html
   или body ломает position:sticky у header в Chromium/WebKit: overflow != visible
   на предке создаёт scroll-контейнер, который перехватывает липкое
   позиционирование. overflow-x:clip чинил sticky, но у него самого нашёлся
   похожий побочный эффект — при восстановлении скролла браузером страница
   могла "залипнуть" сдвинутой по горизонтали без возможности вернуться в 0
   (clip блокирует и сам скролл-жест, которым это можно было бы поправить).
   Поэтому html/body вообще без overflow-x — горизонтальный скролл
   ограничивается ниже, на main/footer (там, где реально может вылезти
   широкий контент), а не на самом скролл-контейнере страницы. */
html{scroll-behavior:smooth;scroll-padding-top:88px;-webkit-text-size-adjust:100%;text-size-adjust:100%}
/* V9 Пакет 1, §1.9: короткие страницы (пример — рубрики блога с 1-3
   статьями) не занимали свободную высоту окна — footer оставался под
   контентом, а не у нижней границы (измерено: /blog/club/ на 1440 —
   112px пустоты под footer при нескроллящейся странице). Классический
   sticky-footer через flex-колонку на body: main растягивается на всё
   оставшееся место, footer всегда получает нижнюю границу без
   position:fixed (не перекрывает контент, не требует запасов padding). */
body{background:var(--bg);color:var(--text);font-family:'Manrope','Manrope Fallback',system-ui,sans-serif;font-weight:400;line-height:1.55;-webkit-font-smoothing:antialiased;
  min-height:100dvh;display:flex;flex-direction:column}
main{flex:1 0 auto}
/* V11 корректирующее ТЗ, пакет 3: overflow-x:hidden здесь — старый guard от
   горизонтального переполнения. Побочный эффект (известная особенность
   спецификации): когда ЗАДАН только overflow-x (не visible), overflow-y
   ВЫЧИСЛЯЕТСЯ как auto, даже если он нигде явно не указан — main незаметно
   становится собственным скролл-контейнером по вертикали. Пока внутри main
   не было ни одного position:sticky, это ничем не проявлялось; sticky
   считает «прилипание» относительно БЛИЖАЙШЕГО скролл-контейнера, а не
   обязательно окна — став им, main тихо ломает любой sticky у потомков
   (обнаружено здесь же, в пакете 3, при добавлении .faq-side/.sp-vis/
   .c-pair-photo{position:sticky} — элемент просто продолжал скроллиться
   вместе со страницей, вообще не прилипая). overflow-x:clip даёт тот же
   guard, но не запускает эту особенность (единственная ось, не auto-парная) —
   в отличие от hidden/scroll/auto. Поддержка Chrome 90+/Firefox 105+/
   Safari 16+, сайт уже полагается на не менее свежие возможности (dvh,
   aspect-ratio). */
main,footer{overflow-x:clip}
/* Батч 10.08.2026 §4: единый fluid-контейнер вместо .wrap:1320px + резкого
   скачка до 1520px на 1640px (три конкурирующих ограничения с 1200px-футером
   давали то узкую «коробку» на 1366px, то пустые поля на 1920px — см. отчёт §4.1). */
.wrap{width:100%;max-width:calc(var(--wrap-max) + var(--gutter)*2);
      margin-inline:auto;padding-inline:var(--gutter)}
.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}
img,svg{max-width:100%;display:block}

/* ===== 12-КОЛОНОЧНАЯ СЕТКА (батч 10.08.2026 §4/§6) — CSS Grid, без JS.
   Мобильная логика не переопределяется отдельно: ниже 1024px каждая .cN —
   grid-column:span 12 (полная ширина), то есть исходный DOM-порядок = порядок
   на мобильном экране, без каких-либо доп. правил. */
.g12{display:grid;grid-template-columns:repeat(12,minmax(0,1fr));gap:var(--grid-gap)}
.g12>.c3,.g12>.c4,.g12>.c5,.g12>.c6,.g12>.c7,.g12>.c8,.g12>.c9{grid-column:span 12}

/* ===== EQUAL-HEIGHT SIBLING CARDS (Opus-study 18.08.2026) — правило дизайн-
   системы, не механическое выравнивание всего сайта.
   Применять к группе sibling-элементов, когда ОДНОВРЕМЕННО:
   1) элементы равноправны — один компонент, одна структура, один статус;
   2) в один мобильный экран видно ≥3 элементов (высота самого высокого ≲200px);
   3) выравнивание НЕ уменьшает число одновременно видимых элементов;
   4) цена по вертикали ≤ ~50px на группу.
   Оставлять natural-height, если элемент высокий и в экран влезает 1-2
   (сравнивать нечего, цена — пустота), либо цена превышает порог, либо
   выравнивание роняет видимость. Правило ограничивается брейкпоинтом, где
   группа ОДНОколоночная — на многоколоночном desktop 1fr уравняет ещё и
   строки сетки между собой, а не только элементы внутри ряда.
   Техника — только grid-auto-rows:1fr, никогда фиксированная высота и
   никогда хардкод min-height: карточка короче дорастает до высоты самой
   высокой соседки без магического числа, привязанного к конкретному тексту.

   Вертикальная посадка контента внутри уравненной карточки (ТЗ 18.08.2026,
   доп. правка) — отдельное решение, не следует из самого equal-height:
   1) есть верхний semantic anchor (eyebrow/номер/категория, напр. .who-i,
      .pro-item) → контент остаётся top-aligned — якорь размечает начало
      карточки, смещать его вниз нельзя;
   2) простая label-card БЕЗ верхнего anchor (напр. .prac-list .inc-col —
      одна строка-заголовок с раскрывающимся описанием) → допустимо
      vertical-center содержимого при сохранении левого выравнивания текста:
      без якоря «прилипший к верху» текст с воздухом снизу читается как
      недоделанная карточка, а не как система. Не применять ко всем
      equal-height группам механически — только к их локальным селекторам. */
.eq-rows{display:grid;grid-auto-rows:1fr}

/* V9 Пакет 1, §1.1 (22.08.2026): равные высоты закрытых карточек-раскрытий
   без растяжения соседей при открытии — требование владельца, .eq-rows
   (grid-auto-rows:1fr) для этого не годится, т.к. растягивает соседей на
   высоту открытой карточки. --sum-h ставит assets/equal-summary.js: ОДНА
   переменная на группу (родитель [data-equal-summary]), не на карточку;
   вычисляется офскрин-клоном со всеми <details> принудительно закрытыми,
   поэтому open-состояние оригинала не трогается вовсе (без переключения,
   без toggle-события, без мигания). Нужен там, где закрытые карточки
   естественно РАЗНОЙ высоты — .pro-acc (pro.html) и .prac-list (space.html,
   V9 корректирующее ТЗ 23.08.2026 §2.2: на 360px заголовки 2 из 4 карточек
   переносятся на вторую строку, 69/92/92/69px). Остальным группам
   раскрытий сайта достаточно обычного align-items:start без JS — их
   закрытые высоты равны на всех проверенных ширинах. */
[data-equal-summary]{align-items:start}
[data-equal-summary] > details{min-height:var(--sum-h,0px)}
[data-equal-summary] > details[open]{min-height:0}
.g12>.c12{grid-column:1 / -1}
.g12--top{align-items:start}

/* ===== MEDIA-ROW — общий паттерн «текст + фото в одной строке сетки»
   (ТЗ реконструкции 12.08.2026 §A.3): единое начало и согласованная нижняя
   граница пары, без ручных margin-top-компенсаций. Мобильный порядок = DOM
   (текст, затем фото), desktop-ограничения высоты на mobile нет — .media-row
   на <1024px обычный блочный поток (никакого grid), поэтому ничего
   переопределять для mobile не нужно. Пропорция 7/5 — ориентир по умолчанию;
   .media-row--equal даёт 1/1 там, где контент равноправен (напр. /contacts). */
.media-row__content,.media-row__visual{min-width:0}
.media-row__visual{display:block;width:100%;height:100%;border-radius:var(--r);border:1px solid var(--line);
  overflow:hidden;object-fit:cover;margin-top:var(--sp-block)}
.media-row__visual img{width:100%;height:100%;display:block;object-fit:cover}

/* ===== ВЕРТИКАЛЬНЫЙ РИТМ (батч 10.08.2026 §4.3) — общие spacing-токены вместо
   случайных чисел на каждом шаблоне. main>section+section покрывает разметку
   вида <main class="wrap"><section>…</section></main> (space/about/pro/school/
   blog/contacts), div-варианты — contacts.html (.c-layout) и about.html
   (.founder-faq-row). Точечные inline/локальные margin-top на страницах,
   которые дублировали эти же интервалы вручную, убраны в этом же батче. */
/* Visual system 17.08.2026, батч 1: +article добавлен для 5 legal-страниц
   (policy/oferta/soglasie/reklama/cookie) — их <section class="hero"> сразу
   сменяется <article class="legal-doc">, а не <section>/<div>, поэтому
   правило раньше не срабатывало и переход был 0px без единого источника
   отступа с обеих сторон. */
main>section+section,main>section+div,main>div+section,main>section+article{margin-top:var(--sp-section)}
.crumb,.eyebrow{margin-bottom:var(--sp-eyebrow)}
h1+.lead,h2+.lead,.p-hero-sub+.lead{margin-top:var(--sp-headlead)}
/* M09: две оставшиеся именованные границы кластера получили владельца здесь,
   рядом с section→section и heading→body, вместо копии числа в каждом
   маршрутном файле.
     текст → доказательство  — .hero-trust (полоса доверия первого экрана)
     доказательство → действие — .cta-row / .detail-actions
   Шаг --rhythm-action до M09 был объявлен трижды одним и тем же числом: в
   .r-hero .cta-row (sigma-space.css), в .v4-pro-detail-page .detail-actions/
   .pa-hero .cta-row (sigma-pro-school.css) и как значение по умолчанию слота
   --v4-split-action-gap (sigma-layout.css). Правила стоят здесь, в первом
   подключаемом файле и с одним классом в селекторе, поэтому маршрут по-прежнему
   выигрывает своими плотностными исключениями той же специфичности. */
.hero-trust{margin-top:var(--rhythm-proof)}
.cta-row,.detail-actions{margin-top:var(--rhythm-action)}

/* Атмосферный тёплый грейд применяется только к декоративным фотографиям.
   Портреты мастеров и коммерческие фото кабинетов показываются без CSS-
   перекраски: кожа, интерьер и фактическое состояние пространства важнее
   декоративной унификации. */
.sp-vis,.a-vis{filter:sepia(10%) saturate(90%) contrast(103%)}

/* Photo QA 28.08.2026: каталог использует портретный формат 4:5. На текущих
   исходниках лица и макушки целы на 320/390/430/1440; мобильный focal 50% 15%
   оставлен как дополнительная защита для высоких исходников 3:4. */
@media(max-width:600px){.ph img{object-position:50% 15%}}

/* §3.6: едва заметное зерно на пустых тёмных зонах — фиксированный слой, не мешает контенту */
body::before{content:"";position:fixed;inset:0;z-index:1;pointer-events:none;opacity:.045;mix-blend-mode:overlay;
  background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='120' height='120'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='2' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E")}

/* ===== HEADER ===== */
header{position:sticky;top:0;z-index:50;border-bottom:1px solid var(--line)}
/* will-change отдельно на ::before (сам фон/цвет шапки), а не на header —
   transform на header создал бы новый containing block для #nav (он лежит
   внутри header и является position:fixed относительно viewport); transform
   на самом header сломал бы это позиционирование. */
header::before{will-change:transform}
/* Отзыв 10.08.2026, три раунда: шапка была полупрозрачной (85% + блюр,
   "frosted glass" при скролле). Первая попытка — гасить прозрачность только
   пока открыто меню — не убрала артефакт на реальных устройствах (после
   проверки трёх независимых скриншотов с разных моментов, при подтверждённо
   свежем деплое). backdrop-filter — известный источник ghosting/blend-глюков
   композитора на части мобильных GPU/WebView, не воспроизводимый в headless-
   тестах. Решение — не гасить эффект условно, а убрать полностью: шапка
   всегда полностью непрозрачна, без блюра, при любом скролле и в любом
   состоянии. Теряем лёгкий "frosted" эффект, зато исключаем целый класс
   рендер-багов на реальных устройствах, которые невозможно ни
   воспроизвести, ни проверить локально. */
header::before{content:"";position:absolute;inset:0;z-index:-1;background:var(--bg)}
.hrow{display:flex;align-items:center;justify-content:space-between;height:var(--hdr-h);gap:20px}
/* V11 корректирующее ТЗ, пакет 1: тач-цель логотипа была 19px (равна
   высоте картинки — сам .logo-link не имел ни padding, ни явной высоты).
   padding+отрицательный margin — тот же приём, что и у .l-incl a на
   /space, — увеличивает кликабельную область без сдвига соседних
   элементов .hrow и без изменения видимого размера логотипа. 14px даёт
   47px в норме и ровно 44px на ≤340px, где логотип сам уменьшается до 16px. */
.logo-link{display:flex;align-items:center;flex-shrink:0;padding:14px 0;margin:-14px 0}
.logo-link svg,.logo-link img{height:19px;width:auto}
@media(max-width:340px){.logo-link svg,.logo-link img{height:16px}}
#nav{display:flex;gap:17px;font-size:var(--fs-meta);color:var(--muted)}
#nav a{color:inherit;text-decoration:none;transition:color var(--t-micro);white-space:nowrap}
#nav a.act{color:var(--text)}
/* V9 Пакет 1, §1.3: десктопная навигация делит --fs-meta (12.5px) с
   .crumb/.tag/.discl/.consent/.fld-error — трогать токен нельзя, разъедет
   весь сайт. Локальный размер только на #nav, только на брейкпоинте, где
   меню уже горизонтальное (комплементарно max-width:1180px строкой ниже).
   min-height вместо padding — центрируется в фиксированной высоте шапки
   (--hdr-h:68px на этой же ширине, строка 358) через align-items:center
   на .hrow, без риска вылезти за пределы шапки. */
.hcta{display:flex;align-items:center;gap:18px}
.burger{display:none;background:none;border:none;color:var(--text);font-size:22px;cursor:pointer;
  min-width:44px;min-height:44px;align-items:center;justify-content:center}
body.nav-lock{overflow:hidden}
@media(max-width:1180px){
  /* Regression-delta 16.08.2026 §1: на реальном Android Chrome между нижним
     краем шапки и фоном открытого #nav иногда виден тонкий seam — не
     воспроизводится в headless-тестах, классический subpixel/DPR-артефакт
     compositor'а на sticky-слое (сумма header{height:var(--hdr-h)}+border-
     bottom 1px может округляться на не-целых DPR не так же, как top:calc()
     у #nav, оставляя долю физического пикселя между слоями). Полная
     переработка стекинга (backdrop на весь viewport + шапка поверх через
     z-index) требует трогать уже трижды вручную выверенный на видео с
     реального устройства фикс "always display:flex, opacity без transition"
     чуть выше — рискованно менять без возможности проверить на реальном
     устройстве в этой среде. Вместо этого — безопасный запас: фон #nav
     заходит на 3px выше границы шапки (top на 3px раньше, height на те же
     3px больше, bottom:0 не трогаем), а padding-top увеличен ровно на те
     же 3px, чтобы первая ссылка меню осталась на прежнем визуальном месте.
     Заход гарантированно перекрывает subpixel-щель на любом DPR (ошибка
     округления всегда меньше 1 физического пикселя, то есть много меньше
     3 CSS px), не требуя знать точную высоту browser chrome. */
  #nav{position:fixed;top:calc(var(--hdr-h) - 2px);left:0;right:0;bottom:0;background:var(--bg);
      /* dvh отслеживает реальную видимую высоту вьюпорта на мобильных, пока
         системная панель браузера скрывается/появляется — bottom:0 у fixed-
         элемента на некоторых мобильных движках считается от "большого"
         вьюпорта (без учёта панели), из-за чего при её анимации на долю
         секунды могла показаться полоска контента под шапкой (отзыв 10.08.2026).
         Браузеры без поддержки dvh просто игнорируют строку и остаются на
         bottom:0 — деградация безопасна. */
      height:calc(100dvh - var(--hdr-h) + 2px);
      flex-direction:column;gap:0;padding:11px 20px 24px;overflow-y:auto;
      /* Отзыв 10.08.2026, подтверждено видеозаписью с реального устройства
         (Android, Chrome/Opera) покадрово: баг был не в позиционировании —
         #nav был display:none → display:flex по классу .open, а это заставляет
         браузер строить весь слой (фон, детей, бордеры шести ссылок) с нуля
         в момент открытия. На кадрах видно, что список ссылок уже отрисован
         и читаем, а вот собственный фон #nav в первые ~5-20 кадров ещё не
         дорисован — и в эту полоску была видна страница позади. Фикс —
         никогда не убирать #nav из рендер-дерева (display всегда flex),
         слой всегда "тёплый" и уже закомпожен; открытие/закрытие — только
         opacity (не требует перестройки слоя, чисто композитор). Видимость
         для доступности и кликабельность держим через visibility и
         pointer-events, с задержкой на выключение, чтобы не потерять
         фокус/клик в момент угасания. */
      transform:translateZ(0);
      opacity:0;visibility:hidden;pointer-events:none}
  /* Правка (следующий раунд): у самого перехода opacity была плавная анимация
     .14s — а значит меню было ПО-НАСТОЯЩЕМУ, гарантированно полупрозрачным
     все эти 140мс на каждое открытие, не изредка при недорисовке слоя, а
     всегда, по определению CSS-перехода. Это и было тем, что оставалось
     видно — не редкий рендер-баг, а сам же фикс. Переход убран: opacity
     переключается мгновенно, слой всё так же не пересобирается с нуля
     (display всегда flex), но никакого окна полупрозрачности не остаётся. */
  #nav.open{opacity:1;visibility:visible;pointer-events:auto}
  #nav a{padding:16px 0;border-bottom:1px solid var(--line);font-size:var(--fs-body)}
  .burger{display:flex}
}
/* Отзыв 10.08.2026: шапка была 51px — при 44px тап-таргетах (.cf-icon, .burger)
   оставалось по 3-4px воздуха сверху и снизу, выглядело зажато. 60px на мобильном
   и 68px от 1181px — премиальный диапазон, логотип и трекинг не трогаем.
   position:sticky и отсутствие overflow-x на html/body не затронуты. */

/* ===== ТИПОГРАФИКА ===== единый h1-токен на весь сайт, максимум 38px (решение
   11.08.2026 — заменяет прежнее разделение .h1-home/.h1-space/.h1-pro/.h1-loft
   на независимые clamp-кривые). h3 намеренно НЕ получает общий font-weight:500 —
   роль (заголовок карточки/аккордеона/секции) задаёт вес точечно, локальные
   компонентные правила по всему сайту уже сами явно указывают свой вес. */
h1,h2{font-family:'Manrope',sans-serif;font-weight:500}
h1{font-size:var(--fs-h1);line-height:1.16;letter-spacing:.005em}
h2{font-size:var(--fs-h2);line-height:1.22}
h3{font-family:'Manrope',sans-serif;font-weight:400;font-size:var(--fs-h3);line-height:1.3}
.eyebrow{font-size:var(--fs-eyebrow);letter-spacing:.32em;text-transform:uppercase;color:var(--accent-text);margin-bottom:18px;font-weight:600}
.lead{color:var(--muted);max-width:var(--measure);font-size:var(--fs-lead);line-height:1.5;margin-top:16px}
/* Visual system 17.08.2026, батч 6 (B1): единая Body-роль для абзацев без
   класса — раньше такие <p> молча наследовали body{16px/var(--text)} вместо
   осознанной роли (тот же приглушённый размер, что уже используется по всему
   сайту как --fs-body-sm/var(--muted): .forpro p, .residency p, details p).
   Один общий класс вместо N локальных копий одного и того же правила. */
.p-body{color:var(--muted);font-size:var(--fs-body-sm)}
.lead b{color:var(--text);font-weight:600}
/* Проза внутри текстовых секций (не карточки/сетки/формы — см. ТЗ §5):
   на широком desktop 7-колоночный текстовый блок легко превышает 720px
   даже при контейнере 1440px, поэтому нужен отдельный измеримый предел. */
.g12>.c7 p,.g12>.c8 p,main>section>p,main>section>div>p{max-width:var(--measure)}

/* длина строки основного текста. Абзац прямо в секции внутри .wrap иначе
   тянется на 1280/1480px — при том что .lead=640, details p=720, .legal-doc=760.
   Специфичность (0,0,3) ниже .lead/.discl/.residency p — их капы не перебиваются. */
main.wrap > section > p,
main.wrap > section > .panel > p{max-width:720px}

/* ===== ВНУТРЕННИЕ СТРАНИЦЫ: hero / крошки / дисклеймер ===== */
.hero{padding:12px 0 0}
.crumb{font-size:var(--fs-meta);letter-spacing:.28em;text-transform:uppercase;color:var(--accent-text);margin-bottom:16px;font-weight:600}
.discl{display:inline-flex;gap:10px;align-items:flex-start;padding:12px 16px;border:1px solid var(--line);
       border-radius:14px;font-size:var(--fs-meta);color:var(--muted);max-width:640px;margin-top:20px}
.discl span{color:var(--accent-text);flex-shrink:0}

/* ===== ПАНЕЛИ / ТЕГИ (общие) ===== */
.panel{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-lg);padding:clamp(28px,4vw,44px)}
.tag{font-size:var(--fs-eyebrow);color:var(--muted);border:1px solid var(--line);border-radius:var(--r-pill);padding:3px 9px;display:inline-block}
.tags{display:flex;flex-wrap:wrap;gap:6px}

/* ===== МОСТИК В ДРУГОЙ РАЗДЕЛ =====
   Не карточка и не подчёркнутая ссылка внутри абзаца, а спокойная переходная
   строка между смысловыми разделами. На mobile текст и действие естественно
   расходятся на две строки; на desktop остаются в одной горизонтали. */
.bridge{margin-top:var(--rhythm-section-dense);padding:12px 0;border-block:1px solid var(--line);
  display:flex;align-items:center;justify-content:space-between;gap:4px 20px;flex-wrap:wrap;
  text-align:left;color:var(--muted);font-size:var(--fs-body-sm);line-height:1.5}
.bridge>span:first-child{flex:1 1 260px}
.bridge a{color:var(--accent-text);text-decoration:none;white-space:normal;
  display:inline-flex;align-items:center;min-height:44px;padding:10px 0;margin:-10px 0;font-weight:600}
.bridge-links{display:flex;align-items:center;gap:0 18px;flex-wrap:wrap}

/* хлебные крошки — A-09 */
.crumbs{display:flex;align-items:center;gap:8px;flex-wrap:wrap;font-size:var(--fs-meta);color:var(--muted);padding-top:20px}
.crumbs a{color:var(--muted);text-decoration:none}
/* правка: на мобильном крошки убраны визуально — остаются в DOM (JSON-LD BreadcrumbList не трогаем) */
@media(max-width:760px){.crumbs{display:none}}
/* Visual system 17.08.2026, батч 1: было #4a463f, контраст 2.11:1 —
   разделитель был почти неразличим. #847f76 уже используется в системе
   (.fmetro) как приглушённый служебный цвет, контраст 4.98:1 — не вводим
   новый оттенок, переиспользуем существующий. */
.bc-sep{color:#847f76}

/* ===== КНОПКИ: Primary/Secondary/Tertiary (§2.6 итогового ТЗ) =====
   Primary — заливка = base направления, текст = on-accent (не общий нейтральный --cta:
   это изменение по сравнению с прошлым проходом). Состояния: default/hover/active/
   focus-visible/disabled на всех трёх типах. */
/* line-height:1 — без него <button> (line-height:normal, унаследовано от UA)
   и <a class="btn"> (line-height:1.55 от body) считались на 5-8px по-разному
   при одинаковом padding, кнопки-ссылки визуально были выше кнопок-<button> */
/* Финальное ТЗ 13.08.2026 §45: inline-block центрировал текст только по
   горизонтали — вертикально текст «плавал» относительно padding/line-height
   на разных элементах (<a> vs <button>). inline-flex с align/justify center
   даёт одинаковое визуальное центрирование независимо от тега и содержимого. */
.btn{border:none;border-radius:var(--r-pill);padding:15px 30px;font-size:14px;line-height:1;cursor:pointer;
     font-family:inherit;font-weight:700;transition:var(--t-micro);text-decoration:none;display:inline-flex;
     align-items:center;justify-content:center;gap:6px;text-align:center;min-height:44px}
.btn.w{background:var(--text);color:#141210;min-height:var(--control-primary-h)}
.btn.w:active{background:#d8d5cf}
/* §46-47: значения цен (8 000 ₽ и т.д.) никогда не переносятся по слову —
   символ ₽ не должен оказаться на отдельной строке; tabular-nums выравнивает
   цифры по ширине в списках цен. */
.price-nowrap{white-space:nowrap;font-variant-numeric:tabular-nums}
/* Финальное ТЗ 13.08.2026 (вечер) §8/§11/§15: две независимые системы
   индикаторов раскрытия — одна деталь на элемент, никогда не смешиваются.
   .p-chev--caret — категория/крупный раздел (⌄/⌃, inline-SVG, не текстовый
   глиф: символы ⌄/⌃ непредсказуемо рендерятся в Manrope на части устройств).
   .p-chev--plus — конкретная программа (+/−). Оба используются и на карточке
   каталога (massage.html), и на анкете (build.js renderMasterProfilePage) —
   общий класс, общий стиль, общее правило поворота ниже (для всех <details>
   сайта разом, не дублируется на каждой странице). */
.p-chev{color:var(--gold);font-size:17px;line-height:1;transition:transform var(--t-micro);flex:0 0 auto}
details[open]>summary .p-chev--caret{transform:rotate(180deg)}
/* Primary */
.btn.g{background:var(--accent);color:var(--on-accent);min-height:var(--control-primary-h)}
.btn.g:active{background:var(--accent-dim)}
/* Secondary — единая обводка, без заливки */
.btn.o{background:transparent;color:var(--text);border:var(--border-emphasis);min-height:var(--control-secondary-h)}
.btn.o:active{background:rgba(255,255,255,.04)}
.btn:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.btn.disabled,.btn:disabled{opacity:.4;pointer-events:none}
/* Tertiary — текстовая ссылка со стрелкой, текст и стрелка не переносятся раздельно */
.btn.t{background:none;border:none;padding:15px 0;margin:-15px 0;min-height:var(--control-tertiary-h);border-radius:0;font-weight:600;
  color:var(--accent-text);display:inline-flex;align-items:center;gap:6px;white-space:nowrap}
.btn.t:active{opacity:.8}
.btn.t .ar{transition:transform var(--t-base)}
/* hover — только для устройств с реальным курсором (не залипает после тапа на touch),
   ТЗ theme_footer_contacts §1. Здесь же — остальные точечные hover по сайту,
   которые раньше стояли без гейта (nav/crumbs/карточки/футер/модалки). */
@media(hover:hover) and (pointer:fine){
  .btn.w:hover{background:#fff}
  .btn.g:hover{filter:brightness(1.12)}
  .btn.o:hover{border-color:var(--accent);color:var(--accent)}
  .btn.t:hover{color:var(--text)}
  .btn.t:hover .ar{transform:translateX(3px)}
  #nav a:hover{color:var(--text)}
  .crumbs a:hover{color:var(--accent-text)}
  .route:hover{transform:translateY(-5px);border-color:var(--accent-dim)}
  .route:hover .bgim{transform:scale(1.05)}
  .rel-card:hover{border-color:var(--gold-dim)}
  .fcol a:hover{color:var(--text)}
  .x:hover{color:var(--text)}
  .lnk:hover{color:var(--text)}
}

/* ===== HERO ===== */
/* точечные правки §1.7/§2: отступ шапка→первый контентный элемент — 20–24px, было ~94px */
/* Отзыв владельца 16.08.2026: убрана коричнево-медная radial-gradient
   заливка первого экрана (::before, rgba(226,149,79,...)) — целиком, без
   замены другим glow/градиентом. Hero — обычный чёрный фон сайта. */
.home-hero{padding:12px 0 24px}
/* V11 корректирующее ТЗ (повторная правка мобильного зазора лид→карточка,
   первопричина): на mobile итоговый видимый интервал складывался из ТРЁХ
   источников одновременно — этого padding-bottom:24px (реальное место
   внутри .home-hero, между .lead и краем секции), .hm-fork{margin-top}
   и .fork{margin-top} (index.html) — коллапсирующихся между собой, но НЕ
   с этим padding (padding не участвует в margin-коллапсе). Предыдущие
   правки этого сезона измеряли зазор от .home-hero.bottom (уже включает
   этот padding) до .fork.top и поэтому не видели его вклад — измеренное
   значение (24/29px) было лишь второй половиной фактического интервала.
   На mobile (≤1023px) источник обнуляется здесь и переносится в
   index.html — .hm-fork{padding-top}, единственный источник интервала
   там. Desktop (≥1024px) не трогаем: там по-прежнему padding-bottom:24px
   + .fork{margin-top:26px} в сумме, как было (см. index.html). */
@media(max-width:1023px){.home-hero{padding-bottom:0}}
.hh-in{text-align:center}
.hh-logo{height:clamp(30px,4.2vw,40px);width:auto;margin:0 auto 36px;opacity:.97}
.hh-eyebrow{font-size:var(--fs-eyebrow);letter-spacing:.34em;text-transform:uppercase;color:var(--accent-text);margin-bottom:22px;font-weight:600}
.home-hero h1{max-width:900px;margin:0 auto}
/* было clamp(15px,1.5vw,17px) — почти дословный дубль --fs-lead
   (clamp(15px,1.6vw,17px)): расхождение кривых даёт разницу в доли
   пикселя на любой ширине, визуально неотличимо. */
.hh-sub{color:var(--muted);max-width:600px;margin:24px auto 0;font-size:var(--fs-lead)}
.hh-meta{display:flex;gap:26px;justify-content:center;flex-wrap:wrap;margin-top:32px;
  font-size:var(--fs-meta);letter-spacing:.14em;text-transform:uppercase;color:var(--muted)}
.hh-meta span{display:flex;align-items:center;gap:8px}
.hh-meta span::before{content:"";width:4px;height:4px;border-radius:50%;background:var(--gold-dim)}
.hh-actions{display:flex;gap:14px;justify-content:center;margin-top:36px;flex-wrap:wrap}

/* ===== ЧЕТЫРЕ НАПРАВЛЕНИЯ ===== */
.routes{display:grid;grid-template-columns:repeat(4,1fr);gap:16px;padding:8px 0 0}
@media(max-width:1020px){.routes{grid-template-columns:repeat(2,1fr)}}
@media(max-width:560px){.routes{grid-template-columns:1fr}}
.routes.fork2{grid-template-columns:1fr 1fr}
.routes.fork2 .route{min-height:400px}
@media(max-width:760px){.routes.fork2{grid-template-columns:1fr}}
.routes.fork3{grid-template-columns:repeat(3,1fr)}
@media(max-width:900px){.routes.fork3{grid-template-columns:1fr 1fr}}
@media(max-width:560px){.routes.fork3{grid-template-columns:1fr}}
/* §6 ТЗ: 4 направления Massage→Space→Pro→School, вертикальный стек на мобильном —
   компактная высота карточки, чтобы Massage+Space помещались целиком, верх Pro — частично */
.routes.fork1{grid-template-columns:1fr;gap:16px;max-width:640px;margin:0 auto}
.routes.fork1 .route{min-height:220px;padding:16px 24px 24px 18px}
@media(min-width:820px){.routes.fork1{grid-template-columns:1fr 1fr;max-width:900px}.routes.fork1 .route{min-height:276px}}
/* ТЗ theme_footer_contacts §2.2: карточки направлений — единая клубная тема (не
   разноцветные по направлениям — см. .route в index.html без inline --accent),
   двухстрочный SubbrandMark вверху карточки (не внизу, как раньше). */
.r-brand{position:relative;z-index:2;font-family:'Manrope';font-weight:500;font-size:17px;letter-spacing:.17em;
  text-transform:uppercase;color:var(--subbrand-color);margin-bottom:4px}
.route{position:relative;display:flex;flex-direction:column;justify-content:flex-start;
  min-height:340px;padding:26px;border-radius:var(--r);border:1px solid var(--line);
  background:var(--panel);text-decoration:none;color:var(--text);overflow:hidden;
  transition:transform .26s cubic-bezier(.2,.7,.3,1),border-color .26s}
.route .bgim{position:absolute;inset:0;z-index:0;transition:transform .5s cubic-bezier(.2,.7,.3,1)}
/* градиент затемняет верх карточки — там теперь текст, а не низ */
.route::after{content:"";position:absolute;inset:0;z-index:1;
  background:linear-gradient(190deg,rgba(8,6,5,.9) 0%,rgba(8,6,5,.35) 42%,transparent 65%)}
.route > *:not(.bgim){position:relative;z-index:2}
.r-desc{display:block;font-size:14px;font-weight:400;color:var(--text);opacity:.85}

/* ===== О КЛУБЕ ===== */
.space{margin-top:24px;display:grid;grid-template-columns:1fr 1fr;gap:56px;align-items:center}
@media(max-width:900px){.space{grid-template-columns:1fr;gap:32px}}
/* Батч 10.08.2026 §6.1/§6.2/§6.3: на широких экранах текстовая колонка чуть
   уже медиа-колонки (было ровно 1:1 — при узком тексте и widescreen-фото
   читалось как случайно разъехавшееся). Один селектор — на / (О клубе),
   /space (Тантрический массаж), /about (Почему появились лофты). */
.space h2{margin-bottom:20px}
.space p{color:var(--muted);font-size:15px;margin-bottom:14px}
.sp-list{display:grid;grid-template-columns:1fr 1fr;gap:12px 20px;margin-top:26px}
.sp-list div{font-size:13.5px;color:var(--muted);display:flex;gap:9px;align-items:flex-start}
.sp-list div::before{content:"◆";color:var(--gold-dim);font-size:8px;margin-top:6px;flex-shrink:0}
.sp-vis{aspect-ratio:4/3.2;border-radius:var(--r);border:1px solid var(--line);position:relative;overflow:hidden}
.sp-vis>img{position:absolute;inset:0;width:100%;height:100%;display:block;object-fit:cover}
.sp-vis .cap{position:absolute;left:20px;bottom:18px;z-index:2;font-size:var(--fs-eyebrow);letter-spacing:.2em;
  text-transform:uppercase;color:var(--muted)}
/* §3.5: на фото — только чёрный градиент для читаемости подписи, без цветного слоя */
.sp-vis::after{content:"";position:absolute;inset:0;background:linear-gradient(180deg,transparent 42%,rgba(18,11,7,.82) 100%)}

/* ===== ЦИФРЫ ===== */
.nums{margin-top:24px;display:grid;grid-template-columns:repeat(4,1fr);gap:16px}
@media(max-width:760px){.nums{grid-template-columns:repeat(2,1fr)}}
.num{background:var(--panel);border:1px solid var(--line);border-radius:18px;padding:18px 16px}
.num b{font-family:'Manrope';font-weight:500;font-size:clamp(30px,3.4vw,40px);color:var(--gold);display:block;line-height:1}
.num b.nowrap{white-space:nowrap}
.num span{font-size:var(--fs-meta);color:var(--muted);display:block;margin-top:10px;line-height:1.45}
.nums5{grid-template-columns:repeat(5,1fr)}
@media(max-width:1040px){.nums5{grid-template-columns:repeat(3,1fr)}}
@media(max-width:560px){.nums5{grid-template-columns:1fr 1fr}}
.num-rating b{font-size:16px;letter-spacing:1px;white-space:nowrap}

/* мост к обучению на главной */
.school-bridge{margin-top:36px;padding:24px 28px;border-radius:var(--r);border:1px solid var(--line);
  background:var(--panel);display:flex;justify-content:space-between;align-items:center;gap:20px;flex-wrap:wrap}
.school-bridge p{font-size:15px}

/* основатель + FAQ в один ряд. Visual system 17.08.2026, батч 3: margin-top
   был хардкод 24px — единственный источник отступа (класс 0,1,0 перебивает
   main>section+section 0,0,3), значение оставлено как есть (компонент
   продолжает предыдущий раздел, не открывает новый), переведено на
   var(--sp-block) — это и есть его роль. */
.founder-faq-row{margin-top:var(--rhythm-section-dense);display:grid;grid-template-columns:1fr 1.3fr;gap:24px;align-items:start}
@media(max-width:860px){.founder-faq-row{grid-template-columns:1fr}}
.founder-faq-row .founder-brief{margin-top:0;padding:26px;border-radius:var(--r);border:1px solid var(--line);
  background:var(--panel);height:100%}

/* компактная подпись автора — фото+имя в одну строку, текст ниже во всю ширину.
   Вне .founder-faq-row (например, на главной, под текстом «О клубе») — просто
   продолжение блока с тонкой верхней линией, не отдельная карточка. Внутри
   .founder-faq-row (/about, /school) правило выше даёт полноценную панель. */
.founder-brief{margin-top:20px;padding-top:18px;border-top:1px solid var(--line)}
.fb-row{display:flex;align-items:center;gap:12px}
.fb-vis{width:44px;height:44px;border-radius:50%;flex-shrink:0;
  background:url('/assets/photos/dmitry.webp') center 22%/cover;
  box-shadow:0 0 0 1px rgba(207,138,82,.34),0 0 14px rgba(207,138,82,.12)}
.fb-who b{display:block;font-size:var(--fs-body-sm);color:var(--text);font-weight:600}
.fb-who span{display:block;font-size:var(--fs-meta);color:var(--accent-text);letter-spacing:.08em;text-transform:uppercase;margin-top:1px}
.founder-brief p{color:var(--muted);font-size:13.5px;line-height:1.5;max-width:560px;margin-top:10px}

/* ===== ДЛЯ МАСТЕРОВ ===== */
.forpro{margin-top:24px;padding:clamp(28px,4vw,44px);border-radius:var(--r-lg);border:var(--border-emphasis);
  background:var(--surface-accent);
  display:flex;justify-content:space-between;align-items:center;gap:34px;flex-wrap:wrap}
.forpro h2{font-size:clamp(23px,2.6vw,31px);margin-bottom:12px}
.forpro p{color:var(--muted);font-size:var(--fs-body-sm);max-width:520px}

/* ===== РЕЗИДЕНТСТВО (используется на /space и /pro) ===== */
.residency{margin-top:var(--rhythm-section-dense);margin-bottom:var(--rhythm-section-dense);padding:clamp(28px,4vw,44px);border-radius:var(--r-lg);border:1px solid var(--line);background:var(--panel)}
.residency p{color:var(--muted);font-size:var(--fs-body-sm);max-width:640px;margin-top:10px}
.residency .res-cta{display:flex;gap:14px;flex-wrap:wrap;margin-top:24px;align-items:center}
.res-list{list-style:none;display:grid;grid-template-columns:1fr 1fr;gap:12px;margin-top:20px;padding:0}
.res-list li{font-size:13.5px;color:var(--muted);display:flex;gap:10px;align-items:flex-start;line-height:1.5}
.res-list li::before{content:"◆";color:var(--gold-dim);font-size:7px;margin-top:6px;flex-shrink:0}
@media(max-width:760px){.res-list{grid-template-columns:1fr}}

/* ===== ОТЗЫВЫ ===== */
.reviews{margin-top:24px}
.reviews h2{margin-bottom:26px}
.rv-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
@media(max-width:900px){.rv-grid{grid-template-columns:1fr}}
.rv{background:var(--panel);border:1px solid var(--line);border-radius:20px;padding:18px}
.rv-stars{color:var(--accent-text);font-size:13px;letter-spacing:2px;margin-bottom:14px}
.rv p{color:var(--muted);font-size:var(--fs-body-sm);margin-bottom:16px}
.rv-who{font-size:var(--fs-meta);color:var(--text);font-weight:600}

/* ===== СТАТЬИ ПО ТЕМЕ ===== */
.related{margin-top:var(--sp-section)}
.related h2{margin-bottom:22px}
.rel-grid{display:grid;grid-template-columns:repeat(3,1fr);gap:16px}
@media(max-width:760px){.rel-grid{grid-template-columns:1fr}}
.rel-card{background:var(--panel);border:1px solid var(--line);border-radius:18px;padding:16px;text-decoration:none;color:var(--text);display:block;transition:border-color var(--t-base)}
.rel-cat{font-size:10px;letter-spacing:.16em;text-transform:uppercase;color:var(--accent-text);margin-bottom:10px;display:block}
/* .rel-card переиспользуется и как h3 (под H2 "Из блога"/"Статьи по теме" на
   профильных страницах — верно), и как h2 (на /blog и в рубриках блога, где
   он сразу после H1 — аудит 09.08.2026 §10.5) — стиль одинаковый для обоих */
.rel-card h3,.rel-card h2{font-size:15.5px;font-weight:400;line-height:1.4}

/* Sitewide-правка 15.08.2026: единый horizontal-swipe для всех лент
   "related articles" (Статьи по теме / Из блога / Читайте также / Другие
   темы блога) — одна карточка целиком на mobile, следующая не выглядывает,
   свайп + стрелки ← → (assets/hswipe-nav.js), на ≥761px обычная сетка.
   Контракт разметки: <div class="related-head"><h2>…</h2><div class="hs-nav"
   data-hswipe-nav="ID"><button class="hs-arrow prev" aria-controls="ID">
   </button><button class="hs-arrow next" aria-controls="ID"></button></div>
   </div><div class="rel-grid h-swipe" id="ID" data-hswipe>\3c !--карточки--></div>
   Раньше жило локально на /massage — вынесено сюда, чтобы не дублировать
   в каждой странице отдельно. */
.related-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:22px}
.related-head h2{margin-bottom:0}
@media(min-width:761px){.related-head .hs-nav{display:none}}
.rel-grid.h-swipe .rel-card{flex:0 0 100%;max-width:none}
@media(min-width:761px){
  .rel-grid.h-swipe{display:grid}
  /* Mobile polish 18.08.2026, §5.1: клоны для mobile-цикла тут не нужны —
     грид уже показывает все карточки разом (тот же принцип, что у
     .mp-other--clone для «Другие мастера»). */
  .rel-card--clone{display:none}
}

/* ===== Ic-card: две равные карточки-ссылки (Батч 4, /pro §4.5) =====
   Компонент для «соседних» переходов вроде «Инфраструктура Sigma Club»
   (/pro → Space/School) или «После обучения» (/school → Space/Pro) —
   карточка целиком кликабельна, на ≥640px в строку. */
.ic-grid{display:grid;gap:14px}
@media(min-width:640px){.ic-grid{grid-template-columns:1fr 1fr}}
.ic-card{display:block;padding:20px 22px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--panel);text-decoration:none;color:var(--text);transition:border-color var(--t-base),background var(--t-base)}
.ic-label{font-size:var(--fs-eyebrow);letter-spacing:.14em;text-transform:uppercase;color:var(--gold);font-weight:600}
.ic-card h3{font-size:16px;font-weight:400;margin:8px 0 6px;line-height:1.35}
.ic-card p{color:var(--muted);font-size:13.5px;line-height:1.5}
.ic-more{display:inline-flex;align-items:center;gap:6px;margin-top:14px;font-size:var(--fs-meta);font-weight:600}
.ic-more .ar{color:var(--gold);transition:transform var(--t-base)}
.ic-card:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
@media(hover:hover) and (pointer:fine){
  .ic-card:hover{border-color:var(--gold-dim);background:var(--panel2)}
  .ic-card:hover .ic-more .ar{transform:translateX(3px)}
}

/* ===== FAQ ===== */
.faq{max-width:900px}
section.faq{margin-top:var(--sp-section)}
.faq h2{margin-bottom:24px}
/* Дельта-ТЗ 13.08.2026 §11: CSS-колонки (ТЗ реконструкции 12.08.2026 §A.10)
   заполняли сначала всю левую колонку сверху донизу, потом правую —
   несимметрично на вид и не «настоящие» парные 2 колонки, как требует ТЗ.
   Заменено на grid 1fr/1fr с align-items:start.
   V11 корректирующее ТЗ, пакет 3: «попарная сетка» (общие строки грида на
   оба столбца) была тогда СОЗНАТЕЛЬНЫМ компромиссом — при открытии вопроса
   слева растягивается вся строка грида, и пустой сосед справа стоит над
   заметной пустотой (752px @1024 на /pro при открытии всех вопросов).
   Производственная приёмка это не приняла. Начиная с этого пакета такие
   группы верстаются НЕ общим грид-контейнером над плоским списком, а
   внешним грид-контейнером (.faq--split, только для позиционирования 2
   столбцов) над ДВУМЯ независимыми .col-flow — то же строение, что уже
   было у .pdisc-body--split/.c6 на /space (там этой проблемы никогда не
   было, потому что <details> изначально лежали в двух отдельных <div>, не
   auto-placement'ом по общим строкам). .col-flow — общий примитив
   независимого столбца: см. определение и другие применения ниже
   (.mm-acc на /massage, .inc-acc/#tantra на /space, .c-pair на /contacts) —
   один и тот же CSS-приём, но каждое применение — отдельная вложенная
   разметка в своём шаблоне, компоненты между собой не смешиваются. */
.faq--split{max-width:none}
.col-flow{display:block}
/* §11: .faq{max-width:900px} выше рамит СЕКЦИЮ, а не только .faq--split
   внутри неё — .faq--split{max-width:none} само по себе не расширяет
   родителя. faq--wide на самой section снимает эту рамку у страниц,
   которым явно нужна полная ширина контейнера (/massage, главная).
   V9 Пакет 1, §1.2: было max-width:none — та же специфичность (0,1,0),
   что у .wrap{max-width:calc(...)} на ТОМ ЖЕ элементе (section.wrap),
   .faq--wide идёт позже в источнике и побеждала по каскаду, снимая
   заодно и ограничение .wrap, а не только 900px от .faq. Секция росла
   до полной ширины окна (измерено: 1920px против 1552px у соседних
   секций на 1920px). Явное значение — та же формула, что у .wrap —
   не может «перепобедить» .wrap сильнее, чем предполагает контейнер,
   каким бы порядком источника ни определялись правила. */
.faq--wide{max-width:calc(var(--wrap-max) + var(--gutter)*2)}
details{border-bottom:1px solid var(--line);padding:0 4px}
summary{cursor:pointer;font-size:16.5px;list-style:none;display:flex;justify-content:space-between;align-items:center;gap:16px;min-height:var(--row-min-h);padding-block:var(--row-pad-y)}
/* Батч 6 (16.08.2026) §6.4: видимый фокус на раскрывашках — раньше только
   браузерный дефолт (непоследовательный, местами почти незаметен на тёмном
   фоне). Sitewide, тот же язык, что у .btn:focus-visible. Native
   <details>/<summary> уже даёт корректную встроенную ARIA-семантику
   (роль/состояние expanded) — отдельные aria-expanded/aria-controls не
   добавляются, чтобы не расходиться с уже принятым в проекте разделением:
   они используются только у кастомных button-дизклоужеров (см. tariff-
   toggle.js, mp-about-toggle), не у нативных <details>. */
summary:focus-visible{outline:2px solid var(--accent);outline-offset:2px;border-radius:4px}
summary::-webkit-details-marker{display:none}
/* UI-унификация 16.08.2026: единый chevron (›) вместо +/– — закрыто
   указывает вправо, открыто поворачивается на 90° вниз, плавно. Тот же
   принцип на .inc-col/.pdisc ниже — один тип disclosure, один тип
   control по сайту (кроме .p-cat/.p-prog/.card-acc-cat — те ценовые
   аккордеоны мастера, отдельный по смыслу компонент со своим CHEVRON_SVG,
   уже отключают этот common-маркер через summary::after{content:none}). */
/* Visual system 17.08.2026, батч 1: было var(--muted) — самый частый на
   сайте аккордеон (FAQ, тематические disclosure) имел наименее заметный,
   серый шеврон, тогда как .pdisc уже был золотым.
   Золото должно помечать интерактивность последовательно. */
summary::after{content:"›";font-family:'Manrope';font-size:22px;color:var(--accent-text);flex-shrink:0;transition:transform var(--t-base) ease}
details[open] summary::after{transform:rotate(90deg)}
/* Visual system 17.08.2026, батч 6 (B4): .inc-col («Что входит» на /space,
   /space/aura, /space/sliyanie) был скопирован в 3 файла байт-в-байт, кроме
   шеврона — только на /space его успели перевести на общую грамматику ›/
   rotate(90deg) при унификации 16.08, два лофта остались на старом +/
   rotate(45deg). Один общий компонент вместо трёх копий — правка шеврона
   теперь одна, а не три. */
.inc-col{background:var(--panel);border:1px solid var(--line);border-radius:var(--r);padding:var(--row-pad-y-card) calc(var(--card-pad) + 2px)}
.inc-col summary{cursor:pointer;list-style:none;display:flex;justify-content:space-between;align-items:center;min-height:44px;padding-block:0}
.inc-col summary::-webkit-details-marker{display:none}
/* V11 корректирующее ТЗ, пакет 4 §Б.6: было color:var(--gold) — на /space
   этим правилом красились разом 12 заголовков (4 «Что входит» + 4 «Для
   каких практик» + 4 «Условия аренды») — золото перестало быть акцентом,
   стало фоновым цветом текста. Переведено на var(--text); шеврон и точки
   списка (ниже) остаются золотыми — это и есть акцент, который теперь
   ни с чем не конкурирует. */
.inc-col summary h3{font-size:18px;color:var(--text);font-weight:400;letter-spacing:.04em;margin:0}
.inc-col summary::after{content:"›";font-size:20px;color:var(--gold);transition:transform .2s ease;flex-shrink:0}
.inc-col[open] summary::after{transform:rotate(90deg)}
.inc-col ul{list-style:none;display:grid;gap:10px;margin-top:18px}
.inc-col li{font-size:13.5px;color:var(--muted);display:flex;gap:10px;align-items:flex-start;line-height:1.45}
.inc-col li::before{content:"◆";color:var(--gold-dim);font-size:7px;margin-top:6px;flex-shrink:0}
/* margin-bottom (не padding-bottom у <details>) — пока <details> закрыт, <p>
   не рендерится вовсе, поэтому на высоту закрытой строки не влияет; воздух
   появляется только когда ответ реально виден. */
details p{color:var(--muted);font-size:var(--fs-body-sm);margin-top:10px;margin-bottom:var(--row-pad-open);max-width:720px}
/* ссылки внутри текста (ответы FAQ, ошибки форм, обычные абзацы вроде
   /about и /pro/*): раньше был описан только details p a — обычный <p> a
   (напр. "Sigma Pro" в описании резидентства на /about) оставался без
   стиля и красился системным синим. Подчёркивание — text-decoration,
   а не border-bottom: корректно разрывается при переносе строки внутри абзаца. */
p a,.fld-error a{color:var(--accent-text);text-decoration:underline;
  text-decoration-color:var(--gold-dim);text-decoration-thickness:1px;text-underline-offset:3px}

/* ===== PARENT DISCLOSURE (UI-унификация 16.08.2026) — длинные разделы
   («Частые вопросы», «Вопросы об аренде/обучении», «Инструкции для
   арендаторов») сворачиваются в один верхнеуровневый <details>, закрытый
   по умолчанию. Контент внутри остаётся в исходном HTML/DOM всегда — nативный
   <details> просто визуально скрывает его, ничего не убирает из дерева, так
   что FAQPage JSON-LD (видимый текст = разметка) и SEO не задеты. Дочерние
   строки внутри (обычные <details>/summary) наследуют тот же chevron с
   правила выше — один визуальный язык на уровень выше и внутри разом. */
.pdisc{border:1px solid var(--line);border-radius:var(--r);background:var(--panel)}
.pdisc>summary{cursor:pointer;list-style:none;display:flex;align-items:center;justify-content:space-between;
  gap:16px;min-height:var(--row-min-h-card);padding:0 var(--card-pad);-webkit-tap-highlight-color:transparent}
.pdisc>summary::-webkit-details-marker{display:none}
.pdisc>summary h2,.pdisc>summary h3{margin:0;font-family:'Manrope',sans-serif;font-weight:500;font-size:var(--fs-h2);line-height:1.22}
.pdisc>summary::after{content:"›";font-family:'Manrope';font-size:24px;line-height:1;color:var(--accent-text);
  flex-shrink:0;transition:transform var(--t-base) ease}
.pdisc[open]>summary::after{transform:rotate(90deg)}
.pdisc>summary:focus-visible{outline:2px solid var(--accent);outline-offset:-2px;border-radius:var(--r-sm)}
.pdisc-body{padding:0 var(--card-pad) var(--card-pad)}
/* закрытая строка внутри тела disclosure не нуждается в верхней разделительной
   линии у самого первого элемента — border-bottom у .pdisc-body>details:last-
   child убирается снаружи по факту border-bottom самого <details>, тут не
   трогаем: тот же базовый details{border-bottom} остаётся консистентным */

/* V9 корректирующее ТЗ 23.08.2026 §2.1: .pdisc-static раньше был обычным
   <div> — заголовок и все вопросы всегда видны, ничего не сворачивается
   (см. историю решения в предыдущей версии этого комментария: <details
   class="pdisc"> пробовали раньше, отказались, т.к. это визуально делало
   H2-заголовок раздела кликабельным аккордеоном). Теперь требование
   обратное: на мобильном весь блок должен закрываться до тапа (сейчас же
   FAQ на входе занимает много места), а H2 при этом обязан оставаться в
   DOM и в дереве доступности постоянно — оба условия совместимы, если
   h2 лежит внутри <summary> (summary у <details> всегда видим независимо
   от open/closed, см. также .pdisc>summary h2 выше). .pdisc-static теперь
   сам <details>, .pdisc-static-head — его <summary>: тот же визуальный
   язык (рамка, паддинг, типографика), что и раньше, плюс шеврон как у
   .pdisc. На десктопе (min-width:1024px) JS принудительно держит open —
   тот же приём, что у .c-acc на /contacts (matchMedia, без блокировки
   клика — можно свернуть вручную, как и там). */
.pdisc-static{border:1px solid var(--line);border-radius:var(--r);background:var(--panel)}
.pdisc-static-head{display:flex;align-items:center;justify-content:space-between;gap:16px;
  min-height:var(--row-min-h-card);padding:var(--row-pad-y-card) var(--card-pad);cursor:pointer;list-style:none;
  -webkit-tap-highlight-color:transparent}
.pdisc-static-head::-webkit-details-marker{display:none}
.pdisc-static-head h2,.pdisc-static-head h3{margin:0;font-family:'Manrope',sans-serif;font-weight:500;font-size:var(--fs-h2);line-height:1.22}
.pdisc-static-head::after{content:"›";font-family:'Manrope';font-size:24px;line-height:1;color:var(--accent-text);
  flex-shrink:0;transition:transform var(--t-base) ease}
.pdisc-static[open]>.pdisc-static-head::after{transform:rotate(90deg)}
.pdisc-static-head:focus-visible{outline:2px solid var(--accent);outline-offset:-2px;border-radius:var(--r-sm)}
.pdisc-static[open]>.pdisc-body{padding-top:12px;border-top:1px solid var(--line)}

/* ===== FOOTER (ТЗ final_footer_contacts_spacing_color §1) — единый компонент на
   всех маршрутах. 5 зон, ритм open–card–card–card–open, зазор между зонами 22px.
   Карточки (Навигация/Связь/Реквизиты): единая обводка var(--line), radius 16px,
   padding 18px — единый --accent, без вариаций по направлению. ===== */
/* Отзыв владельца 16.08.2026: визуальный rollback ритма футера к состоянию
   до Visual-density pass §1.3 (несимметричный 14/6 читался хуже прежнего) —
   не redesign, только эти три значения (margin-top/padding здесь,
   .fcontact padding и десктопный footer padding ниже), остальные правки
   того же прохода (contact sheet, MAX, плотность аккордеонов и т.д.) не
   трогаются. */
footer{margin-top:var(--rhythm-module-footer);border-top:1px solid var(--line);padding:22px 0 calc(12px + env(safe-area-inset-bottom));font-size:13.5px;color:var(--muted)}
footer .wrap > * + *{margin-top:12px}
.fcard{border:1px solid var(--line);border-radius:16px;padding:18px}

.flogo{height:15px;width:auto;margin-bottom:14px;opacity:.9}
.fclub{color:var(--muted);margin-bottom:10px}
.fclub b{color:var(--text);font-weight:600}
.faddr{color:var(--muted);margin-bottom:6px}
.fmetro{display:flex;flex-direction:column;gap:2px;color:#847f76;font-size:var(--fs-meta)}
.fmetro span{display:flex;align-items:center;gap:7px}
.fmetro span::before{content:"";width:4px;height:4px;border-radius:50%;background:currentColor;opacity:.7;flex-shrink:0}

/* §1 ТЗ: колонки строго 60/40 и всегда рядом — проверено рендером, только это
   соотношение не даёт переноса "Направления" на 2 строки даже на узких экранах */
.fgrid2{display:grid;grid-template-columns:60fr 40fr;gap:14px;padding-top:14px;padding-bottom:14px}
/* аудит 09.08.2026 §10.5: были <h4> ради размера шрифта, без реальной роли
   в иерархии заголовков страницы — заменено на визуально идентичный <p> */
.fcol-label{font-family:'Manrope';font-weight:500;font-size:var(--fs-meta);letter-spacing:.22em;text-transform:uppercase;color:var(--accent-text);margin-bottom:14px}
/* V11 корректирующее ТЗ, пакет 1: тач-цель была ~31px (padding:5px 0 + line-height
   текста) — ниже минимума 44px. Увеличенный padding даёт ≥44px и на mobile,
   и на desktop (см. переопределение в @media(min-width:1024px) ниже). */
.fcol a{color:var(--muted);text-decoration:none;display:block;padding:12px 0;white-space:nowrap;transition:color var(--t-micro)}
/* правая колонка «Клуб» не участвует в требовании «Направления не переносятся» —
   при увеличенном системном шрифте (accessibility) пусть переносится на 2 строки,
   а не вылезает за край экрана */
.fcol:not(.fcol-wide) a{white-space:normal}

/* Mobile: сохраняем исходную двухколоночную компоновку футера, но чуть
   уплотняем вертикальный ритм ссылок — без изменения шрифта и ширин колонок. */
@media(width < 1024px){
  .fgrid2{padding-block:10px}
  .fcol-label{margin-bottom:6px}
  /* Owner 03.09.2026: подпись «Связь» над кнопкой связи появилась в футере
     вместе с Desktop V3 (4fed1e5) и на мобильном ничего не держит — контактная
     карточка идёт отдельным блоком под сеткой, выравнивать её не с чем. Ниже
     1024px подпись скрыта; на desktop она остаётся и продолжает задавать общую
     верхнюю линию трёх колонок через footer .fcol-label{min-height:16px}. */
  .fcontact .fcol-label{display:none}
  .fcol a{min-height:44px;padding:7px 0;box-sizing:border-box;display:flex;align-items:center;line-height:1.45}
}

/* Tablet is its own 2×2 footer mode. display:contents promotes the two nav
   columns to grid items, so visual reading order stays identical to DOM/focus
   order: brand → directions → club → contact. Mobile remains unchanged. */
@media(768px <= width < 1024px){
  footer .wrap{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:14px;align-items:stretch}
  footer .wrap > * + *{margin-top:0}
  .fbrand{grid-column:1;grid-row:1}
  .fgrid2:not(.ar-footer-utility){display:contents}
  .fgrid2:not(.ar-footer-utility) .fcol{border:1px solid var(--line);border-radius:16px;padding:16px 18px;box-sizing:border-box}
  .fgrid2 .fcol-wide{grid-column:2;grid-row:1}
  .fgrid2 .fcol:not(.fcol-wide){grid-column:1;grid-row:2}
  .fzone{grid-column:2;grid-row:2}
  .fzone .fcontact{height:100%;box-sizing:border-box}
  body.pg-arendatoram footer .fbrand{grid-row:1 / span 2}
  body.pg-arendatoram footer .fgrid2.ar-footer-utility{display:block;grid-column:2;grid-row:1}
}

/* Contact is visually secondary to the navigation cards and keeps a compact
   inset while reusing the shared button component. */
.fcontact{padding:16px 18px}
/* Отзыв владельца 16.08.2026: «Связаться с нами» в футере теперь тот же
   .btn g, что и на /contacts/везде — только ширина под колонку карточки
   переопределена локально, сам компонент не дублируется. */
.fcontact .btn{width:100%}
.flegal-btn{width:100%;min-height:44px;margin-top:10px;padding:8px 0;border:0;background:transparent;
  color:var(--muted);font:inherit;font-size:var(--fs-meta);cursor:pointer;display:flex;align-items:center;
  justify-content:center;gap:6px;transition:color var(--t-base)}
.flegal-btn span{color:var(--accent-text);transition:transform var(--t-base)}
@media(hover:hover) and (pointer:fine){
  .flegal-btn:hover{color:var(--text)}
  .flegal-btn:hover span{transform:translateX(3px)}
}

/* Legal details live in a fixed top sheet, so opening them never changes the
   footer height. The zone itself contains one compact contact card. */

/* Desktop: four semantic columns on the shared fluid container—brand,
   directions, club and contact/legal. Hairline separators share one row;
   the ink inside each column may end independently. */

/* ===== МОДАЛКА ===== */
.ovl{position:fixed;inset:0;background:rgba(9,6,4,.72);backdrop-filter:blur(6px);display:none;
     align-items:center;justify-content:center;z-index:100;padding:20px}
.ovl.open{display:flex}
.modal{background:var(--panel2);border:1px solid var(--line);border-radius:24px;width:100%;max-width:420px;padding:30px;position:relative;
  max-height:calc(100dvh - 40px);overflow-y:auto;overscroll-behavior:contain}
.modal h3{margin-bottom:4px}
.modal .sub{color:var(--muted);font-size:13.5px;margin-bottom:20px}
.modal .sub b{color:var(--accent-text);font-weight:500}
.fld{width:100%;background:var(--panel);border:1px solid var(--line);border-radius:var(--r-md);color:var(--text);
     padding:13px 15px;font-size:var(--fs-body-sm);font-family:inherit;margin-bottom:11px}
/* Visual system 17.08.2026, батч 1: было outline:none — единственное место
   на сайте, где видимый индикатор фокуса гасился (замена border-color 1px
   на var(--gold-dim) давала контраст 3.35:1, самый слабый на сайте, при
   том что везде остальное — outline 2px на 6.99:1). Приведено к общему
   :focus-visible, тому же языку, что у .btn/summary/.route. */
.fld:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
textarea.fld{resize:vertical;min-height:88px}
.send{width:100%;margin-top:6px;padding:14px}
/* V9 Пакет 1, §1.8: область нажатия ~26×31px (по размеру глифа) — ниже
   цели 44×44px. top/right — якорь верхнего правого угла, min-width/height
   растят бокс внутрь модалки (влево/вниз), не наружу — визуальная позиция
   «×» в углу не меняется, невидимая область нажатия вокруг неё больше. */
.x{position:absolute;top:16px;right:18px;background:none;border:none;color:var(--muted);font-size:26px;cursor:pointer;line-height:1;
  min-width:44px;min-height:44px;display:flex;align-items:center;justify-content:center}
.ok{text-align:center;padding:26px 0 10px;display:none}
/* Батч 0: не типографический дрейф — это иконочный глиф (◆) success-состояния
   формы, не заголовок и не текст. Вне типографической шкалы намеренно. */
.ok .ic{font-size:40px;color:var(--gold)}
.note{font-size:var(--fs-eyebrow);color:var(--muted);margin-top:12px;text-align:center}

/* ===== КНОПКА-ССЫЛКА (Реквизиты и т.п.) ===== */
.lnk{background:none;border:none;padding:0;font:inherit;color:inherit;text-decoration:underline;
     text-underline-offset:2px;cursor:pointer}

/* ===== ИКОНКА СВЯЗИ В ШАПКЕ (ТЗ catalog_masters_final §8) — единственная точка
   входа в глобальную связь, слева от гамбургера. Открывает top sheet #contactPanel
   (тот же компонент, что и кнопка в футере). Полностью отсутствует на /contacts
   и анкетах мастеров (см. body.pg-contacts/.pg-master ниже + build.js вырезает
   разметку из этих страниц — «не рендерится», а не просто скрыта). ===== */
.cf-icon{width:44px;height:44px;flex-shrink:0;display:flex;align-items:center;justify-content:center;
  background:none;border:none;border-radius:50%;color:var(--accent-text);cursor:pointer;outline-offset:2px;transition:color var(--t-micro)}
.cf-icon:focus-visible,.cf-icon.act{outline:2px solid var(--accent)}
body.pg-contacts .cf-icon,
body.pg-master .cf-icon{display:none}
@media(hover:hover) and (pointer:fine){.cf-icon:hover{color:var(--accent-text)}}

/* ===== TOP SHEET СВЯЗИ — растёт из-под шапки, backdrop затемняет, контент
   страницы не сдвигается (§8.2 ТЗ). Отдельные классы от .ovl/.modal — те
   остаются центрированными модалками (формы заявок и т.п.). ===== */
.cp-overlay{position:fixed;inset:calc(var(--hdr-h) + 1px) 0 0;height:calc(100dvh - var(--hdr-h) - 1px);z-index:90;background:rgba(9,6,4,.6);transform:translateZ(0);
  opacity:0;visibility:hidden;pointer-events:none}
.cp-overlay.open{opacity:1;visibility:visible;pointer-events:auto}
.cp-sheet{background:var(--panel2);border-bottom:1px solid var(--line);border-radius:0 0 24px 24px;
  max-width:480px;margin:0 auto;padding:22px 22px calc(22px + env(safe-area-inset-bottom));
  box-shadow:0 24px 50px rgba(0,0,0,.5);position:relative}
.cp-sheet-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:18px}
.cp-sheet-head h3{margin:0}
.cp-sheet .x{position:static}
.cp-legal-overlay{display:flex;align-items:flex-end;padding:0 16px}
.cp-legal-sheet{width:100%;max-width:760px;margin:0 auto;border-top:1px solid var(--line);border-bottom:0;
  border-radius:24px 24px 0 0;padding-bottom:calc(26px + env(safe-area-inset-bottom))}
.cp-legal-grid{display:grid;grid-template-columns:minmax(230px,.8fr) minmax(0,1.4fr);gap:28px}
.cp-legal-data{color:var(--muted);font-size:var(--fs-meta);line-height:1.7}
.cp-legal-data span{display:block}
.cp-legal-links{display:grid;grid-template-columns:1fr 1fr;gap:4px 24px}
.cp-legal-links a{display:flex;align-items:center;min-height:44px;color:var(--muted);font-size:var(--fs-meta);text-decoration:none}
@media(hover:hover) and (pointer:fine){.cp-legal-links a:hover{color:var(--text)}}
@media(max-width:640px){
  .cp-legal-overlay{padding:0}
  .cp-legal-sheet{border-radius:20px 20px 0 0}
  .cp-legal-grid{grid-template-columns:1fr;gap:14px}
  .cp-legal-links{grid-template-columns:1fr}
}
/* Финальное ТЗ 13.08.2026 §43: единая панель связи с мастером — тот же
   .cp-sheet/.cp-channels/.cp-ch, что и клубная (#contactPanel), плюс подзаголовок,
   которого у клубной панели не было. */
.cp-sub{color:var(--muted);font-size:13.5px;margin:-10px 0 16px}
@media(prefers-reduced-motion:no-preference){
  .cp-sheet{animation:cpDrop var(--t-reveal) ease}
  .cp-legal-overlay.open .cp-legal-sheet{animation:cpRise var(--t-reveal) ease}
}
@keyframes cpDrop{from{transform:translateY(-10px);opacity:0}to{transform:translateY(0);opacity:1}}
@keyframes cpRise{from{transform:translateY(18px);opacity:0}to{transform:translateY(0);opacity:1}}

/* ===== ПАНЕЛЬ СВЯЗИ — каналы связи, общие для top sheet и (исторически) модалок ===== */
.cp-channels{display:grid;grid-template-columns:1fr 1fr;gap:10px}
.cp-ch{background:var(--panel);border:1px solid var(--line);border-radius:var(--r-md);padding:14px;
  display:flex;flex-direction:column;align-items:center;gap:8px;text-align:center;
  color:var(--text);text-decoration:none;cursor:pointer;font:inherit;font-size:var(--fs-meta)}
.cp-ch small{color:var(--muted);font-size:var(--fs-eyebrow);font-weight:400}
.cp-ic{width:34px;height:34px;border-radius:50%;background:rgba(207,138,82,.14);color:var(--accent-text);
  display:flex;align-items:center;justify-content:center;font-size:13px;font-weight:700}
@media(hover:hover) and (pointer:fine){.cp-ch:hover{border-color:var(--accent-dim)}}

/* ===== COOKIE-БАННЕР — компактная карточка в правом нижнем углу (батч
   10.08.2026 §3.3). Было: центрированная полоса до 640px внизу экрана,
   перекрывала карточки, отзывы и футер на первом визите. z-index снижен со
   150 до 95: раньше баннер оказывался выше модалок (.ovl, z-index:100) —
   в правом нижнем углу это было бы куда заметнее, поэтому баннер теперь
   между .ovl (100) и .cp-overlay (90), а не поверх всего. ===== */
.cookiebar{position:fixed;z-index:95;display:none;
  left:12px;right:12px;bottom:calc(12px + env(safe-area-inset-bottom));
  background:var(--panel2);border:1px solid var(--line);border-radius:16px;
  padding:14px 16px;box-shadow:0 14px 34px rgba(0,0,0,.5);
  flex-direction:column;gap:12px;
  max-height:52dvh;overflow-y:auto;overscroll-behavior:contain}
.cookiebar.show{display:flex}
.cookiebar p{font-size:12px;line-height:1.45;color:var(--muted);margin:0}
.cookiebar p a{color:var(--accent-text);text-decoration:none;border-bottom:1px solid var(--gold-dim)}
.cookiebar-btns{display:flex;gap:10px;width:100%}
.cookiebar-btns .btn{flex:1;padding:12px 16px;min-height:44px}
@media(min-width:768px){
  .cookiebar{left:auto;right:24px;bottom:calc(24px + env(safe-area-inset-bottom));
    width:min(460px,calc(100vw - 48px));padding:20px 22px;gap:14px;max-height:none;overflow:visible}
  .cookiebar p{font-size:12.5px;line-height:1.5}
  .cookiebar-btns{width:auto;justify-content:flex-end}
  .cookiebar-btns .btn{flex:0 0 auto;padding:11px 24px}
}
/* пока открыто мобильное меню/шторка связи — баннер не спорит с ними за нижнюю зону */
body.nav-lock .cookiebar{opacity:0;pointer-events:none}

/* ===== ЧЕКБОКСЫ СОГЛАСИЯ В ФОРМАХ ===== */
.consent{display:flex;gap:9px;align-items:flex-start;font-size:var(--fs-meta);color:var(--muted);
  line-height:1.5;margin-bottom:11px;cursor:pointer}
.consent input{margin-top:3px;flex-shrink:0;accent-color:var(--gold)}
.consent a{color:var(--accent-text);text-decoration:none;border-bottom:1px solid var(--gold-dim)}
.fld-error{color:#e37b6b;font-size:var(--fs-meta);margin:-4px 0 11px;display:none}
.fld-error.show{display:block}
.fld.fld-invalid,.fld-invalid{border-color:#e37b6b}

/* ===== ЮРИДИЧЕСКИЕ ДОКУМЕНТЫ ===== */
/* Visual system 17.08.2026, батч 1: margin-bottom:100px в паре с
   footer{margin-top:22px} (см. ниже) давали переход к футеру 122px на всех
   5 legal-страницах — единственная страница сайта, где он не 22px. Блог
   уже компенсировал это инлайн-стилем margin-bottom:0 (build.js,
   renderArticlePage) — теперь это поведение по умолчанию, у перехода
   контент→футер остаётся один источник: footer{margin-top}. */
/* margin-left/right/bottom явно, margin-top НЕ трогаем (longhand, не
   shorthand) — иначе класс (специфичность 0,1,0) перебивал бы
   main>section+article (0,0,3) собственным margin-top:0 из шорткода
   "margin:0 auto", и правило выше продолжало бы не работать.
   display:flow-root — без него margin-bottom:14px последнего <p> внутри
   .legal-doc (см. .legal-doc p ниже) просачивался через article (нет
   padding/border-bottom) и складывался с footer{margin-top:22px} в 36px
   вместо 22px — margin последнего ребёнка "убегал" наружу через границу
   article, потому что сам article не создаёт новый BFC. */
.legal-doc{display:flow-root;max-width:760px;margin-left:auto;margin-right:auto;margin-bottom:0;color:var(--muted);font-size:var(--fs-body-sm);line-height:1.75}
/* V9 §5.6: текст статьи блога — 14.5px (общий с .legal-doc, который делят
   и юридические страницы вроде /oferta) слишком мелкий при измеренной
   ширине колонки 720px. Отдельный класс поверх .legal-doc — только для
   статей блога, юридические страницы не трогаем (комбинированный селектор
   0,2,0 — специфичнее самого .legal-doc, порядок в файле не важен). */
.legal-doc.blog-article{font-size:var(--fs-body)}
/* V9 §5.5: компактное раскрываемое оглавление статьи блога — только когда
   H2 много (см. injectArticleToc в build.js, порог ARTICLE_TOC_MIN_H2).
   Нативный <details> — раскрывается без JS. */
.article-toc{border:1px solid var(--line);border-radius:var(--r);margin-bottom:24px;background:var(--panel)}
.article-toc summary{list-style:none;cursor:pointer;display:flex;align-items:center;min-height:48px;padding:0 20px;
  font-size:14px;font-weight:600;color:var(--text)}
.article-toc summary::-webkit-details-marker{display:none}
.article-toc ol{margin:0;padding:2px 20px 18px 38px;display:flex;flex-direction:column;gap:7px}
.article-toc li{font-size:13.5px;line-height:1.5}
.article-toc a{color:var(--muted)}
.article-toc a:hover{color:var(--gold)}
/* Контекстный следующий шаг внутри статьи. Это самостоятельная
   конверсионная панель, а не ещё одна вложенная карточка: один контур,
   спокойная акцентная поверхность и два уровня действия. */
.article-cta{margin:32px 0;padding:22px 20px;border:var(--border-emphasis);border-radius:var(--r);
  background:var(--surface-accent);color:var(--text)}
.article-cta .crumb{margin-bottom:10px}
.article-cta h2{margin:0;font-size:clamp(21px,3vw,26px);line-height:1.25}
.article-cta p{margin:10px 0 0;color:var(--muted);font-size:var(--fs-body-sm);line-height:1.65}
.article-cta-actions{display:flex;flex-direction:column;align-items:stretch;gap:8px;margin-top:18px}
.article-cta-actions .btn{justify-content:center;text-align:center}
@media(min-width:640px){
  .article-cta{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:24px;align-items:center;padding:24px}
  .article-cta-actions{align-items:flex-start;margin-top:0;min-width:210px}
  .article-cta-actions .btn.g{width:100%}
}
/* Источники остаются индексируемыми и доступны без JavaScript, но не уводят
   тёплого читателя длинным перечнем внешних ссылок сразу после статьи. */
.article-sources{margin:24px 0 32px;border-top:1px solid var(--line);border-bottom:1px solid var(--line)}
.article-sources>summary{min-height:56px;padding:8px 2px;display:flex;align-items:center;
  justify-content:space-between;gap:16px;list-style:none;cursor:pointer;color:var(--muted);
  font-size:var(--fs-body-sm);font-weight:600}
.article-sources>summary::-webkit-details-marker{display:none}
.article-sources>summary::after{content:'›';font-size:21px;line-height:1;color:var(--muted);
  transition:transform var(--t-base) ease}
.article-sources[open]>summary::after{transform:rotate(90deg)}
.article-sources-body{padding:0 2px 18px;color:var(--muted)}
.article-sources-body p{margin:0 0 12px}
.article-sources-body ul{margin:0;padding-left:20px}
.article-sources-body li+li{margin-top:8px}
.legal-doc .article-sources-body a{color:inherit;text-decoration:underline;text-decoration-thickness:1px;
  text-decoration-color:color-mix(in srgb,var(--muted) 58%,transparent);text-underline-offset:3px}
.legal-doc .article-sources-body a:hover{color:var(--text);text-decoration-color:currentColor}

/* На отдельных посадочных массажа карточка показывает реальный набор
   программ конкретного мастера. Плоские строки без собственного фона и
   радиуса различают тантрический и расслабляющий каталоги, не создавая
   визуальный эффект «карточки внутри карточки». */
.card-programs-list{list-style:none;margin:4px 0 2px;padding:0;border-top:1px solid var(--line)}
.card-programs-list li{display:grid;grid-template-columns:minmax(0,1fr) auto;gap:12px;
  align-items:baseline;padding:9px 0;border-bottom:1px solid var(--line)}
.card-program-name{color:var(--text);font-size:12.5px;line-height:1.4}
.card-program-meta{color:var(--muted);font-size:12px;line-height:1.4;white-space:nowrap}
.card-program-meta b{color:var(--accent-text);font-weight:600}
@media(max-width:359px){
  .card-programs-list li{grid-template-columns:1fr;gap:2px}
}
/* V9 §5.5: источники — компактный список перед FAQ, каждый пункт привязан
   к конкретному утверждению в тексте статьи (не список "для количества"). */
.sources{max-width:760px;margin-left:auto;margin-right:auto}
section.sources{margin-top:var(--sp-section)}
.sources h2{margin-bottom:14px}
.sources ul{list-style:none;display:flex;flex-direction:column;gap:10px;padding:0;margin:0}
.sources li{font-size:13px;line-height:1.6;color:var(--muted);padding-left:18px;position:relative}
.sources li::before{content:"—";position:absolute;left:0;color:var(--gold-dim)}
.sources a{color:var(--accent-text)}
.legal-doc p{margin-bottom:14px}
.legal-definitions{display:grid;gap:14px;margin:0 0 28px}
.legal-definitions>div{padding-bottom:14px;border-bottom:1px solid var(--line)}
.legal-definitions>div:last-child{padding-bottom:0;border-bottom:0}
.legal-definitions dt{color:var(--text);font-weight:600;line-height:1.45}
.legal-definitions dd{margin:4px 0 0;color:var(--muted);line-height:1.7}
.legal-doc ul,.legal-doc ol{margin:0 0 14px 20px}
.legal-doc li{margin-bottom:6px}
.legal-doc strong{color:var(--text);font-weight:600}
.legal-doc a{color:var(--accent-text)}
/* V11 пакет 7: статьи блога впервые используют markdown-цитаты (blockquote) —
   визуальный язык взят с .a-quote (about.html) без italic/cite, т.к. здесь
   это просто выделенная мысль внутри статьи, а не атрибутированная цитата. */
.legal-doc blockquote{margin:20px 0 24px;padding:2px 0 2px 18px;border-left:2px solid var(--gold-dim)}
.legal-doc blockquote p{margin-bottom:0;color:var(--text)}
/* V9 корректирующее ТЗ 23.08.2026 §1.1: white-space:nowrap заставлял
   .legal-table растягиваться на 3855px (каждая ячейка — одна строка без
   переноса) — и на мобильном, и на десктопе, при контейнере 760px. Без
   nowrap текст переносится, table-layout остаётся табличным за счёт
   CSS-фиксапа (tr/td наследуют table-row/table-cell даже когда сам
   <table> — display:block), поэтому колонки по-прежнему выравниваются. */
.legal-doc table{display:block;max-width:100%;overflow-x:auto;border-collapse:collapse;font-size:var(--fs-meta)}
.legal-doc td,.legal-doc th{border:1px solid var(--line);padding:8px 10px;text-align:left;vertical-align:top}
.legal-doc table p{margin-bottom:8px}
.legal-doc table p:last-child{margin-bottom:0}
.legal-doc .quill-table__wrapper{position:relative}
.legal-doc .quill-table__wrapper::after{
  content:"";position:absolute;top:0;right:0;bottom:0;width:28px;
  background:linear-gradient(to right,transparent,var(--bg) 70%);
  pointer-events:none;
}
/* V9 корректирующее ТЗ 23.08.2026 §1.1: на узких экранах даже перенос
   текста не спасает 5 колонок — переключаем .legal-table на карточную
   раскладку "подпись → значение" через data-label (проставлен в
   policy.html при генерации таблицы). <thead> не удаляем и не
   display:none — прячем визуально приёмом sr-only, чтобы программные
   заголовки колонок остались в дереве доступности (проверено
   page.accessibility.snapshot()). role-атрибуты на table/thead/tbody/
   tr/th/td — подстраховка: часть браузеров снимает неявную табличную
   семантику, когда display у этих элементов переопределён на block. */
@media (max-width:640px){
  .legal-doc .quill-table__wrapper::after{display:none}
  .legal-doc table.legal-table{overflow-x:visible}
  .legal-doc table.legal-table thead{
    position:absolute;width:1px;height:1px;padding:0;margin:-1px;
    overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0;
  }
  .legal-doc table.legal-table tbody{display:block}
  .legal-doc table.legal-table tr{
    display:block;margin-bottom:14px;border:1px solid var(--line);
    border-radius:10px;padding:10px 12px;
  }
  .legal-doc table.legal-table tr:last-child{margin-bottom:0}
  .legal-doc table.legal-table td{display:block;border:none;padding:6px 0}
  .legal-doc table.legal-table td:not(:last-child){border-bottom:1px dashed var(--line)}
  .legal-doc table.legal-table td::before{
    content:attr(data-label);display:block;font-weight:600;color:var(--text);
    margin-bottom:4px;
  }
}
/* Контент-SEO раунд 17.08.2026: статьи блога получили H2/H3-структуру
   (раньше bodyHtml был плоским текстом без единого заголовка) — размер
   заголовков наследуется от общих h2{font-size:var(--fs-h2)}/h3{...} выше по
   файлу, здесь только отступы внутри читательской колонки .legal-doc. */
.legal-doc h2{margin:40px 0 14px;color:var(--text)}
.legal-doc h2:first-child{margin-top:0}
.legal-doc h3{margin:26px 0 10px;color:var(--text)}
@media print{.legal-doc{color:#000}header,footer,.cookiebar,.cookiebar.show{display:none}}

/* ============================================================
   ПИЛОТ: архитектурно-визуальное ТЗ (главная, /space, /space/aura,
   /space/sliyanie) — общие токены и компоненты.
   ============================================================ */

/* --- H1-токены по шаблону (не трогают общий h1{} для остальных страниц) --- */
/* Классы сохранены в разметке для совместимости, но больше не задают
   собственную кривую размера — единый h1-токен, максимум 38px везде. */
.h1-home,.h1-space,.h1-loft,.h1-pro{font-size:var(--fs-h1);line-height:1.16;font-weight:500}

/* --- SubbrandMark: единый двухстрочный компонент (§2.4 итогового ТЗ) —
   строка 1: название направления (accent-text, трекинг). «80% от логотипа»
   считается по ОПТИЧЕСКОЙ высоте, не по числу font-size: у логотипа (SVG,
   заглавные буквы почти без внутренних просветов) высота чернил ≈ 94% от
   рендер-высоты 19px ≈ 17.9px; у текста Manrope 500 высота чернил ≈ 75% от
   font-size. Раньше здесь стоял font-size:15px (просто 15/19=79% от ЧИСЛА
   19px) — визуально это давало лишь ~63% от реальной высоты чернил логотипа,
   отсюда и жалоба, что подпись выглядит мельче 80%. Верное значение —
   font-size:19px (0.8×17.9 / 0.75 ≈ 19). */
.subbrand-mark{margin-bottom:12px}
.subbrand-mark .sm-name{display:block;font-size:19px;font-weight:500;letter-spacing:.2em;
  text-transform:uppercase;color:var(--accent-text)}
.subbrand-mark .sm-desc{display:block;font-size:var(--fs-meta);font-weight:400;color:var(--muted);
  margin-top:3px;text-transform:none;letter-spacing:normal}

/* --- ClickableCard: доступное состояние фокуса поверх существующего .route --- */
.route{position:relative}
.route:focus-visible{outline:2px solid var(--text);outline-offset:3px}
@media(hover:none){
  .route:active{transform:scale(.98);transition:transform .12s}
  .route:active .bgim{transform:scale(1.02)}
}

/* --- GoldMedallion: кольцо + бейдж. Общий компонент для /space, главной,
   /school, /pro. Геометрия дуги (85°, пик .6 на 40°, цикл 9s linear) и цвет
   заморожены — прошли несколько кругов калибровки с клиентом (мягче не
   заметно, ярче/быстрее — «дёшево»/«светофор»). На страницах допустимо менять
   только диаметр кольца (--hb-size, по умолчанию 38px) и animation-delay
   (фазовый сдвиг). Входная анимация (материализация + вспышка при появлении)
   — только для медальонов на первом экране, объявляется локально на странице
   (см. hbIgnite/hbGlow в /space, главной, /school). */
.hb-ring{position:relative;width:var(--hb-size,38px);height:var(--hb-size,38px);flex-shrink:0}
/* Восстановлено по прямому запросу заказчика 10.08.2026 (вечер) — вращающаяся
   анимация возвращена как была. Ранее в этом же батче она была заменена на
   статичный glow как гипотеза устранения «золотых точек, едущих за курсором»
   при скролле; заказчик отклонил эту замену. Если жалоба на «точки» повторится,
   первый кандидат на диагностику снова эта анимация — см. историю коммитов. */
.hb-ring::before{content:"";position:absolute;inset:-4px;border-radius:50%;
  background:conic-gradient(from 0deg,rgba(207,138,82,0) 0deg,rgba(207,138,82,.6) 40deg,rgba(207,138,82,0) 85deg);
  animation:hbHalo var(--t-ambient) linear infinite}
@keyframes hbHalo{to{transform:rotate(360deg)}}
.hb-badge{position:relative;width:100%;height:100%;border-radius:50%;
  display:flex;align-items:center;justify-content:center;
  border:1px solid rgba(207,138,82,.28);
  background:var(--surface-medallion)}
.hb-badge svg{width:16px;height:16px;color:var(--accent-text);flex-shrink:0;transition:color var(--t-reveal)}
@media(hover:hover) and (pointer:fine){
  .hb-item:hover .hb-badge{border-color:var(--accent);box-shadow:0 0 16px rgba(207,138,82,.4)}
  .hb-item:hover svg{color:#F0C896}
}
@media(prefers-reduced-motion:reduce){
  .hb-ring::before{animation:none;opacity:.4}
}
/* Батч 10.08.2026 §3.1: изоляция стекового контекста у родителей golden-halo
   колец — без обрезки (::before у .hb-ring/.mst-ring рисуется за пределами
   рамки, inset:-4px, поэтому overflow/contain здесь недопустимы). */
.hb-item,.mst-i,.tw-badge,.pf-list li,.pil,.ar-i{isolation:isolate}

/* --- TrustCard (.tw): единый блок доверия «5,0 · 150+ отзывов · Хорошее
   место 2026». Разметка собирается один раз в build.js (TRUST_YAMAP) и
   ставится на /, /about, /contacts. Стили до этого лежали инлайном на
   index.html и contacts.html под классом .yamap, а на /about их не было
   вовсе — блок падал в три голые строки текста; поэтому компонент переехал
   сюда, в общую систему. Композиция вертикальная и не зависит от ширины
   вьюпорта — одинаково собирается и в узкой колонке /contacts (340px), и в
   полноширинной секции. Медальон «Хорошее место» переиспользует общий
   .hb-ring/.hb-badge (GoldMedallion), а не рисует собственный бейдж. --- */
.tw{max-width:420px;padding:22px;border:1px solid var(--line);border-radius:var(--r);
  background:var(--panel)}
.tw-top{display:flex;align-items:center;gap:16px}
.tw-score{flex-shrink:0;text-align:center}
/* Батч 0: осознанное исключение из общей шкалы — фиксированные 42px, не
   clamp(). Карточка доверия сама ограничена max-width:420px и одинаково
   компактна на любой ширине viewport (см. .tw выше), поэтому цифра рейтинга
   не должна откликаться на vw — иначе на узких экранах «5,0» визуально
   мельчает без причины, хотя карточка не меняет размер. */
.tw-score b{display:block;font-family:'Manrope',sans-serif;font-weight:500;font-size:42px;
  line-height:1;letter-spacing:-.015em;color:var(--text)}
.tw-stars{display:block;margin-top:8px;font-size:12px;line-height:1;letter-spacing:.16em;
  color:var(--accent-text)}
.tw-meta{min-width:0;padding-left:16px;border-left:1px solid var(--line)}
/* Opus-план 24.08.2026 §8.5/§8.6: «150+» — самостоятельная метрика (была
   частью строки «150+ отзывов»), слабее рейтинга .tw-score (42px), но
   заметно сильнее подписи — фиксированный размер, тот же приём, что и у
   .tw-score b (§ выше про «осознанное исключение из общей шкалы»). */
.tw-meta b{display:block;font-family:'Manrope',sans-serif;font-weight:500;font-size:22px;line-height:1.2;color:var(--text)}
.tw-meta span{display:block;margin-top:3px;font-size:var(--fs-meta);line-height:1.3;color:var(--muted)}
.tw-badge{display:flex;align-items:center;gap:13px;margin-top:20px;padding-top:18px;
  border-top:1px solid var(--line)}
.tw-badge .hb-ring{--hb-size:42px}
.tw-badge .hb-badge img{width:24px;height:auto}
.tw-badge-t{display:block;min-width:0}
.tw-badge-t b{display:block;font-weight:500;font-size:13.5px;line-height:1.35;color:var(--text)}
.tw-badge-t span{display:block;margin-top:2px;font-size:var(--fs-eyebrow);line-height:1.3;color:var(--muted)}
.tw-action{margin-top:18px}
.tw-action .btn{display:flex;width:100%;margin:0;padding:14px 18px;font-size:13.5px}
@media(max-width:400px){
  .tw{padding:18px}
  .tw-top{gap:13px}
  .tw-score b{font-size:36px}
  .tw-meta{padding-left:13px}
  .tw-action .btn{font-size:13px;padding:14px 12px}
}

/* Компактный блок доверия в hero (/space, TRUST_COMPACT) — те же данные, что
   в .tw, но одной прямоугольной плашкой на два поля: общая рамка, волосяной
   разделитель, тот же тёплый градиент, что у .tw. Словарь взят у .trust-strip,
   новая форма не изобретается. Отзыв 10.08.2026: две отдельные «таблетки»
   читались как два самостоятельных объекта и переносились независимо друг от
   друга — плашка имеет предсказуемую высоту, и Primary под ней не ездит.
   От 520px поля встают в один ряд. */
.tw-inline{display:grid;grid-template-columns:1fr;width:fit-content;max-width:100%;
  border:1px solid var(--line);border-radius:var(--r-md);overflow:hidden;
  background:var(--panel)}
.twi{display:flex;align-items:center;gap:8px;min-width:0;padding:8px 14px;
  font-size:var(--fs-meta);line-height:1.25;color:var(--muted);text-decoration:none}
.twi+.twi{border-top:1px solid var(--line)}
.twi i{font-style:normal;letter-spacing:.1em;color:var(--accent-text);flex-shrink:0}
.twi b{font-weight:500;color:var(--text)}
.twi img{height:15px;width:auto;flex-shrink:0}
.twi-review{transition:background var(--t-micro),color var(--t-micro)}
.twi-review:focus-visible{outline:2px solid var(--accent);outline-offset:-2px}
.twi-arrow{margin-left:auto;color:var(--accent-text);font-weight:600;flex:0 0 auto;transition:transform var(--t-micro)}
@media(hover:hover) and (pointer:fine){
  .twi-review:hover{background:rgba(226,149,79,.06);color:var(--text)}
  .twi-review:hover .twi-arrow{transform:translateX(2px)}
}
@media(min-width:520px){
  .tw-inline{grid-template-columns:auto auto}
  .twi{padding:9px 16px}
  .twi+.twi{border-top:none;border-left:1px solid var(--line)}
}

/* --- TrustStrip: компактная полоса из 3–4 показателей --- */
.trust-strip{display:flex;flex-wrap:wrap;gap:0;border:1px solid var(--line);border-radius:var(--r);
  overflow:hidden;margin-top:20px}
.trust-strip .ts-i{flex:1 1 0;min-width:0;padding:16px 14px;text-align:center;
  border-left:1px solid var(--line)}
.trust-strip .ts-i:first-child{border-left:none}
.trust-strip .ts-i b{display:block;font-size:clamp(17px,3vw,21px);font-weight:500;color:var(--text);
  line-height:1.2;white-space:nowrap}
.trust-strip .ts-i span{display:block;font-size:var(--fs-eyebrow);color:var(--muted);margin-top:4px;line-height:1.3}
@media(max-width:480px){.trust-strip{flex-wrap:wrap}.trust-strip .ts-i{flex:1 1 50%;border-left:none;border-top:1px solid var(--line)}.trust-strip .ts-i:nth-child(1),.trust-strip .ts-i:nth-child(2){border-top:none}.trust-strip .ts-i:nth-child(odd){border-left:none}.trust-strip .ts-i:nth-child(even){border-left:1px solid var(--line)}}

/* ===== ECO-FACTS + карточка Яндекса — единый блок доверия на / и /about
   (ТЗ 18+/футер/доверие 11.08.2026 §3): факты экосистемы (с какого года,
   сколько направлений, сколько сеансов) без рейтинга/отзывов — те уже
   показаны ниже, в общей карточке TRUST_YAMAP (та же разметка, что и на
   /contacts, — build.js), поэтому «150+» не задваивается. Одна и та же
   вёрстка/порядок/подписи на обеих страницах. 3 ячейки в один ряд на любой
   ширине — компактно, без лишнего воздуха. */
.eco-facts{display:flex;gap:0;border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.eco-facts .ef-i{flex:1 1 0;min-width:0;padding:16px 14px;text-align:center;border-left:1px solid var(--line)}
.eco-facts .ef-i:first-child{border-left:none}
/* Opus-план 24.08.2026 §8.6: нижняя граница clamp (16px) реально
   рендерилась на 360/390 — ориентир 21px на mobile не достигался. Верхняя
   граница уже была 21px, так что clamp(16px,3vw,21px) сведён к фиксации. */
.eco-facts .ef-i b{display:block;font-family:'Manrope',sans-serif;font-size:21px;
  font-weight:500;color:var(--accent-text);line-height:1.2;white-space:nowrap}
.eco-facts .ef-i span{display:block;font-size:var(--fs-eyebrow);color:var(--muted);margin-top:4px;line-height:1.3}
@media(max-width:480px){.eco-facts .ef-i{padding:12px 8px}}
/* V9 корректирующее ТЗ 23.08.2026 §2.3: .eco-facts и .tw каждый носили
   собственную рамку+radius — рядом (десктоп) или друг под другом
   (мобильный) это читалось как два отдельных блока доверия, а не один.
   Общая рамка на .eco-trust, волосяная линия-разделитель между половинами
   вместо зазора — тот же приём, что у .eco-facts .ef-i+.ef-i выше.
   V11 корректирующее ТЗ, пакет 2 §6: предыдущая версия здесь сознательно
   сохраняла тёплый градиент .tw («тонкое различие двух видов данных внутри
   одного блока») — по производственной приёмке владельца это читалось не
   как тонкое различие, а как закрашенный правый/нижний блок поверх пустой
   левой/верхней половины. Убираем градиент только внутри .eco-trust —
   на /contacts .tw стоит один, без соседней прозрачной половины, там
   тёплый tint не создаёт этой проблемы и остаётся как есть (см. .tw ниже,
   contacts.html #trustCard/.c5). */
.eco-trust{border:1px solid var(--line);border-radius:var(--r);overflow:hidden}
.eco-trust .eco-facts{border:none;border-radius:0}
.eco-trust .tw{margin:0;border:none;border-radius:0;border-top:1px solid var(--line);background:none}

/* V13, вариант A (proof-stack): на телефонах и планшетах доказательства
   читаются последовательными полноширинными рядами. Внутренние разделители
   доходят до общей рамки, а rating/meta не получают конфликтующую линию. */
@media(max-width:1023px){
  .eco-trust--split .tw{max-width:none;padding:0;display:block}
  .eco-trust--split .tw-top{display:grid;grid-template-columns:1fr 1fr;gap:0;min-height:88px;padding:0}
  .eco-trust--split .tw-score,.eco-trust--split .tw-meta{display:flex;flex-direction:column;align-items:center;justify-content:center;text-align:center;padding:14px 10px}
  .eco-trust--split .tw-meta{border-left:1px solid var(--line);padding-left:10px}
  .eco-trust--split .tw-meta span{max-width:120px}
  .eco-trust--split .tw-badge{justify-content:center;min-height:76px;margin:0;padding:14px 20px;border-top:1px solid var(--line);border-right:0}
  .eco-trust--split .tw-action{display:flex;align-items:center;justify-content:center;margin:0;padding:12px 16px 16px;border-top:1px solid var(--line)}
  .eco-trust--split .tw-action .btn{width:100%;min-height:50px;margin:0;padding:13px 20px;border:var(--border-emphasis);border-radius:var(--r-pill);background:transparent}
}

/* ТЗ реконструкции 12.08.2026 §A.5: на /about факты и карточка доверия были
   двумя этажами (строка фактов сверху, узкая карточка по центру ниже) —
   большие пустые поля по бокам карточки. --split собирает их в один
   двухколоночный блок: слева факты вертикальным стеком, справа карточка на
   всю высоту колонки, обе колонки visually одной высоты (align-items:stretch).
   V9 Пакет 2, §2.2: главная переведена на тот же --split (index.html) —
   единый компонент на обеих страницах, прежнее «главная без класса»
   исторически было расхождением, которое V9 явно требует убрать.

   V11 корректирующее ТЗ (внеочередная правка после пакета 3, по прямому
   замечанию владельца на реальном экране): двухколоночная версия выше
   (факты вертикальным стеком слева / карточка справа) визуально ломалась —
   слева 3 РАВНЫЕ строки с 2 горизонтальными линиями через равные интервалы,
   справа 2 НЕРАВНЫЕ группы (рейтинг / бейдж+кнопка) с одной линией на
   произвольной высоте — единая вертикальная линия между половинами не
   привязана ни к чему, что выровнено. Владелец: «если вертикальные
   разделители не удаётся сделать безупречно — горизонтальные и отступы».

   Новая раскладка отказывается от левой/правой колонки совсем. Обе полосы —
   ПОЛНОШИРИННЫЕ ряды, друг под другом, разделены одной горизонтальной
   линией:
     Полоса 1 — .eco-facts, обычный ряд 3 колонок (та же вёрстка, что уже
       работает на мобильном, просто шире) — 2 вертикальные линии, обе
       чётко между соседними ячейками одной строки, ничего не пересекают.
     Полоса 2 — .tw, тоже ряд, но из 3 ячеек: рейтинг | бейдж | кнопка (были
       строками друг под другом) — тоже вертикальные линии только между
       соседями внутри СВОЕЙ строки.
   Обе полосы держит одна общая рамка/фон (.eco-trust, не тронуто), одна
   горизонтальная граница между ними (border-top на .tw, было и на
   мобильном — тут просто не переключается на border-left). Каждая полоса
   сама по себе симметрична; полосы между собой не заявляют выравнивания,
   которого нет. */

/* ===== MEDIA-SLOT — единая заглушка под будущее фото (батч 10.08.2026 §8).
   Назначение слота фиксируется в data-photo-slot, посетителю не показывается.
   aria-hidden — блок декоративный, фальшивого alt нет. Фиксированный
   aspect-ratio — при появлении реального фото высота секции не прыгнет (CLS). */
.mslot{position:relative;overflow:hidden;
  border:1px solid var(--line);border-radius:var(--r);
  aspect-ratio:var(--mslot-ar,16/10);
  background:
    radial-gradient(120% 90% at 50% 0%,rgba(207,138,82,.07),transparent 62%),
    linear-gradient(160deg,var(--card2),var(--card) 72%)}
.mslot::after{content:"";position:absolute;left:50%;top:50%;
  transform:translate(-50%,-50%);width:min(38%,240px);aspect-ratio:191/20;
  background:url('/assets/logo.svg') center/contain no-repeat;opacity:.07}
.mslot--43{--mslot-ar:4/3}
.mslot--45{--mslot-ar:4/5}
.mslot--1610{--mslot-ar:16/10}
@media(max-width:1023px){.mslot--desk-only{display:none}}

/* Батч 10.08.2026 (вечер) §2: фото внутри аккордеона «Что входит» (/space,
   /space/aura, /space/sliyanie) — реальные <img>, не CSS-фон (иначе они
   невидимы для Яндекс.Картинок/Google Images, см. build.js "M-11"). */
.inc-photos{display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:14px}
.inc-photos img{display:block;width:100%;height:auto;min-width:0;aspect-ratio:16/10;
  object-fit:cover;border-radius:12px;border:1px solid var(--line)}

/* --- SwipeStrip: переиспользуемая точка для мобильных свайп-блоков "внутри
   секции" (Батч 0, docs/SIGMA_IMPLEMENTATION_PLAN.md §0.4, решение P3).
   Вынесен из уже проверенного в бою паттерна .mp-others («Другие мастера» на
   анкете мастера): скрытый скроллбар + обязательный snap, карточки не
   вылезают за пределы своей секции — в отличие от .hscroll ниже (тот
   намеренно бледит фото к краю экрана с видимым тонким скроллбаром — другая
   задача, другой визуал, трогать его не нужно). Ширина элементов не задана
   намеренно — её определяет конкретный блок (карточка мастера/статьи);
   для «Статьи по теме»/«Из блога» ширина карточки задана в правиле
   `.rel-grid.h-swipe .rel-card` выше по файлу. */
.h-swipe{display:flex;gap:12px;overflow-x:auto;scroll-snap-type:x mandatory;
  padding-bottom:2px;scrollbar-width:none;-webkit-overflow-scrolling:touch}
.h-swipe::-webkit-scrollbar{display:none}
/* Mobile polish 18.08.2026, §5.2: без scroll-snap-stop сильный/быстрый fling
   на touch-устройстве может по инерции проехать мимо ближайшей карточки и
   осесть через одну-две дальше — «один свайп = один элемент» тогда не
   держится. scroll-snap-stop:always заставляет браузер останавливаться на
   каждой точке привязки по очереди, независимо от силы жеста. */
.h-swipe>*{scroll-snap-align:start;scroll-snap-stop:always;flex:0 0 auto}

/* --- HSwipeNav: единый interaction-pattern для горизонтальных mobile-блоков
   (глобальная корректировка 15.08.2026) — компактные синхронные стрелки
   ‹ › поверх .h-swipe/.mp-others-подобных рядов. Логика (disabled на первом/
   последнем элементе, скролл на «карточку» по клику) — assets/hswipe-nav.js,
   один скрипт на все блоки с data-hswipe, без сторонних carousel-библиотек.
   Визуальный язык — тот же круглый компактный контрол, что у .rv-arrow
   (карусель отзывов /space): 44×44 тач-зона, тонкая рамка, без заливки. */
.hs-nav{display:flex;gap:8px;flex-shrink:0}
.hs-arrow{width:44px;height:44px;border-radius:50%;border:1px solid var(--line);background:var(--panel);
  color:var(--text);font-size:18px;line-height:1;cursor:pointer;display:flex;align-items:center;
  justify-content:center;flex-shrink:0;-webkit-tap-highlight-color:transparent}
.hs-arrow::before{content:'‹'}
.hs-arrow.next::before{content:'›'}
.hs-arrow:disabled{opacity:.35;cursor:default}
.hs-arrow:focus-visible{outline:2px solid var(--text);outline-offset:2px}
@media(hover:hover) and (pointer:fine){.hs-arrow:not(:disabled):hover{border-color:var(--accent-dim)}}

/* --- HorizontalScroll: равноправные наборы, scroll-snap, край следующего виден --- */
.hscroll{display:flex;gap:12px;overflow-x:auto;scroll-snap-type:x proximity;
  padding-bottom:6px;margin-inline:calc(var(--gutter) * -1);padding-inline:var(--gutter);
  scrollbar-width:thin}
.hscroll::-webkit-scrollbar{height:5px}
.hscroll::-webkit-scrollbar-thumb{background:var(--line);border-radius:99px}
.hscroll > *{scroll-snap-align:start;flex:0 0 auto;width:min(78vw,300px)}
.hscroll:focus-visible{outline:2px solid var(--accent);outline-offset:2px}

/* ===== ROOM LANDINGS: /space/aura + /space/sliyanie =====
   Один адаптивный компонент для обеих комнат: реальное изображение, ясная
   коммерческая иерархия, одинаковые CTA и компактные раскрытия на телефоне. */
.room-page .lp-hero{display:grid;gap:20px;padding-top:12px;align-items:start}
.room-page .lp-hero-copy{min-width:0}
.room-page .lp-back{display:inline-flex;align-items:center;min-height:44px;margin-bottom:8px;
  color:var(--muted);font-size:13px;text-decoration:none}
.room-page .lp-hero h1{max-width:760px}
.room-page .lp-hero .lead{max-width:720px;margin-top:12px;font-size:14.5px;line-height:1.58}
.room-page .lp-compact{color:var(--muted);font-size:13.5px;line-height:1.45;margin-top:12px}
.room-page .lp-price{display:flex;align-items:baseline;gap:8px;margin-top:16px}
.room-page .lp-price b{font-family:'Manrope';font-weight:500;font-size:28px;color:var(--gold)}
.room-page .lp-price span{font-size:13px;color:var(--muted)}
.room-page .room-booking-cta{width:100%;min-height:50px;margin-top:16px;padding:0 24px}
.room-page .lp-gal{min-width:0;margin-top:0;position:relative}
.room-page .room-gallery{width:100%;min-width:0}
.room-page .room-gallery>figure{flex:0 0 100%;margin:0;aspect-ratio:4/3;border-radius:24px;
  border:1px solid var(--line);position:relative;overflow:hidden;background:var(--panel)}
.room-page .room-gallery picture,.room-page .room-gallery img{display:block;width:100%;height:100%}
.room-page .room-gallery img{object-fit:cover}
.room-page .room-gallery>figure::after{content:"";position:absolute;inset:0;pointer-events:none;
  background:linear-gradient(180deg,transparent 60%,rgba(10,7,5,.28))}
.room-page .lp-gal-nav{position:absolute;right:12px;bottom:12px;z-index:2}

.room-page .lp-specs,.room-page .prac2,.room-page .inc,.room-page .room-conditions,
.room-page .room-questions,.room-page .room-final-cta,.room-page .room-alt-wrap,
.room-page .room-next-links{margin-top:var(--sp-section)}
.room-page .lp-specs>p{max-width:760px;color:var(--muted);font-size:14px;line-height:1.58;margin:10px 0 18px}
.room-page .lp-specs-grid{display:grid;grid-template-columns:1fr 1fr;gap:1px;background:var(--line);
  border:1px solid var(--line);border-radius:14px;overflow:hidden}
.room-page .lp-specs-grid .r{min-width:0;min-height:82px;background:var(--panel2);padding:12px 14px;
  display:flex;flex-direction:column;justify-content:space-between;gap:5px;font-size:12.5px;line-height:1.4}
.room-page .lp-specs-grid .r span{color:var(--muted)}
.room-page .lp-specs-grid .r b{font-weight:500;text-align:left;color:var(--text)}
.room-page .eqbadges{display:flex;flex-wrap:wrap;gap:8px;margin:16px 0}
.room-page .eqbadge{font-size:10.5px;letter-spacing:.08em;text-transform:uppercase;color:var(--gold);
  border:1px solid var(--gold-dim);border-radius:999px;padding:6px 10px;white-space:nowrap}
@media(max-width:639px){
  .room-page .eqbadges{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));grid-auto-rows:48px}
  .room-page .eqbadge{display:flex;align-items:center;justify-content:center;width:100%;height:48px;
    padding:4px 12px;text-align:center;font-size:11px}
}
.room-page .tariff-toggle{width:100%;min-height:50px;margin:4px 0 0;padding:0 16px;border:1px solid var(--line);
  border-radius:14px;background:var(--panel);color:var(--accent-text);font:inherit;font-size:13.5px;
  cursor:pointer;display:flex;align-items:center;justify-content:space-between;text-align:left;text-decoration:none}
.room-page .room-tariff-disclosure{padding:0;border:0;background:none}
.room-page .room-tariff-disclosure>.tariff-toggle{list-style:none}
.room-page .room-tariff-disclosure>.tariff-toggle::-webkit-details-marker{display:none}
.room-page .tariff-toggle::after{content:"›";font-size:22px;line-height:1;transition:transform var(--t-base)}
.room-page .tariff-toggle[aria-expanded="true"]::after,
.room-page .room-tariff-disclosure[open]>.tariff-toggle::after{transform:rotate(90deg)}
.room-page .tariff-toggle:focus-visible{outline:2px solid var(--accent);outline-offset:2px}
.room-page .tariff-panel{margin-top:10px;border-radius:14px;overflow:hidden;border:1px solid var(--line)}
.room-page .tariff-panel .p-row{font-size:13px}
.room-page .room-tariff-cta{width:100%;min-height:50px;margin-top:14px}

.room-page .room-practice-featured{display:grid;gap:12px;margin-top:18px}
.room-page .prac-i{background:var(--panel);border:1px solid var(--line);border-radius:18px;padding:18px;height:100%}
.room-page .prac-i h3{font-size:16.5px;margin-bottom:8px;font-weight:400}
.room-page .prac-i p{font-size:13px;color:var(--muted);line-height:1.5;margin:0;max-width:none}
.room-page .room-practice-more{margin-top:12px;border:1px solid var(--line);border-radius:18px;background:var(--panel);padding:0}
.room-page .room-practice-more>summary{min-height:50px;padding:0 18px;font-size:14px;color:var(--accent-text)}
.room-page .room-practice-more-body{display:grid;gap:12px;padding:0 12px 12px}
.room-page .room-practice-more[open]>summary{margin-bottom:12px}
@media(max-width:639px){
  /* В раскрытом состоянии остаётся один контейнер: форматы становятся
     плоским списком, а не четырьмя карточками внутри пятой карточки. */
  .room-page .room-practice-more[open]>summary{margin-bottom:0;border-bottom:1px solid var(--line)}
  .room-page .room-practice-more-body{display:block;padding:0 18px}
  .room-page .room-practice-more-body .prac-i{height:auto;padding:16px 0;border:0;border-radius:0;background:none}
  .room-page .room-practice-more-body .prac-i+.prac-i{border-top:1px solid var(--line)}
}

/* Безопасный общий структурный фикс только для оснащения. Базовый .col-flow
   в FAQ и на страницах массажа остаётся display:block. */
.inc-acc>.col-flow{display:grid;gap:inherit}
.inc-acc .inc-text{margin-top:18px;color:var(--muted);font-size:13.5px;line-height:1.55}
.inc-acc .inc-note{margin-top:14px;padding-top:14px;border-top:1px solid var(--line);
  color:var(--muted);font-size:12.5px;line-height:1.55}
.inc-acc>.inc-shared-note{margin-top:14px;color:var(--muted);font-size:12.5px;line-height:1.5}
.room-page .inc-acc{display:grid;gap:12px;margin-top:18px}

.room-page .room-facts{display:grid;gap:10px;margin-top:18px}
.room-page .room-fact{display:flex;flex-direction:column;gap:4px;padding:14px 16px;border:1px solid var(--line);
  border-radius:16px;background:var(--panel)}
.room-page .room-fact b{font-size:14px;font-weight:500}
.room-page .room-fact span{font-size:12.5px;line-height:1.45;color:var(--muted)}
.room-page .room-condition-label{margin-top:28px;font-size:11px;letter-spacing:.22em;text-transform:uppercase;
  color:var(--accent-text);font-weight:600}
.room-page .room-condition-links{display:grid;gap:0;margin-top:10px;border:1px solid var(--line);
  border-radius:18px;background:var(--panel);overflow:hidden}
.room-page .room-condition-links a{min-height:54px;display:flex;align-items:center;justify-content:space-between;
  gap:16px;padding:0 18px;color:var(--text);font-size:13.5px;text-decoration:none}
.room-page .room-condition-links a+a{border-top:1px solid var(--line)}
.room-page .room-condition-links a::after{content:"›";font-family:'Manrope';font-size:20px;
  line-height:1;color:var(--accent-text);flex-shrink:0}

.room-page .room-question-shell{border:1px solid var(--line);border-radius:var(--r);background:var(--panel);padding:0}
.room-page .room-question-body{padding:14px var(--card-pad) var(--card-pad)}
.room-page .room-question-body .faq{max-width:none;margin-top:0}
.room-page .room-question-body .faq h2{display:none}
.room-page .room-question-body .faq>details:last-child{border-bottom:0}

.room-page .room-final-cta{padding:22px 20px;border:var(--border-emphasis);border-radius:24px;
  background:var(--surface-accent)}
.room-page .room-final-cta h2{margin-top:7px}
.room-page .room-final-cta p{margin-top:8px;color:var(--muted);font-size:13.5px}
.room-page .room-final-cta .btn{width:100%;min-height:50px;margin-top:16px}
.room-page .room-alt-card{display:block;padding:20px;border:1px solid var(--line);border-radius:22px;
  background:var(--panel);color:var(--text);text-decoration:none}
.room-page .room-alt-card h3{font-size:18px;font-weight:400}
.room-page .room-alt-card p{margin-top:7px;color:var(--muted);font-size:13.5px;line-height:1.5}
.room-page .room-alt-card .room-alt-action{display:inline-flex;align-items:center;min-height:44px;margin-top:10px;
  color:var(--accent-text);font-size:13px;font-weight:600}
.room-page .room-next-links{display:grid;gap:0;border-block:1px solid var(--line);margin-bottom:0}
.room-page .room-next-links a{min-height:58px;display:flex;align-items:center;justify-content:space-between;gap:16px;
  color:var(--text);font-size:13.5px;text-decoration:none;border-bottom:1px solid var(--line)}
.room-page .room-next-links a:last-child{border-bottom:0}
.room-page .room-next-links span{color:var(--accent-text);font-size:20px}

@media(min-width:640px){
  .room-page .room-booking-cta,.room-page .room-tariff-cta,.room-page .room-final-cta .btn{width:auto}
  .room-page .room-practice-featured,.room-page .room-practice-more-body,
  .room-page .room-facts{grid-template-columns:repeat(2,1fr)}
  .room-page .room-facts .room-fact:last-child{grid-column:1/-1}
}
@media(hover:hover) and (pointer:fine){
  .room-page .lp-back:hover,.room-page .room-condition-links a:hover{color:var(--accent)}
  .room-page .room-alt-card:hover{border-color:var(--gold-dim);background:var(--panel2)}
}

/* --- Аккордеон: summary (закрыт по умолчанию) / full (открыт) — тот же <details>,
   режим задаётся наличием/отсутствием атрибута open, отдельный класс не нужен --- */

/* --- prefers-reduced-motion: все transform-переходы отключаются мгновенно --- */
@media(prefers-reduced-motion:reduce){
  html{scroll-behavior:auto}
  *{transition-duration:.001ms!important;animation-duration:.001ms!important;animation-iteration-count:1!important}
  .route:hover{transform:none}
  .route:hover .bgim{transform:none}
}
}
/* Mobile owner: sigma-home.css */
@media (width < 1024px) {/* Sigma Club Home V4 — one owner for mobile, tablet and desktop. */
.v4-home-page .home-hero{padding-top:12px}
.v4-home-page .home-hero .hh-in{text-align:center}
.v4-home-page .home-hero h1{margin-inline:auto;max-width:900px}
.v4-home-page .home-hero .lead{margin-right:auto;margin-left:auto}

.v4-home-page .hm-fork{margin-top:0;padding-top:28px}
.v4-home-page .fork{display:grid;grid-template-columns:1fr;gap:14px;margin-top:0}
.v4-home-page .mst-i{--mst-h:150px;display:flex;align-items:center;gap:14px;height:var(--mst-h);padding:16px;border:1px solid var(--line);border-radius:18px;background:var(--panel);color:var(--text);text-decoration:none;transition:transform .22s,border-color .22s}
.v4-home-page .mst-i .hb-ring{display:none}
.v4-home-page .mst-i .hb-badge svg{width:25px;height:25px}
.v4-home-page .fork .mst-i:nth-child(2) .hb-ring::before{animation-delay:-2.25s}
.v4-home-page .fork .mst-i:nth-child(3) .hb-ring::before{animation-delay:-4.5s}
.v4-home-page .fork .mst-i:nth-child(4) .hb-ring::before{animation-delay:-6.75s}
.v4-home-page .mst-t{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px}
.v4-home-page .mst-t b{display:block;font-family:'Manrope';font-weight:400;font-size:11px;line-height:16px;letter-spacing:.08em;text-transform:uppercase;color:var(--accent-text)}
.v4-home-page .mst-t span{display:block;order:-1;font-size:16px;font-weight:500;line-height:22px;color:var(--text)}
.v4-home-page .mst-ar{flex-shrink:0;color:var(--accent-text);font-size:19px;line-height:1;transition:transform .2s}
.v4-home-page .mst-i:focus-visible{outline:2px solid var(--text);outline-offset:3px}
.v4-home-page .home-route-media{display:block;flex:none;width:72px;height:112px;border-radius:10px;background-size:cover;background-repeat:no-repeat}
.v4-home-page .home-route-media--massage{background-image:url('/assets/photos/tile-massage.webp');background-position:58% top}
.v4-home-page .home-route-media--space{background-image:url('/assets/photos/tile-space-home.webp');background-position:center 58%}
.v4-home-page .home-route-media--pro{background-image:url('/assets/photos/tile-pro.webp');background-position:center 30%}
.v4-home-page .home-route-media--school{background-image:url('/assets/photos/atmosphere/books-saltlamp.webp');background-position:center}

.v4-home-page .eco-trust{margin-top:calc(var(--sp-section) - 12px)}
.v4-home-page .home-about-action{margin-top:18px}
.v4-home-page .home-faq-shell:not([open])>.pdisc-body{display:none}
.v4-home-page .faq-2col{display:grid;gap:16px}
.v4-home-page .faq-2col details+details{margin-top:16px}
.v4-home-page .home-related-all{margin-top:16px}
.v4-home-page .home-related-all a{color:var(--accent-text);font-size:13.5px;text-decoration:none}
.v4-home-page .home-contact-copy{margin-top:14px;max-width:560px;color:var(--muted);font-size:14.5px}
.v4-home-page .home-contact-action{margin-top:18px}
.v4-home-page .home-contact-image{display:block;width:100%;height:auto;aspect-ratio:16/10;border:1px solid var(--line);border-radius:var(--r);object-fit:cover}

/* Split sections: content sizes only. Composition is .v4-split in sigma-layout.css.
   A size that differs between the modes is declared in the mode where it acts. */
@media(768px <= width < 1024px){
  .v4-home-page #about-club{--v4-split-media-h:360px}
  .v4-home-page .hm-contact-teaser{--v4-split-media-h:280px}
}

@media(hover:hover) and (pointer:fine){
  .v4-home-page .mst-i:hover{transform:translateY(-3px);border-color:var(--accent-dim)}
  .v4-home-page .mst-i:hover .hb-badge{border-color:var(--accent);box-shadow:0 0 16px rgba(207,138,82,.4)}
  .v4-home-page .mst-i:hover .hb-badge svg{color:#f0c896}
  .v4-home-page .mst-i:hover .mst-ar{transform:translateX(3px)}
  .v4-home-page .fork .mst-i:hover .home-route-media{transform:scale(1.025)}
}

@media(prefers-reduced-motion:reduce){
  .v4-home-page .mst-i,.v4-home-page .home-route-media{transition:none}
  .v4-home-page .mst-i:hover,.v4-home-page .fork .mst-i:hover .home-route-media{transform:none}
}
}
/* Mobile owner: sigma-layout.css */
@media (width < 1024px) {/* Sigma Club V4: permanent responsive layout primitives. */
:root{
  --v4-wrap:1440px;
  --v4-gutter:clamp(20px,3vw,56px);
  /* M09: широкий шаг секции — именованное исключение уровня section,
     объявленное один раз в sigma.css (--rhythm-section-wide). */
  --v4-section:var(--rhythm-section-wide);
  /* M09 завёл семантического владельца кластерного зазора
     (--rhythm-cluster-grid в sigma.css). Здесь --v4-gap остаётся только
     историческим псевдонимом этого владельца: два независимых объявления
     одного и того же зазора и были доказанной дублированной policy.
     Базовое значение прежнего второго владельца ни одним живым правилом
     не потреблялось: все потребители --v4-gap живут в планшетном и
     десктопном режимах, где владелец и так даёт то же самое число.
     Замерено: ноль сдвинувшихся боксов на 12 маршрутах и 9 ширинах.
     Owner 03.09.2026: слить на владельца. */
  --v4-gap:var(--rhythm-cluster-grid);
  --v4-measure:min(72ch,720px);
}

.v4-page{min-width:0}
.v4-wrap{width:min(var(--v4-wrap),calc(100% - 2 * var(--v4-gutter)));margin-inline:auto}
.v4-section{margin-block-start:var(--v4-section)}
.v4-section:first-child{margin-block-start:18px}
.v4-stack{display:flex;min-width:0;flex-direction:column;gap:var(--v4-gap)}
.v4-grid{display:grid;min-width:0;gap:var(--v4-gap)}
.v4-measure{width:100%;max-width:var(--v4-measure)}
.v4-copy{min-width:0;max-width:var(--v4-measure)}
.v4-copy>p{line-height:1.68}
.v4-copy>p+p{margin-top:14px}
.v4-pair{display:grid;min-width:0;gap:var(--v4-gap);align-items:start}
.v4-media{position:relative;min-width:0;overflow:hidden;border:1px solid var(--line);border-radius:var(--r-card)}
.v4-media>img,.v4-media>picture,.v4-media picture>img{display:block;width:100%;height:100%;object-fit:cover}
.v4-media>img,.v4-media picture>img{position:absolute;inset:0}
.v4-media--natural{aspect-ratio:4/3}

/* ── SPLIT SECTION ───────────────────────────────────────────────────────────
   Единственный владелец композиции «колонка текста + колонка медиа». Семь
   инстансов на /space, /space/aura, /space/sliyanie, /, /contacts и /pro
   держали по собственной копии этой политики (независимые display/grid, flex
   и min-height правила) — отсюда расхождение осей, разрыв на границе
   1023→1024 и оторванное действие. Маршрут теперь объявляет вариант и свои
   content-размеры; композицию он не объявляет.

   Варианты
     .v4-split--tablet       сплит с 768px, иначе только с 1024px
     .v4-split--equal        две равные дорожки вместо 7fr / 5fr
     .v4-split--stretch      колонки делят нижнюю границу (обязателен, либо --top)
     .v4-split--top          колонки начинаются вместе и живут своей высотой
     .v4-split--top-tablet   то же, но только в планшетном режиме
     .v4-split--media-end    медиа последней — по умолчанию, совпадает с DOM
     .v4-split--media-start  медиа первой, без изменения порядка в DOM
     .v4-split--fill         медиа-колонка тянется на всю строку
     .v4-split--pin          колонка текста — стопка с канонической щелью
                             перед блоком действия

   Слоты содержимого; их объявляет маршрут, но не этот файл. Размер, который
   в планшете и на десктопе разный, маршрут объявляет в том режиме, где он
   действует, — отдельного «десктопного» токена для этого не нужно.
     --v4-split-media      ширина контента, ниже которой дорожка медиа не идёт
     --v4-split-gap        щель между колонками
     --v4-split-media-h    высота контента медиа-колонки
     --v4-split-action-gap щель перед блоком действия у варианта --pin;
                           по умолчанию — роль --rhythm-action (M09)

   Режимов два, и оба канонические: 768px и 1024px. Ниже 768px примитив не
   объявляет ничего — мобильный поток остаётся за своим прежним владельцем.
   Оба режима живут в тех же двух @media-блоках, что и остальные примитивы
   этого файла: инвентарь блоков не меняется.

   Селекторы намеренно составные (.v4-split.v4-split--stretch), а детские несут
   :nth-child(n): и то и другое — приёмы специфичности, а не фильтры. Они
   обязаны перебивать прежних владельцев тех же контейнеров, которые всё ещё
   держат их мобильный поток и которые этой миссии трогать нельзя: .g12>.cN,
   .room-page .lp-hero, .space, .media-row. */
.v4-split{min-width:0}

@media(min-width:768px){
  .v4-grid--2-tablet{grid-template-columns:repeat(2,minmax(0,1fr))}
  .v4-pair--tablet{grid-template-columns:minmax(0,7fr) minmax(280px,5fr)}
  .v4-pair--media-first>.v4-media{grid-column:1;grid-row:1}
  .v4-pair--media-first>.v4-copy{grid-column:2;grid-row:1}

  .v4-split--tablet.v4-split--stretch,
  .v4-split--tablet.v4-split--top{
    display:grid;
    grid-template-columns:minmax(0,7fr) minmax(var(--v4-split-media,0px),5fr);
    gap:var(--v4-split-gap,var(--v4-gap));
  }
  .v4-split--tablet.v4-split--equal{grid-template-columns:repeat(2,minmax(0,1fr))}
  .v4-split--tablet.v4-split--stretch{align-items:stretch}
  .v4-split--tablet.v4-split--top,
  .v4-split--tablet.v4-split--top-tablet{align-items:start}
  .v4-split--tablet>*:nth-child(n){min-width:0;grid-column:auto;grid-row:auto}
  .v4-split--tablet.v4-split--media-start>*:nth-child(n):last-child{order:-1}
  .v4-split--tablet>*:nth-child(n):last-child{margin-block-start:0;min-height:var(--v4-split-media-h,0px)}
  .v4-split--tablet.v4-split--fill>*:nth-child(n):last-child{height:100%;aspect-ratio:auto}
}
}
/* Mobile owner: sigma-components.css */
@media (width < 1024px) {/* Sigma Club V4 component layer. A route opts in with explicit v4-* classes. */
.v4-disclosure>summary{cursor:pointer}
.v4-disclosure>summary:focus-visible{outline:2px solid var(--accent);outline-offset:3px;border-radius:var(--r-focus)}
.trust-badge-icon{width:auto;height:16px;flex-shrink:0}
.p-cat-head{display:flex;min-height:52px;align-items:center;gap:12px;padding:14px 4px;font-size:15px;font-weight:600}
.master-card{position:relative;display:flex;min-width:0;flex-direction:column;overflow:hidden;border:1px solid var(--line);border-radius:var(--r-card);background:var(--panel);color:var(--text)}
.master-card__link{position:absolute;z-index:1;inset:0}
.master-card__media{position:relative;display:flex;overflow:hidden;aspect-ratio:4/5;align-items:flex-end;padding:14px;background-position:center;background-size:cover}
.master-card__media img{position:absolute;z-index:0;inset:0;width:100%;height:100%;object-fit:cover}
.master-card__media::after{position:absolute;z-index:1;inset:0;background:linear-gradient(180deg,transparent 42%,rgba(16,10,7,.78));content:"";pointer-events:none}
.master-card__name{position:relative;z-index:2;font-size:21px;font-weight:500;letter-spacing:.04em}
.master-card__body{padding:16px 18px 18px}
.master-card__positioning{font-size:var(--fs-meta);color:var(--text)}
.master-card__services{font-size:12px;color:var(--accent-text)}
.master-card__location,.master-card__venue{font-size:var(--fs-eyebrow);color:var(--muted)}
.master-card__price{font-size:16px;color:var(--muted)}
.master-card__price b{color:var(--gold);font-weight:700}
.master-card__programs{display:flex;flex-direction:column;gap:8px;padding:10px 0;border-block:1px solid var(--line);list-style:none}
.master-card__programs li{display:grid;gap:2px}
.master-card__program-name{font-size:13px;font-weight:600;color:var(--text)}
.master-card__program-meta{font-size:12px;color:var(--muted)}
.master-card__profile-hint{display:flex;min-height:44px;align-items:center;font-size:13px;color:var(--accent-text)}
.master-card__cta{position:relative;z-index:2;padding-top:var(--rhythm-card-action)}
.master-card__cta .btn{width:100%;min-height:50px;padding-inline:12px;text-align:center}
.v4-master-grid{
  display:flex;
  flex-wrap:wrap;
  justify-content:center;
  gap:18px;
}
.v4-master-grid>.master-card{
  min-width:0;
  width:auto;
  flex:0 0 100%;
  align-self:stretch;
  justify-self:auto;
}
.v4-master-grid .master-card__body{
  display:flex;
  min-width:0;
  flex:1 1 auto;
  flex-direction:column;
  /* M09: внутренний ритм карточки title→meta→action — роль уровня component. */
  gap:var(--rhythm-card-row);
}
.v4-master-grid .master-card__positioning,
.v4-master-grid .master-card__services,
.v4-master-grid .master-card__location{
  display:-webkit-box;
  overflow:hidden;
  line-height:1.4;
  -webkit-box-orient:vertical;
  -webkit-line-clamp:2;
}
.v4-master-grid .master-card__cta{margin-top:auto}
.v4-master-grid--compact .master-card__positioning,
.v4-master-grid--compact .master-card__services,
.v4-master-grid--compact .master-card__programs-legacy,
.v4-master-grid--compact .master-card__location,
.v4-master-grid--compact .master-card__venue,
.v4-master-grid--compact .master-card__profile-hint,
.v4-master-grid--compact .master-card__cta{display:none}
.v4-master-grid--compact .master-card__body{min-height:0;padding:12px 14px 14px}
.v4-master-grid--compact .master-card__media{aspect-ratio:4/5}
.v4-master-grid--compact .master-card__media img{object-position:50% 18%}
.v4-master-grid--compact .master-card__price{margin:0}
.v4-master-grid--swipe-mobile{flex-wrap:nowrap;justify-content:flex-start;overflow-x:auto;scroll-snap-type:x mandatory;scrollbar-width:none}
.v4-master-grid--swipe-mobile::-webkit-scrollbar{display:none}
.v4-master-grid--swipe-mobile>.master-card{flex-basis:100%;scroll-snap-align:start;scroll-snap-stop:always}
.mp-others-head{display:flex;align-items:center;justify-content:space-between;gap:12px;margin-bottom:8px}
.mp-others-head h3{margin-bottom:0}
.mp-others-card{max-width:720px;margin-top:var(--v4-section)}

/* ===== V4 collection primitive: role-aware cardinality (M10) =====
   Коллекция объявляет свою СЕМАНТИЧЕСКУЮ РОЛЬ атрибутом
   data-collection-role на уже существующем контейнере (проставляет
   генератор, см. applyCollectionRoles в build.js). Роль решает, что
   происходит с неполным последним рядом. Единого визуального правила на
   сайт нет и быть не должно — это разные смысловые состояния:

   catalogue — каталог мастеров. Композицию держит .v4-master-grid в этом
               же файле: 1/2/3/4 колонки, остаток центрируется. Это
               утверждённый owner-контракт (AD-001), и примитив его НЕ
               переобъявляет и не трогает.
   editorial — индекс блога, страницы рубрик, ленты «читайте также».
               Стартовая ось, НИКОГДА не центрируется. Остаток
               компонуется шириной карточек, а не добивается пустыми или
               дублированными карточками.
   utility   — служебные сетки с явным детерминированным span. Владелец
               сегодня — assets/sigma-renter.css (.ar-check, M06);
               примитив не создаёт второго владельца той же политики.

   EDITORIAL REMAINDER. C — число колонок в текущем режиме, N — число
   карточек, R = N mod C. При R = 0 ряд полный и делать нечего. При R > 0
   каждая из R карточек остатка занимает

       S = min(2, floor(C / R)) треков,

   и не шире min(2 × normal track + gap, --measure).

   floor(C / R) — это ровно «сколько треков карточка остатка может занять,
   не переполнив ряд»: два трека на карточку физически не помещаются, если
   2R > C. Отсюда S = 1 при R >= 3 (это и есть «при 3+ используется normal
   track») и при C = 3, R = 2 — там две карточки уже держат две трети ряда,
   и расширять их некуда. Ни одна ветка правила не добавляет карточек и не
   меняет порядок в DOM.

   data-collection-tracks сообщает примитиву, по какому расписанию колонок
   живёт коллекция:
     page   — 1/2/3/4 по режимам страницы (.b-grid, .blog-category-grid);
     triple — 3 колонки везде, где модуль вообще сетка (.rel-grid.h-swipe:
              ниже своей границы это flex-рельс, где grid-column не
              действует, поэтому правило объявлено только от tablet).
   Счёт элементов у triple идёт «of :not([aria-hidden="true"])»: клоны
   мобильного рельса не входят ни в доступную коллекцию, ни в её
   кардинальность. */

@media(min-width:768px){
  .v4-master-grid{gap:20px}
  .v4-master-grid>.master-card{flex-basis:min(342px,calc((100% - 20px)/2))}
  .v4-master-grid--swipe-mobile{flex-wrap:wrap;justify-content:center;overflow:visible;scroll-snap-type:none}
  .v4-master-grid--swipe-mobile>.master-card{flex-basis:min(342px,calc((100% - 20px)/2))}
  .mp-others-head .hs-nav{display:none}
  /* editorial, расписание page: C = 2, R = 1 -> S = min(2, floor(2/1)) = 2 */
  [data-collection-tracks="page"]>*:nth-child(2n+1):last-child{grid-column:span 2;max-width:var(--measure)}
  /* editorial, расписание triple: C = 3, R = 1 -> S = min(2, floor(3/1)) = 2.
     R = 2 даёт S = 1 и правила не требует. */
  [data-collection-tracks="triple"]>*:nth-child(3n+1 of :not([aria-hidden="true"])):nth-last-child(1 of :not([aria-hidden="true"])){grid-column:span 2;max-width:var(--measure)}
}

@media(max-width:767px){.mp-others-card{border:0;background:transparent;padding:0}}

.v4-room-page .room-question-heading,
.v4-space-page .faq-heading{padding:20px 22px;border-bottom:1px solid var(--line)}
.v4-room-page .room-question-heading h2,
.v4-space-page .faq-heading h2{margin:0}
.v4-room-page .room-question-heading p,
.v4-space-page .faq-heading p,
.v4-space-page .faq-group-head p{margin-top:6px;color:var(--muted);font-size:13px;line-height:1.5}
.v4-space-page .faq-item{margin:0;border-top:1px solid var(--line)}
.v4-space-page .faq-item:first-child{border-top:0}
.v4-space-page .faq-item>summary{min-height:58px;padding:12px 0}
.v4-space-page .faq-item>summary h4{margin:0;padding-right:12px}
.v4-space-page .faq-item>p{padding:0 0 16px}
.v4-room-page .inc-acc>.inc-shared-note{width:100%;max-width:none}
}
/* Mobile owner: sigma-routes.css */
@media (width < 1024px) {/* Sigma Club V4: route composition only. Component rules belong elsewhere. */

/* Split section: content sizes only. Composition is .v4-split in sigma-layout.css. */
body.v4-room-page .lp-hero{--v4-split-media:360px}

@media(min-width:768px) and (width < 1024px){
  body.pg-master .mp-grid{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--v4-gap)}
  body.pg-master .mp-gallery{width:min(100%,520px);aspect-ratio:4/5;margin-inline:auto;border-radius:var(--r-card)}
  body.pg-master .mp-side{position:static;margin-top:0;gap:var(--v4-gap)}
  body.pg-master .mp-side>.mp-card:first-child{border:1px solid var(--line);border-radius:var(--r-card)}
  body.pg-master .mp-grid>#programs{margin-top:0}
  /* M08: «О себе» больше не потомок .mp-side, поэтому её нулевой отступ
     объявлен здесь явно, а не наследуется от .mp-side .mp-panel. Разрыв
     между «Программы и цены» и «О себе» по-прежнему один — gap .mp-grid. */
  body.pg-master .mp-about-section{max-width:var(--v4-measure);margin-top:0}
  body.pg-master .mp-where{max-width:var(--v4-measure)}
}

@media(min-width:768px) and (width < 1024px){
  body.v4-room-page .lp-gal{width:min(100%,640px);margin-inline:auto}
  body.v4-room-page .lp-specs-grid{grid-template-columns:repeat(4,minmax(0,1fr))}
  body.v4-room-page .room-practice-featured,
  body.v4-room-page .inc-acc,
  body.v4-room-page .room-facts{grid-template-columns:repeat(2,minmax(0,1fr))}
  body.v4-room-page .inc-acc>.inc-shared-note{grid-column:1/-1}
  body.v4-room-page .room-facts .room-fact:last-child{grid-column:1/-1}
}
}