/* ============================================================
   СПА СОЛЬ — theme.css
   Общая тема для версий A (светлая) и B (тёмная)
   ============================================================ */

:root,
[data-theme="light"] {
  /* Фоны и нейтрали */
  --ss-bg: #F5EFE6;
  --ss-bg-alt: #EDE4D3;
  --ss-card: #FDFAF4;
  --ss-dark-panel: #1A1412;

  /* Акценты.
     Золото и CTA заданы ТЗ заказчика 18.08.2026 дословно: тёплое золото #C9A66B,
     CTA #D9784A. Прежние были #C9A66B и #C46B4A — сдвиг на глаз незаметен, но
     палитра теперь совпадает с макетом побайтно, и спорить об оттенке больше не о чем.
     ⚠️ Контраст белого на CTA #D9784A — 3.1:1 (был 3.8:1 на #C46B4A): норму AA 4.5:1
     не берёт ни тот, ни другой. Цвет взят по ТЗ как решение заказчика о бренде;
     компенсируется весом надписи и размером кнопки. Записано в docs/CHECKLIST.md. */
  --ss-rose: #D4A5A0;
  --ss-terracotta: #D9784A;
  --ss-terracotta-hover: #C4653A;
  --ss-sage: #8FA68E;
  --ss-copper: #8E6A47;
  --ss-amber: #C9A66B;
  --ss-wine: #7A3539;
  /* Семантический акцент текста: тёмно-коньячный для светлых фонов.
     В тёмных секциях и на тёмных поверхностях override → amber.
     ⚠️ ЗАМЕРЕНО 01.09.2026 (WCAG 2.x, формула относительной яркости), потому что
     прежняя редакция этого комментария утверждала «4.7:1 на --ss-bg» — числа
     не подтвердились:
        на --ss-bg   #F5EFE6 — 4.13:1
        на --ss-bg-alt #EDE4D3 — 3.74:1
        на --ss-card #FDFAF4 — 4.54:1
     То есть норму AA 4.5:1 берёт только карточка. Ниже нормы ходят `.ss-tag`,
     `.ss-form-label-group`, `.ss-nav-panel-all` и заголовки блока тарифов —
     на ВСЁМ сайте, а не в бане. Не чиню в слайсе S1: сдвиг --ss-accent
     перекрашивает весь портал и это решение о бренде, а не уборка стилей.
     Записано в docs/CHECKLIST.md. */
  --ss-accent: #8B6F3F;

  /* Текст */
  --ss-text: #3A2F28;
  --ss-text-muted: #6E5F54;
  --ss-text-on-dark: #EFE8DC;
  --ss-divider: #E8DDC8;

  /* Bootstrap overrides */
  --bs-body-bg: var(--ss-bg);
  --bs-body-color: var(--ss-text);
  --bs-primary: var(--ss-terracotta);
  --bs-primary-rgb: 217, 120, 74;
  --bs-secondary-rgb: 176, 136, 104;
  --bs-success-rgb: 143, 166, 142;
  --bs-border-color: var(--ss-divider);
}

[data-theme="dark"] {
  --ss-bg: #1A1412;
  --ss-bg-alt: #221B18;
  --ss-card: #2A2320;
  --ss-dark-panel: #1A1412;

  --ss-text: #EFE8DC;
  --ss-text-muted: #B8AE9D;
  --ss-text-on-dark: #EFE8DC;
  --ss-divider: #3A302A;
  /* В тёмной теме акцент = золотой amber */
  --ss-accent: var(--ss-amber);

  --bs-body-bg: var(--ss-bg);
  --bs-body-color: var(--ss-text);
  --bs-primary: var(--ss-terracotta);
  --bs-primary-rgb: 217, 120, 74;
  --bs-secondary-rgb: 201, 168, 115;
  --bs-border-color: var(--ss-divider);
}

/* ============================================================
   Типографика
   ============================================================ */
/* Единый основной текст: Manrope, 14px / 1.5 на всех контентных страницах.
   Размеры заголовков, лидов, цен и элементов управления не меняем. */
:root {
  --ss-copy-font: 'Manrope', -apple-system, BlinkMacSystemFont, sans-serif;
  --ss-copy-size: 14px;
  --ss-copy-leading: 1.5;
}
body {
  font-family: var(--ss-copy-font);
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text);
  background: var(--ss-bg);
  -webkit-font-smoothing: antialiased;
}

/* ⚠️ ЕДИНСТВЕННОЕ правило базового сброса, которого нет в Bootstrap. Переехало из
   легаси template_styles.css при его сносе (A5, 01.09.2026): Bootstrap Reboot
   ставит `img,svg{vertical-align:middle}` и НЕ ставит max-width — «резиновость»
   картинок он отдаёт классу .img-fluid, которого в нашей вёрстке нет.
   На этом правиле висит инвариант «ноль горизонтального скролла» (SPEC-08 №3):
   любое фото шире контейнера — в том числе вставленное заказчиком в WYSIWYG —
   без него растягивает страницу. Остальной базовый слой легаси (box-sizing,
   scroll-behavior) Bootstrap закрывает сам, причём scroll-behavior — ещё и с
   уважением к prefers-reduced-motion; поэтому те правила не переносились. */
img { max-width: 100%; height: auto; }

h1, h2, h3, h4, h5, .ss-serif {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-weight: 500;
  letter-spacing: -0.01em;
  line-height: 1.12;
  color: var(--ss-text);
}

.ss-overline {
  font-family: 'Manrope', sans-serif;
  font-size: 13px;
  font-weight: 500;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ss-copper);
}
[data-theme="dark"] .ss-overline { color: var(--ss-amber); }

/* Лид-абзацы. ТЗ 18.08.2026 разводит гарнитуры прямо: «заголовки — Cormorant
   Garamond; меню, текст, кнопки — Manrope». Лид — текст, а не заголовок, поэтому
   переехал на Manrope; кегль опущен с 19 до 17px, потому что Manrope при равном
   размере крупнее Cormorant по x-height и строка иначе спорит с заголовком. */
.ss-lede {
  font-family: 'Manrope', sans-serif;
  font-size: 17px;
  line-height: 1.6;
  font-weight: 400;
  color: var(--ss-text-muted);
}
[data-theme="dark"] .ss-lede { color: var(--ss-text-muted); }

/* Заголовок первого экрана. Кегль опущен с 76 до 60px: текст ТЗ 18.08.2026
   («Время для себя. / Время для любимых.») — две строки против прежней одной,
   и на 1440px старый размер разгонял их на четыре, выдавливая лид и кнопки
   за нижнюю границу экрана. Проверено скриншотом на 1440×900 и 390×844. */
.ss-title-hero {
  font-size: clamp(40px, 4.2vw, 60px);
  font-weight: 500;
  line-height: 1.12;
}
.ss-title-section {
  font-size: clamp(36px, 3.6vw, 54px);
  font-weight: 500;
}
.ss-title-card {
  font-size: clamp(22px, 1.8vw, 30px);
  font-weight: 500;
}

.ss-italic { font-style: italic; }
.ss-copper { color: var(--ss-copper); }
.ss-amber { color: var(--ss-accent); }
.ss-terracotta { color: var(--ss-terracotta); }
.ss-muted { color: var(--ss-text-muted); }

/* Цена */
.ss-price {
  font-family: 'Manrope', sans-serif;
  font-weight: 500;
  font-size: 24px;
  letter-spacing: -0.01em;
  color: var(--ss-text);
}
[data-theme="dark"] .ss-price { color: var(--ss-amber); }

/* ============================================================
   Кнопки
   ============================================================ */
.btn {
  font-family: 'Manrope', sans-serif;
  font-weight: 500;
  font-size: 15px;
  letter-spacing: 0.01em;
  padding: 14px 28px;
  border-radius: 999px;
  transition: all 0.25s ease;
  border: 1px solid transparent;
}

.btn-ss-primary {
  background: var(--ss-terracotta);
  color: #FDFAF4;
  border-color: var(--ss-terracotta);
}
.btn-ss-primary:hover {
  background: var(--ss-terracotta-hover);
  border-color: var(--ss-terracotta-hover);
  color: #FDFAF4;
  transform: translateY(-1px);
}

.btn-ss-outline {
  background: transparent;
  color: var(--ss-text);
  border-color: currentColor;
}
[data-theme="dark"] .btn-ss-outline {
  color: var(--ss-amber);
}
.btn-ss-outline:hover {
  background: var(--ss-text);
  color: var(--ss-bg);
}
[data-theme="dark"] .btn-ss-outline:hover {
  background: var(--ss-amber);
  color: var(--ss-dark-panel);
}

.btn-ss-ghost {
  background: rgba(255, 255, 255, 0.08);
  color: #FDFAF4;
  border-color: rgba(253, 250, 244, 0.4);
  backdrop-filter: blur(10px);
}
.btn-ss-ghost:hover {
  background: rgba(255, 255, 255, 0.16);
  color: #FDFAF4;
}

/* ============================================================
   Header / Navigation
   ============================================================ */
.ss-header {
  position: fixed;
  top: var(--bx-panel-h, 0px); left: 0; right: 0;
  z-index: 1030;
  padding: 18px 0;
  transition: all 0.3s ease;
  /* По умолчанию (внутренние страницы без hero с фото) — solid светлый фон */
  background: rgba(245, 239, 230, 0.94);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--ss-divider);
}
/* На страницах с hero-видео/фото (главная, детальная бани) — шапка прозрачна до скролла */
.ss-header.on-hero {
  background: transparent;
  backdrop-filter: none;
  border-bottom: 0;
}
.ss-header.is-scrolled,
.ss-header.is-solid {
  background: rgba(245, 239, 230, 0.94);
  backdrop-filter: blur(14px);
  border-bottom: 1px solid var(--ss-divider);
  padding: 12px 0;
}
[data-theme="dark"] .ss-header {
  background: rgba(26, 20, 18, 0.94);
  border-bottom: 1px solid var(--ss-divider);
}
[data-theme="dark"] .ss-header.on-hero {
  background: transparent;
  border-bottom: 0;
}
[data-theme="dark"] .ss-header.is-scrolled,
[data-theme="dark"] .ss-header.is-solid {
  background: rgba(26, 20, 18, 0.94);
  border-bottom: 1px solid var(--ss-divider);
}

.ss-logo {
  font-family: 'Cormorant Garamond', serif;
  font-size: 26px;
  font-weight: 500;
  letter-spacing: 0.02em;
  color: var(--ss-copper);
  text-decoration: none;
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
[data-theme="dark"] .ss-logo { color: var(--ss-amber); }

.ss-logo-mark {
  width: 36px; height: 36px;
  display: inline-block;
  background-image: url('assets/logo.png');
  background-size: contain;
  background-repeat: no-repeat;
  background-position: center;
}

.ss-logo--image { gap: 0; padding: 0; line-height: 0; }
.ss-logo--image img { display: block; height: auto; max-height: 56px; width: auto; }
.ss-footer .ss-logo--image img { max-height: 72px; }

.ss-nav-link {
  font-family: 'Manrope', sans-serif;
  font-size: 14px;
  font-weight: 500;
  color: var(--ss-text);
  text-decoration: none;
  padding: 8px 14px;
  letter-spacing: 0.02em;
  /* ⛔ Переносить пункт меню нельзя. Названия из ТЗ 18.08.2026 длиннее прежних
     («СПА-программы», «Банный комплекс», «Подобрать программу»), и на 1440px
     строка ломалась пополам: пункты налезали друг на друга и на надзаголовок
     первого экрана. Поймано скриншотом, в разметке этого не видно. */
  white-space: nowrap;
  transition: color 0.2s;
}
/* ── Бюджет строки шапки (замер 18.08.2026, 12 ширин) ───────────────────────
   В строку встают: логотип 155px, меню, значки соцсетей, номер текстом, две
   кнопки. Сумма при полном составе — 1612px, и она НЕ помещается ни на 1366,
   ни на 1440, ни на 1600, ни на 1680: кнопка «Записаться» уходила за правый
   край на 40–211px. Скролла вбок при этом не возникало (кнопка обрезалась, а
   не раздвигала страницу), поэтому дефект пережил и чекап, и разбор главной
   поблочно — на глаз пропадает ровно последняя буква.

   Правило: строка НИКОГДА не переполняется, состав редеет по важности.
   Порядок выбывания снизу вверх: номер текстом → значки соцсетей → надпись
   у кнопки «Позвонить» (остаётся значок). Меню и обе кнопки не выбывают.
   Пороги выбраны по замеру с запасом ≥60px — под будущие WhatsApp и Telegram
   (§20 вопросов заказчику): с ними значков станет шесть, а не четыре.
   Механическая проверка — scripts/header-audit.js. */
@media (min-width: 1200px) and (max-width: 1599.98px) {
  .ss-nav-link { padding: 8px 9px; font-size: 13px; }
}
@media (min-width: 1200px) and (max-width: 1379.98px) {
  .ss-nav-link { padding: 8px 6px; font-size: 12.5px; }
}

/* Кнопка «Позвонить» ниже 1380px — один значок без надписи. Действие остаётся
   доступным (это конверсионный элемент, прятать его целиком нельзя), а строка
   экономит ~85px. */
@media (max-width: 1379.98px) {
  .ss-header-call__label { display: none; }
  .ss-header-call { padding-left: 14px; padding-right: 14px; }
}
.ss-nav-link:hover { color: var(--ss-terracotta); }
[data-theme="dark"] .ss-nav-link { color: var(--ss-text-on-dark); }
[data-theme="dark"] .ss-nav-link:hover { color: var(--ss-amber); }

/* Белый текст на hero (только когда шапка прозрачная и поверх фото/видео) */
.ss-header.on-hero:not(.is-scrolled) .ss-nav-link,
.ss-header.on-hero:not(.is-scrolled) .ss-logo { color: #FDFAF4; }

/* Бургер: на solid-светлой шапке тёмно-коньячный, на тёмном hero — светлый */
.ss-burger {
  border-color: var(--ss-accent);
  color: var(--ss-accent);
  background: transparent;
  backdrop-filter: none;
}
.ss-burger:hover { background: rgba(139, 111, 63, 0.08); color: var(--ss-accent); }
.ss-header.on-hero:not(.is-scrolled) .ss-burger {
  border-color: rgba(253, 250, 244, 0.55);
  color: #FDFAF4;
  background: rgba(255, 255, 255, 0.08);
  backdrop-filter: blur(6px);
}
.ss-header.on-hero:not(.is-scrolled) .ss-burger:hover {
  background: rgba(255, 255, 255, 0.18);
  color: #FDFAF4;
}
[data-theme="dark"] .ss-burger { border-color: var(--ss-amber); color: var(--ss-amber); }

/* ============================================================
   Секции / раскладка
   ============================================================ */
.ss-section {
  padding: clamp(60px, 6.5vw, 96px) 0;
}
.ss-section-sm {
  padding: clamp(40px, 5vw, 64px) 0;
}

.ss-container {
  max-width: 1440px;
  padding: 0 32px;
  margin: 0 auto;
}
/* Резиновый контейнер (правка министра 18.08.2026): шапка и первый экран тянутся
   во всю ширину окна, а не упираются в 1440px. На широком мониторе прежний
   контейнер отжимал логотип и текст обложки к середине — на 1905px текст начинался
   с 264-го пикселя вместо 32-го. Боковое поле растёт с шириной окна, но не
   безгранично: на 4K иначе получается коридор в 100+ px. */
.ss-container--fluid {
  max-width: none;
  padding: 0 clamp(20px, 2.2vw, 56px);
}

.ss-divider-ornate {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
  color: var(--ss-copper);
  margin: 20px auto;
  max-width: 240px;
}
[data-theme="dark"] .ss-divider-ornate { color: var(--ss-amber); }
.ss-divider-ornate::before,
.ss-divider-ornate::after {
  content: '';
  flex: 1;
  height: 1px;
  background: currentColor;
  opacity: 0.45;
}
.ss-divider-ornate .dot {
  width: 6px; height: 6px;
  border-radius: 50%;
  background: currentColor;
  display: inline-block;
}

/* ============================================================
   Hero
   ============================================================ */
.ss-hero {
  position: relative;
  min-height: 92vh;
  display: flex;
  align-items: center;
  overflow: hidden;
  color: #FDFAF4;
}
.ss-hero-bg {
  position: absolute;
  inset: 0;
  background: linear-gradient(120deg, #2a2017 0%, #3a2a20 40%, #1a1210 100%);
  z-index: 0;
}
.ss-hero-bg::after {
  content: '';
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(0,0,0,0.35) 0%, rgba(0,0,0,0.15) 30%, rgba(0,0,0,0.55) 100%);
}
.ss-hero-video {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  object-fit: cover;
  z-index: 0;
}
.ss-hero-content {
  position: relative;
  z-index: 2;
  /* ⚠️ width:100% обязателен. `.ss-hero` — flex-контейнер, а `.ss-container`
     ширины сам себе не назначает: как flex-элемент он ужимается по содержимому.
     Пока заголовок был в одну строку, ужиматься было не до чего, и дефект спал.
     С текстом ТЗ 18.08.2026 («Время для себя. / Время для любимых.») колонка
     схлопнулась до 292px из 1440: заголовок ломался на четыре строки, кнопки
     вставали друг под друга. Поймано скриншотом, замерено в браузере. */
  width: 100%;
}
.ss-hero h1 { color: #FDFAF4; }

/* «Узнать больше» (ТЗ 18.08.2026) — теперь ссылка, а не надпись, поэтому у неё
   есть тач-цель (≥44px по высоте вместе с отступами) и видимое кольцо фокуса
   от общего правила. Стрелка — inline-svg, чтобы красилась currentColor. */
.ss-hero-scroll-hint {
  position: absolute;
  bottom: 24px;
  left: 50%;
  transform: translateX(-50%);
  z-index: 2;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 12px 18px;
  color: var(--ss-text-on-dark);
  opacity: 0.72;
  text-decoration: none;
  font-family: 'Manrope', sans-serif;
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  text-align: center;
  transition: opacity 0.2s ease;
}
.ss-hero-scroll-hint:hover,
.ss-hero-scroll-hint:focus-visible { color: var(--ss-text-on-dark); opacity: 1; }
.ss-hero-scroll-hint svg { animation: ss-hint-nudge 2.4s ease-in-out infinite; }
@keyframes ss-hint-nudge {
  0%, 100% { transform: translateY(0); }
  50%      { transform: translateY(3px); }
}
@media (prefers-reduced-motion: reduce) {
  .ss-hero-scroll-hint svg { animation: none; }
}

/* Placeholder фото */
.ss-img-placeholder {
  position: relative;
  background: repeating-linear-gradient(
    135deg,
    #E8DDC8 0px, #E8DDC8 14px,
    #DDD0B8 14px, #DDD0B8 28px
  );
  color: #6E5F54;
  display: flex;
  align-items: center;
  justify-content: center;
  font-family: 'JetBrains Mono', 'Courier New', monospace;
  font-size: 12px;
  letter-spacing: 0.05em;
  overflow: hidden;
}
[data-theme="dark"] .ss-img-placeholder {
  background: repeating-linear-gradient(
    135deg,
    #2a221e 0px, #2a221e 14px,
    #332a24 14px, #332a24 28px
  );
  color: var(--ss-text-muted);
}
.ss-img-placeholder-dark {
  background: repeating-linear-gradient(
    135deg,
    #2a221e 0px, #2a221e 14px,
    #332a24 14px, #332a24 28px
  );
  color: #C9A66B;
}
.ss-img-placeholder .label {
  background: rgba(255,255,255,0.55);
  padding: 6px 12px;
  border-radius: 4px;
  text-align: center;
  max-width: 75%;
}
[data-theme="dark"] .ss-img-placeholder .label,
.ss-img-placeholder-dark .label {
  background: rgba(0,0,0,0.45);
  color: var(--ss-amber);
}

/* Hero: затемнение ТОЛЬКО градиентом (правка министра 18.08.2026).
   Прежняя редакция клала поверх кадра ещё и равномерную подложку 0.48 — вместе
   с клином слева она глушила ролик целиком, и обложка читалась как тёмное
   неподвижное фото. Министр: «Видео надо вернуть. Затемнение градиентом». Поэтому слой
   ровно один, и он прозрачен там, где текста нет.
   ⚠️ Равномерную подложку сюда не возвращать: она гасит именно то, ради чего
   на первом экране стоит видео. Нужна читаемость — двигать точки градиента. */
.ss-hero-bg::after {
  content: "";
  position: absolute;
  inset: 0;
  background:
    /* по горизонтали: тёмное слева под текстом, прозрачное справа (ТЗ: «правую
       часть оставить светлой») */
    linear-gradient(90deg,
      rgba(0,0,0,0.72) 0%,
      rgba(0,0,0,0.55) 26%,
      rgba(0,0,0,0.18) 52%,
      rgba(0,0,0,0.00) 72%),
    /* по вертикали: лёгкое затемнение под шапкой и у нижней кромки, середина чистая */
    linear-gradient(180deg,
      rgba(0,0,0,0.42) 0%,
      rgba(0,0,0,0.00) 26%,
      rgba(0,0,0,0.00) 74%,
      rgba(0,0,0,0.38) 100%);
  pointer-events: none;
  z-index: 1;
}
/* На узком экране текст занимает всю ширину — горизонтальный клин читаемости
   уже не даёт, поэтому остаётся только вертикальный градиент. */
@media (max-width: 991.98px) {
  .ss-hero-bg::after {
    background: linear-gradient(180deg,
        rgba(0,0,0,0.55) 0%,
        rgba(0,0,0,0.28) 38%,
        rgba(0,0,0,0.62) 100%);
  }
}
.ss-hero-bg .ss-img-placeholder .label {
  position: absolute;
  top: auto;
  bottom: 16px;
  right: 16px;
  left: auto;
  transform: none;
  font-size: 11px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  max-width: 280px;
  background: rgba(0,0,0,0.5);
  color: rgba(201, 168, 115, 0.85);
  z-index: 2;
}

/* Аспекты */
.ss-ar-16-9 { aspect-ratio: 16 / 9; }
.ss-ar-16-10 { aspect-ratio: 16 / 10; }
.ss-ar-4-3 { aspect-ratio: 4 / 3; }
.ss-ar-3-4 { aspect-ratio: 3 / 4; }
.ss-ar-1-1 { aspect-ratio: 1 / 1; }
.ss-ar-9-16 { aspect-ratio: 9 / 16; }
.ss-ar-4-5 { aspect-ratio: 4 / 5; }

/* ============================================================
   Карточки
   ============================================================ */
.ss-tile {
  position: relative;
  border-radius: 14px;
  overflow: hidden;
  display: block;
  text-decoration: none;
  color: inherit;
  background: var(--ss-card);
  box-shadow: 0 8px 24px rgba(58, 47, 40, 0.08);
  transition: transform 0.35s ease, box-shadow 0.35s ease;
}
.ss-tile:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 40px rgba(58, 47, 40, 0.14);
}
[data-theme="dark"] .ss-tile {
  background: var(--ss-card);
  box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
}

.ss-tile-photo {
  position: relative;
  overflow: hidden;
}
.ss-tile-photo > .ss-img-placeholder {
  width: 100%;
  height: 100%;
  transition: transform 0.5s ease;
}
.ss-tile:hover .ss-img-placeholder {
  transform: scale(1.04);
}

.ss-tile-overlay {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  padding: 24px 22px;
  /* Плотный нижний градиент: гарантирует читаемость на любой яркости фото.
     13.08.2026 усилен: подпись в две строки («Массажи классические», «Мальчишники
     и девичники») поднимается выше 72% высоты, где затемнения почти не было, и
     светлый текст ложился на светлое фото. Проверено на телефоне 390px. */
  background: linear-gradient(180deg,
    rgba(0,0,0,0) 28%,
    rgba(0,0,0,0.42) 52%,
    rgba(0,0,0,0.70) 76%,
    rgba(0,0,0,0.92) 100%);
  color: #FDFAF4;
}

.ss-tile-title-overlay {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  /* 20–22px по ТЗ 18.08.2026 (было до 26px). Верхняя граница опущена сознательно:
     ТЗ добавляет под названием описание, и прежний кегль съедал под него место. */
  font-size: clamp(20px, 1.5vw, 22px);
  font-weight: 500;
  color: var(--ss-amber);
  line-height: 1.1;
  text-shadow: 0 2px 8px rgba(0,0,0,0.55);
}
/* Описание карточки услуги (ТЗ 18.08.2026): Manrope 13–15px, чистый белый.
   Прижато к названию и обрезано двумя строками — фото под ним остаётся видно,
   а карточки в ряду не разъезжаются по высоте от разной длины текста. */
.ss-tile-text-overlay {
  margin: 8px 0 0;
  font-family: 'Manrope', sans-serif;
  font-size: 14px;
  font-weight: 400;
  line-height: 1.45;
  color: #FFFFFF;
  opacity: 0.92;
  text-shadow: 0 1px 6px rgba(0,0,0,0.6);
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
}

/* ── Плитка витрины /spa/ ────────────────────────────────────────────────────
   Витрина паков переведена на ту же плитку, что блок направлений на главной
   (18.08.2026, «примени всё с главной»). Прежняя .ss-pack-card — фото сверху,
   белое тело снизу — осталась в /aktsii/, где карточка живёт на светлом фоне
   и её тело несёт больше текста.
   Плитке витрины добавлены две вещи, которых на главной нет и которые витрина
   терять не должна: цена «от N ₽» и число программ в пакете. */
.ss-tile-price {
  position: absolute;
  left: 14px;
  top: 14px;
  z-index: 1;
  background: rgba(26, 20, 18, 0.82);
  color: var(--ss-amber);
  font-family: 'Manrope', sans-serif;
  font-weight: 600;
  font-size: 0.85rem;
  padding: 5px 12px;
  border-radius: 999px;
  backdrop-filter: blur(4px);
}
/* Строка «N программ … Смотреть →» под описанием. Отделена волоском, а не
   отступом: без него на светлом кадре она сливается с описанием в один абзац. */
.ss-tile-meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  margin-top: 12px;
  padding-top: 10px;
  border-top: 1px solid rgba(255, 255, 255, 0.22);
  font-family: 'Manrope', sans-serif;
  font-size: 13px;
  color: rgba(255, 255, 255, 0.85);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.6);
}
.ss-tile-cta { color: var(--ss-amber); font-weight: 600; white-space: nowrap; }
/* Страховка от переполнения: если карточка окажется уже, чем сумма «N программ»
   и «Смотреть →», строка переносится, а не вылезает за край кадра. Одной сетки
   мало — ширину колонки задаёт вызывающая страница, а плитка обязана держаться
   в любой. */
.ss-tile-meta { flex-wrap: wrap; }
.ss-tile-meta > span:first-child { min-width: 0; }
.ss-tile--pack:hover .ss-tile-cta { color: #FFFFFF; }
/* ⚠️ Описание остаётся в две строки, как на главной. Пробовал три — снимок
   18.08.2026 показал, почему нельзя: затемняющий градиент плитки растянут на
   всю её высоту, и чем выше блок текста, тем выше поднимается тёмная часть.
   С третьей строкой кадр под ней пропадал почти целиком, и ряд карточек читался
   как ряд тёмных прямоугольников. Это правило про фотографию, а не про текст. */
.ss-tile--pack .ss-tile-text-overlay { -webkit-line-clamp: 2; }
/* Градиент под расширенным содержимым (описание + строка «N программ»):
   тёмная зона начинается ниже, чем на главной, где под названием только
   описание. Иначе затемнение съедает середину кадра. */
/* ── Мобильная вычистка 02.09.2026 ─────────────────────────────────────────
   Плитка на телефоне идёт одна в ряд (col-12 до 576px), и кадр 3:4 при полной
   ширине занял бы почти весь экран — на телефоне пропорция шире. Заодно поля
   подложки уменьшены: при узкой плитке они съедали до трети ширины текста. */
@media (max-width: 575.98px) {
  .ss-tile-photo.ss-ar-3-4 { aspect-ratio: 4 / 3; }
  .ss-tile-overlay { padding: 18px 16px; }
  .ss-tile-text-overlay { -webkit-line-clamp: 3; }
}
/* Название плитки — светлее обычного акцента и с тенью. Та же причина, что у
   заголовков фотографических шапок (02.09.2026): `--ss-amber` (#C9A66B) на
   светлом кадре отличается от фона только светлотой. На снимке 320px
   «Массажи классические» и «Коррекция фигуры» тонули в фотографии. */
.ss-tile-title-overlay { color: #E6C79A; text-shadow: 0 2px 10px rgba(0,0,0,.6); }

/* ── Cookie-полоса: две кнопки не влезали в 320px ──
   Замер 02.09.2026: «Только необходимые» уезжала за экран на 5px НА КАЖДОЙ
   странице сайта — полоса сквозная. Правило ниже по файлу (max-width: 575px)
   растягивало кнопки, но не разрешало им переноситься, а рядом с ними в той же
   строке остаётся текст согласия. */
@media (max-width: 575.98px) {
  .ss-cookie__actions { flex-wrap: wrap; }
  .ss-cookie__actions .btn { flex: 1 1 100%; }
}

/* ── Строка программы: название, длительность и цена в одну строку на телефоне
   сжимали название до 85px, и оно ломалось по одному слову («Мальчишник/
   Девичник в Русской бане» — четыре строки). Общее правило `flex-wrap` ниже по
   файлу до строки-карточки не доставало: у `.ss-menu-row--rich
   .ss-menu-row__head` специфичность выше. Теперь на телефоне название занимает
   свою строку, под ним — длительность и цена. */
@media (max-width: 575.98px) {
  /* Простая строка списка (`.ss-menu-row` без --rich) — то же лечение: она сама
     flex-контейнер, и название делит строку с точками, длительностью и ценой.
     На 320px колонка названия сжималась до 65px («Анти-JET LAG и свежесть кожи» —
     пять строк по слову). Точки при переносе не нужны: они соединяли название с
     ценой в ОДНОЙ строке, а в двух строках висят обрывком. */
  .ss-menu-row { flex-wrap: wrap; }
  .ss-menu-row > .ss-menu-row__name { flex: 1 1 100%; min-width: 0; }
  .ss-menu-row > .ss-menu-row__dots { display: none; }
  .ss-menu-row > .ss-menu-row__dur { margin-right: auto; }
  .ss-menu-row > .ss-menu-row__price { min-width: 0; }

  .ss-menu-row--rich .ss-menu-row__head { flex-wrap: wrap; }
  .ss-menu-row--rich .ss-menu-row__name { flex: 1 1 100%; min-width: 0; }
  .ss-menu-row--rich .ss-menu-row__dots { display: none; }
  .ss-menu-row--rich .ss-menu-row__dur { margin-right: auto; }
}

/* ── Заголовок карточки программы: 24px в колонке 226px давал по одному слову в
   строке («Корректирующий массаж (медовый, баночный)» — три строки из трёх
   слов). На телефоне кегль ниже, перенос по слогам разрешён. */
@media (max-width: 575.98px) {
  .ss-program-card__title { font-size: 19px; }
}

.ss-tile--pack .ss-tile-overlay {
  background: linear-gradient(180deg,
    rgba(0,0,0,0) 34%,
    rgba(0,0,0,0.34) 54%,
    rgba(0,0,0,0.68) 74%,
    rgba(0,0,0,0.93) 100%);
}

/* Заголовок секции бань крупнее прочих — ТЗ 18.08.2026 требует усилить иерархию
   именно этого блока, а не поднять кегль всем секциям сразу. */
.ss-title-section--lg { font-size: clamp(34px, 4vw, 58px); }
.ss-banya-section .ss-lede { font-size: 17px; }

/* Банная карточка. Правки ТЗ 18.08.2026: карточка крупнее, тонкая золотистая
   обводка, скругление, затемнение низа фото выраженнее, название золотом и
   крупнее, характеристики с иконками и вертикальными разделителями, кнопка
   «Подробнее →» золотой обводкой вместо серой. Сетка 2×2 и горизонтальный
   формат сохранены — ТЗ требует именно их. */
.ss-banya-card {
  position: relative;
  border-radius: 18px;
  overflow: hidden;
  display: block;
  color: #FDFAF4;
  text-decoration: none;
  background: var(--ss-card);
  border: 1px solid rgba(201, 166, 107, 0.38);
  box-shadow: 0 10px 30px rgba(0, 0, 0, 0.28);
  transition: transform 0.35s ease, border-color 0.35s ease, box-shadow 0.35s ease;
}
.ss-banya-card:hover {
  transform: translateY(-4px);
  color: #FDFAF4;
  border-color: rgba(201, 166, 107, 0.75);
  box-shadow: 0 18px 44px rgba(0, 0, 0, 0.38);
}
.ss-banya-card .ss-img-placeholder {
  height: 420px;
}
.ss-banya-overlay {
  position: absolute;
  inset: 0;
  padding: 32px 32px 28px;
  display: flex;
  flex-direction: column;
  justify-content: flex-end;
  /* Двухсторонний градиент: лёгкое затемнение сверху для типа,
     плотное снизу для названия/мета. Работает на любой яркости фото. */
  /* Низ затемнён сильнее прежнего (ТЗ: «более выраженное затемнение нижней части
     фото») — под названием, описанием и строкой характеристик теперь три строки
     текста вместо двух, и светлый кадр их глушил. */
  background:
    linear-gradient(180deg, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0.18) 22%, rgba(0,0,0,0) 45%),
    linear-gradient(180deg, rgba(0,0,0,0) 42%, rgba(0,0,0,0.62) 68%, rgba(0,0,0,0.94) 100%);
}
.ss-banya-type {
  position: absolute;
  top: 28px;
  left: 32px;
  right: 32px;
  font-family: 'Manrope', sans-serif;
  font-size: 11px;   /* M20-9 (12px) перенесён в @@SEC:M20-9@@ — на 1440 не должен меняться (Н-2, барьер МР-3) */
  letter-spacing: 0.22em;
  text-transform: uppercase;
  color: #FDFAF4;
  margin: 0;
  text-shadow: 0 1px 4px rgba(0,0,0,0.55);
}
.ss-banya-name {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  /* Крупнее и золотом — ТЗ 18.08.2026 («названия крупнее и золотым #C9A66B»). */
  font-size: clamp(30px, 2.8vw, 40px);
  font-weight: 500;
  color: var(--ss-amber);
  margin: 0 0 6px;
  line-height: 1.05;
  text-shadow: 0 2px 10px rgba(0,0,0,0.55);
}
.ss-banya-teaser {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-size: 16px;
  color: #FDFAF4;
  opacity: 0.92;
  margin: 0 0 14px;
  max-width: 90%;
  text-shadow: 0 1px 4px rgba(0,0,0,0.5);
}
/* Характеристики: строка кусков с иконками, между кусками — вертикальный
   разделитель (ТЗ). Разделитель рисуется границей соседа, а не символом «·»:
   символ переносится на новую строку сам по себе и повисает в начале строки. */
.ss-banya-meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  font-family: 'Manrope', sans-serif;
  font-size: 13px;
  color: #FDFAF4;
  letter-spacing: 0.02em;
  text-shadow: 0 1px 3px rgba(0,0,0,0.6);
}
.ss-banya-meta-item {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 0 12px;
  line-height: 1.3;
  border-left: 1px solid rgba(201, 166, 107, 0.45);
}
.ss-banya-meta-item:first-child { padding-left: 0; border-left: 0; }
.ss-banya-meta-icon { flex: none; color: var(--ss-amber); opacity: 0.9; }
/* Цена заметнее остальных характеристик — ТЗ: «цену сделать заметнее». */
.ss-banya-meta-item.is-price {
  color: var(--ss-amber);
  font-weight: 600;
  font-size: 15px;
}

/* «Подробнее →» — золотая обводка вместо серой (ТЗ). Тач-цель 44px по высоте. */
.btn-ss-gold {
  background: rgba(201, 166, 107, 0.10);
  color: var(--ss-amber);
  border: 1px solid var(--ss-amber);
  font-family: 'Manrope', sans-serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.04em;
  padding: 12px 22px;
  border-radius: 999px;
  transition: background 0.25s ease, color 0.25s ease;
}
.btn-ss-gold:hover,
.btn-ss-gold:focus-visible {
  background: var(--ss-amber);
  color: #201A17;
}
.ss-banya-card:hover .btn-ss-gold { background: var(--ss-amber); color: #201A17; }

/* ============================================================
   Stories strip
   ============================================================ */
.ss-stories {
  display: flex;
  gap: 20px;
  overflow-x: auto;
  padding: 8px 0 16px;
  scroll-snap-type: x mandatory;
}
.ss-stories::-webkit-scrollbar { display: none; }
.ss-story {
  flex: 0 0 auto;
  width: 118px;
  scroll-snap-align: start;
  text-decoration: none;
  color: inherit;
}
.ss-story-frame {
  width: 118px;
  height: 165px;
  border-radius: 18px;
  overflow: hidden;
  border: 2px solid var(--ss-copper);
  padding: 3px;
}
[data-theme="dark"] .ss-story-frame { border-color: var(--ss-amber); }
.ss-story-frame > div {
  width: 100%; height: 100%;
  border-radius: 14px;
  overflow: hidden;
}
.ss-story-title {
  font-family: 'Manrope', sans-serif;
  font-size: 12px;
  margin-top: 8px;
  text-align: center;
  color: var(--ss-text-muted);
}

/* ============================================================
   Tags / chips
   ============================================================ */
.ss-tag {
  display: inline-block;
  font-family: 'Manrope', sans-serif;
  font-size: 14px;
  padding: 8px 18px;
  border-radius: 999px;
  border: 1px solid var(--ss-divider);
  color: var(--ss-text);
  text-decoration: none;
  margin: 0 6px 8px 0;
  transition: all 0.2s ease;
  background: transparent;
}
.ss-tag:hover {
  border-color: var(--ss-copper);
  color: var(--ss-copper);
}
/* Тег с высоким поисковым спросом (идея министра 18.08.2026).
   ⛔ Выделение НЕ размером. Разброс кеглей в облаке тегов — визуальный код
   двадцатилетней давности: он ломает ритм сетки, на телефоне разваливает
   раскладку и читается ровно тем словом, за которое в этом же заходе
   переделывали подпись зоны. Здесь — золотая обводка и чуть плотнее шрифт:
   глаз ведёт туда же, блок остаётся блоком.
   Порог и правило отбора — в index.php (SS_TAG_MIN / SS_TAG_TOP). */
.ss-tag--hot {
  border-color: var(--ss-amber);
  color: var(--ss-accent);
  font-weight: 600;
  background: rgba(201, 166, 107, 0.08);
}
.ss-tag--hot:hover {
  border-color: var(--ss-amber);
  background: rgba(201, 166, 107, 0.18);
}
[data-theme="dark"] .ss-tag:hover {
  border-color: var(--ss-amber);
  color: var(--ss-amber);
}
.ss-tag.is-active {
  background: var(--ss-terracotta);
  border-color: var(--ss-terracotta);
  color: #FDFAF4;
}

/* Конструктор: группы тегов с разделителями */
.ss-constructor-group {
  border-bottom: 1px solid var(--ss-divider);
}
.ss-tag-cloud { display: block; }
.ss-tag-cloud .ss-tag:last-child { margin-right: 0; }

/* 3D-тур: сцена с фото + оверлей-панелью */
.ss-tour-stage {
  position: relative;
  width: 100%;
  border-radius: 18px;
  overflow: hidden;
  aspect-ratio: 16 / 7;
  background: var(--ss-card);
}
.ss-tour-photo {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
}
.ss-tour-photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: opacity 0.35s ease;
}
.ss-tour-photo::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(90deg,
      rgba(10,8,7,0.7) 0%,
      rgba(10,8,7,0.35) 35%,
      rgba(10,8,7,0) 55%);
  pointer-events: none;
}
.ss-tour-panel {
  position: absolute;
  top: 28px;
  left: 28px;
  z-index: 2;
  width: min(320px, 45%);
  background: rgba(10,8,7,0.55);
  border: 1px solid rgba(201,168,115,0.25);
  border-radius: 14px;
  padding: 22px 24px;
  backdrop-filter: blur(6px);
  -webkit-backdrop-filter: blur(6px);
}
.ss-tour-brand {
  font-size: 22px;
  line-height: 1;
  margin-bottom: 18px;
  padding-bottom: 16px;
  border-bottom: 1px solid rgba(201,168,115,0.2);
}
.ss-tour-list {
  list-style: none;
  padding: 0;
  margin: 0;
}
.ss-tour-list li + li { margin-top: 2px; }
.ss-tour-link {
  display: block;
  width: 100%;
  text-align: left;
  background: none;
  border: 0;
  padding: 7px 0;
  font-family: 'Manrope', sans-serif;
  font-size: 15px;
  color: rgba(253,250,244,0.8);
  cursor: pointer;
  transition: color 0.2s ease, transform 0.2s ease;
}
.ss-tour-link:hover { color: var(--ss-amber); }
.ss-tour-link.is-active {
  color: var(--ss-amber);
  transform: translateX(4px);
}
.ss-tour-caption {
  position: absolute;
  bottom: 28px;
  right: 32px;
  z-index: 2;
  text-align: right;
  color: #FDFAF4;
}
.ss-tour-caption #ssTourCaption {
  display: block;
  font-family: 'Cormorant Garamond', serif;
  font-size: 28px;
  font-weight: 500;
  line-height: 1.1;
  margin-bottom: 4px;
}
.ss-tour-sub {
  display: block;
  font-family: 'Manrope', sans-serif;
  font-size: 12px;
  letter-spacing: 0.14em;
  text-transform: uppercase;
  opacity: 0.75;
}
@media (max-width: 991.98px) {
  .ss-tour-stage { aspect-ratio: 4 / 5; }
  .ss-tour-panel {
    top: 16px; left: 16px; right: 16px;
    width: auto;
    padding: 16px 18px;
  }
  .ss-tour-brand { font-size: 18px; margin-bottom: 12px; padding-bottom: 10px; }
  .ss-tour-link { font-size: 14px; padding: 5px 0; }
  .ss-tour-caption { bottom: 16px; right: 16px; left: 16px; text-align: left; }
}

/* Контакты: карта */
.ss-contacts-map {
  position: relative;
  width: 100%;
  height: 100%;
  min-height: 520px;
  border-radius: 16px;
  overflow: hidden;
  background: var(--ss-card);
}
.ss-contacts-map iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
  display: block;
}
@media (max-width: 991.98px) {
  .ss-contacts-map { min-height: 360px; }
}

/* ============================================================
   Footer
   ============================================================ */
/* ⛔ КОНТРАСТ ПОДВАЛА — жалоба заказчика 17.09.2026, «особенно телефоны».
   Замер `scripts/footer-contrast-audit.js` ДО правки (WCAG 2.x, фон #3A2F28):
       телефоны            4.54:1   ← самое важное в подвале и самое бледное
       юридические ссылки  4.86:1
       заголовки колонок   5.66:1
       пункты навигации    8.18:1
   ⚠️ Формальный порог AA 4.5:1 брали ВСЕ 288 замеров — и чекап, и аудит
   контраста были зелены, а подвал заказчик читать не смог. Порог AA — ПОЛ,
   а не комфорт, и дефект тут не в одном числе, а в РАССЛОЕНИИ: телефон
   вдвое бледнее пункта меню, стоящего в 40 пикселях от него. Поэтому
   инвариант, который стережёт лист, сформулирован ОТНОШЕНИЕМ двух живых
   чисел («телефон не бледнее навигации»), а не константой: константа
   зеленеет на любом будущем перекрашивании обеих сторон сразу.

   ⛔ Контакты подвала рисует `include/contacts-block.php` — РЕДАКТОРСКАЯ
   область: активный файл в .gitignore, на проде он принадлежит заказчику
   и правится им из админки. Его инлайновые `color: var(--ss-amber)`
   и `opacity: 0.85` нашей правкой `.dist` НЕ чинятся — на проде лежит его
   копия, не наша. Отсюда два обходных пути, оба намеренные:
     · ЦВЕТ чиним ПЕРЕОПРЕДЕЛЕНИЕМ ПЕРЕМЕННОЙ. Инлайновое
       `color: var(--ss-amber)` выигрывает каскад как объявление, но ЗНАЧЕНИЕ
       переменной берёт из каскада custom properties — и `.ss-footer`
       её подменяет, не трогая ни разметку, ни чужой инлайн.
     · `opacity` переменной не является, и чужой инлайн бьётся только
       `!important`. Он тут не небрежность, а единственный способ дотянуться
       до файла, которого у нас на проде не будет. */
.ss-footer {
  background: #3A2F28;
  color: var(--ss-text-on-dark);
  padding: 80px 0 30px;
  margin-top: 0;

  /* Золото ТЗ #C9A66B задано заказчиком для СВЕТЛОГО фона; на тёмном подвале
     оно даёт 5.66:1, а под редакторской opacity 0.85 — 4.54:1. На ТЁМНОЙ
     ПОВЕРХНОСТИ берём осветлённый вариант того же тона — 8.44:1. Бренд-цвет
     сайта не меняется: правило заперто в `.ss-footer`, `:root` не тронут.

     ⚠️ Оттенок подобран НЕ на глаз и не «чтобы покрасивее»: первая попытка
     (#DFC084, 7.43:1) сняла жалобу по порогу, и лист её ЗАВЕРНУЛ — телефон
     остался бледнее пунктов меню рядом (8.18:1), то есть остаточный дефект
     был ровно тем, на который жаловались. Число выбрано как наименьшее,
     при котором телефон ведёт, а не догоняет. */
  --ss-amber: #E6CE97;
}
[data-theme="dark"] .ss-footer {
  background: var(--ss-bg);
  border-top: 1px solid var(--ss-divider);
}
.ss-footer h6 {
  font-family: 'Manrope', sans-serif;
  font-size: 13px;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ss-amber);
  margin-bottom: 20px;
}
.ss-footer a {
  color: var(--ss-text-on-dark);
  text-decoration: none;
  font-size: 14px;
  display: block;
  padding: 5px 0;
  opacity: 0.85;
}
.ss-footer a:hover { opacity: 1; color: var(--ss-amber); }

/* Телефон — единственная строка подвала, которую читают ПОЗНАКОВО: ошибка
   в одной цифре стоит звонка. Снимаем редакторскую полупрозрачность и даём
   цифрам вес; 20px/600 на 7.43:1 против прежних 20px/400 на 4.54:1.
   `!important` — см. врезку выше: перебиваем инлайн из чужого файла. */
.ss-footer a[href^="tel:"] {
  opacity: 1 !important;
  font-weight: 600;
  letter-spacing: 0.01em;
}

.ss-footer-bottom {
  border-top: 1px solid rgba(239, 232, 220, 0.12);
  padding-top: 24px;
  margin-top: 48px;
  font-size: 13px;
  /* ⛔ Было `opacity: 0.7` НА БЛОКЕ. Она умножалась на 0.85 от `.ss-footer a`
     и давала юридическим ссылкам фактические 0.595 — 4.86:1 при 14px
     с подчёркиванием, второе снизу число подвала. Приглушение переносим
     в ЦВЕТ: альфа цвета не накапливается по предкам, а opacity накапливается,
     и именно это накопление в исходнике не видно — оно написано в двух
     разных правилах, между которыми две тысячи строк. */
  color: rgba(239, 232, 220, 0.78);
}
/* Ссылки нижней строки: своя opacity больше не нужна — приглушение уже
   в наследуемом цвете. 7.16:1 против прежних 4.86:1. */
.ss-footer-bottom a { opacity: 1; }

/* ============================================================
   Certificate preview (главная, блок подарочного сертификата)
   ============================================================ */
.ss-cert-preview {
  background: linear-gradient(135deg, #1A1412 0%, #2A2017 100%);
  color: var(--ss-text-on-dark);
  border-radius: 18px;
  padding: 48px 40px;
  position: relative;
  overflow: hidden;
  border: 1px solid rgba(201, 168, 115, 0.25);
}
.ss-cert-preview::before {
  content: '';
  position: absolute;
  inset: 16px;
  border: 1px solid rgba(201, 168, 115, 0.3);
  border-radius: 10px;
  pointer-events: none;
}

/* ============================================================
   Misc
   ============================================================ */
.ss-icon-line {
  width: 40px; height: 40px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  border: 1px solid currentColor;
  border-radius: 50%;
  color: var(--ss-copper);
}
.ss-icon-line--lg { width: 64px; height: 64px; }
[data-theme="dark"] .ss-icon-line { color: var(--ss-amber); }

/* Преимущества — аккордеон слева + фото справа */
.ss-accordion {
  --bs-accordion-bg: transparent;
  --bs-accordion-border-color: transparent;
  --bs-accordion-border-width: 0;
  --bs-accordion-active-bg: transparent;
  --bs-accordion-active-color: var(--ss-text);
  --bs-accordion-btn-focus-box-shadow: none;
  --bs-accordion-btn-color: var(--ss-text);
  --bs-accordion-color: var(--ss-text-muted);
  --bs-accordion-body-padding-x: 0;
  --bs-accordion-body-padding-y: 0 0 24px;
}
.ss-accordion-item {
  border-top: 1px solid rgba(201,168,115,0.22);
  background: transparent;
}
.ss-accordion-item:last-child {
  border-bottom: 1px solid rgba(201,168,115,0.22);
}
.ss-accordion-btn {
  display: flex;
  align-items: baseline;
  gap: 20px;
  padding: 22px 8px;
  font-family: 'Cormorant Garamond', serif;
  font-size: 24px;
  font-weight: 500;
  line-height: 1.25;
  color: var(--ss-text-muted);
  background: transparent;
  box-shadow: none;
  border: 0;
  border-radius: 0;
  transition: color 0.2s ease;
}
.ss-accordion-btn:hover { color: var(--ss-text); }
.accordion-button.ss-accordion-btn:not(.collapsed) {
  color: var(--ss-text);
}
.accordion-button.ss-accordion-btn.collapsed {
  color: var(--ss-text-muted);
}
.ss-accordion-btn::after {
  flex-shrink: 0;
  margin-left: auto;
  width: 18px;
  height: 18px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' fill='none' stroke='%23C9A66B' stroke-width='1.5'%3E%3Cpath d='M6 9l6 6 6-6'/%3E%3C/svg%3E");
  background-size: 18px;
  transition: transform 0.25s ease;
}
.ss-accordion-num {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-size: 20px;
  color: var(--ss-accent);
  min-width: 32px;
}
.ss-accordion-title { flex: 1; }
.ss-accordion-body {
  padding: 0 8px 26px 60px;
  color: var(--ss-text-muted);
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
}
.ss-accordion-body p { margin: 0; max-width: 520px; }

.ss-advantages-figure {
  position: relative;
  height: 100%;
  min-height: 420px;
  border-radius: 16px;
  overflow: hidden;
  background: var(--ss-card);
}
.ss-advantages-figure img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
@media (max-width: 991.98px) {
  .ss-advantages-figure { min-height: 320px; }
  .ss-accordion-btn { font-size: 20px; padding: 18px 4px; gap: 14px; }
  .ss-accordion-body { padding-left: 46px; }
}

/* Социальные иконки в футере — взяты из блока контактов index-contacts */
.ss-socials {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
}
.ss-socials .index-contacts__social {
  display: flex;
  flex-wrap: wrap;
  gap: 14px;
  align-items: center;
  margin: 0;
  padding: 0;
}
.ss-socials .index-contacts__social-icon {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 32px;
  height: 32px;
  line-height: 0;
  text-decoration: none;
  opacity: 0.9;
  transition: opacity 0.2s, transform 0.2s;
  flex-shrink: 0;
  overflow: hidden;
  color: var(--ss-amber);
}
.ss-socials .index-contacts__social-icon:hover {
  opacity: 1;
  transform: translateY(-2px);
}
.ss-socials .index-contacts__social-icon > svg,
.ss-socials .index-contacts__social-icon > svg > g {
  width: 32px !important;
  height: 32px !important;
  max-width: 32px !important;
  max-height: 32px !important;
  display: block;
}

.ss-num-lg {
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-size: 56px;
  font-weight: 400;
  color: var(--ss-copper);
  line-height: 1;
}
[data-theme="dark"] .ss-num-lg { color: var(--ss-amber); }

.ss-step-line {
  position: relative;
}
.ss-step-line::before {
  content: '';
  position: absolute;
  left: 28px;
  top: 60px;
  bottom: -40px;
  width: 1px;
  background: var(--ss-copper);
  opacity: 0.4;
}
[data-theme="dark"] .ss-step-line::before { background: var(--ss-amber); }
.ss-step-line:last-child::before { display: none; }

.ss-form-label-group {
  font-family: 'Manrope', sans-serif;
  font-size: 13px;
  letter-spacing: 0.15em;
  text-transform: uppercase;
  color: var(--ss-copper);
  margin-bottom: 14px;
  display: block;
}

.ss-input {
  width: 100%;
  padding: 14px 16px;
  border: 1px solid var(--ss-divider);
  border-radius: 10px;
  background: var(--ss-card);
  color: var(--ss-text);
  font-family: 'Manrope', sans-serif;
  font-size: 15px;
  transition: border-color 0.2s;
}
.ss-input:focus {
  outline: none;
  border-color: var(--ss-copper);
}
[data-theme="dark"] .ss-input {
  background: var(--ss-bg-alt);
  border-color: var(--ss-divider);
  color: var(--ss-text);
}

/* ── Stories (имитация Instagram) ── */
.ss-stories-section {
  padding: 40px 0 16px;
  background: var(--ss-bg);
}
.ss-stories-strip {
  display: flex;
  flex-wrap: nowrap;
  justify-content: center;
  gap: 22px;
  overflow-x: auto;
  padding: 4px 2px 12px;
  scrollbar-width: thin;
  scrollbar-color: rgba(201,168,115,0.4) transparent;
}
.ss-stories-strip::-webkit-scrollbar { height: 4px; }
.ss-stories-strip::-webkit-scrollbar-thumb { background: rgba(201,168,115,0.4); border-radius: 2px; }
.ss-story {
  flex: 0 0 auto;
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: 8px;
  background: transparent;
  border: 0;
  padding: 0;
  cursor: pointer;
  color: var(--ss-text-on-dark, #EFE8DC);
  transition: transform 0.2s ease;
}
.ss-story:hover { transform: translateY(-2px); }
.ss-story-ring {
  display: block;
  width: 76px;
  height: 76px;
  border-radius: 50%;
  padding: 2px;
  background: conic-gradient(from 140deg,
    #C9A66B 0deg, #E6C88A 90deg, #8B6F3F 200deg, #C9A66B 360deg);
  box-shadow: 0 4px 16px rgba(201,168,115,0.25);
}
.ss-story-thumb {
  display: block;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  overflow: hidden;
  border: 2px solid var(--ss-bg);
  background: var(--ss-bg-alt);
}
.ss-story-thumb img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
/* ⚠️ Подпись сторис переносится, а не обрезается многоточием (02.09.2026).
   Было `white-space: nowrap` + ellipsis: на телефоне «Японская офуро» показывалась
   как «Японская оф…» — из двух слов терялось одно, а под кружком оставалось
   пустое место. Две строки помещаются, третью режем клэмпом: полоса сторис
   обязана оставаться ровной по высоте. */
.ss-story-title {
  font-size: 12px;
  letter-spacing: 0.02em;
  max-width: 82px;
  text-align: center;
  display: -webkit-box;
  -webkit-line-clamp: 2;
  -webkit-box-orient: vertical;
  overflow: hidden;
  line-height: 1.25;
  /* ⚠️ Ширина 96px, а не 82: «Сертификаты» — одно слово, оно не переносится и при
     82px обрезалось по-живому, без всякого признака обрезки («Сертификать»).
     Первая редакция этой правки поменяла многоточие на такой обрез — то есть
     сделала хуже. overflow-wrap оставлен страховкой на случай слова длиннее
     кружка: лучше перенос по буквам, чем съеденный хвост. */
  max-width: 96px;
  overflow-wrap: anywhere;
  opacity: 0.85;
}
@media (max-width: 767px) {
  .ss-stories-section { padding: 28px 0 8px; }
  .ss-stories-strip { gap: 14px; justify-content: flex-start; }
  .ss-story-ring { width: 64px; height: 64px; }
  .ss-story-title { font-size: 11px; max-width: 88px; }
}

/* Stories modal */
.ss-stories-modal .modal-dialog {
  max-width: 440px;
}
.ss-stories-modal .modal-content {
  background: #000;
  border: 1px solid rgba(201,168,115,0.2);
  border-radius: 18px;
  overflow: hidden;
  aspect-ratio: 9 / 16;
  max-height: 88vh;
  position: relative;
}

/* Шапка: прогресс + аватар/тайтл + действия */
.ss-stories-head {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  z-index: 5;
  padding: 10px 12px 14px;
  background: linear-gradient(to bottom, rgba(0,0,0,0.55) 0%, rgba(0,0,0,0) 100%);
  pointer-events: none;
}
.ss-stories-head > * { pointer-events: auto; }

.ss-stories-progress {
  display: flex;
  gap: 4px;
  margin-bottom: 10px;
}
.ss-stories-bar {
  flex: 1 1 0;
  height: 3px;
  background: rgba(255,255,255,0.3);
  border-radius: 2px;
  overflow: hidden;
  position: relative;
}
.ss-stories-bar .fill {
  display: block;
  height: 100%;
  width: 0%;
  background: #fff;
  border-radius: 2px;
}
.ss-stories-bar.is-done .fill { width: 100% !important; transition: none !important; }

.ss-stories-head-row {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
}
.ss-stories-meta {
  display: flex;
  align-items: center;
  gap: 10px;
  min-width: 0;
}
.ss-stories-avatar {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  overflow: hidden;
  border: 2px solid rgba(255,255,255,0.9);
  flex: 0 0 auto;
  background: rgba(0,0,0,0.4);
}
.ss-stories-avatar img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}
.ss-stories-group-title {
  color: #fff;
  font-size: 15px;
  font-weight: 600;
  white-space: nowrap;
  overflow: hidden;
  text-overflow: ellipsis;
}
.ss-stories-actions {
  display: flex;
  align-items: center;
  gap: 4px;
  flex: 0 0 auto;
}
.ss-stories-btn {
  width: 34px;
  height: 34px;
  border-radius: 50%;
  background: rgba(0,0,0,0.35);
  border: 0;
  color: #fff;
  font-size: 22px;
  line-height: 1;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  cursor: pointer;
  transition: background 0.2s;
}
.ss-stories-btn:hover { background: rgba(0,0,0,0.7); }

/* Слайды */
.ss-stories-slider { height: 100%; }
.ss-stories-slider .slick-list,
.ss-stories-slider .slick-track { height: 100%; }
.ss-stories-slide {
  height: 100%;
  position: relative;
  background: #000;
}
.ss-stories-media {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* Инфо-блок: заголовок/подзаголовок/кнопка */
.ss-stories-info {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  padding: 60px 22px calc(24px + env(safe-area-inset-bottom, 0px));
  color: #fff;
  background: linear-gradient(to top, rgba(0,0,0,0.85) 0%, rgba(0,0,0,0.45) 55%, rgba(0,0,0,0) 100%);
  display: flex;
  flex-direction: column;
  gap: 10px;
}
.ss-stories-title {
  font-size: 26px;
  line-height: 1.15;
  font-weight: 700;
  font-family: 'Cormorant Garamond', Georgia, serif;
}
.ss-stories-subtitle {
  font-size: 15px;
  line-height: 1.4;
  opacity: 0.95;
}
.ss-stories-cta {
  margin-top: 8px;
  display: block;
  text-align: center;
  padding: 14px 20px;
  border-radius: 12px;
  background: rgba(255,255,255,0.18);
  color: #fff;
  text-decoration: none;
  font-size: 15px;
  font-weight: 600;
  backdrop-filter: blur(8px);
  -webkit-backdrop-filter: blur(8px);
  border: 1px solid rgba(255,255,255,0.25);
  transition: background 0.2s;
}
.ss-stories-cta:hover {
  background: rgba(255,255,255,0.28);
  color: #fff;
}

/* ── /spa/ страница: hero, breadcrumbs ── */
.ss-spa-hero {
  padding: 140px 0 60px;
  background: var(--ss-bg);
  border-bottom: 1px solid var(--ss-divider);
}
.ss-breadcrumbs {
  font-size: 13px;
  letter-spacing: 0.02em;
  margin-bottom: 20px;
  opacity: 0.85;
}
.ss-breadcrumbs a {
  color: var(--ss-text, inherit);
  text-decoration: none;
  opacity: 0.7;
  transition: opacity 0.2s, color 0.2s;
}
.ss-breadcrumbs a:hover { opacity: 1; color: var(--ss-accent); }
.ss-breadcrumbs__sep { margin: 0 10px; opacity: 0.5; }
/* Крошки в hero поверх фото: отступ сверху под фиксированную шапку. Раньше стоял
   инлайном в шаблоне детальной бани — переехал сюда вместе с переводом крошек на
   общий хелпер `spasol_breadcrumbs()` (13.08.2026). */
.ss-breadcrumbs--hero { margin-bottom: 1.5rem; padding-top: 80px; }
/* ⛔ РАЗМЕР ЗАГОЛОВКА ЗДЕСЬ БОЛЬШЕ НЕ ПЕРЕОПРЕДЕЛЯЕТСЯ (решение министра
   02.09.2026: «приводи к одному стилю 60»). Было `clamp(40px, 5vw, 72px)` — и это
   давало инверсию: на служебных страницах заголовок 72px, то есть КРУПНЕЕ, чем на
   главной, пакете, бане и программе, где работает базовое правило
   `.ss-title-hero` (60px). Найдено аудитом единства оформления 02.09.2026.
   Размер теперь один на весь сайт и живёт в одном месте — в `.ss-title-hero`. */
.ss-spa-hero .ss-title-hero {
  line-height: 1.05;
  margin: 0;
}

/* Разделитель, прижатый влево. Нужен там, где заголовок стоит не по центру
   полноширинной секции, а в колонке (шапка каталога рядом с фильтром):
   центрованный там повисает посреди сетки карточек.
   ⚠️ Правится именно margin, а не justify-content: у разделителя max-width
   240px и `margin: 20px auto` — прижимать содержимое внутри коробки бесполезно,
   пока сама коробка центрована (18.08.2026, видно на снимке каталога). */
.ss-divider-ornate--start { margin-left: 0; margin-right: auto; }

/* Конструктор: фильтры и результаты — ОДИН блок, а не две секции подряд.
   У каждой `.ss-section` свои вертикальные отступы, и между чипсами и списком
   программ зияло около 280px пустоты (снимок 1440px 02.09.2026, заход по решению
   министра «страницу конструктора вообще не обрабатывали»). Смыкаем их, не трогая
   отступы всех остальных секций сайта. */
.ss-constructor-filters { padding-bottom: 32px; }
.ss-constructor-filters + .ss-catalog { padding-top: 32px; }

/* Приставка «от» у цены: тем же кеглем, но тише самой суммы — иначе читается
   как часть числа. Появилась 18.08.2026 вместе с spasol_price_parts(). */
.ss-price-from {
  font-weight: 400;
  opacity: 0.7;
  font-size: 0.88em;
}

/* ── Декор в правой части шапки раздела /spa/ ────────────────────────────────
   Правка министра 18.08.2026 по макету. Рисунок стоит В ПОТОКЕ ЗА текстом:
   абсолютное позиционирование внутри секции, `pointer-events:none`, отрицательный
   z-index не нужен — шапка ниже по разметке и перекрывает его сама.
   ⚠️ `overflow:hidden` у секции обязателен: рисунок шире правого поля и без него
   даёт горизонтальный скролл на всю страницу. */
.ss-spa-hero.has-decor { position: relative; overflow: hidden; }
.ss-spa-hero__decor {
  position: absolute;
  right: clamp(-40px, -1vw, 0px);
  top: 50%;
  transform: translateY(-46%);
  width: min(46vw, 620px);
  max-width: 620px;
  pointer-events: none;
  user-select: none;
  opacity: 0.85;
}
.ss-spa-hero__decor svg { display: block; width: 100%; height: auto; }
/* Ниже lg рисунок скрыт целиком: там ширины хватает ровно на заголовок и лид,
   и линии под текстом читались бы шумом, а не фоном. */
@media (max-width: 991.98px) { .ss-spa-hero__decor { display: none; } }
/* Текст шапки не должен наезжать на рисунок на средних ширинах. */
@media (min-width: 992px) {
  .ss-spa-hero.has-decor .ss-container > * { position: relative; max-width: 56%; }
  .ss-spa-hero.has-decor .ss-breadcrumbs { max-width: none; }
}
@media (min-width: 1600px) {
  .ss-spa-hero.has-decor .ss-container > * { max-width: 48%; }
}

/* ── Панель навигации по группам пакетов ─────────────────────────────────────
   Правка министра 18.08.2026: «нужна доп панель навигации по пакам».
   Переключение — CSS-radio без JS (см. blocks/tour — тот же приём и та же
   причина: со сломанным JS ни одна группа не должна стать недостижимой). */
.ss-pgroup-radio {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}
.ss-packs-nav {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin: 0 0 32px;
}
.ss-pgroup-tab {
  display: inline-flex;
  align-items: center;
  min-height: 44px;               /* тач-цель — инвариант доступности */
  padding: 10px 20px;
  border: 1px solid var(--ss-divider);
  border-radius: 999px;
  background: var(--ss-card);
  font-family: 'Manrope', sans-serif;
  font-size: 14px;
  line-height: 1.2;
  color: var(--ss-text);
  cursor: pointer;
  white-space: nowrap;
  transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}
.ss-pgroup-tab:hover { border-color: var(--ss-amber); }
/* Не показываем подсказку на desktop: там категории переносятся строками. */
.ss-packs-nav-hint { display: none; }
/* До 992px строка чипов прокручивается вбок, а не переносится рядами, съедая
   экран до того, как посетитель увидит хоть одну карточку. Порог именно 992, а не
   767: на планшете 768px одиннадцать чипов вставали в ТРИ ряда (замер 18.08.2026).
   ⚠️ Скролл — у самой панели; страница вбок не едет (проверено на 320–2560px). */
@media (max-width: 991.98px) {
  .ss-packs-nav-hint {
    display: flex;
    justify-content: flex-end;
    align-items: center;
    gap: 7px;
    margin: -16px 0 10px;
    color: var(--ss-text-muted);
    font: 500 12px/1.4 'Manrope', sans-serif;
  }
  .ss-packs-nav-hint svg {
    flex: none;
    color: var(--ss-accent);
  }
  .ss-packs-nav {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    scrollbar-width: none;
    /* Поля контейнера обходятся отрицательным margin, чтобы первый и последний
       чип не «прилипали» к краю экрана при прокрутке. */
    margin-left: -24px;
    margin-right: -24px;
    padding: 2px 24px 6px;
  }
  .ss-packs-nav::-webkit-scrollbar { display: none; }
}

/* ── @@SEC:POPULAR@@ Второй экран: популярные программы ──────────────────────
   ТЗ министра 18.08.2026: «светлый фон, фирменные шрифты, бежево-золотистые
   акценты, минимум визуального шума; карточки более премиальными и компактными,
   без ощущения каталога/интернет-магазина».
   Отсюда решения: фон секции — базовый светлый (не альтернативный, чтобы блок не
   читался вторым «полом» после сетки паков); у карточки нет рамки, только мягкая
   тень; кадр не увеличивается по наведению — карточка не должна вести себя как
   товар в выдаче. */
.ss-popular { background: var(--ss-bg); }
.ss-popular-grid { align-items: stretch; }

.ss-pop-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--ss-card);
  border-radius: 18px;
  overflow: hidden;
  /* Тень мягче, чем у плиток витрины: карточек в ряду три, и одинаковая с ними
     глубина дала бы два одинаково «тяжёлых» ряда подряд. */
  box-shadow: 0 10px 30px rgba(58, 47, 40, 0.08);
  transition: transform 0.35s ease, box-shadow 0.35s ease;
}
.ss-pop-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 18px 44px rgba(58, 47, 40, 0.14);
}
.ss-pop-card__photo {
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--ss-bg-alt);
}
.ss-pop-card__photo img { width: 100%; height: 100%; object-fit: cover; display: block; }

.ss-pop-card__body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  padding: 26px 28px 28px;
}
.ss-pop-card__over {
  margin: 0;
  font-family: 'Manrope', sans-serif;
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ss-copper);
}
.ss-pop-card__title {
  margin: 4px 0 0;
  font-size: clamp(22px, 1.6vw, 26px);
  line-height: 1.15;
  color: var(--ss-text);
}
.ss-pop-card__title a { color: inherit; text-decoration: none; transition: color 0.2s ease; }
.ss-pop-card__title a:hover { color: var(--ss-terracotta); }

/* Линейка под названием — она есть на макете и делает ровно одну работу:
   отделяет «что это» от «что внутри». */
.ss-pop-card__dur {
  margin: 16px 0 0;
  padding-top: 16px;
  border-top: 1px solid var(--ss-divider);
  font-family: 'Manrope', sans-serif;
  font-size: 14px;
  font-weight: 600;
  color: var(--ss-text);
}
.ss-pop-card__list {
  margin: 12px 0 0;
  padding: 0;
  list-style: none;
  font-family: 'Manrope', sans-serif;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ss-text-muted);
}
.ss-pop-card__list li { position: relative; padding-left: 16px; }
.ss-pop-card__list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 0.62em;
  width: 5px;
  height: 5px;
  border-radius: 50%;
  background: var(--ss-copper);
  opacity: 0.7;
}
.ss-pop-card__more { font-style: italic; opacity: 0.75; }

/* Подвал карточки прижат вниз: у программ разное число пунктов, и без этого
   цена с кнопкой скакали бы по высоте от карточки к карточке. */
.ss-pop-card__foot { margin-top: auto; padding-top: 20px; }
.ss-pop-card__price {
  margin: 0 0 14px;
  font-family: 'Manrope', sans-serif;
  font-size: 20px;
  font-weight: 700;
  color: var(--ss-text);
}
.ss-pop-card__actions {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(130px, 1fr));
  gap: 10px;
}
.ss-pop-card__cta { width: 100%; justify-content: center; gap: 8px; }

/* Promotion with one selected program: compact full-width editorial card.
   Reduce the oversized portrait from 36% / 3:4 to 26% / 4:5 (~1.5x
   shorter on desktop); details stay to the right. Two/three cards and
   all other pages keep the established layout. */
.ss-pop-card--promo-wide {
  flex-direction: row;
  align-items: stretch;
}
.ss-pop-card--promo-wide .ss-pop-card__photo {
  flex: 0 0 26%;
  width: 26%;
  aspect-ratio: 4 / 5;
}
.ss-pop-card--promo-wide .ss-pop-card__body {
  min-width: 0;
  padding: clamp(24px, 3vw, 40px);
}
@media (max-width: 767.98px) {
  .ss-pop-card--promo-wide { flex-direction: column; }
  .ss-pop-card--promo-wide .ss-pop-card__photo {
    flex: none;
    width: 100%;
    aspect-ratio: 4 / 3;
  }
  .ss-pop-card--promo-wide .ss-pop-card__body { padding: 22px 22px 24px; }
}


.ss-popular-all { gap: 8px; }

/* ── Полоса «Не можете выбрать?» ─────────────────────────────────────────────
   Тише карточек над ней: без тени, на альтернативном фоне, с тонкой рамкой. */
.ss-pop-help {
  display: flex;
  align-items: center;
  gap: 24px;
  margin-top: 56px;
  padding: 24px 32px;
  background: var(--ss-bg-alt);
  border: 1px solid var(--ss-divider);
  border-radius: 16px;
}
.ss-pop-help__icon {
  flex: none;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  background: var(--ss-card);
  color: var(--ss-copper);
}
.ss-pop-help__text { flex: 1 1 auto; min-width: 0; }
.ss-pop-help__title {
  margin: 0;
  font-family: 'Cormorant Garamond', serif;
  font-size: 22px;
  color: var(--ss-text);
}
.ss-pop-help__lede {
  margin: 4px 0 0;
  font-family: 'Manrope', sans-serif;
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text-muted);
}
.ss-pop-help__btn { flex: none; gap: 8px; }

@media (max-width: 767.98px) {
  .ss-pop-help {
    flex-direction: column;
    align-items: flex-start;
    text-align: left;
    padding: 24px;
  }
  .ss-pop-help__btn { width: 100%; justify-content: center; }
  .ss-pop-card__body { padding: 22px 22px 24px; }
}

/* ── @@SEC:PROMO@@ Третий экран: акции и специальные предложения ─────────────
   ТЗ министра 18.08.2026: «светлый фон, фирменные шрифты, бежево-золотистые
   акценты». Блок стоит и на витрине /spa/, и на главной, поэтому фон задан
   здесь, а не инлайном страницы. */
.ss-promo { background: var(--ss-bg-alt); }

/* Шапка блока — светлая полоса с рисунком справа (как на макете). Рисунок тот же
   inline-SVG, что в шапке раздела; ему здесь нужны свои размеры и своё поле. */
.ss-promo-head {
  position: relative;
  overflow: hidden;
  border-radius: 20px;
  background: var(--ss-card);
  padding: 44px clamp(24px, 3vw, 56px);
  margin-bottom: 40px;
}
.ss-promo-head__text { position: relative; z-index: 1; max-width: 56%; }
.ss-promo-head .ss-spa-hero__decor {
  right: -20px;
  width: min(38vw, 460px);
  transform: translateY(-50%);
  opacity: 0.9;
}
/* Ниже lg рисунка нет (общее правило декора), и текст занимает всю ширину. */
@media (max-width: 991.98px) {
  .ss-promo-head { padding: 32px 24px; }
  .ss-promo-head__text { max-width: none; }
}
/* Разделитель в шапке блока прижат влево — заголовок здесь не по центру секции. */
.ss-promo-head .ss-lede { max-width: 44ch; }

.ss-promo-card {
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--ss-card);
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 0 8px 24px rgba(58, 47, 40, 0.07);
  transition: transform 0.35s ease, box-shadow 0.35s ease;
}
.ss-promo-card:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 38px rgba(58, 47, 40, 0.13);
}
/* ⚠️ Кадр 9:16 — ВЕРТИКАЛЬНЫЙ, и это следствие данных, а не вкуса.
   До 17.09.2026 здесь стояло 2:1 под рекламные баннеры 800×400 с текстом внутри
   (кроп срезал им бока, и на карточке читалось «ФИКАТ SPA» — снимок 18.08.2026).
   17.09.2026 заказчик заменил материал: все четыре активные акции — 1080×1920,
   ровно 9:16, формат сторис. В рамке 2:1 от постера было видно 28% высоты,
   растянутых вдвое (замер браузером: рамка 443×221, файл 225×400).
   ⛔ object-fit: CONTAIN, а не cover. Для 9:16 в рамке 9:16 разницы нет вовсе —
   она появляется, когда заказчик вернёт горизонтальный баннер: contain положит
   его с полями, cover срежет. Дефект 18.08 повторяться не должен ни в одну,
   ни в другую сторону. Совпадение кадра с материалом стережёт checkup.sh §W2г. */
.ss-promo-card__photo {
  position: relative;
  display: block;
  aspect-ratio: 9 / 16;
  overflow: hidden;
  background: var(--ss-bg-alt);
}
.ss-promo-card__photo img { width: 100%; height: 100%; object-fit: contain; display: block; }

/* Тот же постер в списке на /aktsii/: класс общий с паками (`ss-pack-card`),
   поэтому пропорция ставится модификатором, а не правкой общего правила —
   у паков кадр 3/4 и своя вёрстка, ломать её нечем. */
.ss-pack-card__photo.ss-promo-poster { aspect-ratio: 9 / 16; }
.ss-pack-card__photo.ss-promo-poster > img { object-fit: contain; background: var(--ss-bg-alt); }
.ss-pack-card:hover .ss-pack-card__photo.ss-promo-poster img { transform: none; }

/* ⚠️ На телефоне постер в один столбец (col-12) вытягивался почти на весь экран:
   замер 05.10.2026 на /aktsii/ при ширине 390 — рамка 9:16 давала фото 604px,
   вместе с описанием 166px карточка выходила 773px, то есть выше вьюпорта
   телефона, и текст уезжал за экран. Даём рамке поля по бокам: фото становится
   УЖЕ карточки, и высота падает пропорционально (пропорция 9:16 не меняется,
   постер остаётся целым — object-fit: contain, без кропа надписей). Запрос
   заказчика 05.10.2026. Только <576px: на col-sm-6 карточка вдвое уже и так. */
@media (max-width: 575.98px) {
  .ss-pack-card__photo.ss-promo-poster {
    width: 76%;
    margin: 0 auto;
  }
}

/* Акцентный бейдж со скидкой. Круг, медная заливка, светлый текст — «бежево-
   золотистый акцент» из ТЗ. ⚠️ Рисуется только когда у акции заполнено свойство
   DISCOUNT: процент, которого салон не объявлял, это обещание, а не оформление
   (разбор — в шапке blocks/promo/block.php). */
.ss-promo-card__badge {
  position: absolute;
  left: 16px;
  top: 16px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 56px;
  height: 56px;
  padding: 0 10px;
  border-radius: 999px;
  background: var(--ss-copper);
  color: #FFF6E8;
  font-family: 'Manrope', sans-serif;
  font-size: 15px;
  font-weight: 700;
  line-height: 1.05;
  text-align: center;
  box-shadow: 0 6px 18px rgba(26, 20, 18, 0.24);
}

.ss-promo-card__body {
  display: flex;
  flex-direction: column;
  flex: 1 1 auto;
  padding: 22px 24px 24px;
}
.ss-promo-card__title { margin: 0; font-size: 21px; line-height: 1.2; }
.ss-promo-card__title a { color: var(--ss-text); text-decoration: none; transition: color 0.2s ease; }
.ss-promo-card__title a:hover { color: var(--ss-terracotta); }
.ss-promo-card__text {
  margin: 10px 0 0;
  font-family: 'Manrope', sans-serif;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ss-text-muted);
}
/* Подвал прижат вниз: описания у акций разной длины, иначе «Подробнее» скакало
   бы по высоте от карточки к карточке. */
.ss-promo-card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: auto;
  padding-top: 18px;
  border-top: 1px solid var(--ss-divider);
}
.ss-promo-card__terms {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  font-family: 'Manrope', sans-serif;
  font-size: 12.5px;
  color: var(--ss-text-muted);
  min-width: 0;
}
.ss-promo-card__terms svg { flex: none; opacity: 0.7; }
.ss-promo-card__more {
  font-family: 'Manrope', sans-serif;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ss-terracotta);
  text-decoration: none;
  white-space: nowrap;
}
.ss-promo-card__more:hover { color: var(--ss-accent); }
.ss-promo-all { gap: 8px; }

/* ─────────────────────────────────────────────────────────────────────────────
   @@SEC:RULES@@ Четвёртый экран витрины: правила бронирования
   ТЗ министра 18.08.2026 «4 ЭКРАН ПРАВИЛА БРОНИРОВАНИЯ (ДОБАВИТЬ)»: отдельный
   спокойный информационный блок БЕЗ ИЗОБРАЖЕНИЙ, аккордеон «вопрос → ответ»,
   первый пункт открыт, вопросы крупно и лаконично, раскрытие плавное.
   ───────────────────────────────────────────────────────────────────────────── */
.ss-rules-panel {
  padding: 48px;
  border-radius: 24px;
  background: var(--ss-bg-alt);
  border: 1px solid var(--ss-divider);
}

.ss-rules-list { display: flex; flex-direction: column; gap: 12px; }

.ss-rule {
  padding: 0 24px;
  background: var(--ss-card);
  border: 1px solid var(--ss-divider);
  border-radius: 14px;
  transition: border-color 0.2s;
}
.ss-rule[open] { border-color: var(--ss-amber); }

/* Вопрос. list-style:none + ::-webkit-details-marker — убрать стандартный
   треугольник <summary>; свой значок рисуется псевдоэлементами (см. ниже).
   min-height 44px — палец, а не курсор: строка аккордеона это кнопка. */
.ss-rule__q {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  min-height: 44px;
  padding: 20px 0;
  margin: 0;
  list-style: none;
  cursor: pointer;
  font-family: 'Cormorant Garamond', serif;
  font-size: 22px;
  line-height: 1.3;
  color: var(--ss-text);
  transition: color 0.2s;
}
.ss-rule__q::-webkit-details-marker { display: none; }
.ss-rule__q:hover { color: var(--ss-accent); }

/* Значок «плюс → минус»: вертикальная палочка доворачивается и гаснет. */
.ss-rule__icon { position: relative; flex: none; width: 20px; height: 20px; color: var(--ss-copper); }
.ss-rule__icon::before,
.ss-rule__icon::after {
  content: '';
  position: absolute;
  left: 50%;
  top: 50%;
  background: currentColor;
  transform: translate(-50%, -50%);
  transition: transform 0.28s ease, opacity 0.28s ease;
}
.ss-rule__icon::before { width: 16px; height: 1.5px; }
.ss-rule__icon::after  { width: 1.5px; height: 16px; }
.ss-rule[open] .ss-rule__icon::after { transform: translate(-50%, -50%) rotate(90deg); opacity: 0; }

.ss-rule__a { padding: 0 0 20px; }
.ss-rule__a p {
  margin: 0;
  max-width: 62ch;
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text-muted);
}

/* ⚠️ ПЛАВНОСТЬ — ПРОГРЕССИВНОЕ УЛУЧШЕНИЕ, А НЕ УСЛОВИЕ РАБОТЫ.
   Аккордеон построен на <details>: он открывается силами браузера, без JS, и
   потому условия бронирования доступны даже при упавшем скрипте. Анимация
   высоты добавлена сверху через ::details-content + interpolate-size. Браузер,
   который их не знает, отбросит эти правила целиком и раскроет мгновенно —
   потеряется анимация, а не текст (инвариант SPEC-07). */
.ss-rules-list { interpolate-size: allow-keywords; }
.ss-rule::details-content {
  block-size: 0;
  overflow: hidden;
  transition: block-size 0.3s ease, content-visibility 0.3s allow-discrete;
}
.ss-rule[open]::details-content { block-size: auto; }

@media (prefers-reduced-motion: reduce) {
  .ss-rule::details-content { transition: none; }
  .ss-rule__icon::before, .ss-rule__icon::after { transition: none; }
}

/* Полоса под аккордеоном: тихая строка слева, СТА справа. */
.ss-rules-foot {
  display: flex;
  align-items: center;
  gap: 16px;
  margin-top: 32px;
  padding: 18px 24px;
  background: var(--ss-card);
  border: 1px solid var(--ss-divider);
  border-radius: 14px;
}
.ss-rules-foot__icon { flex: none; display: inline-flex; color: var(--ss-copper); }
.ss-rules-foot__text { flex: 1 1 auto; min-width: 0; }
.ss-rules-foot__lede { margin: 0; font-size: 14px; line-height: 1.5; color: var(--ss-text-muted); }
.ss-rules-foot__cta {
  flex: none;
  display: inline-flex;
  align-items: center;
  gap: 8px;
  font-size: 14px;
  font-weight: 600;
  color: var(--ss-accent);
  text-decoration: none;
  transition: color 0.2s, gap 0.2s;
}
.ss-rules-foot__cta:hover { color: var(--ss-amber); gap: 12px; }

@media (max-width: 991.98px) {
  .ss-rules-panel { padding: 32px 24px; }
}
@media (max-width: 767.98px) {
  .ss-rules-panel { padding: 24px 16px; border-radius: 18px; }
  .ss-rule { padding: 0 18px; }
  .ss-rule__q { font-size: 19px; padding: 16px 0; }
  .ss-rules-foot { flex-direction: column; align-items: flex-start; padding: 18px; }
  .ss-rules-foot__cta { width: 100%; }
}

/* ─────────────────────────────────────────────────────────────────────────────
   @@SEC:CTABAND@@ Пятый экран витрины: полоса «Время выбрать себя»
   ТЗ министра 18.08.2026 «5 ЭКРАН»: широкая тёмная полоса, кадр справа, текст
   слева, кнопка «Подобрать программу →».
   ───────────────────────────────────────────────────────────────────────────── */
.ss-cta-band {
  position: relative;
  overflow: hidden;
  border-radius: 20px;
  background: var(--ss-dark-panel);
  min-height: 280px;
  display: flex;
  align-items: center;
}
/* Кадр занимает правую половину и гаснет к тексту. Именно градиент, а не
   прозрачность целиком: на макете справа фотография читается, слева — только
   тёмный фон, и подпись обязана лежать на ровном поле, а не на деталях снимка. */
.ss-cta-band__photo {
  position: absolute;
  inset: 0 0 0 auto;
  width: 62%;
  height: 100%;
  object-fit: cover;
  -webkit-mask-image: linear-gradient(90deg, transparent 0%, #000 42%);
          mask-image: linear-gradient(90deg, transparent 0%, #000 42%);
}
.ss-cta-band__body {
  position: relative;      /* над кадром */
  z-index: 1;
  max-width: 52%;
  padding: 48px 56px;
}
.ss-cta-band__title {
  margin: 0;
  font-size: clamp(26px, 2.4vw, 38px);
  font-weight: 500;
  line-height: 1.15;
  color: var(--ss-text-on-dark);
}
.ss-cta-band__title em { font-style: italic; }
.ss-cta-band__lede {
  margin: 12px 0 0;
  max-width: 42ch;
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: rgba(239, 232, 220, 0.78);
}
.ss-cta-band__btn { margin-top: 24px; gap: 8px; }

@media (max-width: 991.98px) {
  /* Ниже планшета кадр уходит в подложку целиком: полосой в 52% ширины текст
     на телефоне превращается в столбик по слову. */
  .ss-cta-band { min-height: 0; }
  .ss-cta-band__photo {
    width: 100%;
    -webkit-mask-image: linear-gradient(180deg, transparent 0%, #000 100%);
            mask-image: linear-gradient(180deg, transparent 0%, #000 100%);
    opacity: 0.35;
  }
  .ss-cta-band__body { max-width: 100%; padding: 32px 24px; }
  .ss-cta-band__btn { width: 100%; justify-content: center; }
}

/* ── Каталог: фильтр + сетка ── */
.ss-catalog .ss-catalog__heading { margin-bottom: 32px; }
.ss-catalog__empty { padding: 80px 0; }

/* Кнопка-свернуть фильтр (мобильный) */
.ss-filter-toggle {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 12px;
  padding: 14px 18px;
  border: 1px solid var(--ss-divider);
  border-radius: 10px;
  background: var(--ss-card);
  color: var(--ss-text);
  font-size: 14px;
  font-weight: 600;
  letter-spacing: 0.02em;
  cursor: pointer;
  margin-bottom: 16px;
  transition: border-color 0.2s;
}
.ss-filter-toggle:hover { border-color: var(--ss-amber); }
.ss-filter-toggle__badge {
  min-width: 22px;
  height: 22px;
  padding: 0 6px;
  border-radius: 11px;
  background: var(--ss-amber);
  color: var(--ss-dark-panel);
  font-size: 12px;
  font-weight: 700;
  display: inline-flex;
  align-items: center;
  justify-content: center;
}

/* Сам фильтр */
.ss-filter {
  position: sticky;
  top: calc(var(--bx-panel-h, 0px) + 96px); /* + полоса админ-панели Битрикса */
  padding: 24px 22px;
  border: 1px solid var(--ss-divider);
  border-radius: 14px;
  background: var(--ss-card);
}
.ss-filter__group { margin-bottom: 24px; }
.ss-filter__group:last-of-type { margin-bottom: 12px; }
.ss-filter__group-title {
  display: block;
  margin: 0 0 12px;
  opacity: 0.75;
}
.ss-filter__list {
  list-style: none;
  padding: 0;
  margin: 0;
  display: flex;
  flex-direction: column;
  gap: 2px;
}
.ss-filter__item {
  display: flex;
  align-items: center;
  gap: 10px;
  padding: 8px 10px;
  margin: 0 -10px;
  color: var(--ss-text);
  text-decoration: none;
  font-size: 14px;
  line-height: 1.35;
  border-radius: 8px;
  transition: background 0.15s, color 0.15s;
}
.ss-filter__item:hover {
  background: rgba(201,168,115,0.08);
  color: var(--ss-accent);
}
.ss-filter__check {
  width: 16px;
  height: 16px;
  border: 1px solid rgba(201,168,115,0.5);
  border-radius: 4px;
  flex: 0 0 auto;
  position: relative;
  transition: background 0.2s, border-color 0.2s;
}
.ss-filter__item.is-active {
  color: var(--ss-accent);
  font-weight: 600;
}
.ss-filter__item.is-active .ss-filter__check {
  background: var(--ss-amber);
  border-color: var(--ss-amber);
}
.ss-filter__item.is-active .ss-filter__check::after {
  content: '';
  position: absolute;
  left: 4px;
  top: 1px;
  width: 5px;
  height: 9px;
  border: solid var(--ss-dark-panel);
  border-width: 0 2px 2px 0;
  transform: rotate(45deg);
}
.ss-filter__reset {
  display: inline-block;
  margin-top: 8px;
  padding: 10px 16px;
  border: 1px solid var(--ss-divider);
  border-radius: 8px;
  color: var(--ss-text);
  text-decoration: none;
  font-size: 13px;
  opacity: 0.8;
  transition: all 0.2s;
}
.ss-filter__reset:hover {
  border-color: var(--ss-accent);
  color: var(--ss-accent);
  opacity: 1;
}

/* ── Конструктор: верхние кнопочные фильтры (single-select) ── */
.ss-constructor-filters .ss-chip-group {
  margin-bottom: 28px;
}
.ss-constructor-filters .ss-chip-group:last-of-type { margin-bottom: 0; }
.ss-chip-group__title {
  margin: 0 0 14px;
  opacity: 0.75;
}
.ss-chip-row {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
}
.ss-chip {
  display: inline-flex;
  align-items: center;
  padding: 10px 18px;
  border: 1px solid var(--ss-divider);
  border-radius: 999px;
  background: var(--ss-card);
  color: var(--ss-text);
  font-size: 14px;
  line-height: 1.2;
  letter-spacing: 0.01em;
  text-decoration: none;
  transition: all 0.2s;
  white-space: nowrap;
}
.ss-chip:hover {
  border-color: var(--ss-accent);
  color: var(--ss-accent);
}
.ss-chip.is-active {
  background: var(--ss-amber);
  border-color: var(--ss-amber);
  color: var(--ss-dark-panel);
  font-weight: 600;
}

/* ── Карточка программы ── */
.ss-program-card {
  position: relative;
  display: flex;
  flex-direction: column;
  height: 100%;
  background: var(--ss-card);
  border: 1px solid var(--ss-divider);
  border-radius: 14px;
  overflow: hidden;
  transition: transform 0.3s, border-color 0.3s, box-shadow 0.3s;
}
.ss-program-card:hover {
  transform: translateY(-4px);
  border-color: rgba(201,168,115,0.4);
  box-shadow: 0 18px 40px rgba(0,0,0,0.35);
}
.ss-program-card__media {
  position: relative;
  display: block;
  aspect-ratio: 4 / 3;
  overflow: hidden;
  background: var(--ss-bg-alt);
}
.ss-program-card__media img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.6s;
}
.ss-program-card:hover .ss-program-card__media img { transform: scale(1.04); }
.ss-program-card__labels {
  position: absolute;
  top: 12px;
  left: 12px;
  display: flex;
  flex-wrap: wrap;
  gap: 6px;
}
.ss-program-label {
  font-size: 11px;   /* M20-9 (12px) перенесён в @@SEC:M20-9@@ — на 1440 не должен меняться (Н-2) */
  letter-spacing: 0.12em;
  text-transform: uppercase;
  padding: 5px 10px;
  border-radius: 4px;
  background: var(--ss-amber);
  color: var(--ss-dark-panel);
  font-weight: 600;
}
.ss-program-card__body {
  padding: 22px 22px 24px;
  display: flex;
  flex-direction: column;
  flex: 1;
}
.ss-program-card__title {
  font-size: 24px;
  line-height: 1.2;
  margin: 0 0 12px;
}
.ss-program-card__title a {
  color: var(--ss-accent);
  text-decoration: none;
  transition: opacity 0.2s;
}
.ss-program-card__title a:hover { opacity: 0.85; }
.ss-program-card__text {
  font-size: 14px;
  line-height: 1.6;
  color: var(--ss-text);
  opacity: 0.85;
  margin-bottom: 18px;
}
.ss-program-card__text p { margin: 0 0 6px; }
.ss-program-card__text ul,
.ss-program-card__text ol {
  list-style: none;
  padding: 0;
  margin: 0;
}
.ss-program-card__text li {
  position: relative;
  padding-left: 18px;
  margin-bottom: 4px;
}
.ss-program-card__text li::before {
  content: '✓';
  position: absolute;
  left: 0;
  color: var(--ss-accent);
}
.ss-program-card__foot {
  margin-top: auto;
  padding-top: 16px;
  border-top: 1px solid var(--ss-divider);
}
.ss-program-card__meta {
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 12px;
  margin-bottom: 14px;
}
.ss-program-card__duration {
  font-size: 13px;
  opacity: 0.7;
}
.ss-program-card__price {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-size: 22px;
  color: var(--ss-accent);
  font-weight: 600;
}
.ss-program-card__actions {
  display: flex;
  gap: 8px;
}
.ss-program-card__actions .btn {
  flex: 1 1 auto;
  padding: 10px 14px;
  font-size: 13px;
}

/* ── Детальная программы ── */
.ss-program-hero { padding-bottom: 40px; }
.ss-program-hero__meta {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 12px;
  margin-top: 28px;
}
.ss-program-hero__chip {
  display: inline-flex;
  align-items: center;
  gap: 6px;
  padding: 8px 16px;
  border: 1px solid var(--ss-divider);
  border-radius: 999px;
  font-size: 14px;
  opacity: 0.9;
}
.ss-program-hero__price {
  font-family: 'Manrope', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 24px;
  line-height: 1.35;
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--ss-accent);
  font-weight: 600;
  margin-left: auto;
}

.ss-program-gallery {
  border-radius: 16px;
  overflow: hidden;
  background: var(--ss-bg-alt);
}
.ss-program-gallery--single img,
.ss-program-gallery__slide img {
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  display: block;
}
/* Slick-dots (без slick-theme.css) */
.ss-program-gallery .slick-dots {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 14px;
  display: flex !important;
  justify-content: center;
  gap: 8px;
  list-style: none;
  margin: 0;
  padding: 0;
  z-index: 2;
}
.ss-program-gallery .slick-dots li { margin: 0; padding: 0; }
.ss-program-gallery .slick-dots li button {
  width: 10px;
  height: 10px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(255,255,255,0.45);
  font-size: 0;
  color: transparent;
  line-height: 0;
  cursor: pointer;
  transition: background 0.2s, transform 0.2s;
}
.ss-program-gallery .slick-dots li button:hover { background: rgba(255,255,255,0.75); }
.ss-program-gallery .slick-dots li.slick-active button {
  background: var(--ss-amber);
  transform: scale(1.2);
}

.ss-gallery-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 2;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  background: rgba(0,0,0,0.55);
  color: #fff;
  border: 0;
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  opacity: 0;
  transition: opacity 0.2s, background 0.2s;
}
.ss-program-gallery:hover .ss-gallery-arrow { opacity: 1; }
.ss-gallery-arrow:hover { background: rgba(0,0,0,0.85); }
.ss-gallery-arrow--prev { left: 16px; }
.ss-gallery-arrow--next { right: 16px; }

/* Карточка бронирования */
.ss-booking-card {
  position: sticky;
  top: calc(var(--bx-panel-h, 0px) + 96px); /* + полоса админ-панели Битрикса */
  padding: 28px 28px 24px;
  border: 1px solid var(--ss-divider);
  border-radius: 16px;
  background: var(--ss-card);
}
.ss-booking-card__title {
  font-size: 26px;
  line-height: 1.2;
  margin: 0 0 20px;
  color: var(--ss-accent);
}
.ss-booking-card__meta {
  display: grid;
  grid-template-columns: 1fr auto;
  gap: 12px 20px;
  padding: 16px 0;
  border-top: 1px solid var(--ss-divider);
  border-bottom: 1px solid var(--ss-divider);
  margin-bottom: 20px;
}
.ss-booking-card__label {
  margin: 0 0 4px;
  font-size: 12px;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  opacity: 0.6;
}
.ss-booking-card__val {
  margin: 0;
  font-size: 16px;
  font-weight: 500;
}
.ss-booking-card__price {
  margin: 0;
  font-family: 'Manrope', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 22px;
  font-weight: 600;
  font-variant-numeric: lining-nums tabular-nums;
  color: var(--ss-accent);
  text-align: right;
  line-height: 1.35;
}
.ss-booking-card__actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-bottom: 20px;
}
.ss-booking-card__phone a {
  display: inline-block;
  margin-top: 4px;
  font-family: 'Manrope', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 19px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.45;
  color: var(--ss-accent);
  text-decoration: none;
}

/* Описание */
/* Проза программ — общая гарнитура основного текста с настоящим жирным начертанием.
   Декоративный ss-serif оставляем заголовкам, а не длинному тексту и <strong>. */
.ss-program-desc {
  font-family: var(--ss-copy-font);
  font-size: var(--ss-copy-size);
  font-weight: 400;
  line-height: var(--ss-copy-leading);
  letter-spacing: normal;
  color: var(--ss-text);
}
/* Контент из редактора не возвращает декоративную гарнитуру и чужие кегли. */
.ss-program-desc :where(p, div, ul, ol, li, span, strong, b, em, i, font) {
  font-family: inherit !important;
  font-size: inherit !important;
  line-height: inherit !important;
}
.ss-program-desc strong,
.ss-program-desc b {
  font-weight: 700;
  color: var(--ss-text);
}
.ss-program-desc p { margin: 0 0 16px; }
.ss-program-desc h2,
.ss-program-desc h3 {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-size: 26px;
  color: var(--ss-accent);
  margin: 28px 0 14px;
  font-style: italic;
}
.ss-program-desc ul,
.ss-program-desc ol {
  padding-left: 0;
  list-style: none;
}
.ss-program-desc li {
  position: relative;
  padding-left: 22px;
  margin-bottom: 8px;
}
.ss-program-desc ul li::before {
  content: '✓';
  position: absolute;
  left: 0;
  color: var(--ss-accent);
}
.ss-program-desc ol { counter-reset: desc; }
.ss-program-desc ol li {
  counter-increment: desc;
  padding-left: 32px;
}
.ss-program-desc ol li::before {
  content: counter(desc, decimal-leading-zero);
  position: absolute;
  left: 0;
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-style: italic;
  color: var(--ss-accent);
  font-size: 18px;
}

/* ── Dark-overlay секции: общий цвет текста (hero, final-cta, опциональный --dark модификатор) ── */
.ss-hero,
.ss-hero h1,
.ss-hero p,
.ss-banya-detail-hero,
.ss-banya-detail-hero .ss-breadcrumbs,
.ss-banya-detail-hero .ss-breadcrumbs a,
.ss-banya-detail-hero h1,
.ss-banya-detail-hero p,
.ss-banya-final-cta,
.ss-banya-final-cta p,
.ss-banya-final-cta h2,
.ss-section--dark,
.ss-section--dark h1,
.ss-section--dark h2,
.ss-section--dark h3,
.ss-section--dark h4,
.ss-section--dark p,
.ss-section--dark .ss-overline,
.ss-section--dark .ss-lede,
.ss-section--dark .ss-title-section {
  color: var(--ss-text-on-dark);
}

/* В тёмных секциях акцент возвращается к ярко-золотому amber. */
.ss-hero,
.ss-banya-detail-hero,
.ss-banya-final-cta,
.ss-section--dark,
.ss-tour-panel,
.ss-footer,
.ss-cert-preview,
.ss-banya-card,
.ss-tile,
.ss-stories-modal {
  --ss-accent: var(--ss-amber);
}
.ss-banya-detail-hero .ss-breadcrumbs a:hover { color: var(--ss-amber); }

/* ⛔ Кнопка-контур на ТЁМНОЙ ПОВЕРХНОСТИ при СВЕТЛОЙ теме документа.
   `.btn-ss-outline` берёт `color: var(--ss-text)` (#3A2F28) и рисует рамку тем же
   currentColor. Пока /banya* стоял под data-theme="dark", амбровый вариант давало
   правило `[data-theme="dark"] .btn-ss-outline`. 01.09.2026 тёмную тему сняли
   (SPEC-08), тёмное стало ОСТРОВАМИ на светлой странице — и «Все бани» в блоке
   «Ещё N миров» вместе с телефоном в финальном СТА оказались #3A2F28 на #2A2420
   и на затемнённом фото: ровно класс дефекта «невидимые кнопки» из
   docs/CHECKLIST.md («btn-ss-ghost — только на тёмном»), только с другой стороны.
   Поэтому амбровый вариант привязан к тёмной ПОВЕРХНОСТИ, а не к теме документа.
   Токен --ss-accent на этих поверхностях уже = amber (правило выше), берём его. */
/* ⛔ `.ss-serif` на ТЁМНОЙ ПОВЕРХНОСТИ. Группа `h1…h5, .ss-serif` в начале файла
   ставит `color: var(--ss-text)` (#3A2F28) ЯВНО, а значит перебивает наследование
   от `.ss-footer { color: var(--ss-text-on-dark) }` — и абзац «СПА-центр в
   Санкт-Петербурге» в подвале рисовался #3A2F28 на #3A2F28: контраст 1.00,
   строка невидима буква в букву. На /banya* это пряталось за тёмной темой
   (там --ss-text светлый) и вылезло ровно в тот момент, когда тему сняли
   (SPEC-08, 01.09.2026); на остальных 270 страницах строка была невидима и до
   этого. Найдено машинным аудитом контраста, не глазами: 1.00 — это ноль
   пикселей разницы, глаз такое не «замечает», он просто не видит текста. */
.ss-hero .ss-serif,
.ss-banya-detail-hero .ss-serif,
.ss-banya-final-cta .ss-serif,
.ss-section--dark .ss-serif,
.ss-footer .ss-serif {
  color: var(--ss-text-on-dark);
}

.ss-hero .btn-ss-outline,
.ss-banya-detail-hero .btn-ss-outline,
.ss-banya-final-cta .btn-ss-outline,
.ss-section--dark .btn-ss-outline,
.ss-tour-panel .btn-ss-outline,
.ss-footer .btn-ss-outline {
  color: var(--ss-amber);
}
.ss-hero .btn-ss-outline:hover,
.ss-banya-detail-hero .btn-ss-outline:hover,
.ss-banya-final-cta .btn-ss-outline:hover,
.ss-section--dark .btn-ss-outline:hover,
.ss-tour-panel .btn-ss-outline:hover,
.ss-footer .btn-ss-outline:hover {
  background: var(--ss-amber);
  color: var(--ss-dark-panel);
}

/* Dark-секция: цвет ss-overline и muted подсветки — чуть светлее основного */
.ss-section--dark .ss-overline { color: var(--ss-amber); }
.ss-section--dark .ss-muted { color: rgba(239,232,220,0.7); }

/* ── Banya detail page ── */
.ss-banya-detail-hero {
  min-height: 90vh;
  background-size: cover;
  background-position: center;
  background-color: #1a1412;
  position: relative;
}
.ss-banya-detail-hero .ss-hero-bg-dim {
  position: absolute; inset: 0;
  background: linear-gradient(180deg, rgba(26,20,18,0.55) 0%, rgba(26,20,18,0.88) 100%);
  z-index: 0;
}
.ss-banya-detail-hero .ss-hero-content { position: relative; z-index: 1; }

.ss-banya-legend__photo img,
.ss-banya-legend__photo .ss-img-placeholder {
  width: 100%;
  aspect-ratio: 4/5;
  object-fit: cover;
  border-radius: 10px;
  display: block;
}
@media (min-width: 992px) {
  .ss-banya-legend__photo {
    position: sticky;
    top: calc(var(--bx-panel-h, 0px) + 100px); /* + полоса админ-панели Битрикса */
  }
}

.ss-banya-legend {
  font-family: var(--ss-copy-font);
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  font-weight: 400;
}
.ss-banya-legend :where(p, div, ul, ol, li, span, strong, b, em, i, font) {
  font-family: inherit !important;
  font-size: inherit !important;
  line-height: inherit !important;
}
.ss-banya-legend p { font-size: inherit; line-height: inherit; color: var(--ss-text); margin-bottom: 18px; }
.ss-banya-legend blockquote {
  font-style: italic;
  color: var(--ss-accent);
  font-size: 24px;
  line-height: 1.4;
  border: 0;
  margin: 32px 0 8px;
  padding: 0;
}

.ss-feature-card {
  background: var(--ss-card);
  border-radius: 10px;
  overflow: hidden;
  transition: transform 0.3s ease;
  height: 100%;
}
.ss-feature-card:hover { transform: translateY(-4px); }
.ss-feature-card__photo { aspect-ratio: 3/4; }
.ss-feature-card__body { padding: 20px 22px; }

/* Текст ритуала бани — обычный текст, не декоративный подзаголовок. */
.ss-timeline-step__text {
  font-family: var(--ss-copy-font);
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
}
.ss-timeline-step {
  position: relative;
  padding-left: 90px;
  padding-bottom: 40px;
}
.ss-timeline-step::before {
  content: '';
  position: absolute;
  left: 33px;
  top: 52px;
  bottom: 0;
  width: 1px;
  background: rgba(201, 168, 115, 0.3);
}
.ss-timeline-step:last-child::before { display: none; }
.ss-timeline-num {
  position: absolute;
  left: 0;
  top: 0;
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-style: italic;
  font-size: 44px;
  color: var(--ss-accent);
  line-height: 1;
  width: 66px;
  text-align: right;
}

.ss-price-table {
  border-collapse: separate;
  border-spacing: 0;
  width: 100%;
}
.ss-price-table th,
.ss-price-table td {
  padding: 16px 14px;
  border-bottom: 1px solid var(--ss-divider);
  text-align: left;
  font-size: 15px;
}
.ss-price-table th {
  font-family: 'Manrope', sans-serif;
  font-weight: 500;
  font-size: 12px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ss-accent);
}
.ss-price-table td.price {
  font-family: 'Manrope', sans-serif;
  font-weight: 500;
  color: var(--ss-accent);
}

.ss-check-list { list-style: none; padding: 0; margin: 0; }
.ss-check-list li {
  padding: 10px 0 10px 32px;
  position: relative;
  font-size: 15px;
}
.ss-check-list li::before {
  content: '';
  position: absolute;
  left: 0;
  top: 15px;
  width: 16px;
  height: 1px;
  background: var(--ss-amber);
}

.ss-banya-final-cta {
  position: relative;
  padding: clamp(60px, 6.5vw, 96px) 0;
  overflow: hidden;
}
.ss-banya-final-cta__bg { position: absolute; inset: 0; z-index: 0; }
.ss-banya-final-cta__bg img {
  width: 100%; height: 100%;
  object-fit: cover;
  display: block;
}
.ss-banya-final-cta__dim {
  position: absolute;
  inset: 0;
  background: linear-gradient(180deg, rgba(26,20,18,0.75) 0%, rgba(26,20,18,0.92) 100%);
}

/* ── Reviews: сканы ── */
.ss-reviews-scans {
  display: grid;
  grid-template-columns: repeat(4, 1fr);
  gap: 16px;
}
.ss-reviews-scans__item {
  display: block;
  aspect-ratio: 3/4;
  overflow: hidden;
  border-radius: 8px;
  background: var(--ss-card);
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.ss-reviews-scans__item.is-hidden { display: none; }
.ss-reviews-scans__item img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
  transition: transform 0.4s ease;
}
.ss-reviews-scans__item:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 36px rgba(0,0,0,0.35);
}
.ss-reviews-scans__item:hover img { transform: scale(1.05); }
@media (max-width: 991px) { .ss-reviews-scans { grid-template-columns: repeat(3, 1fr); } }
@media (max-width: 575px) { .ss-reviews-scans { grid-template-columns: repeat(2, 1fr); gap: 10px; } }

/* ── Reviews: виджеты ── */
.ss-reviews-widget {
  background: var(--ss-card);
  border-radius: 14px;
  padding: 28px;
  min-height: 240px;
}

/* ── Certificate configurator ── */
.ss-cert-group { margin-bottom: 36px; }
.ss-cert-group .ss-overline { margin-bottom: 14px; display: block; }

.ss-cert-tabs {
  display: inline-flex;
  background: var(--ss-card);
  border-radius: 10px;
  padding: 4px;
  gap: 4px;
}
.ss-cert-tab {
  margin: 0;
  cursor: pointer;
  display: inline-flex;
}
.ss-cert-tab input { position: absolute; opacity: 0; pointer-events: none; }
.ss-cert-tab span {
  display: block;
  padding: 12px 22px;
  border-radius: 8px;
  font-size: 14px;
  color: var(--ss-text);
  transition: background 0.2s, color 0.2s;
}
.ss-cert-tab input:checked + span {
  background: var(--ss-amber);
  color: #1a1412;
  font-weight: 500;
}
.ss-cert-tab--inline {
  background: transparent;
  padding: 0;
}
.ss-cert-tab--inline span { padding: 10px 18px; border: 1px solid var(--ss-divider); }
.ss-cert-custom {
  display: grid;
  grid-template-columns: max-content minmax(220px, 360px);
  align-items: center;
  gap: 10px;
}
.ss-cert-custom .ss-input { width: 100%; min-width: 0; }
.ss-input.is-invalid {
  border-color: var(--ss-terracotta);
  box-shadow: 0 0 0 2px rgba(217, 120, 74, 0.12);
}
.ss-cert-custom__hint {
  grid-column: 2;
  color: var(--ss-text-muted);
  font-size: 12px;
  line-height: 1.4;
}
@media (max-width: 575.98px) {
  .ss-cert-custom { grid-template-columns: 1fr; align-items: stretch; }
  .ss-cert-custom .ss-cert-tab { justify-self: start; }
  .ss-cert-custom__hint { grid-column: 1; }
}

.ss-cert-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.ss-cert-chip {
  margin: 0;
  cursor: pointer;
  position: relative;
}
.ss-cert-chip input { position: absolute; opacity: 0; pointer-events: none; }
.ss-cert-chip span {
  display: block;
  padding: 14px 22px;
  border-radius: 10px;
  font-size: 15px;
  color: var(--ss-text);
  border: 1px solid var(--ss-divider);
  background: var(--ss-card);
  font-family: 'Manrope', sans-serif;
  font-weight: 500;
  transition: all 0.2s;
}
.ss-cert-chip:hover span { border-color: var(--ss-amber); }
.ss-cert-chip input:checked + span {
  background: var(--ss-amber);
  color: #1a1412;
  border-color: var(--ss-amber);
}

.ss-cert-card {
  display: block;
  margin: 0;
  cursor: pointer;
  background: var(--ss-card);
  border: 1px solid var(--ss-divider);
  border-radius: 12px;
  overflow: hidden;
  transition: all 0.2s ease;
  height: 100%;
  position: relative;
}
.ss-cert-card input { position: absolute; opacity: 0; pointer-events: none; }
.ss-cert-card:hover { transform: translateY(-2px); border-color: var(--ss-amber); }
.ss-cert-card__photo { aspect-ratio: 1/1; }
.ss-cert-card__photo--image {
  display: flex;
  align-items: center;
  justify-content: center;
  background: var(--ss-bg-alt);
  border-bottom: 1px solid var(--ss-divider);
}
.ss-cert-card__photo--image img {
  display: block;
  width: 100%;
  height: 100%;
  object-fit: contain;
}
.ss-cert-card__body { padding: 14px 16px; }

/* A6: карточки конструктора без фото — иконка на фактурной подложке.
   Реальных фото упаковки/допов у заказчика нет, полосатый плейсхолдер на
   боевой странице выглядел незаконченной вёрсткой. */
.ss-cert-icon {
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(circle at 50% 42%, rgba(201,168,115,0.16) 0%, rgba(201,168,115,0) 62%),
    linear-gradient(160deg, #2c2420 0%, #1d1815 100%);
  color: var(--ss-amber);
  border-bottom: 1px solid var(--ss-divider);
  transition: color 0.25s ease;
}
.ss-cert-icon__svg {
  width: 42%; max-width: 76px; height: auto; display: block;
  transition: transform 0.35s ease;
}
.ss-cert-card:hover .ss-cert-icon__svg { transform: scale(1.06); }
.ss-cert-card:has(input:checked) .ss-cert-icon { color: #E8CFA2; }
.ss-cert-card__title { font-size: 14px; margin: 0 0 4px; color: var(--ss-text); }
/* ⚠️ На телефоне карточка — строкой: иконка слева, подпись справа. Причина в
   двух шагах (02.09.2026). Сначала карточки шли по две в ряд, и подпись
   «Стандартная упаковка» ломалась по слову в колонке 94px. Развели по одной в
   ряд — и квадратная иконка 1:1 растянулась на всю ширину: выбор из двух
   упаковок занял два экрана. Строкой обе беды закрыты сразу, и колонка текста
   остаётся широкой. */
@media (max-width: 575.98px) {
  .ss-cert-card { display: flex; align-items: center; }
  .ss-cert-card .ss-cert-icon,
  .ss-cert-card__photo { flex: 0 0 104px; width: 104px; aspect-ratio: 1/1; }
  .ss-cert-card__body { flex: 1 1 auto; padding: 12px 14px; }
}
.ss-cert-card__note { font-size: 12px; margin: 0; color: var(--ss-text-muted); }
.ss-cert-card input:checked ~ .ss-cert-card__body,
.ss-cert-card:has(input:checked) {
  border-color: var(--ss-amber);
  box-shadow: 0 0 0 2px var(--ss-amber), 0 8px 22px rgba(0,0,0,0.3);
}
.ss-cert-card:has(input:checked)::after {
  content: '✓';
  position: absolute;
  top: 10px; right: 10px;
  width: 28px; height: 28px;
  background: var(--ss-amber);
  color: #1a1412;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 14px;
  font-weight: 600;
  z-index: 2;
}

.ss-cert-summary {
  background: var(--ss-card);
  border-radius: 16px;
  padding: 28px;
  position: sticky;
  top: calc(var(--bx-panel-h, 0px) + 100px); /* + полоса админ-панели Битрикса */
}
.ss-cert-summary__items {
  list-style: none;
  padding: 0;
  margin: 0 0 18px;
}
.ss-cert-summary__items li {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 10px 0;
  border-bottom: 1px solid var(--ss-divider);
  gap: 12px;
  font-size: 14px;
}
.ss-cert-summary__items li span { color: var(--ss-text); }
.ss-cert-summary__items li strong { font-family: 'Manrope', sans-serif; font-weight: 500; white-space: nowrap; }
.ss-cert-summary__delivery {
  display: flex;
  justify-content: space-between;
  padding: 10px 0;
  font-size: 14px;
  color: var(--ss-text-muted);
}
.ss-cert-summary__delivery strong { color: var(--ss-text); font-family: 'Manrope', sans-serif; font-weight: 500; }
.ss-cert-summary__total {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  padding: 18px 0;
  border-top: 1px solid var(--ss-divider);
  margin-top: 8px;
}
.ss-cert-summary__total span {
  font-size: 13px;
  letter-spacing: 0.12em;
  text-transform: uppercase;
  color: var(--ss-text-muted);
}
.ss-cert-summary__total strong {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-style: italic;
  font-size: 32px;
  color: var(--ss-accent);
  line-height: 1;
}
.ss-cert-summary__agree {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  font-size: 12px;
  color: var(--ss-text-muted);
  line-height: 1.5;
  margin-top: 10px;
  cursor: pointer;
}
.ss-cert-summary__agree a { color: var(--ss-accent); text-decoration: underline; }

/* ── Certificate preset cards ── */
.ss-cert-preset {
  background: var(--ss-card);
  border-radius: 14px;
  overflow: hidden;
  height: 100%;
  display: flex;
  flex-direction: column;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.ss-cert-preset:hover {
  transform: translateY(-4px);
  box-shadow: 0 16px 36px rgba(0,0,0,0.35);
}
.ss-cert-preset__photo { aspect-ratio: 4/3; }
.ss-cert-preset__body { padding: 22px 24px 24px; display: flex; flex-direction: column; flex: 1; }
.ss-cert-preset__buy { margin-top: auto; align-self: flex-start; }

/* ── FAQ ── */
.ss-faq { margin: 0; }
.ss-faq__item {
  border-bottom: 1px solid var(--ss-divider);
  padding: 4px 0;
}
.ss-faq__item[open] { padding-bottom: 8px; }
.ss-faq__q {
  display: flex;
  justify-content: space-between;
  align-items: center;
  gap: 16px;
  padding: 20px 4px;
  cursor: pointer;
  list-style: none;
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-style: italic;
  font-size: 22px;
  color: var(--ss-text);
  transition: color 0.2s;
}
.ss-faq__q::-webkit-details-marker { display: none; }
.ss-faq__q:hover { color: var(--ss-accent); }
.ss-faq__icon {
  width: 28px; height: 28px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid var(--ss-divider);
  border-radius: 50%;
  font-size: 18px;
  color: var(--ss-accent);
  font-style: normal;
  line-height: 1;
  transition: transform 0.25s;
  flex-shrink: 0;
}
.ss-faq__item[open] .ss-faq__icon {
  transform: rotate(45deg);
  border-color: var(--ss-accent);
}
.ss-faq__a {
  padding: 4px 4px 20px;
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text-muted);
  max-width: 680px;
}

/* ── Banya price block: устойчиво к произвольной разметке менеджера ──
   Конвенция для админки:
   - <h3> или <h4> — название тарифной группы ("С процедурами" / "Без процедур")
   - <p>Описание — <b>5 500 ₽</b></p> — строка тарифа, <b> подсветит цену
   - <p><small>* Условие</small></p> или <hr> + <p>* ...</p> — примечание
   Любой простой текст из визуального редактора рендерится прилично без классов.
*/
.ss-banya-price-block {
  font-family: var(--ss-copy-font);
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text);
}
.ss-banya-price-block h2,
.ss-banya-price-block h3,
.ss-banya-price-block h4 {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-style: italic;
  font-weight: 500;
  font-size: 22px;
  line-height: 1.25;
  color: var(--ss-accent);
  margin: 28px 0 12px;
}
.ss-banya-price-block > :first-child { margin-top: 0; }
.ss-banya-price-block p { margin: 0 0 6px; }
.ss-banya-price-block p + p { margin-top: 0; }
/* Строка с тарифом: текст + <b> с ценой выравниваются как «название · цена» */
.ss-banya-price-block p b,
.ss-banya-price-block p strong {
  color: var(--ss-accent);
  font-family: 'Manrope', sans-serif;
  font-weight: 600;
  white-space: nowrap;
  margin-left: 4px;
}
.ss-banya-price-block ul,
.ss-banya-price-block ol {
  margin: 8px 0 12px;
  padding-left: 20px;
}
.ss-banya-price-block li { margin-bottom: 4px; }
/* Примечания: <small> или строки начинающиеся со звёздочки выглядят как сноска */
.ss-banya-price-block small,
.ss-banya-price-block .ss-note {
  display: block;
  font-size: 13px;
  line-height: 1.55;
  color: var(--ss-text-muted);
  margin-top: 4px;
}
.ss-banya-price-block hr {
  border: 0;
  border-top: 1px solid var(--ss-divider);
  margin: 22px 0 18px;
}
/* Если менеджер вставит <table class="ss-price-table"> — она наследует
   уже существующие стили прайс-таблицы. Если просто <table> — даём базовое: */
.ss-banya-price-block table:not([class]) {
  width: 100%;
  margin: 8px 0 16px;
  border-collapse: collapse;
}
.ss-banya-price-block table:not([class]) td {
  padding: 8px 0;
  border-bottom: 1px solid var(--ss-divider);
  vertical-align: baseline;
}
.ss-banya-price-block table:not([class]) td:last-child {
  text-align: right;
  white-space: nowrap;
  color: var(--ss-accent);
  font-weight: 600;
}

/* Responsive */
@media (max-width: 991px) {
  .ss-filter { position: static; }
  .ss-booking-card { position: static; margin-top: 20px; }
  .ss-program-hero__price { margin-left: 0; }
  .ss-timeline-step { padding-left: 70px; }
  .ss-timeline-num { font-size: 34px; width: 52px; }
  .ss-timeline-step::before { left: 24px; top: 42px; }
}
@media (max-width: 767px) {
  .ss-section { padding: 52px 0; }
  /* 24px, а не 20: строки Bootstrap `.row.g-5` внутри контейнера уходят полями
     -24px влево и вправо, и при меньшем паддинге они вылезали за экран на 4px —
     страница ездила вбок на КАЖДОЙ странице сайта (проверено 13.08.2026). */
  .ss-container { padding: 0 24px; }
  /* Пятизначная цена («36 100 ₽», люкс-пакеты) выталкивала строку списка за экран
     на узких телефонах: у флекс-элемента с названием min-width:auto, и он не
     сжимался под ширину. Проверено 13.08.2026 на /spa/lux-programmy/ при 360px. */
  .ss-menu-row__head { flex-wrap: wrap; }
  .ss-menu-row__name { min-width: 0; }
  .ss-banya-card .ss-img-placeholder { height: 360px; }
  .ss-stories-modal .modal-dialog { max-width: 100%; margin: 0; }
  .ss-stories-modal .modal-content { border-radius: 0; aspect-ratio: auto; height: 100vh; max-height: 100vh; }
  .ss-spa-hero { padding: 110px 0 50px; }
  .ss-program-card__actions { flex-direction: column; }
  .ss-banya-detail-hero { min-height: 70vh; }
}

/* ══════════════════════ Pack-centric (2026-07) ══════════════════════ */
/* Карточки паков (витрина /spa/) */
.ss-pack-card{display:flex;flex-direction:column;height:100%;background:var(--ss-card);border:1px solid var(--ss-divider);border-radius:14px;overflow:hidden;text-decoration:none;color:var(--ss-text);transition:transform .35s ease,box-shadow .35s ease,border-color .35s ease}
.ss-pack-card:hover{transform:translateY(-6px);box-shadow:0 18px 40px rgba(58,47,40,.14);border-color:var(--ss-accent)}
.ss-pack-card__photo{position:relative;overflow:hidden;aspect-ratio:3/4}
.ss-pack-card__photo>img{width:100%;height:100%;object-fit:cover;transition:transform .6s ease}
.ss-pack-card__photo>.ss-img-placeholder{position:absolute;inset:0;display:flex;align-items:center;justify-content:center}
.ss-pack-card:hover .ss-pack-card__photo img{transform:scale(1.05)}
.ss-pack-card__price{position:absolute;left:14px;bottom:14px;background:rgba(26,20,18,.82);color:var(--ss-amber);font-weight:600;font-size:.9rem;padding:6px 12px;border-radius:999px;backdrop-filter:blur(4px)}
.ss-pack-card__body{display:flex;flex-direction:column;gap:.5rem;padding:1.25rem 1.35rem 1.4rem}
.ss-pack-card__title{font-size:1.5rem;line-height:1.15;margin:0;color:var(--ss-text)}
.ss-pack-card__teaser{color:var(--ss-text-muted);font-size:var(--ss-copy-size);line-height:var(--ss-copy-leading);margin:0}
/* ── Карточка статьи блога (без фото) ─────────────────────────────────────── */
.ss-article-card{display:flex;flex-direction:column;height:100%;padding:1.6rem 1.6rem 1.5rem;background:var(--ss-card);border:1px solid var(--ss-divider);border-radius:14px;text-decoration:none;color:var(--ss-text);transition:transform .35s ease,box-shadow .35s ease,border-color .35s ease}
.ss-article-card:hover{transform:translateY(-6px);box-shadow:0 18px 40px rgba(58,47,40,.14);border-color:var(--ss-accent)}
.ss-article-card__kicker{font-size:12px;letter-spacing:.14em;text-transform:uppercase;color:var(--ss-amber);margin-bottom:.75rem}
.ss-article-card__title{font-size:1.4rem;line-height:1.2;margin:0 0 .7rem;color:var(--ss-text)}
.ss-article-card__teaser{color:var(--ss-text-muted);font-size:var(--ss-copy-size);line-height:var(--ss-copy-leading);margin:0 0 1.2rem;flex:1}
.ss-article-card__cta{color:var(--ss-accent);font-weight:600;font-size:.95rem}
/* ── Мини-CRM заявок (/crm/) ──────────────────────────────────────────────── */
.ss-crm-head{background:var(--ss-bg-alt);padding:2.2rem 0 1.6rem;border-bottom:1px solid var(--ss-divider)}
.ss-crm-sub{color:var(--ss-text-muted);font-size:.92rem;margin:.6rem 0 0}
.ss-crm-sub a{color:var(--ss-accent)}
.ss-crm-tabs{display:flex;flex-wrap:wrap;gap:.5rem;margin-bottom:1.6rem}
.ss-crm-tab{display:inline-flex;align-items:center;gap:.4rem;padding:.4rem .9rem;border-radius:999px;background:var(--ss-card);border:1px solid var(--ss-divider);color:var(--ss-text);text-decoration:none;font-size:.9rem;transition:all .2s}
.ss-crm-tab span{font-size:.78rem;opacity:.7;background:rgba(0,0,0,.06);padding:.05em .5em;border-radius:999px}
.ss-crm-tab:hover{border-color:var(--ss-accent)}
.ss-crm-tab.is-active{background:var(--ss-text);color:#fff;border-color:var(--ss-text)}
.ss-crm-tab.is-active span{background:rgba(255,255,255,.2);opacity:1}
.ss-crm-empty{color:var(--ss-text-muted);padding:2rem 0}
.ss-crm-list{display:grid;grid-template-columns:repeat(auto-fill,minmax(340px,1fr));gap:1.1rem}
.ss-crm-card{display:flex;flex-direction:column;background:var(--ss-card);border:1px solid var(--ss-divider);border-radius:14px;overflow:hidden}
.ss-crm-card__head{display:flex;justify-content:space-between;align-items:flex-start;gap:.5rem;padding:1rem 1.1rem;border-bottom:1px solid var(--ss-divider)}
.ss-crm-card__name{display:block;font-weight:600;font-size:1.05rem;color:var(--ss-text)}
.ss-crm-src{font-size:.78rem;color:var(--ss-text-muted)}
.ss-crm-card__meta{text-align:right;white-space:nowrap}
.ss-crm-date{display:block;font-size:.76rem;color:var(--ss-text-muted);margin-top:.35rem}
.ss-crm-card__body{padding:.9rem 1.1rem;flex:1}
.ss-crm-fields{display:grid;grid-template-columns:auto 1fr;gap:.25rem .8rem;margin:0}
.ss-crm-fields dt{color:var(--ss-text-muted);font-size:.82rem}
.ss-crm-fields dd{margin:0;font-size:.9rem;color:var(--ss-text);word-break:break-word}
.ss-crm-fields a{color:var(--ss-accent)}
.ss-crm-details{margin-top:.7rem;font-size:.85rem}
.ss-crm-details summary{cursor:pointer;color:var(--ss-text-muted)}
.ss-crm-details pre{white-space:pre-wrap;font-family:inherit;font-size:.82rem;background:var(--ss-bg-alt);padding:.6rem;border-radius:8px;margin:.5rem 0 0}
.ss-crm-log{margin-top:.8rem}
.ss-crm-log__h{font-size:.76rem;text-transform:uppercase;letter-spacing:.08em;color:var(--ss-text-muted);margin:0 0 .3rem}
.ss-crm-log__line{font-size:.82rem;color:var(--ss-text);padding:.2rem 0;border-top:1px dashed var(--ss-divider)}
.ss-crm-card__foot{display:flex;flex-wrap:wrap;gap:.5rem;align-items:center;padding:.9rem 1.1rem;background:var(--ss-bg-alt);border-top:1px solid var(--ss-divider)}
.ss-crm-select,.ss-crm-comment{padding:.45rem .6rem;border:1px solid var(--ss-divider);border-radius:8px;font-size:.88rem;background:#fff;color:var(--ss-text)}
.ss-crm-comment{flex:1;min-width:140px}
.ss-crm-card__foot .btn{padding:.45rem 1rem;font-size:.88rem}
.ss-crm-msg{font-size:.82rem;width:100%}
.ss-crm-msg.is-ok{color:#4a9d5b}
.ss-crm-msg.is-err{color:#c0563e}
/* Бейджи статусов */
.ss-badge{display:inline-block;padding:.25em .75em;border-radius:999px;font-size:.8rem;font-weight:600;line-height:1.5}
.ss-badge--new{background:#f6e3cd;color:#a4611c}
.ss-badge--work{background:#d9e6f7;color:#2c5aa0}
.ss-badge--booked{background:#d8ecdc;color:#357a45}
.ss-badge--done{background:#e6e3df;color:#6a6258}
.ss-badge--reject{background:#f4d9d2;color:#a53f28}
.ss-badge--spam{background:#ddd9d5;color:#555049}
.ss-crm-tab.ss-badge--new,.ss-crm-tab.ss-badge--work,.ss-crm-tab.ss-badge--booked,.ss-crm-tab.ss-badge--done,.ss-crm-tab.ss-badge--reject,.ss-crm-tab.ss-badge--spam{border-color:transparent}
/* Предоплата */
.ss-crm-prepay{margin-top:.9rem;padding:.7rem .8rem;background:var(--ss-bg-alt);border-radius:10px}
.ss-crm-prepay__top{display:flex;justify-content:space-between;align-items:center;gap:.5rem}
.ss-crm-prepay__cap{font-size:.76rem;text-transform:uppercase;letter-spacing:.08em;color:var(--ss-text-muted)}
.ss-crm-prepay__amt{font-size:1.05rem;margin-top:.25rem;color:var(--ss-text)}
.ss-crm-prepay__of{font-size:.82rem;color:var(--ss-text-muted);font-weight:400}
.ss-crm-prepay__bar{height:6px;background:rgba(0,0,0,.08);border-radius:999px;overflow:hidden;margin-top:.5rem}
.ss-crm-prepay__bar>i{display:block;height:100%;background:var(--ss-accent);border-radius:999px;transition:width .3s ease}
.ss-crm-prepay__meta{font-size:.78rem;color:var(--ss-text-muted);margin-top:.4rem}
.ss-crm-prepay__meta:empty{display:none}
.ss-pp-badge{display:inline-block;padding:.15em .6em;border-radius:999px;font-size:.75rem;font-weight:600}
.ss-pp--none{background:#e6e3df;color:#6a6258}
.ss-pp--partial{background:#f6e3cd;color:#a4611c}
.ss-pp--paid{background:#d8ecdc;color:#357a45}
.ss-crm-card__foot--pay{gap:.4rem;padding-top:.6rem}
.ss-crm-pp-in{padding:.45rem .55rem;border:1px solid var(--ss-divider);border-radius:8px;font-size:.85rem;background:#fff;color:var(--ss-text);width:108px}
.ss-crm-pp-in.ss-crm-pp-date{width:122px}
.ss-crm-card__foot--pay .btn{padding:.45rem .9rem;font-size:.85rem}
/* Переключатель вида списка */
.ss-crm-toolbar{display:flex;justify-content:space-between;align-items:center;flex-wrap:wrap;gap:1rem;margin-bottom:1.6rem}
.ss-crm-toolbar .ss-crm-tabs{margin-bottom:0}
.ss-crm-viewswitch{display:inline-flex;gap:.25rem;background:var(--ss-card);border:1px solid var(--ss-divider);border-radius:999px;padding:.25rem}
.ss-crm-vbtn{border:0;background:transparent;color:var(--ss-text-muted);padding:.4rem .85rem;border-radius:999px;cursor:pointer;font-size:.85rem;line-height:1;white-space:nowrap}
.ss-crm-vbtn.is-active{background:var(--ss-text);color:#fff}
/* Вид «список»: одна колонка, карточки во всю ширину, тело горизонтально */
.ss-crm-list--rows{grid-template-columns:1fr;gap:.8rem}
.ss-crm-list--rows .ss-crm-card__body{display:flex;flex-wrap:wrap;gap:1.4rem;align-items:flex-start}
.ss-crm-list--rows .ss-crm-fields{flex:1 1 240px}
.ss-crm-list--rows .ss-crm-prepay{flex:1 1 260px;margin-top:0}
.ss-crm-list--rows .ss-crm-details,.ss-crm-list--rows .ss-crm-log{flex-basis:100%}
.ss-pack-card__meta{display:flex;align-items:center;justify-content:space-between;margin-top:auto;padding-top:.75rem;font-size:.88rem;color:var(--ss-text-muted)}
.ss-pack-card__cta{color:var(--ss-terracotta);font-weight:600}

/* Лендинг пака: hero */
.ss-pack-hero{position:relative;padding:120px 0 64px;background:var(--ss-bg-alt);background-size:cover;background-position:center}
/* Высота героя пакета — как у детальной бани (комментарий заказчика 02.09.2026:
   «давай сделаем hero как на банях, широкий»). Числа взяты не на глаз, а из
   `.ss-banya-detail-hero`: 90vh на широком экране и 70vh на телефоне — чтобы два
   раздела не разъезжались по высоте первого экрана. Контент центрируется, как в
   `.ss-hero`; width:100% у контейнера обязателен по той же причине, что описана
   у `.ss-hero-content` (flex-элемент ужимается по содержимому). */
.ss-pack-hero{min-height:90vh;display:flex;align-items:center}
.ss-pack-hero>.ss-container{width:100%}
@media (max-width: 767.98px){
  .ss-pack-hero{min-height:70vh}
}
.ss-pack-hero.has-photo,.ss-pack-hero.has-photo .ss-title-hero,.ss-pack-hero.has-photo .ss-lede{color:var(--ss-text-on-dark)}
.ss-pack-hero.has-photo .ss-overline{color:var(--ss-amber)}
.ss-breadcrumbs--onphoto a,.ss-breadcrumbs--onphoto span{color:rgba(239,232,220,.85)}
/* Фон героя пакета слайдером (12.08.2026). Слои внутри секции, а не
   background-image на ней: перекрёстное затухание требует двух картинок сразу.
   Затемнение — отдельным слоем, иначе мигало бы вместе с фото. */
.ss-pack-hero__bg,.ss-pack-hero__scrim{position:absolute;inset:0;pointer-events:none}
.ss-pack-hero__slide{position:absolute;inset:0;background-size:cover;background-position:center;opacity:0;transition:opacity 1.6s ease-in-out}
.ss-pack-hero__slide.is-active{opacity:1}
/* Затемнение героя пакета — тот же приём, что на обложке главной (утверждён
   18.08.2026): по горизонтали тёмное слева под текстом, светлое справа; по
   вертикали лёгкая подложка под шапкой и у нижней кромки. Прежний равномерный
   скрим сверху вниз оставлял левый верх кадра светлым, и золотой заголовок
   «SPA для двоих» на нём почти не читался (снимок 18.08.2026). */
.ss-pack-hero__scrim{
  background:
    linear-gradient(90deg,
      rgba(0,0,0,.74) 0%,
      rgba(0,0,0,.56) 26%,
      rgba(0,0,0,.20) 54%,
      rgba(0,0,0,.00) 74%),
    linear-gradient(180deg,
      rgba(0,0,0,.46) 0%,
      rgba(0,0,0,.06) 30%,
      rgba(0,0,0,.10) 70%,
      rgba(0,0,0,.52) 100%);
}
/* На телефоне колонки нет — текст занимает всю ширину, и горизонтальный
   градиент оставил бы правый край подписи на светлом. То же исключение, что
   у обложки главной. */
@media (max-width: 767.98px){
  /* ⚠️ Середина градиента поднята с .30 до .50 (02.09.2026). Ровно тот же дефект,
     что чинили 18.08 на широком экране, и ровно на том же заголовке: на кадре с
     белыми халатами «SPA для двоих» золотом по светлому не читался — снимок 390px
     02.09.2026. Тогда починили горизонтальную ветку и не заметили, что телефонная
     осталась с прежним просветом; заголовок стоит как раз на 38% высоты. */
  .ss-pack-hero__scrim{
    background:linear-gradient(180deg,rgba(0,0,0,.66) 0%,rgba(0,0,0,.62) 50%,rgba(0,0,0,.76) 100%);
  }
}
/* Контент героя — над слоями фона. */
.ss-pack-hero>.ss-container{position:relative;z-index:1}
.ss-pack-hero__actions{display:flex;align-items:center;gap:1.25rem;flex-wrap:wrap}
.ss-pack-hero__price{font-size:1.35rem;font-weight:600;color:var(--ss-amber)}
/* Тень под текстом героя пакета — тот же приём, что уже стоит на детальной
   программы (`.ss-program-hero.has-photo .ss-title-hero`). Скрима мало: заголовок
   золотой, а кадр «SPA для двоих» — белые халаты, и на телефоне буквы садятся
   ровно на самое светлое место (снимок 390px 02.09.2026, скрим к тому моменту уже
   был усилен — одного его не хватило). */
.ss-pack-hero.has-photo .ss-title-hero,
.ss-pack-hero.has-photo .ss-pack-hero__price,
.ss-pack-hero.has-photo .ss-overline,
.ss-pack-hero.has-photo .ss-lede { text-shadow: 0 2px 14px rgba(0,0,0,.72); }
/* ⛔ АКЦЕНТНОЕ СЛОВО НА ФОТОГРАФИИ — СВЕТЛЕЕ, ЧЕМ В ТЕКСТЕ. Обычный `--ss-amber`
   (#B08D57) на кадре светлого интерьера сливается: заголовок «Отзывы» стоял
   золотом на подсвеченной ониксовой стене и не читался (снимок 390px 02.09.2026,
   после того как шапки стали фотографическими). Скрима и тени не хватило —
   проблема не в яркости фона вообще, а в том, что фон САМ ЗОЛОТОЙ, то есть
   отличается от акцента только светлотой. Поднимаем светлоту акцента там и
   только там, где он лежит на кадре. */
.ss-pack-hero.has-photo .ss-title-hero .ss-amber,
.ss-pack-hero.has-photo .ss-overline { color: #E6C79A; }

/* Точки-указатели набора фотографий героя (комментарий заказчика 02.09.2026:
   «точки для количества и управления этими фото»). Две задачи сразу: сказать,
   сколько кадров в наборе, и дать переключить их руками — до этого набор
   перелистывался только сам собой раз в 6 секунд, и на странице с одним фото
   (а такие сегодня все пакеты, кроме «SPA для двоих») понять, что слайдер
   вообще есть, было неоткуда.

   ⚠️ Точки рисует JS, а не PHP. Без скриптов фон остаётся первым кадром и
   листаться не может — нарисованные в разметке точки были бы мёртвыми
   кнопками, которые обещают то, чего нет.

   Тач-цель кнопки — 44x44 (рекомендация, по которой у нас уже числится долг T2
   в PLAN.md), сама точка рисуется псевдоэлементом внутри неё. */
.ss-pack-hero__dots{position:absolute;left:0;right:0;bottom:16px;z-index:2;display:flex;justify-content:center;gap:4px;pointer-events:none}
.ss-pack-hero__dot{width:44px;height:44px;padding:0;border:0;background:none;display:grid;place-items:center;cursor:pointer;pointer-events:auto}
.ss-pack-hero__dot::before{content:'';width:10px;height:10px;border-radius:50%;border:1px solid rgba(239,232,220,.9);background:rgba(0,0,0,.25);transition:background .25s ease,border-color .25s ease,transform .25s ease}
.ss-pack-hero__dot.is-active::before{background:var(--ss-amber);border-color:var(--ss-amber);transform:scale(1.25)}
.ss-pack-hero__dot:hover::before{border-color:var(--ss-amber)}

/* Меню-список программ в паке */
.ss-menu-section{background:var(--ss-bg-alt)}
.ss-menu-list{max-width:820px;margin:0 auto;display:flex;flex-direction:column}
.ss-menu-row{display:flex;align-items:baseline;gap:.5rem;padding:.9rem .25rem;border-bottom:1px solid var(--ss-divider);text-decoration:none;color:var(--ss-text);transition:color .2s ease,padding .2s ease}
.ss-menu-row:hover{color:var(--ss-terracotta);padding-left:.6rem}
.ss-menu-row__name{font-size:1.08rem}
.ss-menu-row__dots{flex:1 1 auto;border-bottom:1px dotted var(--ss-divider);transform:translateY(-.28em);min-width:1.5rem}
.ss-menu-row__dur{color:var(--ss-text-muted);font-size:.9rem;white-space:nowrap}
.ss-menu-row__price{font-weight:600;white-space:nowrap;min-width:5.5rem;text-align:right}

/* Проза (описание пака / контентные тексты) */
.ss-prose{font-family:var(--ss-copy-font);color:var(--ss-text);font-size:var(--ss-copy-size);line-height:var(--ss-copy-leading)}
/* В материалах редактора основной текст не зависит от устаревших inline-стилей.
   Заголовки и декоративные цитаты сохраняют своё оформление. */
.ss-prose :where(p, div, ul, ol, li, span, strong, b, em, i, font) {
  font-family: inherit !important;
  font-size: inherit !important;
  line-height: inherit !important;
}

/* ── Контент из визуального редактора: защита вёрстки от того, что в нём лежит ──
   13.08.2026 сплошной прогон 276 страниц в браузере при экране 390px показал 11
   страниц, растянутых вбок содержимым: до 2352px. Три причины, все из импорта со
   старого сайта: (1) текст, где пробелы заменены на `&nbsp;` — 45 активных
   элементов, абзац становится одним «словом» в 456 символов и не переносится;
   (2) широкие таблицы — 22 элемента; (3) iframe шириной 640px.
   Правки ниже — защита шаблона; сами данные чинятся отдельно (миграция). */
.ss-prose, .ss-program-desc, .ss-article { overflow-wrap: anywhere; }
/* Длинное слово в заголовке («карбокситерапия», «конфиденциальности») не влезало
   в 360px и растягивало страницу. Ломаем только когда слово не помещается. */
h1, h2, h3, .ss-title-hero, .section-title { overflow-wrap: break-word; }
.ss-prose table { display: block; width: 100%; max-width: 100%; overflow-x: auto; }
.ss-prose iframe, .ss-prose video, .ss-prose embed, .ss-prose object { max-width: 100%; }
.ss-prose h2,.ss-prose h3{margin:1.6em 0 .6em;line-height:1.2}
.ss-prose p{margin:0 0 1em}
.ss-prose ul,.ss-prose ol{margin:0 0 1em 1.25em}
.ss-prose img{max-width:100%;height:auto;border-radius:10px}

/* ── Контентные ссылки: контраст на светлой теме (WCAG AA) ──
   Легаси template_styles.css красит `a` в --color-accent #ba9875 (бежевый акцент
   под СТАРУЮ тёмную тему). На кремовом фоне светлой темы это 2.34:1 — ниже AA,
   отсюда «светлые ссылки на светлом». Задаём читаемый тёплый цвет ссылки
   (#A24B2B — 5.1:1 на креме, тёмная терракота, на бренде). Все контентные ссылки
   в проекте — на светлых фонах (проверено: ss-prose, banya-detail
   #f2efe7, program-detail__desc #321708). Компоненты .ss-* и футер красят ссылки
   своими классами и по специфичности не затрагиваются; для ss-section-страниц
   ловим только БЕЗ-классовые текстовые ссылки, чтобы не задеть карточки/CTA. */
:root { --ss-link: #A24B2B; --ss-link-hover: #7E3A20; }
:root[data-theme="dark"] { --ss-link: #E08A63; --ss-link-hover: #EBA588; }
.ss-prose a,
.banyas-section a,
.banya-detail__content a,
.program-detail__desc a,
.ss-section .ss-container p a:not([class]),
.ss-section .ss-container li a:not([class]) {
  color: var(--ss-link);
  text-decoration: underline;
  text-underline-offset: 2px;
}
.ss-prose a:hover,
.banyas-section a:hover,
.banya-detail__content a:hover,
.program-detail__desc a:hover,
.ss-section .ss-container p a:not([class]):hover,
.ss-section .ss-container li a:not([class]):hover { color: var(--ss-link-hover); }

/* Акцентные слова в контенте помечены инлайном color:var(--ss-terracotta) (#D9784A,
   3.3:1 на светлом — ниже AA, бледно-персиковые слова в описаниях). Контентные зоны
   всегда на светлом фоне → перебиваем на читаемый --ss-link. !important обязателен:
   инлайн-стиль иначе выигрывает. */
.program-detail__desc [style*="terracotta"],
.banya-detail__content [style*="terracotta"],
.ss-prose [style*="terracotta"] { color: var(--ss-link) !important; }

/* Доступность программ (не скрываем — бейдж + похожие) */
.ss-menu-row__badge{display:inline-block;margin-left:.5rem;font-size:.68rem;font-weight:600;letter-spacing:.03em;text-transform:uppercase;color:var(--ss-terracotta);background:rgba(196,107,74,.1);border:1px solid rgba(196,107,74,.35);border-radius:999px;padding:1px 8px;vertical-align:middle;white-space:nowrap}
/* M20-9 (.75rem) перенесён в @@SEC:M20-9@@ — на 1440 не должен меняться (Н-2) */
.ss-menu-row.is-unavail .ss-menu-row__name{color:var(--ss-text-muted)}
.ss-menu-row.is-unavail .ss-menu-row__price{opacity:.55}
.ss-program-hero__unavail{display:inline-flex;align-items:center;font-size:.8rem;font-weight:600;text-transform:uppercase;letter-spacing:.03em;color:#fff;background:var(--ss-terracotta);border-radius:999px;padding:4px 12px}

/* ── Программы пакета (12.08.2026) ──
   Название пакета повторяется под разделителем: секция на 10–20 позиций длинная,
   и в её середине уже не видно, к какому пакету относится список. */
.ss-menu-section__pack{margin:.75rem 0 0;color:var(--ss-text-muted);font-size:.95rem;letter-spacing:.02em}

/* Насыщенная строка списка: описание + кнопки, но БЕЗ фото.
   ⛔ Сетку карточек с фотографиями тут пробовали и отказались — своей фотографии
   у программы обычно нет, и одно и то же фото повторялось по всей странице. */
/* Каждый пункт в собственной рамке: три строки текста подряд без границы
   сливаются в сплошное полотно, и где кончается одна программа, а где начинается
   следующая, читается только по кнопкам (правка заказчика 12.08.2026).
   Токены те же, что у карточки каталога, — рамка и фон карточки, без фото. */
.ss-menu-list--rich{max-width:900px;gap:.85rem}
.ss-menu-row--rich{display:block;padding:1.25rem 1.4rem 1.35rem;color:var(--ss-text);
  background:var(--ss-card);border:1px solid var(--ss-divider);border-radius:14px;
  transition:border-color .25s ease,box-shadow .25s ease}
.ss-menu-row--rich:hover{padding-left:1.4rem;border-color:rgba(201,168,115,.55);box-shadow:0 6px 18px rgba(0,0,0,.06)}
.ss-menu-row--rich .ss-menu-row__head{display:flex;align-items:baseline;gap:.5rem}
.ss-menu-row--rich .ss-menu-row__name{font-size:1.08rem}
.ss-menu-row--rich .ss-menu-row__name a{color:inherit;text-decoration:none;transition:color .2s ease}
.ss-menu-row--rich .ss-menu-row__name a:hover{color:var(--ss-terracotta)}
.ss-menu-row__text{margin:.5rem 0 0;max-width:62ch;color:var(--ss-text-muted);font-size:var(--ss-copy-size);line-height:var(--ss-copy-leading)}
.ss-menu-row__actions{display:flex;gap:.6rem;flex-wrap:wrap;margin-top:.9rem}
/* Недоступную программу не прячем, а гасим: она остаётся в составе пакета. */
.ss-menu-row--rich.is-unavail .ss-menu-row__name{color:var(--ss-text-muted)}
.ss-menu-row--rich.is-unavail .ss-menu-row__price{opacity:.55}
.ss-program-card.is-unavail .ss-program-card__media{opacity:.55}
.ss-program-card.is-unavail .ss-program-card__price{opacity:.55}

/* ── Юридические страницы: политика, оферта ── */
.pk-date { opacity: .65; font-size: .9rem; margin-bottom: 1.5rem; }
.pk-table { width: 100%; border-collapse: collapse; margin: 1.2em 0; font-size: .93rem; }
.pk-table th, .pk-table td { border: 1px solid var(--ss-divider); padding: 10px 12px; text-align: left; vertical-align: top; }
.pk-table th { background: var(--ss-bg-alt); font-weight: 600; }
.pk-req { display: block; margin-top: 4px; font-size: .82rem; opacity: .7; }
/* Таблица процессоров не должна ломать вёрстку на телефоне */
@media (max-width: 700px) {
  .pk-table, .pk-table thead, .pk-table tbody, .pk-table tr, .pk-table th, .pk-table td { display: block; width: 100%; }
  .pk-table thead { display: none; }
  .pk-table tr { margin-bottom: 14px; border: 1px solid var(--ss-divider); border-radius: 8px; overflow: hidden; }
  .pk-table td { border: none; border-bottom: 1px solid var(--ss-divider); }
  .pk-table td:last-child { border-bottom: none; }
}

/* ─────────────────────────────────────────────────────────────────────────────
   @@SEC:PAGES@@ Наследование языка на внутренние страницы (18.08.2026)
   Решение министра: «пронаследуй стиль теперь на все страницы сайта».
   Здесь три вещи: общая шапка страницы, длинный текст (юридические страницы,
   этикет) и выдача поиска — единственное место, где до сих пор жила дефолтная
   вёрстка Битрикса.
   ───────────────────────────────────────────────────────────────────────────── */

/* Шапка внутренней страницы. Разметку рисует blocks/pagehero/block.php. */
.ss-page-hero .ss-divider-ornate { margin-top: 18px; }
.ss-page-hero .ss-lede { margin-top: 18px; max-width: 62ch; }
/* Шапка внутренней страницы стала фотографической (SPEC-11, 02.09.2026): классы
   `.ss-pack-hero` дают ей высоту, слои, скрим и точки. Здесь остаётся только то,
   что у неё своё: светлый текст лида и надзаголовка поверх кадра и орнамент,
   который на тёмном фоне обязан быть светлым, а не коричневым. */
.ss-page-hero .ss-lede { color: var(--ss-text-on-dark); }
.ss-page-hero .ss-divider-ornate { filter: brightness(1.9); }

/* ── Длинный текст: оферта, политика, соглашение, этикет ──
   ⚠️ Ширина колонки задана в ch, а не в px: у длинного текста читаемость
   определяется числом знаков в строке, а не шириной экрана. На 2560px без
   ограничения строка растягивалась на весь контейнер, и глаз терял начало
   следующей строки. */
.ss-prose { max-width: 76ch; }
.ss-prose p,
.ss-prose li { font-size: var(--ss-copy-size); line-height: var(--ss-copy-leading); color: var(--ss-text); }
.ss-prose p { margin: 0 0 1.1em; }
.ss-prose ul, .ss-prose ol { margin: 0 0 1.2em; padding-left: 1.3em; }
.ss-prose li { margin-bottom: .5em; }
.ss-prose li::marker { color: var(--ss-copper); }
.ss-prose h2 {
  margin: 2.2em 0 .7em;
  font-family: 'Cormorant Garamond', serif;
  font-size: 28px;
  font-weight: 500;
  line-height: 1.2;
  color: var(--ss-text);
}
.ss-prose h2:first-child { margin-top: 0; }
.ss-prose h3 {
  margin: 1.8em 0 .6em;
  font-family: 'Cormorant Garamond', serif;
  font-size: 22px;
  font-weight: 500;
  color: var(--ss-text);
}

/* ── Поиск по сайту: выдача, форма, карточки, пагинация ──
   SPEC-15, строки S1/S2 (16.09.2026).
   ⛔ ЗАПИСЬ 18.08.2026 «свой шаблон компонента не заводим» ОТМЕНЕНА подписью
   министра по развилке Р2. Она была верна для своей задачи — типографики, —
   и неверна для этой: `<font>`-теги, сырой html в сниппетах и «Путь: Главная»
   живут в РАЗМЕТКЕ, через CSS их не снять. Разметку теперь даёт свой шаблон
   `components/bitrix/search.page/spasol_search`, стили ниже одевают его.
   Классов `.search-page` здесь больше нет: вендорной разметки на странице нет. */
.ss-search { max-width: 860px; }

.ss-search-form { margin-bottom: 28px; }
.ss-search-form .input-group { max-width: 560px; }
.ss-search-form .form-control {
  background: var(--ss-card);
  color: var(--ss-text);
  border-color: rgba(201, 168, 115, 0.3);
}
.ss-search-form .form-control:focus {
  border-color: var(--ss-accent);
  box-shadow: none;
}

.ss-search-guess { margin: -16px 0 24px; font-size: 15px; color: var(--ss-text-muted); }
.ss-search-guess a { color: var(--ss-accent); }

.ss-search-note {
  margin: 0 0 20px;
  max-width: 70ch;
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text-muted);
}

.ss-search-links {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
  margin: 0;
  padding: 0;
  list-style: none;
}

.ss-search-results {
  margin: 0;
  padding: 0;
  list-style: none;
}
.ss-search-item {
  padding: 22px 0;
  border-top: 1px solid var(--ss-divider);
}
.ss-search-item:first-child { border-top: 0; padding-top: 0; }

.ss-search-item__title {
  font-family: 'Cormorant Garamond', serif;
  font-size: 21px;
  line-height: 1.25;
  color: var(--ss-text);
  text-decoration: none;
}
.ss-search-item__title:hover { color: var(--ss-accent); }
.ss-search-item__title b { color: var(--ss-accent); font-weight: 600; }

.ss-search-item__section {
  display: inline-block;
  margin-left: 10px;
  padding: 2px 10px;
  border: 1px solid var(--ss-divider);
  border-radius: 999px;
  font-size: 12px;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: var(--ss-text-muted);
  vertical-align: 3px;
}

.ss-search-item__body {
  margin: 10px 0 0;
  max-width: 70ch;
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text-muted);
}
.ss-search-item__body b { color: var(--ss-text); font-weight: 600; }

/* ── Пагинация (system.pagenavigation/spasol_pager) ── */
.ss-pager { margin-top: 36px; }
.ss-pager__count {
  margin-bottom: 14px;
  font-size: 14px;
  color: var(--ss-text-muted);
}
.ss-pager__list {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 8px;
  margin: 0;
  padding: 0;
  list-style: none;
}
.ss-pager__link {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-width: 44px;
  height: 44px;
  padding: 0 12px;
  border: 1px solid var(--ss-divider);
  border-radius: 999px;
  background: var(--ss-card);
  color: var(--ss-text);
  font-size: 15px;
  text-decoration: none;
}
.ss-pager__link:hover { border-color: var(--ss-accent); color: var(--ss-accent); }
.ss-pager__link.is-current {
  background: var(--ss-accent);
  border-color: var(--ss-accent);
  color: #fff;
}
.ss-pager__link.is-off { opacity: 0.4; }
.ss-pager__link.is-off:hover { border-color: var(--ss-divider); color: var(--ss-text); }
.ss-pager__gap { padding: 0 4px; color: var(--ss-text-muted); }

@media (max-width: 767.98px) {
  .ss-prose h2 { font-size: 24px; }
  .ss-search-form .btn { width: auto; }
  .ss-pager__link { min-width: 40px; height: 40px; }
}

/* ── Юридические ссылки в подвале (152-ФЗ: политика доступна с любой страницы) ── */
.ss-footer-legal a { color: inherit; text-decoration: underline; text-underline-offset: 3px; }
.ss-footer-legal a:hover { color: var(--ss-accent); }

/* ── Cookie-баннер (согласие на обработку ПДн) ── */
.ss-cookie {
  position: fixed;
  left: 16px;
  right: 16px;
  bottom: 16px;
  z-index: 1080;
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  max-width: 980px;
  margin: 0 auto;
  padding: 18px 22px;
  border-radius: 14px;
  background: var(--ss-card);
  color: var(--ss-text);
  border: 1px solid var(--ss-divider);
  box-shadow: 0 18px 50px rgba(0, 0, 0, 0.28);
  font-size: 13.5px;
  line-height: 1.5;
}
.ss-cookie[hidden] { display: none; }
.ss-cookie__text { flex: 1 1 420px; opacity: .85; }
.ss-cookie__text a { color: var(--ss-accent); text-decoration: underline; text-underline-offset: 3px; }
.ss-cookie__actions { display: flex; gap: 10px; flex: 0 0 auto; }
@media (max-width: 575px) {
  .ss-cookie { padding: 16px; gap: 12px; }
  .ss-cookie__actions { width: 100%; }
  .ss-cookie__actions .btn { flex: 1 1 auto; }
}

/* ── Доступность: видимый фокус при навигации с клавиатуры (WCAG 2.4.7).
   :focus-visible срабатывает только для клавиатуры/AT — мышь и тач не видят кольцо,
   поэтому визуал не меняется для обычных кликов. Аддитивно, ничего не ломает. */
:where(a,button,summary,[tabindex]):focus-visible,
.btn:focus-visible,
.ss-tab:focus-visible,
.ss-crm-vbtn:focus-visible{outline:2px solid var(--ss-accent);outline-offset:2px;border-radius:6px}
/* Инпуты: кольцо вместо одной лишь смены цвета границы (было слабо по контрасту). */
.ss-input:focus-visible{outline:2px solid var(--ss-accent);outline-offset:1px}
/* Не показываем кольцо мыши там, где раньше был свой outline:none у инпута. */
.ss-input:focus:not(:focus-visible){outline:none}

/* ════════════════════════════════════════════════════════════════════════════
   ЗАХОД 18.08.2026 — правки ТЗ по главной. Секции ниже разделены маркерами:
   каждый слайс правит ТОЛЬКО свою секцию, чтобы параллельные правки не дрались.
   ════════════════════════════════════════════════════════════════════════════ */

/* @@SEC:LOGO@@ — логотип при прокрутке */
/* ТЗ заказчика 18.08.2026, дословно: «при прокрутке снять слово и оставить только цветную
   иконку лого».

   ПОЧЕМУ КАДРИРОВАНИЕ ИСХОДНИКА, А НЕ ОТДЕЛЬНЫЙ ФАЙЛ ИКОНКИ. Отдельной иконки в деле нет
   (в img/ лежит только цельный spa-sol-logo.png), а дорисовывать её самим нельзя: это чужой
   товарный знак, и «похожая» иконка — уже не он. Кадрировать при этом можно честно, потому
   что растр делится геометрически. Разбор PNG по колонкам 18.08.2026 (155×56, палитра, tRNS):
       x=  1..47  — цветная галька, насыщенность до 0.9, до 32 цветных пикселей в колонке;
       x= 48..61  — НИ ОДНОГО непрозрачного пикселя (проверено bbox: пусто);
       x= 62..154 — серая пропись «соль», насыщенных пикселей 0–1 на колонку.
   То есть между иконкой и словом есть настоящий прозрачный разрыв в 14px, и рез по нему
   не задевает ни того, ни другого. Показываем 52px из 155px: конец иконки (47) плюс запас
   до середины разрыва, чтобы правый край зрительно уравновесил левый отступ (иконка
   начинается не с нуля, а с x=1).

   Масштабирования здесь нет: картинка внутри всегда в натуральную величину, меняется только
   ширина окна, через которое её видно. Поэтому иконка не «прыгает» в размере и не мылится. */
.ss-header .ss-logo--shrink {
  --ss-logo-full-w: 155px;   /* натуральная ширина растра */
  --ss-logo-icon-w: 52px;    /* видно только гальку (см. разбор выше) */

  /* display:block вместо inline-flex, унаследованного от .ss-logo. Во flex-контексте
     картинка внутри была бы flex-элементом и при сужении ссылки ужалась бы вместе с ней —
     логотип уменьшился бы целиком вместо того, чтобы обрезаться. */
  display: block;
  /* Сама ссылка — flex-элемент шапки (.ss-container.d-flex). Без flex:0 0 auto её ширину
     пересчитывал бы флекс родителя, и заданная нами ширина не соблюдалась бы. */
  flex: 0 0 auto;
  overflow: hidden;
  width: var(--ss-logo-full-w);
  transition: width .38s cubic-bezier(.4, 0, .2, 1);
}
.ss-header .ss-logo--shrink img {
  /* Держим картинку в натуральную величину независимо от ширины ссылки — это и превращает
     overflow:hidden в кадрирование. max-width:none — страховка от правил вида
     img{max-width:100%} (такое в теме есть у .ss-prose): иначе картинка поехала бы за
     шириной ссылки и логотип уменьшился бы целиком. */
  width: var(--ss-logo-full-w);
  max-width: none;
  height: auto;
}
/* Прокрутили — окно сужается до иконки, слово уходит за правый край «шторкой». */
.ss-header.ss-logo-compact .ss-logo--shrink { width: var(--ss-logo-icon-w); }

/* Просили меньше движения — состояния оставляем, анимацию убираем: смысл правки в том,
   ЧТО видно, а не в том, как оно туда переезжает. */
@media (prefers-reduced-motion: reduce) {
  .ss-header .ss-logo--shrink { transition: none; }
}
/* @@/SEC:LOGO@@ */

/* @@SEC:BENEFITS@@ — преимущества из инфоблока */
/* Фон-декор секции (правка министра 18.08.2026, п.4: «нужен какой-то похожий
   на ТЗ декор фон»). На макете ТЗ блок стоит на тёплой подложке с растительными
   мотивами и солью по краям.
   ⛔ Фотографий заказчика мы сюда не ставим и похожие не подбираем — фото это
   данные. Декор нарисован нами: два градиента и два контурных мотива, оба
   inline-SVG в самом стиле, что иконки набора (одна толщина штриха, золото).
   Мотивы висят у краёв, не пересекают колонку текста и не ловят курсор. */
.ss-benefits {
  position: relative;
  overflow: hidden;   /* декор уходит за край секции, а не в горизонтальный скролл */
  background:
    radial-gradient(60% 55% at 12% 8%,  rgba(201, 166, 107, 0.13) 0%, rgba(201, 166, 107, 0) 100%),
    radial-gradient(52% 48% at 88% 92%, rgba(212, 165, 160, 0.12) 0%, rgba(212, 165, 160, 0) 100%),
    linear-gradient(180deg, var(--ss-bg) 0%, var(--ss-bg-alt) 100%);
}
.ss-benefits::before,
.ss-benefits::after {
  content: "";
  position: absolute;
  pointer-events: none;
  background-repeat: no-repeat;
  background-size: contain;
  opacity: 0.22;
}
/* Веточка — сверху слева, развёрнута от угла внутрь. */
.ss-benefits::before {
  top: -28px;
  left: -34px;
  width: 190px;
  height: 250px;
  transform: rotate(18deg);
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 200 260' fill='none' stroke='%23C9A66B' stroke-width='2' stroke-linecap='round'%3E%3Cpath d='M100 250V70'/%3E%3Cpath d='M100 150c-46 4-70-22-74-62 42-4 70 20 74 62z'/%3E%3Cpath d='M100 150c4-42 32-66 74-62-4 40-28 66-74 62z' opacity='.75'/%3E%3Cpath d='M100 96c-34 3-52-16-55-46 31-3 52 15 55 46z' opacity='.55'/%3E%3Cpath d='M100 96c3-31 24-49 55-46-3 30-21 49-55 46z' opacity='.4'/%3E%3C/svg%3E");
}
/* Соль в чаше — снизу справа, там же, где она на макете. */
.ss-benefits::after {
  right: 6px;
  bottom: 18px;
  width: 210px;
  height: 140px;
  background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 240 160' fill='none' stroke='%23C9A66B' stroke-width='2'%3E%3Cellipse cx='120' cy='118' rx='86' ry='26'/%3E%3Ccircle cx='84' cy='104' r='15'/%3E%3Ccircle cx='120' cy='96' r='21'/%3E%3Ccircle cx='157' cy='106' r='13' opacity='.8'/%3E%3Ccircle cx='101' cy='120' r='9' opacity='.6'/%3E%3Ccircle cx='142' cy='122' r='8' opacity='.6'/%3E%3C/svg%3E");
}
[data-theme="dark"] .ss-benefits::before,
[data-theme="dark"] .ss-benefits::after { opacity: 0.14; }
/* На телефоне декор снимается: там он налезает на текст, а не обрамляет его. */
@media (max-width: 767.98px) {
  .ss-benefits::before,
  .ss-benefits::after { display: none; }
}
/* Плитка «цифра + единица + подпись + иконка» по ТЗ 18.08.2026.
   Разметку даёт blocks/advantages/block.php; прежний аккордеон (.ss-accordion*)
   остаётся выше как фолбэк до прогона миграции 44 и здесь не трогается. */
.ss-benefits-head {
  text-align: center;
  max-width: 860px;
  margin: 0 auto 48px;
}
/* Выделенная часть заголовка начинает новую строку — как на макете ТЗ, где
   «Пространство,» стоит отдельной строкой над «где можно остановиться».
   Перенос привязан к <em>, а не к ширине: иначе он ездит от длины заголовка,
   и заказчик, поправив текст, получит разрыв посреди фразы.
   Правило намеренно узкое — только этот блок; в шапке блока бань выделение
   идёт внутри строки, и там разрыв не нужен. */
.ss-benefits-head h2 em { display: block; }
.ss-benefits-grid {
  display: grid;
  /* Ровно четыре колонки на десктопе — столько пунктов в ТЗ. auto-fit тут не нужен:
     заказчик добавит пятый, и он встанет во второй ряд по той же сетке. */
  grid-template-columns: repeat(4, minmax(0, 1fr));
  /* Зазора между колонками нет: разделитель — граница соседа, и при gap он
     оторвался бы от обоих пунктов и повис в пустоте. Воздух даёт padding. */
  gap: 28px 0;
}
/* ⛔ Пункт преимущества — НЕ карточка (правка министра 18.08.2026, п.3).
   На макете ТЗ карточек нет вовсе: четыре пункта стоят в ряд и разделены
   тонкими вертикальными линиями. Прежняя редакция дала им рамку, скругление
   и фон — получился ряд плиток, то есть другой блок. Рамку сюда не возвращать:
   разделители рисуются границей соседа и переключаются с вертикальных на
   горизонтальные вместе с числом колонок. */
.ss-benefit {
  display: flex;
  flex-direction: column;
  align-items: center;
  text-align: center;
  gap: 12px;
  padding: 8px 26px;
  border-left: 1px solid rgba(201, 166, 107, 0.34);
}
/* Первый в ряду разделителя слева не имеет — иначе линия повисает у края блока.
   Правило пишется под каждое число колонок отдельно: «лишний» разделитель это
   не эстетика, а первый признак того, что раскладку не проверяли на телефоне. */
.ss-benefits-grid > .ss-benefit:nth-child(4n + 1) { border-left: 0; }
.ss-benefit-icon {
  width: 44px;
  height: 44px;
  color: var(--ss-accent);
}
.ss-benefit-icon svg { width: 100%; height: 100%; display: block; }
/* Своя иконка заказчика приходит картинкой анонса (PNG/WebP — SVG площадка не
   принимает). contain, а не cover: неквадратный логотип обязан ужаться целиком,
   а не обрезаться по краям. */
.ss-benefit-icon img { width: 100%; height: 100%; display: block; object-fit: contain; }
.ss-benefit-value {
  margin: 0;
  font-family: 'Cormorant Garamond', serif;
  font-weight: 500;
  font-size: 52px;
  line-height: 1;
  /* --ss-accent, а не --ss-amber: на светлой карточке #FDFAF4 амбер даёт слишком
     низкий контраст; в тёмной теме --ss-accent сам равен амберу. */
  color: var(--ss-accent);
  white-space: nowrap;
}
.ss-benefit-unit {
  font-size: 0.42em;
  margin-left: 6px;
  letter-spacing: 0.02em;
}
/* Четвёртая плитка ТЗ идёт без цифры — там фраза, и 52-м кеглем она разваливает ряд. */
.ss-benefit-value--text {
  font-size: 26px;
  line-height: 1.2;
  white-space: normal;
}
.ss-benefit-caption {
  margin: 0;
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text-muted);
  max-width: 240px;
}
/* Две колонки: вертикальный разделитель остаётся между парой, между рядами
   появляется горизонтальный. Правило под 4 колонки здесь обязано быть отменено —
   иначе третий пункт останется без левой границы посреди ряда. */
@media (max-width: 991.98px) {
  .ss-benefits-grid { grid-template-columns: repeat(2, minmax(0, 1fr)); gap: 0; }
  .ss-benefits-head { margin-bottom: 32px; }
  .ss-benefit { padding: 26px 18px; }
  .ss-benefit-value { font-size: 42px; }
  .ss-benefit-value--text { font-size: 22px; }

  .ss-benefits-grid > .ss-benefit:nth-child(4n + 1) { border-left: 1px solid rgba(201, 166, 107, 0.34); }
  .ss-benefits-grid > .ss-benefit:nth-child(2n + 1) { border-left: 0; }
  /* Горизонтальный разделитель — всем, кроме первого ряда. */
  .ss-benefits-grid > .ss-benefit:nth-child(n + 3) { border-top: 1px solid rgba(201, 166, 107, 0.34); }
}
/* Одна колонка: вертикальных разделителей нет ни одного, горизонтальный —
   между соседями, но не над первым (правка министра: «прятать лишний»). */
@media (max-width: 575.98px) {
  .ss-benefits-grid { grid-template-columns: minmax(0, 1fr); }
  .ss-benefit { padding: 24px 8px; gap: 10px; }
  .ss-benefit-icon { width: 36px; height: 36px; }
  .ss-benefit-value { font-size: 36px; }
  .ss-benefit-value--text { font-size: 20px; }
  .ss-benefit-caption { font-size: 14px; }

  .ss-benefits-grid > .ss-benefit { border-left: 0; }
  .ss-benefits-grid > .ss-benefit:nth-child(4n + 1) { border-left: 0; }
  .ss-benefits-grid > .ss-benefit:nth-child(n + 2) { border-top: 1px solid rgba(201, 166, 107, 0.34); }
  .ss-benefits-grid > .ss-benefit:first-child { border-top: 0; }
}
/* @@/SEC:BENEFITS@@ */

/* @@SEC:CERT@@ — блок сертификата с картинкой */

/* Секция сертификата. Фон по умолчанию — прежний ровный `--ss-bg-alt`
   (раньше он стоял inline в blocks/certificate/block.php).
   Сезонный фон приезжает переменной `--ss-cert-bg` и ТАЙЛИТСЯ: на старом сайте
   spasol.ru это был бесшовный паттерн 800×500 (снежинки), а не фотография,
   и растягивать его на всю секцию нельзя — расплывётся. Заказчик может
   загрузить и фото: тогда паттерн просто повторится, а не порвёт вёрстку. */
.ss-cert-section { background: var(--ss-bg-alt); }
.ss-cert-section.has-season-bg {
  background-image: var(--ss-cert-bg);
  background-repeat: repeat;
  background-position: center top;
}

/* Рамка сертификата: та же карточка `.ss-cert-preview` (тёмный градиент,
   янтарная обводка и внутренняя линейка через ::before), но внутри вместо
   нарисованного CSS-макета — реальное фото. Отступы снимаем: фото кадрируется
   само, а внутренняя линейка ::before остаётся поверх него рамкой. */
.ss-cert-preview--photo {
  padding: 0;
  display: block;
  margin: 0;
}
.ss-cert-photo {
  display: block;
  width: 100%;
  height: auto;
  aspect-ratio: 4 / 3;
  object-fit: cover;
  border-radius: 18px;
}

/* Плашка с номиналом и сроком действия. Лежит поверх низа фото на собственном
   градиенте — читаемость не должна зависеть от того, какой снимок загрузил
   заказчик (светлый тубус на белом, ёлка, лепестки). */
.ss-cert-plate {
  position: absolute;
  left: 0; right: 0; bottom: 0;
  display: flex;
  align-items: baseline;
  justify-content: space-between;
  gap: 16px;
  flex-wrap: wrap;
  padding: 56px 34px 30px;
  background: linear-gradient(180deg, rgba(20, 15, 13, 0) 0%, rgba(20, 15, 13, 0.86) 55%, rgba(20, 15, 13, 0.94) 100%);
  border-radius: 0 0 18px 18px;
  pointer-events: none;
}
.ss-cert-plate__sum {
  font-size: 44px;
  line-height: 1;
  color: var(--ss-amber);
}
.ss-cert-plate__note {
  font-size: 12px;
  letter-spacing: 0.04em;
  color: #B8AE9D;
}

@media (max-width: 575.98px) {
  .ss-cert-plate { padding: 44px 20px 18px; }
  .ss-cert-plate__sum { font-size: 32px; }
}

/* Легаси-блок сертификата на детальной странице программы: подпись над
   кнопкой, вставшей на место нерабочей формы (см. комментарий в шаблоне
   news.detail/.default/template.php). Правило живёт здесь, а не в
   template_styles.css: тот стиль на вывод (A5), новых строк в нём не заводим. */
.cert-block__form-lead {
  font-size: 14px;
  line-height: 1.55;
  color: #555;
  margin-bottom: 18px;
}
/* @@/SEC:CERT@@ */

/* @@SEC:TOUR@@ — зоны: слайдер на каждую зону */
/* Блок «Познакомьтесь ближе со СПА СОЛЬ» (bloks/tour). Пришёл на смену имитации
   3D-тура: вместо одного фото на восемь подписей — карточка на зону, в карточке
   слайдер её собственных фотографий. Классы намеренно в новом пространстве имён
   .ss-zone*, чтобы не пересечься с мёртвыми теперь правилами .ss-tour-* выше:
   те правила чистятся отдельным заходом, когда сольются параллельные слайсы. */

/* ── Одна галерея во всю ширину + переключатель зон (правка министра 18.08.2026)
   Было: сетка из восьми карточек, в каждой свой слайдер. Восемь каруселей на
   экране спорят друг с другом, и ни одна не читается как главная. Стало: одна
   сцена во всю ширину блока и меню зон над ней.

   ⛔ Переключение держится на радиокнопках и правилах `:checked ~`, которые
   блок генерирует под своё число зон. Классы .ss-zone-radio / .ss-zone-tab /
   .ss-zone-panel трогать вместе с ними: панель показывается по позиции
   (`nth-child`), поэтому лишний элемент внутри .ss-zones-stage сдвинет
   соответствие «зона ↔ панель» молча. */
.ss-zones-switch { position: relative; }
/* Радиокнопка не display:none — иначе она выпадает из порядка обхода табом
   и зоны становятся недоступны с клавиатуры. Прячем визуально, оставляя
   фокусируемой; кольцо фокуса рисуется на подписи (правило ниже). */
.ss-zone-radio {
  position: absolute;
  width: 1px;
  height: 1px;
  margin: 0;
  opacity: 0;
  pointer-events: none;
}
.ss-zones-tabs {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 10px;
  margin-bottom: 28px;
}
.ss-zone-tab {
  display: inline-flex;
  align-items: center;
  min-height: 44px;               /* тач-цель — инвариант доступности */
  padding: 10px 20px;
  border: 1px solid var(--ss-divider);
  border-radius: 999px;
  font-family: 'Manrope', sans-serif;
  font-size: 14px;
  line-height: 1.2;
  color: var(--ss-text);
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}
.ss-zone-tab:hover { border-color: var(--ss-amber); }
/* Кольцо фокуса рисуется на подписи выбранной радиокнопки — правило по её id
   генерирует блок вместе с правилами видимости панелей (общий стиль здесь,
   адресация там). Без него зона фокусируется невидимо. */
.ss-zone-tab.is-focus { outline: 2px solid var(--ss-amber); outline-offset: 2px; }
.ss-zones-stage {
  background: var(--ss-card);
  border: 1px solid var(--ss-divider);
  border-radius: 16px;
  overflow: hidden;
}
/* Панели скрыты все; нужную открывает сгенерированное блоком правило `:checked`.
   ⚠️ Если CSS не доехал вовсе, видны все восемь — это хуже видом, но ни одна
   зона не пропадает: терять разрешено ДАННЫЕ, а не наоборот. */
.ss-zone-panel { display: none; }

/* Кадр карточки. Пропорция задана самой картинкой (width/height в разметке +
   aspect-ratio ниже), поэтому место под слайдер занято ещё до загрузки фото и до
   инициализации slick — «прыжка» вёрстки не происходит. */
.ss-zone-media {
  position: relative;
  background: rgba(10, 8, 7, 0.35);
}
.ss-zone-slide img {
  display: block;
  width: 100%;
  height: auto;
  /* 3:2 — пропорция исходников галереи (1400×934): на узком экране кадр почти
     не режется. */
  aspect-ratio: 3 / 2;
  object-fit: cover;
}
/* ⚠️ Пропорция зависит от ширины, и это не украшательство. Галерея стала во всю
   ширину блока (правка министра 18.08.2026), а 3:2 от 1374 px — это 916 px
   высоты: кадр перестаёт помещаться в экран целиком, и переключатель зон уезжает
   за верхнюю кромку сразу после клика. Поэтому чем шире экран, тем более
   панорамный кадр: 2:1 на десктопе, 16:9 на планшете, 3:2 на телефоне. */
@media (min-width: 768px) {
  .ss-zone-slide img { aspect-ratio: 16 / 9; }
}
@media (min-width: 1200px) {
  .ss-zone-slide img { aspect-ratio: 2 / 1; }
}

/* ── Состояние ДО инициализации slick и при выключенном JS ──────────────────
   Контейнер работает как горизонтальная лента с прокруткой и «прилипанием»:
   все фотографии остаются доступны пальцем и колесом, ничего не спрятано.
   Как только slick навесит .slick-initialized, эти правила отключаются сами. */
.ss-zone-track:not(.slick-initialized) {
  display: flex;
  overflow-x: auto;
  scroll-snap-type: x mandatory;
  scrollbar-width: none;              /* полосу прокрутки прячем: она тут шумит */
  -ms-overflow-style: none;
}
.ss-zone-track:not(.slick-initialized)::-webkit-scrollbar { display: none; }
.ss-zone-track:not(.slick-initialized) > .ss-zone-slide {
  flex: 0 0 100%;
  max-width: 100%;
  scroll-snap-align: start;
}

/* ── Стрелки. slick-theme.css в проекте не подключён, рисуем сами. ────────── */
.ss-zone-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 3;
  width: 40px;
  height: 40px;
  display: flex;
  align-items: center;
  justify-content: center;
  border: 1px solid rgba(201, 168, 115, 0.45);
  border-radius: 50%;
  background: rgba(10, 8, 7, 0.55);
  color: #FDFAF4;
  font-size: 22px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease, border-color 0.2s ease;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
}
.ss-zone-arrow:hover { background: rgba(10, 8, 7, 0.8); border-color: var(--ss-amber); }
.ss-zone-arrow:focus-visible { outline: 2px solid var(--ss-amber); outline-offset: 2px; }
.ss-zone-arrow--prev { left: 12px; }
.ss-zone-arrow--next { right: 12px; }
/* slick прячет стрелки классом .slick-disabled, когда листать некуда. */
.ss-zone-arrow.slick-disabled { opacity: 0.35; cursor: default; }

/* ── Точки ── */
.ss-zones-stage .slick-dots {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 10px;
  z-index: 3;
  display: flex;
  justify-content: center;
  gap: 7px;
  list-style: none;
  margin: 0;
  padding: 0;
}
.ss-zones-stage .slick-dots li { margin: 0; padding: 0; line-height: 0; }
.ss-zones-stage .slick-dots li button {
  width: 8px;
  height: 8px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(253, 250, 244, 0.45);
  font-size: 0;
  cursor: pointer;
  transition: background 0.2s ease, transform 0.2s ease;
}
.ss-zones-stage .slick-dots li button:hover { background: rgba(253, 250, 244, 0.8); }
.ss-zones-stage .slick-dots li.slick-active button { background: var(--ss-amber); transform: scale(1.25); }
.ss-zones-stage .slick-dots li button:focus-visible { outline: 2px solid var(--ss-amber); outline-offset: 3px; }

/* ── Плашка «фото ещё не привязаны» ──────────────────────────────────────────
   Видна только пока у зоны нет собственных фотографий. Нужна, чтобы случайные
   кадры из общей галереи не читались как «вот так выглядит эта зона» — на этом
   и держался обман прежнего 3D-тура. */
.ss-zone-note {
  position: absolute;
  top: 10px;
  left: 10px;
  right: 10px;
  z-index: 3;
  margin: 0;
  padding: 6px 10px;
  border-radius: 8px;
  background: rgba(10, 8, 7, 0.6);
  color: rgba(253, 250, 244, 0.9);
  font-family: 'Manrope', sans-serif;
  font-size: 11px;   /* M20-9 (12px) перенесён в мобильный override ниже — на 1440 не должен меняться (Н-2) */
  line-height: 1.35;
  letter-spacing: 0.02em;
  -webkit-backdrop-filter: blur(4px);
  backdrop-filter: blur(4px);
  pointer-events: none;
}

/* ── Подпись зоны ────────────────────────────────────────────────────────────
   Правка министра 18.08.2026: «заголовок и описание снизу выглядят очень дёшево».
   Так и было: под панорамным кадром шла светлая полоса-приступок с мелким
   заголовком — она читалась как подпись к картинке в каталоге, а не как часть
   галереи. Подпись переехала НА кадр, в его нижний левый угол, — тем же приёмом,
   что в карточках бань, который министр принял без правок. Полосы больше нет:
   высота панели равна высоте кадра.

   ⛔ Читаемость держит не тень, а собственный градиент кадра (.ss-zone-media::after):
   тень под текстом на светлом фото даёт грязь, а градиент работает на любом. */
.ss-zone-media::after {
  content: "";
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  height: 62%;
  z-index: 2;
  pointer-events: none;
  background: linear-gradient(180deg,
      rgba(0,0,0,0.00) 0%,
      rgba(0,0,0,0.28) 42%,
      rgba(0,0,0,0.68) 78%,
      rgba(0,0,0,0.86) 100%);
}
.ss-zone-panel { position: relative; }
.ss-zone-body {
  position: absolute;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 4;
  padding: 28px 32px 30px;
  pointer-events: none;   /* стрелки и точки под подписью остаются кликабельны */
}
.ss-zone-name {
  margin: 0;
  font-family: 'Cormorant Garamond', serif;
  font-style: italic;
  font-size: clamp(26px, 2.4vw, 36px);
  font-weight: 500;
  line-height: 1.1;
  color: var(--ss-amber);
  text-shadow: 0 2px 12px rgba(0,0,0,0.5);
}
.ss-zone-text {
  margin: 8px 0 0;
  max-width: 620px;
  font-family: 'Manrope', sans-serif;
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: #FFFFFF;
  opacity: 0.92;
  text-shadow: 0 1px 8px rgba(0,0,0,0.55);
}
/* Точки уходят вправо: подпись теперь занимает низ кадра слева, и по центру
   они ложились ровно на описание. */
.ss-zones-stage .slick-dots {
  left: auto;
  right: 26px;
  bottom: 22px;
  justify-content: flex-end;
}

@media (max-width: 767.98px) {
  /* На телефоне листают пальцем — стрелки только мешают и перекрывают кадр. */
  .ss-zone-arrow { display: none !important; }
  /* ⚠️ На телефоне подпись НЕ ложится на кадр. Замер: при ширине 390 кадр 3:2 —
     это 260px, а название с описанием в три строки занимают из них больше сотни;
     фотография превращается в фон для текста. Поэтому подпись возвращается под
     кадр — но не прежним светлым приступком, из-за которого блок и выглядел
     дёшево, а тёмной панелью, продолжающей саму фотографию: карточка читается
     одним предметом, а кадр остаётся кадром. */
  .ss-zone-body {
    position: static;
    padding: 16px 18px 20px;
    background: #1A1412;
  }
  .ss-zone-name { font-size: 23px; text-shadow: none; }
  .ss-zone-text { font-size: 14px; text-shadow: none; opacity: 0.85; }
  /* Градиент под подписью больше не нужен — текста на кадре нет. Оставляем лёгкий,
     чтобы низ фотографии сходился по тону с тёмной панелью под ней. */
  .ss-zone-media::after {
    height: 26%;
    background: linear-gradient(180deg, rgba(0,0,0,0) 0%, rgba(26,20,18,0.55) 100%);
  }
  .ss-zones-stage .slick-dots { left: 0; right: 0; bottom: 10px; justify-content: center; }
  /* M20-9 итерация 2 (барьер МР-3, Н-3): при 12px (было 10px) плашка «Фотографии
     этой бани ещё не подобраны» на 320 уходила в 3 строки вместо 2 — той же тесной
     подгонкой, что и у .ss-about-spec__label: letter-spacing до 0, паддинг 8→6px
     (измерено — возвращает 2 строки на всех пяти адресах с плашкой). */
  .ss-zone-note { font-size: 12px; padding: 5px 6px; letter-spacing: 0; }
  /* Восемь названий зон в строку на 390px не помещаются никак. Переключатель
     становится горизонтальной лентой с прокруткой: пункты остаются видимыми
     и не сжимаются до нечитаемости. `flex: none` обязателен — без него
     flex-элементы ужимаются вместо прокрутки. */
  .ss-zones-tabs {
    flex-wrap: nowrap;
    justify-content: flex-start;
    overflow-x: auto;
    scroll-snap-type: x proximity;
    -webkit-overflow-scrolling: touch;
    scrollbar-width: none;
    margin-left: -4px;
    margin-right: -4px;
    padding: 0 4px 4px;
  }
  .ss-zones-tabs::-webkit-scrollbar { display: none; }
  .ss-zone-tab { flex: none; scroll-snap-align: start; font-size: 13px; padding: 10px 16px; }
}
/* @@/SEC:TOUR@@ */

/* @@SEC:CONSTRUCTOR@@ — конструктор во всю ширину */
/* Правка ТЗ п.6: колонки убраны, заголовок/подпись/кнопка подняты наверх (шапка
   оформлена по образцу других full-width секций страницы — #directions, #banya:
   text-center + ss-divider-ornate), облако тегов развёрнуто на всю ширину блока.
   Решение по внутренней вёрстке: у шапки лид ограничен max-width:680px инлайн-стилем
   (тот же приём, что в #banya) — иначе строка растягивается на всю ширину контейнера
   (до 1376px) и теряет читаемость. Само облако тегов (.ss-tag-cloud) НЕ ограничено:
   это не форма с шагами, а чипы (inline-block + перенос строк), они не "расползаются"
   с ростом ширины — просто помещается больше чипов в строку. Проверено на 1440 и 390px:
   document.documentElement.scrollWidth === clientWidth на обеих (см. отчёт захода). */
/* @@/SEC:CONSTRUCTOR@@ */

/* @@SEC:SOCIAL@@ — единые иконки соцсетей */
/* ЗАЧЕМ. Иконки соцсетей были надёрганы из трёх разных наборов и жили в трёх разных
   цветовых режимах одновременно: VK и Instagram красились легаси-правилом
   `template_styles.css:1759` в rgba(186,152,117,.56) — бежевый с прозрачностью 56%,
   YouTube нёс зашитый в разметку `fill="#ba9875"` (то есть 100% того же цвета),
   а Max был полноцветным градиентом на подложке и вообще не подчинялся теме.
   Замер 18.08.2026 (оптический вес = alpha-взвешенная доля закрашенных пикселей
   квадрата рендера, canvas 400×400, VK/Instagram/YouTube/Max/Facebook):
   было 36.3 / 61.0 / 62.6 / 94.6 / 25.7 % — разброс ×3.7, стало 27.4 / 32.5 /
   21.6 / 32.3 / 17.8 % — разброс ×1.8 (по четырём видимым, без выключенного
   Facebook: ×2.6 → ×1.5).
   Контраст к фону (WCAG 1.4.11, порог 3:1 для нетекстовой графики): бежевый под
   .56 смешивается с фоном и давал 1.49:1 на секции контактов и 2.55:1 в подвале —
   ниже порога в обоих местах.

   МОДЕЛЬ. Новый набор рисуется в сетке 24×24 в `currentColor`, поэтому цветом
   управляют стили, а не разметка в БД, и ховер работает сменой `color`.
   Цвет берётся семантическим токеном: на светлых секциях --ss-accent (#8B6F3F,
   3.74:1 на #EDE4D3), в тёмном подвале --ss-amber (5.77:1 на #3A2F28) — оба
   выше 3:1, замерено в браузере на стенде 18.08.2026.

   ДЕГРАДАЦИЯ. Пока миграция 47 не прогнана, в БД лежат СТАРЫЕ svg — они без класса
   `.ss-soc-svg`, и ни одно правило ниже их не трогает, кроме размера бокса. Именно
   поэтому заливка переопределяется только для `.ss-soc-svg`: глобальный
   `fill: currentColor` расплющил бы градиент старого Max в сплошной квадрат. */

/* Тач-цель 44×44 (WCAG 2.5.5) — одинаковая на всех ширинах: раньше кликабельная
   область равнялась самой иконке, 32×32. Зазор маленький, потому что паддинг
   теперь внутри бокса, а не между иконками. */
.ss-socials,
.ss-socials .index-contacts__social { gap: 4px; }
.ss-socials .index-contacts__social-icon {
  width: 44px;
  height: 44px;
  border-radius: 12px;
  opacity: 1;                      /* было .9 — приглушало и без того слабый контраст */
  color: var(--ss-accent);
  background: transparent;
  transition: color .18s, background-color .18s, transform .18s;
}
.ss-footer .ss-socials .index-contacts__social-icon { color: var(--ss-amber); }

/* Ховер и фокус ведут себя одинаково. `outline` НЕ трогаем: видимое кольцо задаёт
   общее правило доступности выше (:focus-visible → outline 2px), и оно должно
   остаться единственным источником кольца. Здесь только цвет и подложка. */
.ss-socials .index-contacts__social-icon:hover,
.ss-socials .index-contacts__social-icon:focus-visible {
  color: var(--ss-terracotta);
  background: rgba(217, 120, 74, 0.10);
  transform: translateY(-2px);
}
.ss-footer .ss-socials .index-contacts__social-icon:hover,
.ss-footer .ss-socials .index-contacts__social-icon:focus-visible {
  color: var(--ss-text-on-dark);
  background: rgba(239, 232, 220, 0.12);
}

/* Инвариант SPEC-07 №5 требует уважать prefers-reduced-motion, а подскок иконки —
   это движение. Гасим и его, и легаси-подскок из правила выше (0,3,0 против его
   (0,2,0) — перебивает), оставляя смену цвета: она и есть сигнал наведения. */
@media (prefers-reduced-motion: reduce) {
  .ss-socials .index-contacts__social-icon { transition: color .18s, background-color .18s; }
  .ss-socials .index-contacts__social-icon:hover,
  .ss-socials .index-contacts__social-icon:focus-visible { transform: none; }
}

/* Размер самой марки. !important нужен, чтобы перебить такое же !important-правило
   выше (32px), написанное под старые полноразмерные svg. Правило идёт позже при
   равной специфичности — выигрывает оно. */
.ss-socials .index-contacts__social-icon > svg {
  width: 26px !important;
  height: 26px !important;
  max-width: 26px !important;
  max-height: 26px !important;
  display: block;
  flex-shrink: 0;
}

/* Заливка — только у НОВЫХ иконок. Специфичность (0,3,1) перебивает легаси
   `.index-contacts__social-icon svg` (0,1,1) и его :hover-вариант (0,2,1).
   Селектор `*` обязателен: у VK/Max/Facebook марка лежит внутри <g>, у которого
   своей заливки нет, и без него путь унаследовал бы легаси-бежевый. */
.ss-socials .index-contacts__social-icon > svg.ss-soc-svg,
.ss-socials .index-contacts__social-icon > svg.ss-soc-svg * {
  fill: currentColor;
}
/* @@/SEC:SOCIAL@@ */


/* ============================================================
   @@SEC:LEAD@@ — блок «Оставить заявку» (ТЗ заказчика 18.08.2026)
   Новый блок: до него единственная форма на главной пряталась в модалке,
   то есть требовала клика и намерения. Здесь — три поля прямо на странице.
   ============================================================ */
.ss-lead-section {
  background: var(--ss-bg-alt);
}
.ss-lead-note {
  font-family: 'Manrope', sans-serif;
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text-muted);
  margin-top: 18px;
  max-width: 460px;
}
.ss-lead-form {
  background: var(--ss-card);
  border: 1px solid rgba(201, 166, 107, 0.28);
  border-radius: 18px;
  padding: 32px;
  box-shadow: 0 14px 40px rgba(58, 47, 40, 0.10);
}
.ss-lead-form .form-label {
  font-family: 'Manrope', sans-serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ss-text-muted);
  margin-bottom: 6px;   /* M20-9 (8px) перенесён в @@SEC:M20-9@@ — на 1440 не должен меняться (Н-2) */
}
.ss-lead-form .form-control {
  min-height: 48px;   /* тач-цель ≥44px — инвариант доступности SPEC-07 */
  border-radius: 10px;
}
/* Honeypot: поле обязано быть недостижимым и для мыши, и для клавиатуры,
   но не display:none — часть ботов такие поля пропускает. */
.ss-hp-field {
  position: absolute;
  left: -9999px;
  opacity: 0;
  height: 0;
  width: 0;
  pointer-events: none;
}
/* «Что вас интересует?» — четыре варианта ТЗ. Радиокнопки, а не select:
   вариантов ровно четыре, и на телефоне тап по чипу дешевле открытия списка. */
.ss-lead-interest legend {
  float: none;   /* Bootstrap растягивает legend на всю ширину и ломает ритм */
  width: auto;
}
.ss-lead-chips {
  display: flex;
  flex-wrap: wrap;
  gap: 10px;
}
.ss-lead-chip-input {
  position: absolute;
  opacity: 0;
  width: 0;
  height: 0;
}
.ss-lead-chip {
  display: inline-flex;
  align-items: center;
  min-height: 44px;
  padding: 10px 18px;
  border: 1px solid var(--ss-divider);
  border-radius: 999px;
  font-family: 'Manrope', sans-serif;
  font-size: 14px;
  color: var(--ss-text);
  cursor: pointer;
  transition: border-color 0.2s ease, background 0.2s ease, color 0.2s ease;
}
.ss-lead-chip:hover { border-color: var(--ss-amber); }
.ss-lead-chip-input:checked + .ss-lead-chip {
  background: var(--ss-amber);
  border-color: var(--ss-amber);
  color: #201A17;
  font-weight: 600;
}
/* Кольцо фокуса рисуется на подписи: сам input визуально скрыт, и без этого
   правила вариант нельзя выбрать с клавиатуры «вслепую». */
.ss-lead-chip-input:focus-visible + .ss-lead-chip {
  outline: 2px solid var(--ss-amber);
  outline-offset: 2px;
}
.ss-lead-submit {
  width: 100%;
  min-height: 52px;
  margin-top: 6px;
  font-weight: 600;
}
.ss-lead-after {
  font-family: 'Manrope', sans-serif;
  font-size: 13px;
  color: var(--ss-text-muted);
  text-align: center;
  margin: 12px 0 0;
}
.ss-lead-consent {
  font-family: 'Manrope', sans-serif;
  font-size: 12px;
  line-height: 1.5;
  color: var(--ss-text-muted);
  margin-top: 18px;
  padding-top: 16px;
  border-top: 1px solid var(--ss-divider);
}
.ss-lead-consent input { margin-right: 6px; }

@media (max-width: 575.98px) {
  .ss-lead-form { padding: 24px 20px; }
}


/* ============================================================
   @@SEC:NAV@@ — выпадающее меню и действия в шапке (ТЗ 18.08.2026)
   Прежнее меню было плоским списком из семи ссылок; ТЗ просит раскрытие
   «СПА-программы» в две колонки, «Банный комплекс» списком бань и телефон
   кнопкой «Позвонить».
   ============================================================ */
.ss-nav-drop {
  position: relative;
}
/* Галочка у пунктов с выпадающим списком (правка министра 18.08.2026): без неё
   по виду пункта не отличить, раскроется он или уведёт на страницу. Ссылка
   становится flex-строкой, поэтому и подпись, и значок стоят на одной базовой
   линии, а не разъезжаются на разных кеглях. */
.ss-nav-drop-toggle {
  display: inline-flex;
  align-items: center;
  gap: 6px;
}
.ss-nav-chev {
  flex: none;
  opacity: 0.65;
  transition: transform 0.2s ease, opacity 0.2s ease;
}
.ss-nav-drop:hover .ss-nav-chev,
.ss-nav-drop:focus-within .ss-nav-chev {
  transform: rotate(180deg);
  opacity: 1;
}
@media (prefers-reduced-motion: reduce) {
  .ss-nav-chev { transition: none; }
}
/* Раскрытие и по наведению, и по фокусу с клавиатуры: панель живёт внутри
   .ss-nav-drop, поэтому :focus-within держит её открытой всё время, пока таб
   идёт по её ссылкам. Без этого меню недостижимо без мыши. */
.ss-nav-panel {
  position: absolute;
  top: 100%;
  left: 0;
  z-index: 70;
  min-width: 240px;
  padding: 18px 20px;
  background: var(--ss-card);
  color: var(--ss-text);
  border: 1px solid rgba(201, 166, 107, 0.3);
  border-radius: 14px;
  box-shadow: 0 18px 44px rgba(26, 20, 18, 0.22);
  opacity: 0;
  visibility: hidden;
  transform: translateY(6px);
  transition: opacity 0.18s ease, transform 0.18s ease, visibility 0.18s;
}
.ss-nav-drop:hover > .ss-nav-panel,
.ss-nav-drop:focus-within > .ss-nav-panel {
  opacity: 1;
  visibility: visible;
  transform: translateY(0);
}
/* Последний пункт меню («О центре») стоит у правого края навигации, и панель
   с left:0 уезжала за край окна на 21px при 992px — при открытии её пункты
   оказывались обрезаны. Выравниваем такую панель по правому краю пункта.
   Поймано scripts/header-audit.js 18.08.2026, в разметке не видно: панель
   скрыта visibility, но размеры у неё живые. */
.ss-nav-drop:last-of-type > .ss-nav-panel {
  left: auto;
  right: 0;
}

/* Мостик под кнопкой: без него курсор проваливается в зазор между ссылкой
   и панелью, панель успевает закрыться и до пунктов не доехать. */
.ss-nav-drop::after {
  content: "";
  position: absolute;
  top: 100%;
  left: 0;
  right: 0;
  height: 10px;
}
.ss-nav-panel--wide { min-width: 480px; }
.ss-nav-panel-cols {
  display: grid;
  grid-template-columns: 1fr 1fr;
  gap: 4px 28px;
}
.ss-nav-panel-col {
  list-style: none;
  margin: 0;
  padding: 0;
}
.ss-nav-panel-col a {
  display: block;
  padding: 9px 6px;
  font-family: 'Manrope', sans-serif;
  font-size: 14px;
  line-height: 1.3;
  color: var(--ss-text);
  text-decoration: none;
  border-radius: 8px;
  transition: background 0.15s ease, color 0.15s ease;
}
.ss-nav-panel-col a:hover,
.ss-nav-panel-col a:focus-visible {
  background: rgba(201, 166, 107, 0.14);
  color: var(--ss-accent);
}
.ss-nav-panel-title {
  font-family: 'Manrope', sans-serif;
  font-size: 11px;
  letter-spacing: 0.18em;
  text-transform: uppercase;
  color: var(--ss-text-muted);
  margin: 0 0 8px;
  padding-left: 6px;
}
.ss-nav-panel-all {
  display: block;
  margin-top: 14px;
  padding: 12px 6px 2px;
  border-top: 1px solid var(--ss-divider);
  font-family: 'Manrope', sans-serif;
  font-size: 13px;
  font-weight: 600;
  color: var(--ss-accent);
  text-decoration: none;
}
.ss-nav-panel-all:hover { color: var(--ss-terracotta); }

/* Значки мессенджеров. Тач-цель 44×44 — инвариант доступности; на глаз значок
   24px, остальное добирается отступами. */
.ss-header-msgr {
  display: inline-flex;
  align-items: center;
  gap: 2px;
}
/* ⚠️ Ширина значка — 34px, а не 40: с правкой «выводить все соцсети» их в шапке
   четыре и больше, и прежний шаг выдавливал кнопку «Записаться» за край на 1440px.
   Тач-цель при этом остаётся 44px по высоте — она добирается высотой строки
   шапки, а не размером кружка. */
.ss-header-msgr a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  border-radius: 50%;
  color: inherit;
  transition: background 0.18s ease, color 0.18s ease;
}
.ss-header-msgr a:hover,
.ss-header-msgr a:focus-visible {
  background: rgba(201, 166, 107, 0.16);
  color: var(--ss-amber);
}
.ss-header-msgr svg { width: 18px; height: 18px; }

.ss-header-call {
  align-items: center;
  gap: 8px;
  white-space: nowrap;
}
/* На тёмной шапке поверх hero номер и значки светлые — иначе тонут в видео.
   ⚠️ 17.09.2026 сюда добавлена иконка поиска. Без этой строки она красилась
   в var(--ss-text) — тёмный цвет для светлой страницы — и на обложке читалась
   заметно тусклее соседних пунктов меню: поймано снимком шапки на 1600px,
   в разметке и в замерах достижимости этого не видно вовсе. */
.ss-header.on-hero .ss-header-phone,
.ss-header.on-hero .ss-nav-search,
.ss-header.on-hero .ss-header-msgr a { color: var(--ss-text-on-dark); }

/* ⚠️ Собственная подложка шапки поверх обложки. Появилась вместе с отказом от
   равномерного затемнения кадра: как только ролик перестали глушить, светлый
   кадр под шапкой начал съедать меню, значки и особенно кнопку «Позвонить» —
   золотая обводка на белом окне читалась хуже всего (видно на снимке 1905px).
   Подложка узкая и растворяется к 120px, поэтому видео остаётся видно. */
.ss-header.on-hero:not(.is-scrolled) {
  background: linear-gradient(180deg,
      rgba(0,0,0,0.58) 0%,
      rgba(0,0,0,0.30) 55%,
      rgba(0,0,0,0.00) 100%);
}
/* Кнопке мало одной обводки: под ней может оказаться любой кадр. Даём тёмную
   заливку — контур остаётся золотым, а надпись перестаёт зависеть от видео. */
.ss-header.on-hero:not(.is-scrolled) .btn-ss-gold {
  background: rgba(20, 15, 13, 0.55);
  color: #F0DFC0;
  border-color: #E0C48E;
  backdrop-filter: blur(4px);
}
.ss-header.on-hero:not(.is-scrolled) .btn-ss-gold:hover,
.ss-header.on-hero:not(.is-scrolled) .btn-ss-gold:focus-visible {
  background: var(--ss-amber);
  color: #201A17;
}

/* Номер текстом — самый нижний по важности: он же стоит на кнопке «Позвонить»
   и в подвале. Порог 1800px, а не 1600: на 1600 и 1680 строка с номером в
   прежней редакции не помещалась (перебор 82 и 6px соответственно).
   ⚠️ 17.09.2026 порог поднят 1800 → 1860: в меню добавилась иконка поиска (36px
   вместе с отступом), и на 1800 запас строки стал 0px при норме 24. Замер той же
   методикой, что и прежний порог, — с иконкой и включённым номером: 1800 → 0px,
   1840 → 14px, 1860 → 33px, 1880 → 53px. Взята первая ширина, проходящая норму. */
@media (max-width: 1859.98px) {
  .ss-header-phone { display: none !important; }
}
/* Значки соцсетей — от 1536px. Ниже строка занята меню и двумя кнопками;
   значки продублированы в подвале и в мобильном меню, поэтому уходят они,
   а не навигация.
   ⛔ 17.09.2026 порог поднят 1500 → 1536, и это была ПОЧИНКА, а не подгонка.
   Прежние 1500px стояли ровно на краю: запас строки на этой ширине был 0px уже
   до иконки поиска. С иконкой значок мессенджера лёг ПОВЕРХ неё — кнопка
   перестала нажиматься на 1500 и 1600 (trial-клик через elementFromPoint,
   scripts/header-audit.js её арифметикой прямоугольников не ловил: `over`
   оставался нулём, элементы не вылезали за край окна, они наезжали друг
   на друга ВНУТРИ строки).
   Замер с иконкой и включёнными значками: 1500 → 8px, 1520 → 27px, 1536 → 42px.
   Взята не первая проходящая (1520, запас 27px), а 1536: норма 24px объявлена
   как место под ШЕСТОЙ значок соцсети (34px), и 27px этого места не дают. */
@media (max-width: 1535.98px) {
  .ss-header-msgr { display: none !important; }
}
/* Строка шапки не переносится и не растягивает страницу: если состав всё же
   перестанет влезать (длиннее пункт меню, шестой значок), сожмётся меню, а не
   вылезет кнопка. Без min-width:0 flex-элемент отказывается ужиматься ниже
   своего содержимого — именно так «Записаться» и оказывалась за краем. */
.ss-header > .ss-container {
  flex-wrap: nowrap;
  min-width: 0;
}
.ss-header > .ss-container > * { min-width: 0; }


/* ============================================================
   @@SEC:CTA@@ — карточка подбора программы над облаком тегов
   Правка министра 18.08.2026: «блок расширить, добавив сверху заголовок
   на основе картинки и блока справа + конструктор снизу».
   ============================================================ */
/* Секция начинается прямо с карточки — своей шапки у неё больше нет, поэтому
   отступ сверху карточка держит сама. */
.ss-cta-card {
  display: grid;
  grid-template-columns: minmax(0, 5fr) minmax(0, 7fr);
  align-items: stretch;
  background: var(--ss-card);
  border: 1px solid rgba(201, 166, 107, 0.28);
  border-radius: 18px;
  overflow: hidden;
  box-shadow: 0 14px 40px rgba(58, 47, 40, 0.10);
}
/* Кадр держит пропорцию сам, поэтому место под него занято до загрузки —
   карточка не «прыгает», когда фотография доезжает. */
/* Высоту карточки задаёт кадр, а не текст. Без явной пропорции колонка тянулась
   на всю высоту сетки, и справа оставалось полполотна пустоты (снимок 1440px). */
.ss-cta-photo { position: relative; }
.ss-cta-photo img {
  display: block;
  width: 100%;
  height: 100%;
  aspect-ratio: 4 / 3;
  object-fit: cover;
}
.ss-cta-body {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  justify-content: center;
  padding: 48px 56px;
}
.ss-cta-title {
  margin: 12px 0 0;
  font-size: clamp(28px, 2.6vw, 42px);
  font-weight: 500;
  line-height: 1.15;
  color: var(--ss-text);
}
/* Выделенная часть заголовка карточки. Разметку <em> ставит редактор в
   include-области; здесь она получает цвет — иначе «SPA» на макете золотое,
   а на сайте просто курсив (замер на снимке 1440px). */
.ss-cta-title em {
  font-style: italic;
  color: var(--ss-amber);
}
.ss-cta-text {
  margin: 18px 0 0;
  max-width: 460px;
  font-family: 'Manrope', sans-serif;
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text-muted);
}
.ss-cta-btn {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  margin-top: 28px;
  min-height: 52px;
  padding: 14px 30px;
  font-weight: 600;
}
.ss-cta-note {
  display: inline-flex;
  align-items: center;
  gap: 7px;
  margin: 14px 0 0;
  font-family: 'Manrope', sans-serif;
  font-size: 13px;
  color: var(--ss-text-muted);
}
.ss-cta-note svg { flex: none; opacity: 0.75; }

/* Разделительная строка между двумя предложениями блока: «или подберите
   самостоятельно». Линии по бокам — чтобы строка читалась как переход, а не
   как ещё один заголовок. */
.ss-constructor-or {
  display: flex;
  align-items: center;
  gap: 18px;
  margin: 44px 0 28px;
  font-family: 'Manrope', sans-serif;
  font-size: 14px;
  color: var(--ss-text-muted);
  text-align: center;
}
.ss-constructor-or::before,
.ss-constructor-or::after {
  content: "";
  flex: 1;
  height: 1px;
  background: var(--ss-divider);
}

@media (max-width: 991.98px) {
  /* Кадр уходит наверх: в две колонки на планшете он ужимается до полосы,
     а текст всё равно не помещается в свою половину. */
  .ss-cta-card { grid-template-columns: minmax(0, 1fr); }
  .ss-cta-photo img { min-height: 0; aspect-ratio: 16 / 9; }
  .ss-cta-body { padding: 32px 28px 36px; }
}
@media (max-width: 575.98px) {
  .ss-cta-body { padding: 26px 20px 30px; }
  .ss-cta-btn { width: 100%; justify-content: center; }
  .ss-constructor-or { margin: 32px 0 22px; font-size: 13px; }
}


/* ============================================================
   @@SEC:A5@@ — то, что пережило снос легаси `template_styles.css`
   ============================================================
   ЗАЧЕМ ЭТА СЕКЦИЯ. 01.09.2026 (SPEC-08, слайс S1) удалён легаси-стиль
   `local/templates/spasol/template_styles.css` — 2547 строк, написанных под
   СТАРУЮ тёмную тему (`--color-bg #010809`, `--color-accent #ba9875`,
   Fira Sans / Euclid Square / PF Scandal Pro). Он ждал сноса с июля (PLAN §A5)
   и держался единственным условием: «подтвердить, что тёмная тема не нужна».
   Заказчик подтвердил сам — тёмная тема «портит общий стиль сайта».

   КАК ОТБИРАЛОСЬ, ЧТО ПЕРЕНОСИТЬ (метод, а не вкус). Из файла извлечены все
   290 классов-селекторов и сверены с разметкой ВСЕХ 276 страниц карты сайта
   плюс восьми страниц вне карты (поиск, /thanks/, /auth/, /crm/, 404,
   пагинация, фасет каталога). На страницах встретились 22 класса; из них
   Bootstrap-овские (.btn, .form-control, .modal-*, .offcanvas-*, .breadcrumb-*,
   .page-*, .dropdown-*) легаси НЕ красил ни одного:
   ⛔ `bootstrap.min.css` подключается в header.php ПОЗЖЕ, чем Bitrix отдаёт
   template_styles.css в ShowHead(), и при равной специфичности выигрывал он.
   Проверено замером computed style на живом стенде: голая ссылка отдавала
   rgb(13,110,253) — бутстраповский синий, а не легаси-бежевый #ba9875.
   Ещё часть (.index-contacts__social*, .scroll-to-top, .booking-modal__body,
   .site-modal-booking .modal-content) перекрыта либо более специфичными
   правилами theme.css, либо инлайновым style= в разметке.
   Реально работали и потому переехали сюда — правила ниже. Всё остальное
   удалено вместе с файлом.

   ⚠️ Названия классов НЕ `.ss-`: это разметка, которую слайс S1 не переверстывал.
   Галерея переезжает на новый вид в слайсе S2 — тогда и класс сменится. */

/* ── Полноширинный слайдер галереи (`news.list/spasol_gallery`) ──
   Единственный крупный блок вёрстки, живший только в легаси. Стрелки и точки
   рисует slick уже после загрузки страницы, поэтому в разметке их не видно и
   грепом по шаблонам они не находятся — отсюда и риск снести их «как мёртвые».
   Фон: был `--color-bg #010809` (чёрный старой тёмной темы). Стал токеном
   --ss-dark-panel #1A1412 — тёмная поверхность дизайн-системы. Фон виден
   только по краям кадров, которые не заполняют полосу (object-fit: contain). */
.gallery-fullwidth {
  position: relative;
  width: 100%;
  overflow: hidden;
  background: var(--ss-dark-panel);
}
.gallery-fullwidth__slick { width: 100%; }
.gallery-fullwidth__slide {
  position: relative;
  width: 100%;
  height: 75vh;
  min-height: 400px;
  max-height: 800px;
}
.gallery-fullwidth__slide img {
  width: 100%;
  height: 100%;
  object-fit: contain;
  display: block;
}
.gfw-arrow {
  position: absolute;
  top: 50%;
  transform: translateY(-50%);
  z-index: 10;
  background: none;
  border: none;
  cursor: pointer;
  padding: 0;
  width: 48px;
  height: 48px;
  opacity: 0.6;
  transition: opacity 0.2s;
}
.gfw-arrow svg { width: 48px; height: 48px; }
.gfw-arrow:hover { opacity: 1; }
.gfw-arrow--prev { left: 20px; }
.gfw-arrow--next { right: 20px; }
.gallery-fullwidth__slick .slick-dots {
  position: absolute;
  bottom: 20px;
  width: 100%;
  text-align: center;
  padding: 0;
  margin: 0;
  list-style: none;
  z-index: 10;
}
.gallery-fullwidth__slick .slick-dots li { display: inline-block; margin: 0 4px; }
.gallery-fullwidth__slick .slick-dots li button {
  width: 8px;
  height: 8px;
  border-radius: 50%;
  border: 1px solid rgba(255, 255, 255, 0.7);
  background: transparent;
  font-size: 0;
  padding: 0;
  cursor: pointer;
  transition: background 0.3s;
}
.gallery-fullwidth__slick .slick-dots li.slick-active button { background: #fff; }
@media (max-width: 767px) {
  .gallery-fullwidth__slide { height: 50vh; min-height: 250px; }
}

/* ── Обёртка контента между шапкой и подвалом (header.php) ──
   Держит подвал внизу на коротких страницах (/thanks/, 404, пустая выдача
   поиска). Без неё подвал уезжает под шапку. */
.site-content { min-height: 60vh; }

/* ── Кнопка «наверх» (footer.php) ──
   Геометрия и цвета заданы инлайном в разметке; приглушение в покое и отклик
   на наведение — легаси. Show/hide по прокрутке (SPEC-20 M20-6, 23.09.2026)
   переехал сюда из инлайна: `js/site.js` переключает атрибут `hidden`,
   а display — здесь, единственное место, которое его задаёт. */
.scroll-to-top {
  display: flex;
  align-items: center;
  justify-content: center;
  opacity: 0.85;
  transition: opacity 0.2s ease, transform 0.2s ease;
}
.scroll-to-top[hidden] { display: none; }
.scroll-to-top:hover { opacity: 1; transform: translateY(-2px); }

/* ── Шапка модалки записи (footer.php) ──
   Тёплая подложка заголовка. Значения rgba перенесены ИЗ ЛЕГАСИ БАЙТ В БАЙТ
   (#ba9875 под .25/.10), а не переведены на --ss-amber: снос легаси не должен
   менять вид, а на кремовом фоне разница между #ba9875 и #C9A66B под альфой
   .25 — заметная. Перекрасить — отдельное решение по виду, не побочный эффект
   уборки. `margin: 0` нужен: без него Bootstrap Reboot даёт h5 нижний отступ,
   и заголовок отъезжает от разделителя. */
.booking-modal__header {
  background: linear-gradient(135deg, rgba(186, 152, 117, 0.25), rgba(186, 152, 117, 0.10));
  display: flex;
  align-items: center;
  justify-content: space-between;
}
.booking-modal__title { margin: 0; }
/* @@/SEC:A5@@ */

/* ────────────────────────────────────────────────────────────────────────────
   @@SEC:S2@@ — галерея с переключателем: пункты слева, полотно справа
   Слайс S2 спеки SPEC-08, 01.09.2026.

   РЕШЕНИЕ МИНИСТРА (дословно): «пункты переключения по галерее слева, галерея
   справа (сейчас они сверху, галерея снизу). Так она станет покороче высотой и
   будет помещаться в экран, а пункты станут более читаемыми. Это вид галереи
   наследовать везде.»

   ⚠️ СЕКЦИЯ ПЕРЕКРЫВАЕТ `@@SEC:TOUR@@`, А НЕ ЗАМЕНЯЕТ ЕЁ. Правки лежат отдельным
   куском в конце файла по двум причинам. Первая — организационная: theme.css в эту
   волну правят два сабагента параллельно, и разойтись они могут только внутри
   чужой секции. Вторая содержательная: `@@SEC:TOUR@@` сама по себе рисует ИМЕННО
   прежний вид, поэтому она же и есть рабочий архив раскладки — снял эту секцию,
   и вернулся переключатель над полотном (см.
   `docs/archive/2026-09-01-galereya-pereklyuchatel-sverhu.md`, шаг 4).

   ⛔ РАСКЛАДКА СДЕЛАНА ГРИДОМ НА САМОМ `.ss-zones-switch`, А НЕ ОБЁРТКОЙ ВОКРУГ
   КОЛОНОК. Переключение зон работает без JS на правилах `#id:checked ~ .ss-zones-tabs`
   и `#id:checked ~ .ss-zones-stage` — комбинатор `~` видит только СОСЕДЕЙ. Обёртка
   `<div class="ss-gal-layout">` вокруг вкладок и полотна выглядела бы естественнее,
   но разорвала бы соседство и убила переключение при выключенном скрипте — то есть
   оставила бы посетителю одну зону из восьми. Это инвариант спеки (SPEC-08 §2),
   поэтому колонками стали сами вкладки и полотно.
   Радиокнопки грид-элементами не становятся (они `position: absolute`, вне потока),
   а `<style>` — потому что у него `display: none`. Проверять при любой правке
   разметки блока: лишний ВИДИМЫЙ прямой потомок `.ss-zones-switch` встанет третьей
   колонкой и молча развалит раскладку.
   ──────────────────────────────────────────────────────────────────────────── */

/* ── Узкий экран (< 992px): колонки НЕТ, вкладки остаются лентой над полотном ──
   ⛔ Это не «мобильная версия на отвяжись», а замер. Колонка пунктов читаема от
   ~180px. При 390px на полотно осталось бы 390 − 32 (поля) − 180 − 20 (зазор) =
   158px: фотография перестаёт быть фотографией. Между 768 и 991 арифметика лучше,
   но всё ещё плохая — на планшете 768 полотно вышло бы 480px при колонке в 200px,
   и 16:9 от него — 270px высоты против 408px высоты самой колонки из восьми зон:
   переключатель стал бы выше галереи, то есть главным предметом блока.
   Поэтому порог — 992px (та же граница, что у `lg` бутстрапа, на котором стоит
   остальная сетка сайта), а ниже работает раскладка из `@@SEC:TOUR@@`: лента
   вкладок с горизонтальной прокруткой над полотном. Она уже проверена на
   отсутствие горизонтального скролла, и менять в ней нечего.
   ⚠️ `@@SEC:TOUR@@` включает ленту только до 767.98px, а с 768 до 991.98 вкладки
   остаются переносящимся рядом по центру — на планшете восемь зон встают в две
   строки, и это нормально. Здесь этот диапазон не трогается. */

@media (min-width: 992px) {

  /* Две колонки: пункты слева, полотно справа. `minmax(0, 1fr)` у второй колонки
     обязателен — без него полотно с длинной лентой кадров внутри (`overflow-x`
     до инициализации slick) раздувает грид по min-content и вылезает за контейнер
     горизонтальным скроллом (инвариант SPEC-08 §3). */
  .ss-zones-switch {
    display: grid;
    grid-template-columns: 220px minmax(0, 1fr);
    gap: 24px;
    align-items: start;
  }

  /* Колонка пунктов. Прокрутка по вертикали — страховка на случай, когда зон
     станет заметно больше восьми (список заводит заказчик): колонка не растянет
     блок выше полотна, а начнёт прокручиваться внутри себя.
     `min-height: 0` нужен гриду, иначе `max-height` у элемента с `align-items:
     start` не сработает. */
  .ss-zones-tabs {
    flex-direction: column;
    flex-wrap: nowrap;
    align-items: stretch;
    justify-content: flex-start;
    gap: 8px;
    margin-bottom: 0;
    min-height: 0;
    max-height: 100%;
    overflow-y: auto;
    scrollbar-width: thin;
  }

  /* Пункт. Прямоугольник со скруглением вместо «таблетки»: пункты стоят столбиком,
     и у таблеток левый край текста пляшет вслед за скруглением. Текст влево —
     министр просил читаемости, а колонка центрованных подписей читается хуже
     ровно потому, что взгляду не за что зацепиться слева. */
  .ss-zone-tab {
    justify-content: flex-start;
    text-align: left;
    border-radius: 12px;
    padding: 11px 16px;
    font-size: 15px;
    line-height: 1.3;
  }

  /* Полотно прижато к верху колонки пунктов: у обоих `align-items: start`,
     поэтому высота блока = высота более длинного из двух, а не сумма. Ради
     этого всё и затевалось. */
  .ss-zones-stage { border-radius: 14px; }

  /* Подпись на кадре чуть плотнее: полотно уже, чем было во всю ширину блока,
     и прежние 28/32px полей съедали заметную долю кадра. */
  .ss-zone-body { padding: 22px 26px 24px; }
  .ss-zones-stage .slick-dots { right: 20px; bottom: 18px; }
}

/* ── Очень широкий экран ──────────────────────────────────────────────────────
   Контейнер упирается в 1440px, поэтому дальше 1200px полотно уже не растёт, и
   колонку можно позволить пошире: длинные названия («Турецкая зона (хаммам)»)
   перестают переноситься на вторую строку. */
@media (min-width: 1200px) {
  .ss-zones-switch { grid-template-columns: 260px minmax(0, 1fr); gap: 32px; }
  .ss-zone-tab { padding: 12px 18px; font-size: 16px; }
}
/* @@/SEC:S2@@ */

/* ════════════════════════════════════════════════════════════════════════════
   @@SEC:S3a@@ — /banya/: hero с фото, «Почему наши бани», карточки как на главной
   SPEC-08, слайс S3a, 01.09.2026. Файлы-потребители:
     - components/bitrix/news/spasol_banyas/bitrix/news.list/.default/template.php
       (hero .ss-banya-list-hero* + карточки .ss-banya-card, переиспользуют уже
       существующие правила карточки из главной — новых классов карточки здесь нет);
     - blocks/banya-why/block.php (список .ss-banya-why*).
   ════════════════════════════════════════════════════════════════════════════ */

/* ── Hero /banya/: крупное фото, тёмный градиент, текст по центру ──
   ⚠️ 02.09.2026 высота поднята с 62vh до 90vh (решение министра «все страницы
   приводи к hero как на детальной бани»), и вместе с ней ОБЯЗАН был поменяться
   способ выравнивания. Прежний `flex-end` был осмыслен на низком герое: текст
   стоял у нижней кромки кадра. На 90vh он прижал крошки, заголовок и кнопку к
   самому низу, а верхние три четверти экрана остались пустой фотографией —
   на высоком окне (1550px) это читается как сломанная страница; поймано
   министром на снимке, а не проверкой: замер высоты был зелёным, потому что
   мерил высоту, а не то, где внутри неё стоит текст.
   .ss-hero-bg-dim — то же имя класса дым-подложки, что и в
   .ss-banya-detail-hero, но правило ниже скоуплено через родителя. */
.ss-banya-list-hero {
  position: relative;
  /* 90vh — как у детальной бани и у всех остальных первых экранов (решение
     министра 02.09.2026: «все страницы приводи к hero как на детальной бани»).
     Было 62vh, и раздел бань оказывался единственной страницей сайта с высотой
     первого экрана «посередине» — аудит 02.09.2026 поймал его последним. */
  min-height: 90vh;
  display: flex;
  align-items: center;      /* как у .ss-pack-hero и .ss-hero: текст по центру экрана */
  overflow: hidden;
  background-size: cover;
  background-position: center;
  background-color: #1A1412;
}
.ss-banya-list-hero .ss-hero-bg-dim {
  position: absolute;
  inset: 0;
  z-index: 0;
  background: linear-gradient(180deg, rgba(26,20,18,0.28) 0%, rgba(26,20,18,0.86) 100%);
}
.ss-banya-list-hero__inner {
  position: relative;
  z-index: 1;
  width: 100%;
}
.ss-banya-list-hero__text { max-width: 640px; }
.ss-banya-list-hero .ss-breadcrumbs { margin-bottom: 26px; }
/* ⚠️ `.ss-serif` в общем блоке типографики ставит `color: var(--ss-text)` явно
   (тёмно-коричневый) — на светлой теме документа (SPEC-08 S1, тема снята
   сайт-целиком) это правило иначе перебивает наследование от тёмного фото и
   заголовок становится нечитаемым на собственном фоне: тот же класс дефекта,
   что уже чинили у .ss-hero/.ss-banya-detail-hero/.ss-section--dark
   (@@SEC:A5@@ рядом, «Dark-overlay секции»). Переопределяем явно, а не
   полагаемся на каскад. */
.ss-banya-list-hero .ss-serif,
.ss-banya-list-hero h1,
.ss-banya-list-hero p,
.ss-banya-list-hero .ss-lede { color: var(--ss-text-on-dark); }
.ss-banya-list-hero .ss-overline { color: var(--ss-amber); }
.ss-banya-list-hero .ss-divider-ornate { color: var(--ss-amber); }
@media (max-width: 767px) {
  .ss-banya-list-hero { min-height: 70vh; }   /* как у остальных первых экранов на телефоне (02.09.2026) */
}

/* ── «Почему наши бани»: аккуратный СПИСОК, не сетка карточек (дословно ТЗ) ──
   Пункт без фона и рамки, разделён волосяной линией — по духу того же приёма,
   что и .ss-rules-list/.ss-check-list у соседних блоков, но с собственными
   классами: список «Почему» не аккордеон и не чек-лист, смешивать правила
   с чужим блоком означало бы держать в одном селекторе два разных инварианта. */
.ss-banya-why-list {
  display: flex;
  flex-direction: column;
  max-width: 880px;
  margin: 0 auto;
}
.ss-banya-why-item {
  display: flex;
  align-items: flex-start;
  gap: 24px;
  padding: 22px 4px;
  border-bottom: 1px solid var(--ss-divider);
}
.ss-banya-why-item:last-child { border-bottom: 0; }
.ss-banya-why-item__num {
  flex: none;
  width: 48px;
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-style: italic;
  font-size: 32px;
  line-height: 1;
  color: var(--ss-amber);
}
.ss-banya-why-item__title {
  font-family: 'Manrope', sans-serif;
  font-weight: 600;
  font-size: 18px;
  color: var(--ss-text);
  margin: 0 0 4px;
}
.ss-banya-why-item__desc {
  font-family: 'Manrope', sans-serif;
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text-muted);
  margin: 0;
}
@media (max-width: 575px) {
  .ss-banya-why-item { gap: 16px; padding: 18px 2px; }
  .ss-banya-why-item__num { font-size: 26px; width: 36px; }
}
/* @@/SEC:S3a@@ */

/* ════════════════════════════════════════════════════════════════════════════
   @@SEC:S3b@@ — /banya/: таблица сравнения бань
   SPEC-08, слайс S3b, 01.09.2026. Файл-потребитель один: blocks/banya-compare/block.php.

   ТЗ заказчика часть 1 §4: светлый фон, шесть строк сравнения, фотографии бань
   над колонками, «узнать больше» под каждой колонкой. Решение министра
   01.09.2026: «Таблица сравнения на телефоне — карточками в столбик».

   ─── ОДНА СЕТКА, ДВЕ ОСИ ────────────────────────────────────────────────────
   Разметка — плоский список без обёрток вокруг колонок:
     [подписи ×8][баня 1 ×8][баня 2 ×8]…   где 8 = фото + 6 клеток + ссылка.
   Телефон (по умолчанию): `grid-auto-flow: row`, одна колонка — элементы встают
   в DOM-порядке, и восемь подряд идущих элементов одной бани читаются карточкой
   за счёт боковых границ на самих элементах (скругление и верхняя граница — у
   фото, нижняя и отступ — у ссылки). От 992px: `grid-auto-flow: column` —
   те же элементы ложатся сверху вниз по колонке и переходят в следующую,
   получается таблица.

   ⛔ ОБЁРТКИ ВОКРУГ КОЛОНКИ БЫТЬ НЕ МОЖЕТ. `<div>` вокруг восьми элементов
   бани выглядит естественнее и молча ломает главное свойство таблицы:
   высоты клеток «Атмосфера» в соседних колонках перестают совпадать, потому
   что каждая обёртка становится своим гридом со своими треками. Строка
   сравнения расползается по диагонали. Тот же класс ловушки, что у галереи
   в @@SEC:S2@@ (там обёртка убивала переключение без JS), и стережётся так же —
   счётчиком открывающих `<div>` в checkup.sh §29.

   ⚠️ ЧИСЛО КОЛОНОК НЕ ЗАШИТО. Явно задан только трек подписей, остальные —
   `grid-auto-columns`. Заказчик заведёт пятую баню — колонка появится сама.
   `repeat(var(--n), …)` здесь сознательно не используется: подстановка
   переменной в счётчик repeat() поддерживается неровно, а тихо развалившийся
   `grid-template-columns` даёт горизонтальный скролл — инвариант SPEC-08 №3.
   ════════════════════════════════════════════════════════════════════════════ */

.ss-banya-compare { background: var(--ss-bg); }

.ss-cmp {
  display: grid;
  grid-template-columns: 1fr;
  /* Длинные значения («уточняйте у администратора») в узкой колонке обязаны
     переноситься, а не распирать трек: это и есть защита от бокового скролла. */
  overflow-wrap: anywhere;
}

/* Колонка подписей строк живёт только на десктопе: на телефоне подпись
   показывается внутри каждой клетки (.ss-cmp__cell-label). */
.ss-cmp__labels-head,
.ss-cmp__label,
.ss-cmp__labels-foot { display: none; }

.ss-cmp__head,
.ss-cmp__cell,
.ss-cmp__foot {
  background: var(--ss-card);
  border-left: 1px solid var(--ss-divider);
  border-right: 1px solid var(--ss-divider);
}

.ss-cmp__head {
  border-top: 1px solid var(--ss-divider);
  border-radius: 14px 14px 0 0;
  overflow: hidden;          /* скругление верхних углов фотографии */
  padding: 0 18px 14px;
}
.ss-cmp__photo {
  display: block;
  width: calc(100% + 36px);  /* фото распирает падинги карточки во всю ширину */
  margin: 0 -18px 16px;
  height: 200px;
  object-fit: cover;
}
.ss-cmp__type {
  font-family: 'Manrope', sans-serif;
  font-size: 11px;   /* M20-9 (12px) перенесён в @@SEC:M20-9@@ — на 1440 не должен меняться (Н-2) */
  letter-spacing: 0.14em;
  text-transform: uppercase;
  color: var(--ss-accent);
  margin: 0 0 4px;
}
.ss-cmp__name {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-size: 26px;
  line-height: 1.15;
  color: var(--ss-text);
  margin: 0;
}

.ss-cmp__cell {
  display: flex;
  justify-content: space-between;
  align-items: baseline;
  gap: 18px;
  padding: 12px 18px;
  border-bottom: 1px solid var(--ss-divider);
}
.ss-cmp__cell-label {
  flex: none;
  font-family: 'Manrope', sans-serif;
  font-size: 13px;
  color: var(--ss-text-muted);
}
.ss-cmp__cell-value {
  font-family: 'Manrope', sans-serif;
  font-size: 15px;
  line-height: 1.45;
  color: var(--ss-text);
  text-align: right;
}
/* ⚠️ ПУСТАЯ КЛЕТКА — ШТАТНОЕ СОСТОЯНИЕ, А НЕ КРАЙНИЙ СЛУЧАЙ. Стоимость есть на
   боевом сайте только у турецкой бани; у русской две её страницы противоречат
   друг другу, у фито и японской цены нет вовсе (docs/facts/banya-prices.md).
   Клетка обязана выглядеть законченной без значения — поэтому не прочерк
   в полный вес, а приглушённая строка того же кегля: пустота читается как
   «уточняется», а не как «вёрстка развалилась». */
.ss-cmp__cell.is-empty .ss-cmp__cell-value {
  color: var(--ss-text-muted);
  font-style: italic;
}

.ss-cmp__foot {
  border-bottom: 1px solid var(--ss-divider);
  border-radius: 0 0 14px 14px;
  padding: 16px 18px 18px;
  margin-bottom: 28px;       /* просвет между карточками на телефоне */
  text-align: center;
}
.ss-cmp__more {
  font-family: 'Manrope', sans-serif;
  font-weight: 600;
  font-size: 14px;
  color: var(--ss-accent);
  text-decoration: none;
  border-bottom: 1px solid transparent;
  transition: border-color 0.2s ease, color 0.2s ease;
}
.ss-cmp__more:hover,
.ss-cmp__more:focus-visible {
  color: var(--ss-copper);
  border-bottom-color: currentColor;
}

/* ── Десктоп: та же разметка превращается в таблицу ────────────────────────── */
@media (min-width: 992px) {
  .ss-cmp {
    grid-auto-flow: column;                     /* заполняем сверху вниз по колонке */
    grid-template-rows: auto repeat(6, auto) auto;   /* фото + 6 строк ТЗ + ссылка */
    grid-template-columns: minmax(140px, 190px);     /* только колонка подписей */
    grid-auto-columns: minmax(0, 1fr);               /* бани — сколько заведено */
    border: 1px solid var(--ss-divider);
    border-radius: 16px;
    overflow: hidden;
  }
  .ss-cmp__labels-head,
  .ss-cmp__labels-foot { display: block; background: var(--ss-bg-alt); }
  .ss-cmp__labels-head { border-bottom: 1px solid var(--ss-divider); }
  .ss-cmp__label {
    display: flex;
    align-items: center;
    background: var(--ss-bg-alt);
    border-bottom: 1px solid var(--ss-divider);
    padding: 12px 16px;
    font-family: 'Manrope', sans-serif;
    font-size: 13px;
    font-weight: 600;
    color: var(--ss-text-muted);
  }
  /* Подпись внутри клетки уходит из вида И из дерева доступности: слева уже
     стоит видимая колонка подписей, две подписи подряд читались бы дважды. */
  .ss-cmp__cell-label { display: none; }

  .ss-cmp__head,
  .ss-cmp__cell,
  .ss-cmp__foot {
    border-right: 0;
    border-radius: 0;
    margin-bottom: 0;
  }
  .ss-cmp__head {
    border-top: 0;
    border-bottom: 1px solid var(--ss-divider);
    padding: 0 16px 16px;
    text-align: center;
  }
  .ss-cmp__photo {
    width: calc(100% + 32px);
    margin: 0 -16px 14px;
    height: 180px;
  }
  .ss-cmp__name { font-size: 23px; }

  .ss-cmp__cell {
    display: block;
    text-align: center;
    padding: 14px 16px;
  }
  .ss-cmp__cell-value { text-align: center; display: block; }

  .ss-cmp__foot { border-bottom: 0; padding: 18px 16px; }
}

@media (max-width: 575px) {
  .ss-cmp__photo { height: 170px; }
  .ss-cmp__name { font-size: 23px; }
  .ss-cmp__cell { padding: 11px 14px; gap: 12px; }
  .ss-cmp__head { padding: 0 14px 12px; }
  .ss-cmp__photo { width: calc(100% + 28px); margin: 0 -14px 14px; }
  .ss-cmp__foot { padding: 14px; }
}
/* @@/SEC:S3b@@ */

/* ── @@SEC:S6@@ Страница пакета: hero на телефоне, бегущая строка, показатели,
   SEO-текст (SPEC-09, слайс S6, 01.09.2026) ─────────────────────────────────

   ⛔ Секцию не растаскивать по файлу: чекап §29 стережёт её целиком, и правило
   overflow у ленты — load-bearing (см. ниже). */

/* 1. Два набора фоновых фото героя: горизонтальный — широкий экран, вертикальный
      — телефон. Переключение медиазапросом, а не скриптом: набор виден сразу при
      первой отрисовке, без прыжка.
   ⚠️ Горизонтальный слой прячется на телефоне ТОЛЬКО при наличии вертикального
      (класс has-mob-slideshow ставит spa/index.php). Безусловное правило оставило
      бы телефон без фона на всех пакетах, где вертикальных фото ещё нет, — а
      сегодня их нет ни у одного. */
.ss-pack-hero__bg--mob,.ss-pack-hero__dots--mob{display:none}
@media (max-width: 767.98px){
  .ss-pack-hero.has-mob-slideshow .ss-pack-hero__bg--desk{display:none}
  .ss-pack-hero.has-mob-slideshow .ss-pack-hero__dots--desk{display:none}
  .ss-pack-hero.has-mob-slideshow .ss-pack-hero__bg--mob{display:block}
  .ss-pack-hero.has-mob-slideshow .ss-pack-hero__dots--mob{display:flex}
}

/* 2. Бегущая строка сразу под hero.
   ⛔ overflow:hidden ЗДЕСЬ — ЗАЩИТА, А НЕ ОФОРМЛЕНИЕ. Лента заведомо шире
      вьюпорта; без обрезки она растягивает <body>, и вбок едет ВСЯ страница
      (инвариант 4 SPEC-09; 13.08.2026 таким образом ехали все 276 страниц).
      Снять «чтобы тень не резалась» нельзя — сначала проверка §29 в чекапе. */
.ss-marquee{
  display:block;
  position:relative;
  overflow:hidden;
  max-width:100%;
  text-decoration:none;
  background:var(--ss-dark-panel);
  color:var(--ss-text-on-dark);
  padding:.85rem 0;
  cursor:pointer;
}
.ss-marquee:hover{color:var(--ss-amber)}
/* width:max-content — лента ровно по содержимому; иначе группы сожмутся по ширине
   экрана и «бесконечность» превратится в дёрганый цикл. */
.ss-marquee__track{
  display:flex;
  width:max-content;
  animation:ss-marquee-run 38s linear infinite;
  will-change:transform;
}
.ss-marquee__group{display:flex;align-items:center;flex:none}
.ss-marquee__item{
  font-family:'Cormorant Garamond', Georgia, serif;
  font-style:italic;
  font-size:1.45rem;
  line-height:1.2;
  white-space:nowrap;
  padding:0 .55rem;
}
.ss-marquee__item--brand{color:var(--ss-amber)}
.ss-marquee__sep{font-size:.55rem;opacity:.55;padding:0 .55rem;transform:translateY(-.35em)}
/* Пауза под курсором: строка кликабельная, и читать её на ходу неудобно. */
.ss-marquee:hover .ss-marquee__track,
.ss-marquee:focus-visible .ss-marquee__track{animation-play-state:paused}
/* Две одинаковые группы подряд: сдвиг ровно на -50% возвращает ленту в исходное
   положение, и шва не видно. */
@keyframes ss-marquee-run{from{transform:translateX(0)}to{transform:translateX(-50%)}}
/* ⛔ Инвариант 5 SPEC-09: при «уменьшить движение» лента СТОИТ. Тот же принцип,
   что у слайдера фона героя выше по файлу. */
@media (prefers-reduced-motion: reduce){
  .ss-marquee__track{animation:none}
}
@media (max-width: 575.98px){
  .ss-marquee{padding:.7rem 0}
  .ss-marquee__item{font-size:1.2rem;padding:0 .4rem}
  .ss-marquee__sep{padding:0 .4rem}
}

/* 3. Информационный блок: текст о формате слева, показатели справа.
   До 992px — одна колонка: показатели уходят под текст, а не жмутся в 120px. */
.ss-pack-info__grid{display:grid;gap:2rem;align-items:start}
@media (min-width: 992px){
  .ss-pack-info__grid{grid-template-columns:minmax(0,1fr) minmax(300px,360px);gap:3rem}
  .ss-pack-info__grid--facts-only{grid-template-columns:minmax(0,1fr)}
}
.ss-pack-info__text{max-width:720px}
.ss-pack-facts{
  list-style:none;
  margin:0;
  padding:0;
  display:grid;
  grid-template-columns:repeat(2, minmax(0,1fr));
  gap:1rem;
}
.ss-pack-fact{
  background:var(--ss-card);
  border:1px solid var(--ss-divider);
  border-radius:14px;
  padding:1.1rem 1rem;
  display:flex;
  flex-direction:column;
  gap:.35rem;
  min-width:0;                 /* иначе длинное значение растянет колонку наружу */
}
.ss-pack-fact__value{
  font-family:'Cormorant Garamond', Georgia, serif;
  font-size:1.6rem;
  line-height:1.15;
  color:var(--ss-accent);
  overflow-wrap:anywhere;      /* «2–4 часа» переносится, а не выпирает из плитки */
}
.ss-pack-fact__caption{
  font-size:.86rem;
  line-height:1.4;
  color:var(--ss-text-muted);
  /* break-word, а не anywhere: anywhere рвёт «Продолжительность» посреди слова
     даже когда её можно уместить, поджав кегль (снимок 390px, 01.09.2026). */
  overflow-wrap:break-word;
}
/* На телефоне плитка узкая, и самая длинная подпись ТЗ («Продолжительность»)
   в неё при базовом кегле не влезает — поджимаем поля и шрифт, а не ломаем слово. */
@media (max-width: 575.98px){
  .ss-pack-fact{padding:.9rem .75rem;border-radius:12px}
  .ss-pack-fact__value{font-size:1.4rem}
  .ss-pack-fact__caption{font-size:.78rem}
}
/* На 390 (наш опорный телефон) плитки остаются в две колонки: одна колонка
   растягивает блок на четыре экрана прокрутки. Одна колонка — только на узких
   320–360, где подпись «Продолжительность» в половину ширины уже не помещается. */
@media (max-width: 359.98px){
  .ss-pack-facts{grid-template-columns:minmax(0,1fr)}
}

/* 4. SEO-текст под списком программ — обычная проза, ширина как у описания. */
.ss-pack-seo__body{max-width:820px;margin:0 auto}
/* @@/SEC:S6@@ */

/* ─────────────────────────────────────────────────────────────────────────────
   @@SEC:S4a@@ — детальная бани: hero и блок «О бане» (SPEC-08, слайс S4a)

   ТЗ заказчика, часть 2 (docs/tz-banya.md), дословно:
   · HERO — «изменить цвет шрифта заголовка бани на белый, подзаголовки цветными»,
     «усилить акцент на количество гостей · длительность · стоимость»,
     «добавить сноску узнать больше»;
   · «2 О БАНЕ» — «часть текста сформировать вдоль картинки + добавить „окошки“ с
     характеристиками», «весь остальной текст уводим под фото и характеристики +
     кнопка раскрыть».

   ⚠️ Секция дописана В КОНЕЦ файла одним куском — на 01.09.2026 theme.css правят
   параллельно три слайса волны (S3b, S4a, S6), и это единственный способ не
   разъехаться. Ничего выше не тронуто.
   ───────────────────────────────────────────────────────────────────────────── */

/* ── HERO ──────────────────────────────────────────────────────────────────── */

/* ⛔ БЕЛЫЙ ЗАГОЛОВОК ЗАКРЕПЛЁН ПРАВИЛОМ, А НЕ ТОЛЬКО СНЯТЫМ КЛАССОМ. Снять
   `ss-amber` с <em> недостаточно: выше по файлу лежит
   `.ss-banya-detail-hero .ss-serif { color: var(--ss-text-on-dark) }` — та же
   специфичность (0,2,0), и без этого правила заголовок красился бы в кремовый
   #EFE8DC, а не в белый #FDFAF4. Разница видна на затемнённом фото и ровно её
   ТЗ и просит. */
.ss-banya-detail-hero .ss-banya-hero__title,
.ss-banya-detail-hero .ss-banya-hero__title em {
  color: #FDFAF4;
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.45);
}

/* «Подзаголовки цветными» — надзаголовок (тип бани) и тизер.
   ⚠️ КОНТРАСТ ЗДЕСЬ НЕ ЗАМЕРЕН ПО AA, И ЭТО НЕ ЗАБЫВЧИВОСТЬ: фон — фотография,
   у каждой из четырёх бань своя, и одного числа для него не существует. Цвет
   назначен ТЗ заказчика («подзаголовки цветными») — как и терракота CTA, это
   решение о бренде, а не наша уборка стилей. Что сделано безусловно полезного:
   тень под текстом и плотная подложка у плашек ниже. Записать в CHECKLIST как
   замеренное расхождение нельзя — замера нет. */
.ss-banya-detail-hero .ss-banya-hero__kicker {
  color: var(--ss-amber);
  text-shadow: 0 1px 6px rgba(0, 0, 0, 0.6);
}
.ss-banya-detail-hero .ss-banya-hero__lede {
  color: var(--ss-amber);
  font-size: clamp(19px, 2.1vw, 26px);
  font-weight: 400;
  line-height: 1.35;
  max-width: 34ch;
  text-shadow: 0 1px 8px rgba(0, 0, 0, 0.6);
}

/* Три показателя — раздельными плашками вместо одной строки через «·».
   flex-wrap + flex:1 1 auto: на 1440 три плашки встают в ряд, на телефоне
   переносятся; количество их — от строки заказчика, а не от вёрстки. */
.ss-hero-stats {
  display: flex;
  flex-wrap: wrap;
  gap: 12px;
  margin: 0 0 30px;
}
.ss-hero-stat {
  flex: 1 1 auto;
  min-width: 0;
  display: flex;
  align-items: center;
  gap: 12px;
  padding: 14px 20px;
  border: 1px solid rgba(201, 166, 107, 0.38);
  border-radius: 14px;
  /* Подложка плотная НАМЕРЕННО: плашка лежит на фотографии, и светлого кадра под
     ней достаточно, чтобы белая надпись растворилась. Прозрачнее делать нельзя. */
  background: rgba(26, 20, 18, 0.55);
}
.ss-hero-stat__icon { flex: none; display: inline-flex; color: var(--ss-amber); }
/* Иконка приезжает из spasol_banya_meta_icon() с атрибутами 16×16 — в hero она
   крупнее, атрибуты перебиваются стилем. */
.ss-hero-stat__icon .ss-banya-meta-icon { width: 22px; height: 22px; }
.ss-hero-stat__body { display: flex; flex-direction: column; gap: 3px; min-width: 0; }
.ss-hero-stat__label {
  font-family: 'Manrope', sans-serif;
  font-size: 11px;   /* M20-9 (12px) перенесён в @@SEC:M20-9@@ — на 1440 не должен меняться (Н-2) */
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: rgba(201, 166, 107, 0.9);
}
.ss-hero-stat__value {
  font-family: 'Manrope', sans-serif;
  font-size: 17px;
  font-weight: 600;
  line-height: 1.25;
  color: #FDFAF4;
}
/* «Цену сделать заметнее» — то же решение, что у .ss-banya-meta-item.is-price
   на карточках, чтобы страница и карточка говорили одним языком. */
.ss-hero-stat.is-price { border-color: rgba(201, 166, 107, 0.7); }
.ss-hero-stat.is-price .ss-hero-stat__value { color: var(--ss-amber); font-size: 19px; }

/* Сноска «узнать больше» — якорь на блок «О бане». Тач-цель 44px по высоте:
   это ссылка, а не подпись. */
.ss-hero-more {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  margin-top: 26px;
  padding: 12px 0;
  min-height: 44px;
  font-family: 'Manrope', sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.2em;
  text-transform: uppercase;
  color: var(--ss-text-on-dark);
  opacity: 0.8;
  text-decoration: none;
  border-bottom: 1px solid rgba(239, 232, 220, 0.3);
  transition: opacity 0.2s ease, color 0.2s ease, gap 0.2s ease;
}
.ss-hero-more:hover,
.ss-hero-more:focus-visible { opacity: 1; color: var(--ss-amber); gap: 12px; }
.ss-hero-more svg { animation: ss-hint-nudge 2.4s ease-in-out infinite; }
@media (prefers-reduced-motion: reduce) { .ss-hero-more svg { animation: none; } }

@media (max-width: 575.98px) {
  .ss-hero-stats { gap: 8px; margin-bottom: 24px; }
  .ss-hero-stat { padding: 11px 15px; border-radius: 12px; gap: 10px; }
  .ss-hero-stat__icon .ss-banya-meta-icon { width: 18px; height: 18px; }
  .ss-hero-stat__value { font-size: 15px; }
  .ss-hero-stat.is-price .ss-hero-stat__value { font-size: 16px; }
  .ss-hero-more { letter-spacing: 0.14em; }
}

/* ── «О БАНЕ» ──────────────────────────────────────────────────────────────── */

/* ⚠️ ПОБОЧНЫЙ СЛЕД ДЛЯ УБОРКИ. Правила `.ss-banya-legend__photo` (выше по файлу,
   ~строка 2811) стали мёртвыми: блок «Легенда» на детальной бани заменён блоком
   «О бане» со своим `.ss-banya-about__photo`, а больше `__photo` никто не звал.
   Не удалены сознательно — они лежат в общей части файла, которую в волне
   01.09.2026 параллельно правят ещё два слайса. Сам набор `.ss-banya-legend`
   (типографика описания) ЖИВОЙ: его зовут пять статических страниц
   (/spa-tsentr/, /detskaya-komnata/, /korporativnoe-obsluzhivanie/, /cashback/,
   /presents/) и оба текста этого блока. Сносить можно только `__photo`. */


/* Фото 4:5, как было у «Легенды». max-height добавлен из-за фито-бани: у неё в
   базе нет описания, рядом с фото стоит одна строка превью, и неограниченная
   колонка 4:5 на 1440 давала 690px фотографии против трёх строк текста. */
.ss-banya-about__photo img,
.ss-banya-about__photo .ss-img-placeholder {
  width: 100%;
  aspect-ratio: 4 / 5;
  max-height: min(70vh, 600px);
  object-fit: cover;
  border-radius: 14px;
  display: block;
}

/* Текст описания. Типографику даёт .ss-banya-legend (общая часть файла), здесь
   только ширина строки и укрощение заголовков ИЗ ТЕКСТА ЗАКАЗЧИКА: в описаниях
   бань, приехавших со старого сайта, стоят <h2> («Что ждёт поклонников русской
   бани?»), и без этого правила они рисуются кеглем заголовка секции — крупнее,
   чем название самого блока. */
.ss-banya-about__text {
  max-width: 68ch;
  font-family: var(--ss-copy-font);
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text);
}
.ss-banya-about__text :where(p, div, ul, ol, li, span, strong, b, em, i, font) {
  font-family: inherit !important;
  font-size: inherit !important;
  line-height: inherit !important;
}
.ss-banya-about__text :where(p, div, ul, ol) { margin-bottom: 18px; }
.ss-banya-about__text :where(p, div, ul, ol):last-child { margin-bottom: 0; }
.ss-banya-about__text :where(h1, h2, h3, h4):empty { display: none; }
.ss-banya-about__text h1,
.ss-banya-about__text h2,
.ss-banya-about__text h3,
.ss-banya-about__text h4 {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-size: 26px;
  line-height: 1.25;
  color: var(--ss-text);
  margin: 30px 0 12px;
}
.ss-banya-about__text a { color: var(--ss-accent); }

/* «Окошки» с характеристиками. auto-fit: их от нуля до трёх — сколько данных
   нашлось, столько и колонок (см. шапку шаблона: температуру даёт свойство,
   которого до прогона миграции слайса S3b в базе нет). */
.ss-about-specs {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(148px, 1fr));
  gap: 12px;
  margin: 30px 0 0;
}
.ss-about-spec {
  padding: 16px 18px;
  background: var(--ss-card);
  border: 1px solid var(--ss-divider);
  border-radius: 14px;
}
.ss-about-spec__label {
  font-family: 'Manrope', sans-serif;
  font-size: 11px;   /* M20-9 (12px) перенесён в @@SEC:M20-9@@ — на 1440 не должен меняться (Н-2) */
  font-weight: 600;
  letter-spacing: 0.16em;
  text-transform: uppercase;
  color: var(--ss-text-muted);
  margin: 0 0 6px;
}
/* margin: 0 обязателен — у <dd> браузерный отступ слева 40px. */
.ss-about-spec__value {
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-style: italic;
  font-size: 24px;
  line-height: 1.2;
  color: var(--ss-accent);
  margin: 0;
}

/* Кнопка «раскрыть». Это <summary>, а не <button>: раскрытие обязано работать
   без JS (инвариант дела, тот же приём у аккордеона правил бронирования). */
.ss-about-more { margin-top: 38px; }
.ss-about-more__toggle {
  display: inline-flex;
  align-items: center;
  gap: 10px;
  min-height: 44px;
  padding: 12px 26px;
  margin: 0;
  list-style: none;
  cursor: pointer;
  border: 1px solid var(--ss-amber);
  border-radius: 999px;
  background: rgba(201, 166, 107, 0.10);
  color: var(--ss-accent);
  font-family: 'Manrope', sans-serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  transition: background 0.2s ease, color 0.2s ease;
}
.ss-about-more__toggle::-webkit-details-marker { display: none; }
.ss-about-more__toggle:hover { background: var(--ss-amber); color: var(--ss-dark-panel); }

/* Две подписи, переключаются состоянием самого <details> — без единой строки JS. */
.ss-about-more__label--open { display: none; }
.ss-about-more[open] .ss-about-more__label { display: none; }
.ss-about-more[open] .ss-about-more__label--open { display: inline; }

/* Шеврон: вниз → вверх. */
.ss-about-more__icon { position: relative; flex: none; width: 12px; height: 12px; }
.ss-about-more__icon::before {
  content: '';
  position: absolute;
  left: 1px;
  top: 1px;
  width: 8px;
  height: 8px;
  border-right: 1.6px solid currentColor;
  border-bottom: 1.6px solid currentColor;
  transform: rotate(45deg);
  transition: transform 0.28s ease;
}
.ss-about-more[open] .ss-about-more__icon::before { transform: rotate(-135deg); }

.ss-about-more__body { margin-top: 30px; max-width: 78ch; }

/* ⚠️ ПЛАВНОСТЬ — ПРОГРЕССИВНОЕ УЛУЧШЕНИЕ, А НЕ УСЛОВИЕ РАБОТЫ. Тот же приём и
   тот же довод, что у .ss-rule: браузер, не знающий ::details-content и
   interpolate-size, отбросит эти правила целиком и раскроет мгновенно —
   потеряется анимация, а не текст. */
.ss-banya-about { interpolate-size: allow-keywords; }
.ss-about-more::details-content {
  block-size: 0;
  overflow: hidden;
  transition: block-size 0.35s ease, content-visibility 0.35s allow-discrete;
}
.ss-about-more[open]::details-content { block-size: auto; }
@media (prefers-reduced-motion: reduce) {
  .ss-about-more::details-content { transition: none; }
  .ss-about-more__icon::before { transition: none; }
}

@media (max-width: 767.98px) {
  .ss-banya-about__photo img,
  .ss-banya-about__photo .ss-img-placeholder { max-height: 62vh; }
  .ss-about-specs { grid-template-columns: repeat(auto-fit, minmax(130px, 1fr)); gap: 10px; }
  .ss-about-spec { padding: 13px 15px; }
  .ss-about-spec__value { font-size: 21px; }
  .ss-about-more__toggle { padding: 12px 20px; font-size: 12px; }
}
/* ⚠️ КОРОТКОЕ ОПИСАНИЕ — свой вид, а не тот же с дырой. Случай фито-бани:
   описания в базе нет, рядом с фото одна строка превью. Колонка 4:5 (600px)
   против 250px содержимого оставляла под окошками треть экрана пустоты —
   замерено скриншотом 01.09.2026 @1440. Кадр становится 4:3 и ниже, колонки
   центрируются по вертикали (класс ряда ставит шаблон). Порог — длина текста,
   не код бани: заказчик допишет описание — вид переключится сам. */
.ss-banya-about--short .ss-banya-about__photo img,
.ss-banya-about--short .ss-banya-about__photo .ss-img-placeholder {
  aspect-ratio: 4 / 3;
  max-height: 420px;
}
@media (max-width: 991.98px) {
  .ss-banya-about--short .ss-banya-about__photo img,
  .ss-banya-about--short .ss-banya-about__photo .ss-img-placeholder { max-height: 320px; }
}
/* @@/SEC:S4a@@ */


/* ── @@SEC:S7@@ Список программ в пакете: название крупнее и цветом
   (SPEC-09, слайс S7, ТЗ заказчика 01.09.2026 §5) ────────────────────────────

   ТЗ дословно: «Название программы крупнее и выделить цветом». Остальные четыре
   требования того же пункта — скрытие цены, скрытие перехода, недоступные вниз,
   ручной порядок — вида не имеют вовсе: они живут в PHP и в свойствах, и в
   theme.css им делать нечего.

   ⚠️ ЦВЕТ — --ss-accent, А НЕ «КАКОЙ-НИБУДЬ ЗОЛОТОЙ». Это семантический акцент
   дизайн-системы: на светлом фоне тёмно-коньячный #8B6F3F, в тёмной теме сам
   переключается на amber (см. объявление токенов в начале файла). Замер контраста
   01.09.2026 по WCAG: на фоне карточки --ss-card 4.54:1 — норму AA берёт, а именно
   на карточке строка и лежит (.ss-menu-row--rich{background:var(--ss-card)}).
   Взять --ss-terracotta было нельзя: он же назначен цветом наведения, и название
   в состоянии покоя совпало бы с ним — hover перестал бы что-либо сообщать.

   ⚠️ СЕКЦИЯ ПЕРЕКРЫВАЕТ ПРАВИЛА ВЫШЕ, А НЕ ЗАМЕНЯЕТ ИХ. Базовые
   `.ss-menu-row--rich .ss-menu-row__name{font-size:1.08rem}` и правило гашения
   недоступной остаются на своих местах; здесь они переопределяются в конце файла —
   тот же приём, что у @@SEC:S2@@ поверх @@SEC:TOUR@@. Поэтому гашение недоступной
   ПОВТОРЕНО ниже явно: без повтора цветное правило этой секции победило бы по
   порядку следования, и снятая с продажи программа выглядела бы как обычная. */

.ss-menu-row--rich .ss-menu-row__name{
  font-size:1.32rem;
  font-weight:600;
  line-height:1.25;
  color:var(--ss-accent);
  letter-spacing:.005em;
}
.ss-menu-row--rich .ss-menu-row__name a{
  color:inherit;
  text-decoration:none;
}
.ss-menu-row--rich .ss-menu-row__name a:hover,
.ss-menu-row--rich .ss-menu-row__name a:focus-visible{
  color:var(--ss-terracotta);
}

/* ⛔ Недоступная программа гаснет — правило повторено здесь сознательно, см. шапку
   секции. Название приглушается, плашка «временно недоступна» цвет сохраняет:
   она и есть то, что в этой строке надо прочитать. */
.ss-menu-row--rich.is-unavail .ss-menu-row__name{color:var(--ss-text-muted)}
.ss-menu-row--rich.is-unavail .ss-menu-row__name a{color:inherit}

/* Крупное название и цена на одной baseline расходятся по весу: цену подтягиваем,
   иначе она читается подписью к названию, а не второй величиной строки. */
.ss-menu-row--rich .ss-menu-row__price{font-size:1.05rem}

@media (max-width: 575.98px){
  /* На телефоне строка переносится (см. правило .ss-menu-row__head{flex-wrap} выше),
     и полные 1.32rem у длинных названий занимают три строки — поэтому здесь размер
     чуть меньше.
     ⛔ НО НЕ МЕНЬШЕ 1.22rem. Требование ТЗ «название крупнее» проверяется
     ОТНОШЕНИЕМ к описанию строки (0.95rem), и на 1.18rem отношение падало до
     1.24× — то есть почти к прежнему 1.14×, при котором ТЗ и было написано.
     Замер браузером 02.09.2026: 1.22rem даёт 1.28×, порог замера — 1.25×
     (scripts/pack-programs-audit.js). */
  .ss-menu-row--rich .ss-menu-row__name{font-size:1.22rem}
}
/* @@/SEC:S7@@ */

/* ─────────────────────────────────────────────────────────────────────────────
   @@SEC:S4b@@ — детальная бани: «Особенности», «Что входит в посещение»,
   галерея бани (SPEC-08, слайс S4b, 02.09.2026; волна 01.09.2026)

   ТЗ заказчика, часть 2 (docs/tz-banya.md), дословно:
   · «3 ОСОБЕННОСТИ» — «сделать 4 карточки в сетке 2×2»; «дизайн карточек:
     скругление углов, крупное фото без лишних элементов»; «описание слева —
     справа возможность декоративного элемента»;
   · «5 ВХОДИТ В ПОСЕЩЕНИЕ» — «между колонками добавить тонкий вертикальный
     разделитель»; «между пунктами — лёгкие горизонтальные линии»; «заголовки
     выделить фирменным золотистым цветом»; «основной текст оставить спокойным
     нейтральным цветом»; «добавить справа атмосферное фото деталей бани с мягким
     переходом в фон»;
   · «6 ГАЛЕРЕЯ» — «сделать как на главной»: своих правил не заводит вовсе, вид
     живёт в @@SEC:S2@@ и @@SEC:TOUR@@, слайс приносит туда только группы.

   ⚠️ Секция дописана В КОНЕЦ файла одним куском — 01.09.2026 theme.css правят
   параллельно несколько слайсов волны, и это единственный способ не разъехаться.
   Ничего выше не тронуто.

   ⚠️ ПОБОЧНЫЙ СЛЕД ДЛЯ УБОРКИ. Правила `.ss-feature-card*` (выше по файлу,
   ~строка 2837) стали мёртвыми: карточка особенности переверстана в `.ss-feature`,
   а больше `.ss-feature-card` никто не зовёт (проверено грепом по всему клону).
   Не удалены сознательно — они лежат в общей части файла, которую в этой же волне
   правят соседние слайсы; снос делается отдельным решением, а не походя.
   ───────────────────────────────────────────────────────────────────────────── */

/* ═══ 1. ОСОБЕННОСТИ ═══════════════════════════════════════════════════════ */

/* «Описание слева — справа возможность декоративного элемента»: заголовок блока
   уходит из центра влево, орнамент встаёт справа. `auto` у второй колонки, а не
   доля: орнамент не должен отбирать ширину у заголовка на 992–1200px. */
.ss-features__head {
  display: grid;
  grid-template-columns: minmax(0, 1fr) auto;
  align-items: center;
  gap: 40px;
  margin-bottom: 46px;
}
/* .ss-divider-ornate центрируется `margin: 20px auto` — под левое выравнивание
   отменяем именно правый auto, а не задаём margin целиком: вертикальные отступы
   принадлежат общему правилу и должны остаться его. */
.ss-features__rule { margin-left: 0; margin-right: 0; }
.ss-features__ornament {
  flex: none;
  width: 118px;
  color: var(--ss-amber);
  opacity: 0.5;
}
.ss-features__ornament svg { display: block; width: 100%; height: auto; }

/* ⛔ ДВА СТОЛБЦА ЗАДАНЫ ЯВНО, ЧИСЛО КАРТОЧЕК В НИХ НЕ УЧАСТВУЕТ. «Сетка 2×2» —
   это про столбцы: заказчик заведёт пятую особенность — станет три ряда, а не
   ряд из пяти. Прежняя вёрстка считала ширину колонки от числа карточек
   (`intdiv(12, count)`) и на пяти особенностях рассыпалась. */
.ss-features__grid {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 30px;
}
/* ⚠️ ПОТОЛОК ШИРИНЫ — ЗАМЕР, А НЕ ВКУС. Без него на 1440 карточка выходит 670px,
   кадр 4:3 даёт 500px высоты, и блок из четырёх особенностей занимает 1700px —
   вдвое больше экрана. Тот же довод, что заставил в S2 понизить галерею:
   «крупное фото» и «блок помещается в экран» — оба требования, а не одно.
   Замер после правки: карточка 575px, кадр 383px, блок ~1100px. */
.ss-features__head,
.ss-features__grid { max-width: 1180px; margin-left: auto; margin-right: auto; }

.ss-feature {
  display: flex;
  flex-direction: column;
  background: var(--ss-card);
  /* «Скругление углов» ТЗ. 22px — заметно крупнее прежних 10px: при кадре во всю
     ширину карточки мелкий радиус на глаз не читается вовсе. */
  border-radius: 22px;
  overflow: hidden;
  transition: transform 0.3s ease, box-shadow 0.3s ease;
}
.ss-feature:hover {
  transform: translateY(-4px);
  box-shadow: 0 18px 40px rgba(58, 47, 40, 0.10);
}

/* «Крупное фото без лишних элементов»: кадр 4:3 во всю ширину карточки, поверх
   него ничего не лежит — ни подписи, ни затемнения, ни иконки. */
.ss-feature__photo {
  position: relative;
  aspect-ratio: 3 / 2;
  overflow: hidden;
  background: var(--ss-bg-alt);
}
.ss-feature__photo img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ⛔ ЗАГЛУШКА — ДЕКОРАТИВНАЯ ПАНЕЛЬ, А НЕ ИНЖЕНЕРНАЯ ШТРИХОВКА. Сегодня фотографии
   нет НИ У ОДНОЙ из шестнадцати особенностей (снято с базы стенда 02.09.2026), то
   есть это не крайний случай, а единственный вид блока, который видит посетитель.
   Общий `.ss-img-placeholder` (косая штриховка + подпись-код моноширинным) в сетке
   2×2 из крупных кадров читается как поломка вёрстки.
   Угол градиента задаёт шаблон переменной `--ss-blank` (0..3), иначе четыре
   одинаковые панели рядом. Значения по умолчанию — на случай, если переменную
   забудут передать. */
.ss-feature__photo--blank {
  --ss-blank: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  background:
    radial-gradient(110% 80% at 28% 18%, rgba(253, 250, 244, 0.55), transparent 62%),
    linear-gradient(calc(118deg + var(--ss-blank) * 37deg), #EBDDC3 0%, #DDCBA9 52%, #CDB88F 100%);
}
.ss-feature__photo--blank svg {
  width: 40%;
  max-width: 140px;
  height: auto;
  color: var(--ss-copper);
  opacity: 0.42;
}

.ss-feature__body {
  padding: 26px 28px 30px;
  display: flex;
  flex-direction: column;
  gap: 10px;
}
/* Золотой заголовок = `--ss-accent`, а не `--ss-amber`: на светлой карточке
   #C9A66B даёт контраст около 2:1 и текстом не читается. Ровно поэтому класс
   `.ss-amber` во всём деле объявлен как `color: var(--ss-accent)` (строка 154). */
.ss-feature__title {
  font-size: 27px;
  font-style: italic;
  line-height: 1.2;
  color: var(--ss-accent);
  margin: 0;
}
.ss-feature__text {
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text-muted);
  margin: 0;
}

@media (max-width: 767.98px) {
  /* Один столбец, а не два. Прежняя вёрстка держала `col-6` до самого узкого
     экрана: на 390px кадр «крупного фото» получал ~170px ширины. */
  .ss-features__grid { grid-template-columns: minmax(0, 1fr); gap: 22px; }
  .ss-features__head { gap: 20px; margin-bottom: 32px; }
  .ss-features__ornament { width: 74px; }
  .ss-feature { border-radius: 18px; }
  .ss-feature__body { padding: 20px 22px 24px; }
  .ss-feature__title { font-size: 24px; }
}
@media (max-width: 399.98px) {
  /* Орнамент — украшение; на самом узком экране он отбирает у заголовка треть
     строки и заголовок начинает переноситься по одному слову. */
  .ss-features__head { grid-template-columns: minmax(0, 1fr); }
  .ss-features__ornament { display: none; }
}

/* ═══ 2. «ЧТО ВХОДИТ В ПОСЕЩЕНИЕ» ══════════════════════════════════════════ */

/* Светлая карточная поверхность: блок стоит между «О бане» (--ss-bg) и
   «Особенностями» (--ss-bg-alt), и без своего фона три секции подряд слились бы
   в одно полотно. */
.ss-included { background: var(--ss-card); }

/* ⛔ ТРИ КОЛОНКИ — ПРЯМЫЕ ДЕТИ ОДНОГО ГРИДА, БЕЗ ОБЁРТКИ ВОКРУГ ПАРЫ СПИСКОВ.
   «Тонкий вертикальный разделитель» ТЗ — это левая граница второй колонки, и она
   обязана идти во всю высоту блока. Обёртка вокруг двух списков выравнивает
   высоты внутри себя, и линия обрывается там, где кончается более короткий
   список (у нас 3 пункта против 6 — обрыв на середине). Тот же класс ловушки,
   что у галереи в @@SEC:S2@@ и у таблицы сравнения в @@SEC:S3b@@. */
.ss-included__grid {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr) minmax(0, 0.82fr);
  gap: 0 44px;
  align-items: stretch;
}
.ss-included__col { min-width: 0; }
/* «Между колонками — тонкий вертикальный разделитель». Не `border-right` у
   первой: колонок может стать одна (заказчик очистит вторую), и висящая справа
   линия осталась бы разделять пустоту. */
.ss-included__col + .ss-included__col {
  border-left: 1px solid var(--ss-divider);
  padding-left: 44px;
}
.ss-included__overline { margin-bottom: 12px; }
/* «Заголовки выделить фирменным золотистым цветом» — см. довод о контрасте выше. */
.ss-included__title {
  font-size: clamp(28px, 3vw, 38px);
  line-height: 1.15;
  color: var(--ss-accent);
  margin: 0 0 22px;
}
.ss-included__list { list-style: none; padding: 0; margin: 0; }
/* «Между пунктами — лёгкие горизонтальные линии». Именно МЕЖДУ: `li + li`, а не
   `border-bottom` у каждого, иначе список кончается висящей чертой. */
.ss-included__item { padding: 13px 0; }
.ss-included__item + .ss-included__item { border-top: 1px solid var(--ss-divider); }
/* «Основной текст оставить спокойным нейтральным цветом». */
.ss-included__text {
  display: block;
  font-family: var(--ss-copy-font);
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text);
}
.ss-included__item-note {
  display: block;
  margin-top: 4px;
  font-size: 13px;
  line-height: 1.4;
  color: var(--ss-text-muted);
}

/* «Атмосферное фото деталей бани с мягким переходом в фон».
   ⚠️ ПЕРЕХОД СДЕЛАН МАСКОЙ, А НЕ ПОЛУПРОЗРАЧНОЙ КАРТИНКОЙ ПОВЕРХ: маска не знает
   цвета фона и потому не сломается, когда соседний слайс поменяет фон секции.
   Снизу — отдельная растушёвка `::after` в цвет секции: одной маской обе стороны
   не сделать без `mask-composite`, который в старых движках даёт объединение
   вместо пересечения и растворяет кадр целиком. */
.ss-included__photo {
  position: relative;
  align-self: stretch;
  min-height: 100%;
  overflow: hidden;
  border-radius: 0 18px 18px 0;
  -webkit-mask-image: linear-gradient(to right, transparent 0%, rgba(0, 0, 0, 0.55) 18%, #000 46%);
          mask-image: linear-gradient(to right, transparent 0%, rgba(0, 0, 0, 0.55) 18%, #000 46%);
}
.ss-included__photo img {
  width: 100%;
  height: 100%;
  min-height: 420px;
  object-fit: cover;
  display: block;
}
.ss-included__photo::after {
  content: '';
  position: absolute;
  inset: 0;
  background: linear-gradient(to top, var(--ss-card) 0%, rgba(253, 250, 244, 0) 26%);
  pointer-events: none;
}

.ss-included__foot {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 20px 32px;
  margin-top: 38px;
  padding-top: 26px;
  border-top: 1px solid var(--ss-divider);
}
.ss-included__note {
  margin: 0;
  max-width: 52ch;
  font-size: 14px;
  line-height: 1.55;
  color: var(--ss-text-muted);
}
/* ⛔ Кнопка — не украшение подвала блока, а причина, по которой блок подняли
   вверх (решение министра «блок конверсионный»). Не убирать. */
.ss-included__cta { flex: none; }

@media (max-width: 991.98px) {
  /* Фото уходит под списки во всю ширину: в третью колонку на 768px ему
     оставалось бы около 150px, и «атмосферное фото деталей» превратилось бы в
     вертикальную полоску. */
  .ss-included__grid { grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 0 32px; }
  .ss-included__col + .ss-included__col { padding-left: 32px; }
  .ss-included__photo {
    grid-column: 1 / -1;
    margin-top: 34px;
    border-radius: 18px;
    -webkit-mask-image: none;
            mask-image: none;
  }
  .ss-included__photo img { min-height: 0; aspect-ratio: 16 / 7; }
  .ss-included__photo::after { background: none; }
}
@media (max-width: 575.98px) {
  /* Одна колонка: вертикальный разделитель между списками теряет смысл, вместо
     него списки разделяет горизонтальная линия — та же «лёгкая линия» ТЗ. */
  .ss-included__grid { grid-template-columns: minmax(0, 1fr); }
  .ss-included__col + .ss-included__col {
    border-left: 0;
    padding-left: 0;
    margin-top: 34px;
    padding-top: 30px;
    border-top: 1px solid var(--ss-divider);
  }
  .ss-included__photo img { aspect-ratio: 4 / 3; }
  /* Распорка нужна только когда колонки стоят рядом; в столбик она даёт пустую
     строку между разделителем и заголовком второго списка. */
  .ss-included__overline--spacer { display: none; }
  .ss-included__foot { gap: 18px; }
  .ss-included__cta { width: 100%; text-align: center; }
}
/* @@/SEC:S4b@@ */

/* ─────────────────────────────────────────────────────────────────────────────
   @@SEC:S8@@ — детальная программы: hero с фото и показатели «окошками»
   (SPEC-09, слайс S8, 02.09.2026)

   ТЗ на страницу программы заказчик не присылал; решения приняты «на усмотрение»
   и подписаны министром 01.09.2026 — разбор в спеке, «Страница программы».
   Здесь ровно два предмета: первый экран, который до сих пор был без изображения,
   и полоса показателей вместо россыпи чипов.

   ⚠️ Секция дописана В КОНЕЦ файла одним куском: theme.css правят параллельные
   слайсы волны, и это единственный способ не затереть соседа. Ничего выше не
   тронуто.
   ───────────────────────────────────────────────────────────────────────────── */

/* ── 1. Первый экран с фотографией ─────────────────────────────────────────── */

/* Кадр — фоном самой секции, значит полноширинный, как у пакета (`.ss-pack-hero`).
   Затемнение приезжает градиентом в том же background из шаблона: у программы кадр
   один, перекрёстного затухания нет, и отдельный слой-скрим был бы лишним
   абсолютным элементом поверх текста. */
.ss-program-hero {
  position: relative;
  background-size: cover;
  background-position: center;
}
/* Без фотографии всё остаётся ровно как было: светлая шапка, тёмный текст. Класс
   has-photo ставит шаблон, и все правила ниже висят на нём — программа без кадра
   (в базе таких нет, но данные ведёт заказчик) не должна получить белый текст на
   белом фоне. */
/* Высота и выравнивание — те же, что у героя пакета (комментарий заказчика
   02.09.2026: «те же правки будут для этого блока»). Числа не свои: 90vh/70vh
   пришли от `.ss-banya-detail-hero`, через `.ss-pack-hero`. Прежний clamp
   (340–540px) давал первый экран вдвое ниже соседних разделов, и три страницы
   подряд — баня, пакет, программа — читались как три разных сайта. */
.ss-program-hero.has-photo {
  min-height: 90vh;
  display: flex;
  align-items: center;
  padding: 150px 0 46px;
  border-bottom: 0;
}
.ss-program-hero.has-photo > .ss-container { width: 100%; position: relative; z-index: 1; }
/* Частного правила размера здесь больше нет: 02.09.2026 переопределение 72px
   снято у самого `.ss-spa-hero`, и заголовок программы приходит базовым — 60px,
   как везде. Строка-предшественник (частный клэмп ровно с теми же числами)
   удалена в том же заходе, чтобы размер не был объявлен дважды. */
/* Слои фона и точки на детальной — те же классы, что у пакета (см. шаблон).
   Отдельного правила им не нужно, кроме одного: у `.ss-spa-hero` есть нижняя
   граница и светлый фон, и при слайдере они обязаны уйти — иначе под фотографией
   останется полоса. */
.ss-program-hero.has-slideshow { background: #1a1412; border-bottom: 0; }
.ss-program-hero.has-photo,
.ss-program-hero.has-photo .ss-title-hero { color: var(--ss-text-on-dark); }
.ss-program-hero.has-photo .ss-overline { color: var(--ss-amber); }
/* Тень под заголовком и ценой — не украшение: кадры у 60 программ из 215 мелкие
   (300×200, замер 02.09.2026), растянуты и потому светлые пятнами; на «Сказке о
   русалке» золотой заголовок без тени сливался с песком. */
.ss-program-hero.has-photo .ss-title-hero,
.ss-program-hero.has-photo .ss-program-hero__price { text-shadow: 0 2px 12px rgba(0, 0, 0, 0.55); }

/* Плашки под заголовком: «временно недоступна» и метки программы. */
.ss-program-hero__badges {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  gap: 10px;
  margin-top: 22px;
}

/* Цена и «Записаться» — одной строкой, как у пакета.
   ⛔ margin-left ОБНУЛЯЕТСЯ ЯВНО: у .ss-program-hero__price выше по файлу стоит
   `margin-left: auto` — он прижимал цену к правому краю прежней строки чипов, а в
   этой строке отбросил бы кнопку на другой конец экрана. */
.ss-program-hero__actions {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  gap: 1.25rem;
  margin-top: 28px;
}
.ss-program-hero__actions .ss-program-hero__price { margin-left: 0; }
.ss-program-hero.has-photo .ss-program-hero__price { color: var(--ss-amber); }

@media (max-width: 767.98px) {
  /* 70vh — как у героя пакета и детальной бани на телефоне (02.09.2026).
     ⚠️ Правило стоит ИМЕННО ЗДЕСЬ: телефонный блок ниже по файлу перебивал
     любую высоту, поставленную рядом с базовым правилом, — там было 300px. */
  .ss-program-hero.has-photo { min-height: 70vh; padding: 118px 0 34px; }
  .ss-program-hero__actions { gap: 0.9rem; margin-top: 22px; }
  /* Кнопка на телефоне — во всю ширину: цена уходит на строку выше, и кнопка в
     половину экрана рядом с пустотой выглядит обрубком. */
  .ss-program-hero__actions .btn { flex: 1 1 100%; }
}

/* ── 2. Показатели «окошками» ──────────────────────────────────────────────── */

/* Сами рамки, кегль и подписи — общие с деталью бани (@@SEC:S4a@@, `.ss-about-spec*`).
   Здесь только раскладка полосой под героем: у бани окошки стоят в колонке рядом с
   фотографией, у программы — в ряд во всю ширину контейнера. */
.ss-program-specs { padding: 34px 0 0; }
.ss-program-specs .ss-about-specs {
  margin: 0;
  /* min(100%, 220px): без min() у длинного значения («Тело · Голова/волосы ·
     Массаж · Пилинг») колонка не сжимается ниже 220px и полоса выезжает за экран
     на 390 — типовая причина горизонтального скролла (инвариант 4 SPEC-09). */
  grid-template-columns: repeat(auto-fit, minmax(min(100%, 220px), 1fr));
}
/* Перечисление зон и уходов длиннее двух слов кеглем 24px превращается в четыре
   строки и ломает высоту ряда — поджимаем его, а не рвём слово. Порог по длине
   значения ставит шаблон (22 знака), а не список кодов программ. */
.ss-about-spec__value.is-long { font-size: 19px; line-height: 1.32; }

/* ⛔ ОДНО-ДВА ОКОШКА НЕ РАСТЯГИВАЮТСЯ НА ВСЮ ШИРИНУ. auto-fit с 1fr отдаёт
   единственной плитке всю строку, и у самой бедной программы («Брови и ресницы»:
   ни длительности, ни зон, ни числа гостей) получалась рамка в 1400px с надписью
   «от 800 ₽» — снимок 02.09.2026 @1440. Число окошек шаблон кладёт в атрибут
   секции, поэтому вид переключается без единой строки скрипта и без класса-костыля.
   Три и четыре плитки по-прежнему делят строку поровну — там растяжение как раз
   и требуется. */
.ss-program-specs[data-ss-specs="1"] .ss-about-specs { grid-template-columns: minmax(0, 340px); }
.ss-program-specs[data-ss-specs="2"] .ss-about-specs { grid-template-columns: repeat(2, minmax(0, 340px)); }

@media (max-width: 767.98px) {
  .ss-program-specs { padding: 26px 0 0; }
  /* Две колонки, а не одна: четыре окошка в столбик — это ещё экран прокрутки до
     описания. Тот же вывод, что у показателей пакета в @@SEC:S6@@. */
  .ss-program-specs .ss-about-specs { grid-template-columns: repeat(2, minmax(0, 1fr)); }
  .ss-about-spec__value.is-long { font-size: 16px; }
}
/* Ниже 360px две колонки уже не держат подпись «Длительность» — распускаем в одну. */
@media (max-width: 359.98px) {
  .ss-program-specs .ss-about-specs { grid-template-columns: minmax(0, 1fr); }
}
/* @@/SEC:S8@@ */

/* ═══════════════════════════════════════════════════════════════════════════
   @@SEC:S5@@ — детальная бани: правило аренды и блок программ (SPEC-08, S5)

   ТЗ заказчика, часть 2 §4 «ПРОГРАММЫ В БАНЯХ»: «перенести блок с тёмного фона
   на светлый фирменный фон сайта (кремовый/бежевый)». Решение министра
   01.09.2026: программы привязываются к бане так же, как к пакам, и отдельно
   оформляется ПРАВИЛО АРЕНДЫ (docs/facts/banya-rental.md).

   ⚠️ СЕКЦИЯ ДОПИСАНА В КОНЕЦ ФАЙЛА ОДНИМ КУСКОМ И НИЧЕГО ВЫШЕ НЕ ПРАВИТ.
   theme.css — общий файл, и в ночь на 02.09.2026 слайс уже потерял чужую строку,
   записав файл целиком из прочитанной раньше копии. Правки поверх чужих секций
   тут не делаются вовсе: всё, что нужно перебить, перебивается отсюда.
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Блок программ ──────────────────────────────────────────────────────────
   ⛔ ФОН ОБЪЯВЛЕН ЯВНО, И ЭТО НЕ ДЕКОРАЦИЯ. После снятия тёмной темы (S1) секция
   и так стоит на светлом — но лишь потому, что светлой стала вся страница, а
   требование ТЗ относится к БЛОКУ. Явное правило делает требование проверяемым:
   вернут блоку тёмную подложку — покраснеет checkup.sh §34, а не «заметим
   глазами когда-нибудь».
   ⚠️ Кремовый --ss-bg (#F5EFE6), а НЕ бежевый --ss-bg-alt: сверху галерея, снизу
   бронирование — обе на --ss-bg-alt, и третья бежевая полоса подряд слепила бы
   три секции в одну ленту. «Кремовый/бежевый» ТЗ — про обе краски дела. */
.ss-banya-programs { background: var(--ss-bg); }

/* Дополнительные программы продолжают один flex-список без промежуточного отступа. */
.ss-banya-programs-more__extra { display: contents; }
.ss-banya-programs-more__extra[hidden],
.ss-banya-programs-more__toggle[hidden] { display: none !important; }


/* ── Правило аренды: карточка-сценарий из трёх шагов ────────────────────────
   ⚠️ ПОЧЕМУ КАРТОЧКА, А НЕ ПОЛОСА ФОНОМ. Блок стоит между «Что входит»
   (--ss-bg) и «Особенностями» (--ss-bg-alt). Полоса --ss-bg-alt слилась бы с
   особенностями, полоса --ss-bg — с «Что входит»; отделяет блок сама панель. */
.ss-banya-rental__panel {
  background: var(--ss-card);
  border: 1px solid rgba(139, 111, 63, 0.18);
  border-radius: 22px;                      /* тот же радиус, что у карточек S4b */
  padding: clamp(28px, 4vw, 56px);
  max-width: 1180px;                        /* потолок сетки особенностей, S4b */
  margin: 0 auto;
  box-shadow: 0 8px 24px rgba(58, 47, 40, 0.06);
}
.ss-banya-rental__head { text-align: center; max-width: 720px; margin: 0 auto 40px; }
.ss-banya-rental__title { margin: 12px 0 0; }
.ss-banya-rental__lead { margin: 16px 0 0; }

/* ⚠️ Список остаётся списком: маркер снят, семантика <ol> сохранена — порядок
   шагов здесь несёт смысл, и скринридер обязан прочитать «список из трёх». */
.ss-banya-rental__steps {
  list-style: none;
  margin: 0;
  padding: 0;
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: clamp(20px, 3vw, 40px);
}
.ss-banya-rental__step { position: relative; padding-top: 4px; }

/* Разделитель между шагами — волосяная линия, как между строками «Почему наши
   бани». На телефоне колонок нет, и линия переезжает наверх (см. медиазапрос). */
.ss-banya-rental__step + .ss-banya-rental__step { border-left: 1px solid rgba(139, 111, 63, 0.16); padding-left: clamp(20px, 3vw, 40px); }

.ss-banya-rental__num {
  display: block;
  font-family: 'Cormorant Garamond', serif;
  font-size: clamp(34px, 3.4vw, 46px);
  line-height: 1;
  /* ⛔ --ss-accent (#8B6F3F), а НЕ --ss-amber (#C9A66B): амбра на карточке
     #FDFAF4 даёт около 2:1 и текстом не читается. Ровно поэтому класс .ss-amber
     во всём деле объявлен через --ss-accent (разбор — @@SEC:S4b@@). */
  color: var(--ss-accent);
  margin-bottom: 14px;
}
.ss-banya-rental__step-title { font-size: clamp(22px, 1.9vw, 26px); margin: 0 0 10px; }
.ss-banya-rental__step-text  { font-size: var(--ss-copy-size); line-height: var(--ss-copy-leading); color: var(--ss-text-muted); margin: 0; }
.ss-banya-rental__foot { margin-top: 40px; text-align: center; }

@media (max-width: 767.98px) {
  .ss-banya-rental__steps { grid-template-columns: minmax(0, 1fr); gap: 26px; }
  /* Вертикальная линия на телефоне не имеет смысла — шаги идут друг под другом,
     и разделитель обязан лечь поперёк, а не вдоль. */
  .ss-banya-rental__step + .ss-banya-rental__step {
    border-left: 0;
    padding-left: 0;
    border-top: 1px solid rgba(139, 111, 63, 0.16);
    padding-top: 24px;
  }
  .ss-banya-rental__panel { padding: 26px 20px; border-radius: 18px; }
  .ss-banya-rental__cta { width: 100%; text-align: center; }
}
/* @@/SEC:S5@@ */

/* ═════════════════════════════════════════════════════════════════════════════
   @@SEC:W1@@ — обложка страницы программы: смешанное выделение заголовка,
   короткое описание, усиленное затемнение слева (SPEC-12 §О1, ТЗ 08.09.2026)

   ⚠️ Секция дописана В КОНЕЦ файла одним куском — тот же порядок, что у слайсов
   волны 01–02.09: theme.css правят разные сессии, и дописывание в хвост —
   единственный способ не затереть соседа. Ничего выше не тронуто.
   ───────────────────────────────────────────────────────────────────────────── */

/* Светлая часть названия. Курсив здесь объявляется явно: <em> его даёт сам,
   а <span> — нет, и без этой строки половина заголовка встала бы прямым
   начертанием рядом с курсивной. Цвет — тот же, которым обложка красит текст
   на фото, чтобы «светлая часть» не оказалась третьим оттенком белого. */
.ss-title-hero__lead {
  font-style: italic;
  color: var(--ss-text-on-dark);
}
/* Программа без фотографии (в базе таких нет, но кадр ведёт заказчик) стоит на
   светлом фоне — там белая половина заголовка исчезла бы. Наследуем цвет секции. */
.ss-program-hero:not(.has-photo) .ss-title-hero__lead { color: inherit; }

/* Короткое описание под заголовком. Ширина ограничена намеренно: строка во весь
   экран на 1440 читается тяжело и спорит с требованием ТЗ «минимум текста поверх
   изображения». Тень — по той же причине, что у заголовка и цены: кадры у 60
   программ из 215 мелкие и растянуто-светлые (замер 02.09.2026). */
.ss-program-hero__lede {
  margin: 1rem 0 0;
  max-width: 33rem;
  font-size: 1.02rem;
  line-height: 1.55;
}
.ss-program-hero.has-photo .ss-program-hero__lede {
  color: rgba(255, 255, 255, 0.88);
  text-shadow: 0 2px 10px rgba(0, 0, 0, 0.55);
}

/* Затемнение у страниц БЕЗ слайд-шоу — отдельным слоем, а не вторым фоном
   секции. Причина не косметическая: градиент в inline-стиле шаблона нельзя
   перебить медиазапросом, и на 390px горизонтальная ветка оставалась там, где
   она вредна (поймано замером 08.09.2026, см. комментарий в шаблоне).
   Слой лежит ПОД контейнером: у `.ss-program-hero.has-photo > .ss-container`
   уже стоит z-index:1. */
.ss-program-hero.has-photo:not(.has-slideshow)::before {
  content: "";
  position: absolute;
  inset: 0;
  pointer-events: none;
  background:
    linear-gradient(90deg,
      rgba(26, 20, 18, .82) 0%,
      rgba(26, 20, 18, .62) 26%,
      rgba(26, 20, 18, .22) 54%,
      rgba(26, 20, 18, .00) 74%),
    linear-gradient(180deg,
      rgba(26, 20, 18, .46) 0%,
      rgba(26, 20, 18, .06) 30%,
      rgba(26, 20, 18, .10) 70%,
      rgba(26, 20, 18, .55) 100%);
}

/* Затемнение слева у страниц со слайд-шоу. Общий `.ss-pack-hero__scrim` не
   трогаем — он несёт шапки пакетов и бань, это чужая зона; здесь только
   частное усиление под требование ТЗ. Разница с общим скримом — первые две
   остановки (.74→.82, .56→.62): текста в левой колонке у программы больше,
   чем у пакета, теперь ещё и описание. */
.ss-program-hero .ss-pack-hero__scrim {
  background:
    linear-gradient(90deg,
      rgba(0, 0, 0, .82) 0%,
      rgba(0, 0, 0, .62) 26%,
      rgba(0, 0, 0, .22) 54%,
      rgba(0, 0, 0, .00) 74%),
    linear-gradient(180deg,
      rgba(0, 0, 0, .46) 0%,
      rgba(0, 0, 0, .06) 30%,
      rgba(0, 0, 0, .10) 70%,
      rgba(0, 0, 0, .52) 100%);
}
/* На телефоне колонки нет — текст во всю ширину, и горизонтальный градиент
   оставил бы правый край строки на светлом. Исключение то же, что у шапки
   пакета (@@SEC:S6@@) и обложки главной. */
@media (max-width: 767.98px) {
  .ss-program-hero .ss-pack-hero__scrim {
    background: linear-gradient(180deg, rgba(0, 0, 0, .68) 0%, rgba(0, 0, 0, .62) 50%, rgba(0, 0, 0, .76) 100%);
  }
  .ss-program-hero.has-photo:not(.has-slideshow)::before {
    background: linear-gradient(180deg, rgba(26, 20, 18, .68) 0%, rgba(26, 20, 18, .62) 50%, rgba(26, 20, 18, .76) 100%);
  }
  .ss-program-hero__lede { font-size: 0.96rem; max-width: none; }
}
/* @@/SEC:W1@@ */

/* ─────────────────────────────────────────────────────────────────────────────
   @@SEC:W2@@ — блок акций «Особенный повод для отдыха»: ряд из трёх,
   фото как основная часть карточки (SPEC-12 §О2, ТЗ заказчика 08.09.2026)

   ⚠️ Секция дописана В КОНЕЦ файла, как и @@SEC:W1@@ выше: theme.css правят
   разные сессии, дописывание в хвост — единственный способ не затереть соседа.
   Ничего в @@SEC:PROMO@@ не тронуто, правки лежат отдельным слоем поверх.
   ───────────────────────────────────────────────────────────────────────────── */

/* Ряд из трёх вместо четырёх. Сетку задаёт разметка (`col-lg-4`), здесь только
   то, что от неё зависит: карточка стала шире на треть, и прежние кегли в ней
   выглядят мелкими относительно кадра — а ТЗ просит ровно обратного, «фото
   основная визуальная часть, текст компактным блоком под ним». */
@media (min-width: 992px) {
  .ss-promo-card__body { padding: 20px 26px 24px; }
  .ss-promo-card__title { font-size: 23px; }
}

/* ⛔ ПРОПОРЦИЯ КАДРА ОСТАЁТСЯ 2:1 — ЗДЕСЬ ОНА НЕ ПЕРЕОПРЕДЕЛЯЕТСЯ НАМЕРЕННО.
   SPEC-12 §О2.3 вывела из ТЗ «фото крупнее и ближе к 4:3». Первая половина
   исполнена рядом из трёх: кадр вырос с ~312 до ~416 px по ширине, то есть
   почти вдвое по площади. Вторая — отвергнута замером 08.09.2026: из шести
   активных акций четыре имеют кадр РОВНО 800×400, одна 1348×540, то есть
   в инфоблоке лежат рекламные БАННЕРЫ с вёрсткой и надписями внутри, а не
   фотографии. Кроп 2:1 → 4:3 съедает у такого баннера треть ширины по бокам
   и возвращает дефект, снятый 18.08.2026 (на карточках читалось «ФИКАТ SPA»,
   «…СКИЙ …аж тела»).
   Настоящее лечение — чистые кадры без текста, это §27 вопросов заказчику.
   Пока их нет, пропорцию сторожит checkup.sh §W2. */
/* @@/SEC:W2@@ */

/* ─────────────────────────────────────────────────────────────────────────────
   @@SEC:W3@@ — блок «Нам доверяют гости»: лента отзывов с сервисов и плашка
   сводной оценки (SPEC-12 §О3, ТЗ заказчика 08.09.2026)

   ⚠️ Секция дописана В КОНЕЦ файла, как @@SEC:W1@@ и @@SEC:W2@@ выше.
   ───────────────────────────────────────────────────────────────────────────── */

.ss-rx--alt { background: var(--ss-bg-alt); }

/* ⚠️ ЛЕНТА ВО ВСЮ ШИРИНУ, ПЛАШКИ — СТРОКОЙ ПОД НЕЙ (запрос заказчика 05.10.2026).
   Было: узкая колонка 300px справа, плашки столбиком. Рядом с высокой карточкой
   отзыва (214px) узкая плашка (196px) читалась обрубком — заказчик: «Яндекс и
   Гугл меньше соседнего отзыва слева». Теперь лента и плашки не делят строку:
   лента 2×N сверху во всю ширину, под ней ряд из трёх плашек равной высоты.
   Раскладку ряда задаёт .ss-rx-agg-list ниже. */
.ss-rx-layout {
  display: grid;
  grid-template-columns: minmax(0, 1fr);
  gap: 28px;
  align-items: start;
}
/* Плашек в базе нет — раскладка та же (одна колонка). Класс оставлен меткой
   для чекапа §W3ж («плашка есть, а лента в одиночной раскладке»). */
.ss-rx-layout--solo { grid-template-columns: minmax(0, 1fr); }

/* Лента — две карточки в ряд. При четырёх отзывах это два ряда по две; при
   двух (столько их в базе на 08.09.2026) — один ряд, и блок не выглядит
   недозаполненным. */
.ss-rx-feed {
  display: grid;
  grid-template-columns: repeat(2, minmax(0, 1fr));
  gap: 20px;
}

.ss-rx-card {
  display: flex;
  flex-direction: column;
  background: var(--ss-card);
  border-radius: 16px;
  padding: 22px 24px;
  box-shadow: 0 8px 24px rgba(58, 47, 40, 0.07);
}
.ss-rx-card__head { display: flex; align-items: center; gap: 12px; }
/* Аватар — инициал в круге на фирменном фоне. ⛔ Фотографий гостей у нас нет
   и выдумывать их нельзя: это настоящие люди, а не персонажи макета. */
.ss-rx-card__ava {
  flex: none;
  width: 44px;
  height: 44px;
  border-radius: 999px;
  display: inline-flex;
  align-items: center;
  justify-content: center;
  background: var(--ss-copper);
  color: #FFF6E8;
  font-family: 'Manrope', sans-serif;
  font-size: 18px;
  font-weight: 700;
  line-height: 1;
}
.ss-rx-card__who { min-width: 0; flex: 1 1 auto; }
.ss-rx-card__name {
  margin: 0;
  font-family: 'Manrope', sans-serif;
  font-size: 15px;
  font-weight: 600;
  color: var(--ss-text);
  overflow: hidden;
  text-overflow: ellipsis;
  white-space: nowrap;
}
.ss-rx-card__date {
  flex: none;
  font-family: 'Manrope', sans-serif;
  font-size: 12.5px;
  color: var(--ss-text-muted);
}

/* Звёзды. Погашенные не убираем, а гасим: «4 из 5» читается только когда
   видно, из скольких. */
.ss-rx-stars { display: inline-flex; gap: 2px; margin-top: 3px; }
.ss-rx-stars svg { fill: var(--ss-divider); }
.ss-rx-stars svg.is-on { fill: var(--ss-accent); }
.ss-rx-stars--lg { margin-top: 6px; }

.ss-rx-card__text {
  margin: 14px 0 0;
  font-family: 'Manrope', sans-serif;
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text-muted);
}
/* Подвал прижат вниз: тексты отзывов разной длины, иначе «Читать отзыв»
   скакало бы по высоте от карточки к карточке (тот же приём, что у акций). */
.ss-rx-card__foot {
  display: flex;
  align-items: center;
  justify-content: space-between;
  gap: 10px;
  flex-wrap: wrap;
  margin-top: auto;
  padding-top: 16px;
}
.ss-rx-card__src {
  font-family: 'Manrope', sans-serif;
  font-size: 12.5px;
  color: var(--ss-text-muted);
}
.ss-rx-card__more {
  font-family: 'Manrope', sans-serif;
  font-size: 13.5px;
  font-weight: 600;
  color: var(--ss-terracotta);
  text-decoration: none;
  white-space: nowrap;
}
.ss-rx-card__more:hover { color: var(--ss-accent); }

/* Столбик плашек (SPEC-18, слой R2, 29.09.2026) → СТРОКА плашек (05.10.2026).
   Один раздел инфоблока — одна плашка; разделов может быть сколько угодно.
   Теперь плашки идут одной строкой в порядке сортировки разделов, и grid-строка
   выравнивает их по высоте (align-items: stretch): все плашки в ряду одной
   высоты, даже если у одной есть кнопка перехода, а у другой нет. */
.ss-rx-agg-list {
  display: grid;
  grid-template-columns: repeat(3, minmax(0, 1fr));
  gap: 20px;
  align-items: stretch;
}

/* Плашка сводной оценки. Логотип сервиса — «Изображение» раздела, если
   заказчик его загрузил (SPEC-18 R5, 30.09.2026); в коде и в деле знака
   нет, виджета/iframe по-прежнему нет (решение министра 08.09.2026). */
.ss-rx-agg {
  background: var(--ss-card);
  border-radius: 16px;
  padding: 26px 24px;
  text-align: center;
  height: 100%;              /* в ряду плашки равной высоты (grid stretch) */
  box-shadow: 0 8px 24px rgba(58, 47, 40, 0.07);
}
.ss-rx-agg__src {
  margin: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 6px;
  font-family: 'Manrope', sans-serif;
  font-size: 12px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ss-text-muted);
}
/* Логотип — высота 24px, плашка от него не растёт (SPEC-18 R5, решение 2).
   Ширина авто (пропорция сохранена ресайзом в block.php); нет изображения —
   <img> не рендерится вовсе, класс тут не при чём. */
.ss-rx-agg__logo {
  height: 24px;
  width: auto;
  flex-shrink: 0;
}
.ss-rx-agg__score {
  margin: 8px 0 0;
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-size: 54px;
  line-height: 1;
  color: var(--ss-text);
}
.ss-rx-agg__count,
.ss-rx-agg__reviews {
  margin: 10px 0 0;
  font-family: 'Manrope', sans-serif;
  font-size: 13.5px;
  color: var(--ss-text-muted);
}
/* Части строки чисел (SPEC-18 R5, 30.09.2026): «1 110 оценок» и
   «· 576 отзывов с текстом» — целиком, без внутреннего переноса; между
   span'ами в разметке стоит обычный пробел — единственная точка переноса,
   поэтому строка бьётся ровно по точке, а не посреди числа или слова. */
.ss-rx-agg__count-part { white-space: nowrap; }
/* Кнопка в две-три строки: фраза «Смотреть все 576 отзывов на Яндекс.Картах»
   в колонку 300px в одну строку не влезает, а nowrap выдавил бы её за плашку. */
.ss-rx-agg__btn {
  margin-top: 18px;
  width: 100%;
  justify-content: center;
  gap: 6px;
  flex-wrap: wrap;
  white-space: normal;
  line-height: 1.35;
  text-align: center;
}
.ss-rx-agg__btn-n { font-weight: 700; }

/* ── Планшет и телефон ────────────────────────────────────────────────────── */
@media (max-width: 991.98px) {
  /* Лента и плашки и так идут одной колонкой (см. .ss-rx-layout выше); на
     планшете плашки ещё помещаются строкой по три — не трогаем. */
  .ss-rx-layout { grid-template-columns: minmax(0, 1fr); }
}
@media (max-width: 767.98px) {
  .ss-rx-feed { grid-template-columns: minmax(0, 1fr); }
  .ss-rx-card { padding: 20px; }
  /* На телефоне три плашки в строку не влезают (по ~110px) — ставим столбиком:
     оценка и кнопка в такой ширине ломаются. */
  .ss-rx-agg-list { grid-template-columns: minmax(0, 1fr); }
  /* Длинное имя на 390 не режем многоточием в одну строку — переносим:
     обрезанное имя гостя читается как дефект данных. */
  .ss-rx-card__name { white-space: normal; }
}
/* @@/SEC:W3@@ */

/* ─────────────────────────────────────────────────────────────────────────────
   @@SEC:W3b@@ — сторис: признак непрочитанного (SPEC-12 §О5, ответ министра
   08.09.2026: «кольцо/точка, цвет подобрать под стиль»)

   ⛔ ИНЦИДЕНТ-ОСНОВАНИЕ — САМО ПРЕЖНЕЕ КОЛЬЦО. Оно уже стояло у всех кружков
   и горело ВСЕГДА, то есть признаком не являлось: горящее у всех эквивалентно
   отсутствующему. Здесь оно разделено на два состояния.

   ⚠️ ЦВЕТ ПОДОБРАН ЗАМЕРОМ, А НЕ НА ГЛАЗ. Прежний градиент начинался с #C9A66B,
   и на светлом фоне #F5EFE6 это 2,01:1 — ниже порога 3:1 из приёмки §5.6.
   То есть кольцо, стоявшее на сайте, само по себе было почти неразличимо.
   Взяты тона с замеренным контрастом (расчёт 08.09.2026 по WCAG):
     #8E6A47 → 4,27:1 · #A67C40 → 3,29:1 · #7E6234 → 4,99:1.
   На тёмной теме фон #1A1412, и там прежнее золото даёт 7,94:1 — его и
   оставляем: затемнять кольцо на тёмном значило бы гасить его.
   ───────────────────────────────────────────────────────────────────────────── */

/* Непрочитанная: насыщенное кольцо из фирменных тонов, все ≥3:1 к фону. */
.ss-story.is-unseen .ss-story-ring {
  background: conic-gradient(from 140deg,
    #8E6A47 0deg, #A67C40 90deg, #7E6234 200deg, #8E6A47 360deg);
  box-shadow: 0 4px 16px rgba(142, 106, 71, 0.30);
}

/* Прочитанная: кольцо гаснет до линии-разделителя. ⛔ Не убираем его совсем —
   кружки поехали бы по вертикали на 4px, и полоса дёргалась бы при каждом
   открытии истории. */
.ss-story:not(.is-unseen) .ss-story-ring {
  background: var(--ss-divider);
  box-shadow: none;
}
.ss-story:not(.is-unseen) .ss-story-thumb img { opacity: 0.82; }
.ss-story:not(.is-unseen) .ss-story-title { color: var(--ss-text-muted); }

/* Точка — второй признак того же состояния, формой, а не цветом: цветовое
   различие в одиночку не работает при цветовой слепоте, а на золотистой
   обложке кольцо ещё и сливается с самим кадром. */
.ss-story { position: relative; }
.ss-story-dot {
  position: absolute;
  top: 2px;
  right: 2px;
  width: 14px;
  height: 14px;
  border-radius: 50%;
  background: var(--ss-terracotta);
  border: 2px solid var(--ss-bg);
  opacity: 0;
  transform: scale(0.4);
  transition: opacity 0.25s ease, transform 0.25s ease;
  pointer-events: none;
}
.ss-story.is-unseen .ss-story-dot { opacity: 1; transform: scale(1); }

/* Кружки на полосе ужимаются до 64px — точка вслед за ними, иначе на телефоне
   она закрывает четверть обложки. */
@media (max-width: 767.98px) {
  .ss-story-dot { width: 12px; height: 12px; top: 0; right: 0; }
}

/* Тёмная тема: фон #1A1412, прежнее золото даёт на нём 7,94:1 — оно и остаётся
   признаком непрочитанного; затемнённые тона светлой темы здесь бы утонули. */
@media (prefers-color-scheme: dark) {
  :root:not([data-theme="light"]) .ss-story.is-unseen .ss-story-ring {
    background: conic-gradient(from 140deg,
      #C9A66B 0deg, #E6C88A 90deg, #8B6F3F 200deg, #C9A66B 360deg);
    box-shadow: 0 4px 16px rgba(201, 168, 115, 0.25);
  }
}
[data-theme="dark"] .ss-story.is-unseen .ss-story-ring {
  background: conic-gradient(from 140deg,
    #C9A66B 0deg, #E6C88A 90deg, #8B6F3F 200deg, #C9A66B 360deg);
  box-shadow: 0 4px 16px rgba(201, 168, 115, 0.25);
}

/* Гость просил не двигать ничего при переходе состояния: анимируем только
   цвет и точку. ⚠️ Уважаем prefers-reduced-motion — полоса сторис у входа
   на страницу и без того подвижна. */
@media (prefers-reduced-motion: reduce) {
  .ss-story-dot { transition: none; }
}
/* @@/SEC:W3b@@ */

/* ═════════════════════════════════════════════════════════════════════════════
   @@SEC:W4@@ — книга отзывов на /otzyvy/ (SPEC-12 §О4, слайс W4, 14.09.2026)

   ⚠️ Секция дописана В КОНЕЦ файла, как @@SEC:W1@@…@@SEC:W3b@@ выше: theme.css
   правят только точечно и только дописыванием — 02.09.2026 слайс записал файл
   из прочитанной раньше копии и молча стёр строку соседа.

   ⛔ ШИРИНА СТРАНИЦЫ ОГРАНИЧЕНА 420px, И ЭТО НЕ ВКУС. Скан приезжает превью
   400×533 — тем же, что и в сетке. Растянутый шире своих пикселей, он идёт
   мылом, а отзыв читают глазами. Четвёртый размер под разворот означал бы ещё
   227 файлов на диске и вдвое тяжелее первый экран; вместо этого под картинку
   подогнана книга.

   ⚠️ Сетка сканов НЕ удалена из разметки, а спрятана — и прячет её скрипт,
   только когда книга уже собрана (@@JS:REVIEWS_BOOK@@). Без JS секция
   остаётся прежней сеткой, а не пустым местом (§О4, последний пункт).
   ───────────────────────────────────────────────────────────────────────── */

/* Сетка уступает место книге. Класс ставит скрипт — в разметке его нет. */
.ss-reviews-scans--replaced { display: none; }

.ss-book {
  --ss-book-page: 420px;   /* предел ширины страницы — см. врезку выше */
  max-width: calc(var(--ss-book-page) * 2 + 96px);
  margin: 0 auto;
}

/* ── Разворот ─────────────────────────────────────────────────────────────── */
.ss-book__stage {
  display: flex;
  align-items: center;
  gap: 12px;
  outline: none;
}
/* Клавиатурная рамка у самой книги: листание висит на ней, и гость должен
   видеть, что фокус здесь. :focus-visible, а не :focus, — мышиный клик рамку
   не зажигает. */
.ss-book__stage:focus-visible {
  outline: 2px solid var(--ss-accent);
  outline-offset: 6px;
  border-radius: 4px;
}

/* ── Обложка книги ────────────────────────────────────────────────────────
   ⛔ ТЕКСТУРА НАРИСОВАНА, А НЕ ЗАГРУЖЕНА. Фотография кожи или бумаги — это
   лишний файл на первом экране (требование §О4 — не тяжелее прежней сетки,
   запас там 46 КБ) и чужая лицензия, которой у дела нет. Всё, что ниже, —
   градиенты и один инлайновый SVG с шумом: около 1 КБ внутри самого CSS,
   отдельным запросом не идёт вовсе и не может не загрузиться.
   Понадобится настоящее фото обложки — заменяется один слой `background`
   у `.ss-book__spread`, остальное не трогается.
   ───────────────────────────────────────────────────────────────────────── */
.ss-book__spread {
  flex: 1 1 auto;
  display: flex;
  /* ⛔ ЗАЗОРА У КОРЕШКА НЕТ, И ЭТО НЕ ВКУС. Перевёрнутый лист садится на
     соседнюю половину, отмеряя от корешка СВОЮ ширину: любой зазор — и он
     накрывает её со сдвигом ровно на этот зазор, а когда поворот кончается
     и на место встают настоящие страницы, содержимое дёргается вбок.
     Поймано министром на записи анимации 14.09.2026: лист шёл вплотную,
     а после паузы «отскакивал влево».
     Корешок рисуется тенью поверх сомкнутых страниц (`::after`), а не
     пустотой между ними — в настоящей книге между половинами разворота
     дырки нет тоже. */
  gap: 0;
  padding: 22px 20px;
  border-radius: 4px 8px 8px 4px;
  /* Слои снизу вверх: тёмная кожа переплёта → продольный нажим у корешка →
     зерно. Зерно последним и с `overlay`, иначе оно затирает нажим. */
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23n)' opacity='0.5'/%3E%3C/svg%3E"),
    linear-gradient(90deg, rgba(0,0,0,0.30) 0%, rgba(0,0,0,0) 4%,
                           rgba(0,0,0,0) 46%, rgba(0,0,0,0.34) 50%,
                           rgba(0,0,0,0) 54%, rgba(0,0,0,0) 96%,
                           rgba(0,0,0,0.30) 100%),
    linear-gradient(160deg, #5A3C2A 0%, #43291C 38%, #553926 62%, #3A241A 100%);
  background-blend-mode: overlay, normal, normal;
  box-shadow:
    inset 0 0 0 1px rgba(255, 236, 205, 0.10),
    0 22px 56px rgba(41, 27, 19, 0.34);
  /* Летящая страница ставится в пикселях от коробки половины — значит,
     разворот обязан быть её системой координат. */
  position: relative;
  /* Поворот листа идёт вокруг корешка — отсюда перспектива на родителе
     и объёмная раскладка у самого разворота. */
  perspective: 1800px;
  transform-style: preserve-3d;
}

/* Обрез страничного блока — то, по чему книга опознаётся книгой: у корешка
   его нет, к внешнему краю он нарастает. Две стопки, левая и правая. */
.ss-book__spread::before {
  content: '';
  position: absolute;
  inset: 22px 6px;
  pointer-events: none;
  background:
    repeating-linear-gradient(90deg, rgba(120, 96, 70, 0.55) 0 1px,
                                     rgba(253, 250, 244, 0.85) 1px 3px),
    repeating-linear-gradient(90deg, rgba(120, 96, 70, 0.55) 0 1px,
                                     rgba(253, 250, 244, 0.85) 1px 3px);
  background-size: 12px 100%, 12px 100%;
  background-position: left center, right center;
  background-repeat: no-repeat, no-repeat;
  border-radius: 2px;
  box-shadow: inset 0 0 6px rgba(58, 47, 40, 0.25);
  z-index: 0;
}

/* Изгиб листа у корешка: страница у переплёта уходит в тень и слегка
   светлеет к внешнему краю. Лежит ПОВЕРХ сканов — иначе изгиба не видно. */
.ss-book__spread::after {
  content: '';
  position: absolute;
  inset: 22px 20px;
  pointer-events: none;
  z-index: 3;
  background:
    linear-gradient(90deg,
      rgba(58, 47, 40, 0.16) 0%, rgba(58, 47, 40, 0) 7%,
      rgba(58, 47, 40, 0) 41%, rgba(58, 47, 40, 0.30) 49%,
      rgba(58, 47, 40, 0.34) 50%, rgba(58, 47, 40, 0.30) 51%,
      rgba(58, 47, 40, 0) 59%, rgba(58, 47, 40, 0) 93%,
      rgba(58, 47, 40, 0.16) 100%);
}

.ss-book__page {
  position: relative;
  z-index: 1;
  flex: 1 1 0;
  min-width: 0;
  max-width: var(--ss-book-page);
  aspect-ratio: 3 / 4;
  /* Бумага: тёплый лист с тем же зерном, что у обложки. Видна у пустой
     подложки и просвечивает по краям скана. */
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='p'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23p)' opacity='0.22'/%3E%3C/svg%3E"),
    linear-gradient(180deg, #FBF5E9 0%, #F6EEDF 52%, #F1E7D4 100%);
  background-blend-mode: multiply, normal;
  box-shadow: inset 0 0 0 1px rgba(120, 96, 70, 0.18);
  overflow: hidden;
}
/* Пустая подложка: нечётный последний разворот. Страницу оставляем — без неё
   книга на последнем шаге схлопывалась бы вдвое и «дёргала» соседние блоки.
   Фон у неё — та же бумага, поэтому отдельного правила фона не нужно. */
.ss-book__page.is-blank .ss-book__zoom { display: none; }

.ss-book__zoom {
  display: block;
  width: 100%;
  height: 100%;
  cursor: zoom-in;
}
.ss-book__zoom img {
  width: 100%;
  height: 100%;
  object-fit: cover;
  display: block;
}

/* ── Поворот страницы ─────────────────────────────────────────────────────
   ⛔ ЭТО НЕ ПОДМЕНА КАРТИНКИ ПОД НАКЛОНОМ. Первая редакция W4 наклоняла весь
   разворот и меняла сканы на середине — «эффект перелистывания» был, листа
   не было. Здесь летает настоящий лист: у него две стороны, он поворачивается
   вокруг корешка, отбрасывает тень на остающуюся половину и сам темнеет,
   уходя от света.

   ⚠️ Длительность продублирована в @@JS:REVIEWS_BOOK@@ (`FLIP_MS`) — скрипт
   по ней снимает слой и досчитывает состояние. Разъедутся — гость увидит
   оборванный поворот; стережёт `checkup.sh` §W4з.
   ───────────────────────────────────────────────────────────────────────── */
.ss-book__turn {
  position: absolute;
  z-index: 4;                     /* выше страниц и выше изгиба у корешка */
  transform-style: preserve-3d;
  pointer-events: none;
  will-change: transform;
}
.ss-book__turn-face {
  position: absolute;
  inset: 0;
  overflow: hidden;
  backface-visibility: hidden;
  background:
    url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='140' height='140'%3E%3Cfilter id='t'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.75' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='140' height='140' filter='url(%23t)' opacity='0.22'/%3E%3C/svg%3E"),
    linear-gradient(180deg, #FBF5E9 0%, #F6EEDF 52%, #F1E7D4 100%);
  background-blend-mode: multiply, normal;
  box-shadow: 0 0 18px rgba(41, 27, 19, 0.28);
}
.ss-book__turn-face img { width: 100%; height: 100%; object-fit: cover; display: block; }
/* Оборот — это та же страница с изнанки: развёрнут на 180°, иначе он смотрел бы
   в ту же сторону, что лицо, и при повороте показал бы пустоту. */
.ss-book__turn-face--back { transform: rotateY(180deg); }

/* Свет на листе: поднимаясь, страница уходит из-под лампы и темнеет, у корешка
   ложится сгиб. Слой отдельный — тонировать саму картинку `filter`-ом дорого
   на каждом кадре. */
.ss-book__turn-face::after {
  content: '';
  position: absolute;
  inset: 0;
  opacity: 0;
  background: linear-gradient(90deg, rgba(41,27,19,0.55) 0%, rgba(41,27,19,0.08) 22%, rgba(41,27,19,0) 60%);
}
.ss-book__turn.is-turning-next .ss-book__turn-face::after,
.ss-book__turn.is-turning-prev .ss-book__turn-face::after {
  animation: ss-book-page-shade 760ms ease-in-out;
}
@keyframes ss-book-page-shade {
  0%   { opacity: 0; }
  45%  { opacity: 1; }
  100% { opacity: 0; }
}

@keyframes ss-book-turn-next {
  0%   { transform: rotateY(0deg); }
  100% { transform: rotateY(-180deg); }
}
@keyframes ss-book-turn-prev {
  0%   { transform: rotateY(0deg); }
  100% { transform: rotateY(180deg); }
}
/* cubic-bezier, а не ease: лист трогается неохотно и падает на место быстро —
   линейный поворот читается как деталь механизма, а не как бумага. */
.ss-book__turn.is-turning-next { animation: ss-book-turn-next 760ms cubic-bezier(0.42, 0, 0.28, 1) forwards; }
.ss-book__turn.is-turning-prev { animation: ss-book-turn-prev 760ms cubic-bezier(0.42, 0, 0.28, 1) forwards; }

/* ── Стрелки ─────────────────────────────────────────────────────────────── */
.ss-book__nav {
  flex: none;
  width: 44px;                    /* тач-цель: не мельче 44px (замер 13.08.2026) */
  height: 44px;
  border-radius: 50%;
  border: 1px solid var(--ss-divider);
  background: var(--ss-card);
  color: var(--ss-accent);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
  transition: background 0.2s ease, color 0.2s ease, border-color 0.2s ease;
}
.ss-book__nav:hover:not(:disabled) {
  background: var(--ss-accent);
  border-color: var(--ss-accent);
  color: #fff;
}
.ss-book__nav:disabled { opacity: 0.35; cursor: default; }

/* ── Счётчик ─────────────────────────────────────────────────────────────── */
/* ⛔ Числа здесь нет и быть не может: и номер, и знаменатель считает скрипт от
   реального количества сканов. На макете ТЗ стояло «01 / 24» при 227 сканах. */
.ss-book__counter {
  margin: 18px 0 0;
  text-align: center;
  font-family: 'Cormorant Garamond', Georgia, serif;
  font-size: 15px;
  letter-spacing: 0.14em;
  color: var(--ss-text-muted);
}

/* ── Лента миниатюр ──────────────────────────────────────────────────────── */
.ss-book__strip {
  display: flex;
  gap: 8px;
  margin-top: 20px;
  padding: 4px 2px 12px;
  overflow-x: auto;
  scroll-behavior: smooth;
  scrollbar-width: thin;
}
.ss-book__thumb {
  flex: none;
  width: 55px;
  height: 74px;
  padding: 0;
  border: 1px solid var(--ss-divider);
  border-radius: 3px;
  background: var(--ss-card);
  overflow: hidden;
  cursor: pointer;
  opacity: 0.68;
  transition: opacity 0.2s ease, box-shadow 0.2s ease, border-color 0.2s ease;
}
.ss-book__thumb img { width: 100%; height: 100%; object-fit: cover; display: block; }
.ss-book__thumb:hover { opacity: 1; }
/* Текущая миниатюра — рамкой И насыщенностью: одного цвета мало, лента мелкая. */
.ss-book__thumb.is-current {
  opacity: 1;
  border-color: var(--ss-accent);
  box-shadow: 0 0 0 2px var(--ss-accent);
}
.ss-book__more-wrap { text-align: center; margin-top: 8px; }

/* ── Телефон: один скан на экран ─────────────────────────────────────────── */
@media (max-width: 767.98px) {
  /* Правая половина на телефоне пуста всегда (разворот = один скан), и
     показывать её значило бы ужать сам скан вдвое. Подложка остаётся только
     на широком экране, где она означает «книга кончилась». */
  .ss-book__page.is-blank { display: none; }
  /* ⚠️ Отступы обложки и врезки её псевдослоёв — одни и те же числа в трёх
     местах. Разойдутся — обрез страничного блока съедет с края бумаги,
     а тень корешка ляжет мимо. */
  .ss-book__spread { padding: 12px; gap: 0; border-radius: 4px; }
  /* На телефоне разворот — одна страница, и середины у него нет: корешок
     уходит к левому краю, обрез страничного блока остаётся только справа.
     Оставить «книжную» середину значило бы провести тёмную полосу прямо
     по скану отзыва. */
  .ss-book__spread::before {
    inset: 12px 4px;
    background-size: 0 0, 7px 100%;
  }
  .ss-book__spread::after {
    inset: 12px;
    background: linear-gradient(90deg,
      rgba(58, 47, 40, 0.34) 0%, rgba(58, 47, 40, 0.12) 4%,
      rgba(58, 47, 40, 0) 12%, rgba(58, 47, 40, 0) 94%,
      rgba(58, 47, 40, 0.14) 100%);
  }
  .ss-book__stage { gap: 6px; }
  .ss-book__nav { width: 40px; height: 40px; font-size: 22px; }
  .ss-book__thumb { width: 46px; height: 62px; }
}

/* ── Модалка увеличения ──────────────────────────────────────────────────── */
/* ⛔ z-index выше cookie-баннера (1080) и шапки (1030): скан открывают, чтобы
     прочитать, и полоса согласия поперёк него — тот же дефект, что админ-панель
     под шапкой. */
.ss-book-modal {
  position: fixed;
  inset: 0;
  z-index: 1090;
  display: none;
  align-items: center;
  justify-content: center;
  padding: 24px;
  background: rgba(26, 20, 18, 0.92);
}
.ss-book-modal.is-open { display: flex; }
.ss-book-modal__img {
  max-width: 92vw;
  max-height: 88vh;
  object-fit: contain;
  box-shadow: 0 24px 64px rgba(0, 0, 0, 0.5);
}
.ss-book-modal__close {
  position: absolute;
  top: 16px;
  right: 16px;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  border: 1px solid rgba(239, 232, 220, 0.4);
  background: rgba(26, 20, 18, 0.6);
  color: var(--ss-text-on-dark);
  font-size: 26px;
  line-height: 1;
  cursor: pointer;
}
.ss-book-modal__close:hover { background: var(--ss-accent); border-color: var(--ss-accent); }
/* Страница под модалкой не прокручивается — иначе колесо уводит фон, а скан
   остаётся на месте. */
body.ss-book-modal-open { overflow: hidden; }

/* ⚠️ Уважаем prefers-reduced-motion: перелистывание — украшение, а книга на
   227 сканов листается подолгу. */
@media (prefers-reduced-motion: reduce) {
  .ss-book__turn.is-turning-next,
  .ss-book__turn.is-turning-prev,
  .ss-book__turn.is-turning-next .ss-book__turn-face::after,
  .ss-book__turn.is-turning-prev .ss-book__turn-face::after { animation: none; }
  .ss-book__strip { scroll-behavior: auto; }
}
/* @@/SEC:W4@@ */

/* ═══════════════════════════════════════════════════════════════════════════
   @@SEC:X1@@ — «О SPA СОЛЬ»: блоки «Для кого» и «Почему выбирают» (SPEC-13, S1)

   ⚠️ Имя секции — X1, а не S1, как написано в раскладке SPEC-13: S1/S2/S3
   в этом файле уже заняты волной SPEC-08 (S2 — галерея зон, S3a/S3b — баня).
   Волна SPEC-13 берёт свободный префикс X; в спеке имена выправлены там же.
   ⚠️ Секции дописаны В КОНЕЦ файла пустыми до старта волны — тремя сессиями
   сразу, чтобы каждая правила СВОЙ маркер точечно и не переписывала хвост
   поверх соседа (инцидент 02.09.2026: слайс записал файл из старой копии
   и молча стёр строку соседа).
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Надзаголовок между двумя линиями (макет «Для кого», §О2.2) ──────────────
   Модификатор общий, не привязанный к блоку: линии — псевдоэлементы флекса,
   поэтому держат любую длину надзаголовка и не разъезжаются на переносе.
   ⚠️ Цвет линий — currentColor с прозрачностью, а не токен-разделитель: у
   надзаголовка свой цвет (--ss-copper в светлой теме, --ss-amber в тёмной),
   и жёсткий токен в тёмной теме дал бы линии темнее фона. */
.ss-overline--lines {
  display: flex;
  align-items: center;
  justify-content: center;
  gap: 16px;
}
.ss-overline--lines::before,
.ss-overline--lines::after {
  content: "";
  width: clamp(28px, 6vw, 72px);
  height: 1px;
  background: currentColor;
  opacity: 0.45;
}

/* ── Две колонки: фотография и список пунктов ────────────────────────────────
   ⛔ ТЕЛЕФОННАЯ РАСКЛАДКА ЗДЕСЬ НЕ ПИШЕТСЯ, ОНА ДОСТАЁТСЯ ИЗ РАЗМЕТКИ.
   ТЗ 14.09.2026 требует у ОБОИХ блоков «сначала изображение, затем список»;
   фото стоит в разметке первым, одна колонка до 992px — и требование
   выполняется без единого правила. Колонки переставляет только рабочий стол
   (@media min-width ниже). Обратный порядок — разметка «как на десктопе» плюс
   `order` для телефона — нарушал бы ТЗ ровно там, где этот файл не доехал. */
.ss-points__grid {
  display: grid;
  grid-template-columns: 1fr;
  gap: 32px;
  align-items: center;
}

@media (min-width: 992px) {
  /* Фото уже текста: пунктов шесть-семь, и колонка списка должна дышать. */
  .ss-points__grid { grid-template-columns: minmax(0, 5fr) minmax(0, 7fr); gap: clamp(40px, 5vw, 80px); }
  /* Зеркальная композиция §О3: текст слева, фото справа. Переставляются и
     порядок, и ширины — иначе у зеркального блока фото стало бы шире текста. */
  .ss-points__grid--mirror { grid-template-columns: minmax(0, 7fr) minmax(0, 5fr); }
  .ss-points__grid--mirror > .ss-points__photo { order: 2; }
  .ss-points__grid--mirror > .ss-points__list  { order: 1; }
}

/* Кадр: «с закруглёнными углами, без лишних рамок» (ТЗ дословно).
   ⚠️ aspect-ratio обязателен: кадр грузится лениво, и без заранее занятой
   высоты он дёргал бы раскладку после загрузки. На телефоне рамка
   горизонтальная — вертикальная на всю ширину экрана съедала бы его целиком
   до первого пункта, то есть прятала бы список, который она предваряет. */
.ss-points__photo {
  aspect-ratio: 4 / 3;
  border-radius: 18px;
  overflow: hidden;
}
.ss-points__photo img {
  display: block;
  width: 100%;
  height: 100%;
  /* Хелпер отдаёт горизонтальный 1920×1080 (второй реализации подбора кадра
     не заводим, §О2) — разницу с вертикальной рамкой гасит cover. */
  object-fit: cover;
}
@media (min-width: 992px) {
  .ss-points__photo { aspect-ratio: 3 / 4; }
}

/* ── Список пунктов: тонкие линии, без иконок ────────────────────────────────
   Тот же приём, что у .ss-banya-why-item: пункт без фона и рамки, разделённый
   волосяной линией. Классы свои: у того списка нумерация «01–04», здесь —
   акцент-ромб, и один селектор на два разных инварианта не годится. */
.ss-points__list {
  list-style: none;
  margin: 0;
  padding: 0;
}
.ss-points__item {
  display: flex;
  align-items: flex-start;
  gap: 16px;
  padding: 20px 2px;
  border-bottom: 1px solid var(--ss-divider);
}
.ss-points__item:last-child { border-bottom: 0; }

/* Золотистый ромб вместо иконки. ТЗ просит «без иконок», но пункт совсем без
   маркера сливается в абзац: макет ставит здесь мелкий ромб. Рисуется темой
   (повёрнутый квадрат), а не картинкой — значит красится вместе с ней. */
.ss-points__mark {
  flex: none;
  width: 8px;
  height: 8px;
  margin-top: 9px;                 /* середина первой строки при 16px/1.6 */
  background: var(--ss-amber);
  transform: rotate(45deg);
}

.ss-points__text {
  margin: 0;
  font-family: 'Manrope', sans-serif;
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  color: var(--ss-text-muted);     /* продолжение фразы — светлее (макет) */
}
.ss-points__lead {
  font-weight: 600;
  color: var(--ss-text);           /* первая фраза полужирным (ТЗ дословно) */
}

@media (max-width: 575px) {
  .ss-points__item { gap: 12px; padding: 16px 0; }
  .ss-points__text { font-size: var(--ss-copy-size); }
  .ss-points__mark { margin-top: 8px; }
}
/* @@/SEC:X1@@ */

/* ═══════════════════════════════════════════════════════════════════════════
   @@SEC:X2@@ — страница подбора: светлый фон, фильтры в колонку, счётчик,
   сортировка, кнопки блока фильтров (SPEC-13, S2)

   ⚠️ ФОН СТРАНИЦЫ ЗДЕСЬ НЕ ОБЪЯВЛЯЕТСЯ, И ЭТО НЕ ПРОПУСК. Тёмная полоса над
   каталогом была инлайновым `background: var(--ss-bg-alt)` у секции фильтров —
   секция убрана вместе с ней (konstruktor-programm/index.php), и ниже обложки
   остался общий светлый фон страницы. Правило `.ss-constructor { background:
   var(--ss-bg) }` только переобъявляло бы то, что уже есть у body, и создавало
   бы второе место, где фон этой страницы задан.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Блок фильтров стал вдвое выше: к пакетам приехали три группы чипов. Чипы,
   рассчитанные на широкую секцию (padding 10/18, кегль 14), в колонке 300px
   ложились бы по одному в строку — тот же дефект «слова по одному в строке»,
   который чинили по всему мобильному 02.09.2026. */
.ss-constructor .ss-filter .ss-chip-row { gap: 6px; }
.ss-constructor .ss-filter .ss-chip {
  padding: 7px 13px;
  font-size: 13px;
  white-space: normal;        /* «4 и более» переносится внутри чипа, а не рвёт ряд */
}

/* ⛔ ВЫСОТА ЛИПКОГО БЛОКА ОГРАНИЧЕНА, ИНАЧЕ КНОПКИ НЕДОСТИЖИМЫ. `position: sticky`
   у `.ss-filter` держит блок у верхней кромки, и всё, что не поместилось в экран,
   из виду уходит навсегда: до 14.09.2026 в колонке лежали только пакеты (~700px
   при 804px доступной высоты), теперь — четыре группы и три кнопки (~1030px), то
   есть внизу отрезало бы ровно «Показать программы» и «Заказать звонок».
   Только на lg+: ниже 992px блок лежит внутри свёрнутой панели и не липкий. */
@media (min-width: 992px) {
  .ss-constructor .ss-filter {
    max-height: calc(100vh - var(--bx-panel-h, 0px) - 120px);
    overflow-y: auto;
    /* ⛔ НИЖНИЙ ОТСТУП ОТДАН ЛИПКОЙ ПАНЕЛИ, А НЕ КОЛОНКЕ. Липкий подвал
       прижимается к низу СОДЕРЖИМОГО прокручиваемого блока, и всё, что колонка
       держит ниже, — щель, сквозь которую виден уезжающий список (замер 15.09.2026:
       полоса 25px, в ней выглядывал пункт «Массажи тайские» под «Сбросить фильтры»).
       ⚠️ Отрицательное поле у самой панели эту щель НЕ закрывает: у `sticky`
       смещение `bottom: 0` считается от содержимого контейнера и отрицательный
       margin его не растягивает — проверено, полоса осталась те же 25px. */
    padding-bottom: 0;
  }
}

/* ⚠️ Ограничения высоты МАЛО: замер 14.09.2026 (1440×900) — блок 780px при
   содержимом 1284px, и «Показать программы» лежит на 1165px, то есть за нижней
   кромкой: кнопка достижима, но не видна, и гость о ней не знает. Поэтому кнопки
   прилипают ко дну прокручиваемого блока — основная видна всегда, а не после того,
   как посетитель догадается прокрутить фильтры внутри себя. Подложка обязательна:
   без неё чипы просвечивают сквозь кнопки при прокрутке.

   ⛔ ПОДЛОЖКА БЕЗ ЩЕЛЕЙ, И ОБЕ ЩЕЛИ БЫЛИ НАСТОЯЩИМИ (замер 15.09.2026, приёмка S6,
   кадр снят штатным путём гостя на 1440×1000):
   1. Растяжка начиналась ПРОЗРАЧНОЙ и гасла к `--ss-card` за 14px, а сверху у
      панели стоит `border-top` из правила ниже. Пункт, уезжающий под панель,
      просвечивал сквозь эти 14px, и бортик ложился ровно поперёк его текста:
      «Турецкая баня» читалась ПЕРЕЧЁРКНУТОЙ. Плавное затухание и линия-разделитель
      в одной кромке несовместимы — подложка сплошная с нулевой отметки, а роль
      разделителя целиком у бортика.
   2. У колонки `padding-bottom: 24px`, и панель его не накрывала: ниже кнопок
      оставалась полоса 25px (замер), в которой выглядывал следующий пункт списка —
      «Массажи тайские» под ссылкой «Сбросить фильтры». Панель дотягивается до низа
      колонки отрицательным полем, а собственный нижний отступ держит кнопки на месте.
   ⚠️ Пункты при этом БЫЛИ достижимы: trial-клик по всем 15 прошёл до правки и после.
   Дефект был в виде, а не в доступности, — и мерить его надо кадром и геометрией,
   а не перечнем перекрытий: перечень «перекрыто 7» описывает штатное устройство
   липкого подвала над прокручиваемым списком и дефектом не является. */
@media (min-width: 992px) {
  .ss-constructor .ss-filter__actions {
    position: sticky;
    bottom: 0;
    margin-top: 4px;
    padding: 12px 0 24px;       /* нижние 24px — бывший паддинг колонки, он снят выше */
    background: var(--ss-card); /* сплошная: затухание + бортик давали перечёркнутый пункт */
  }
}

/* Кнопки блока фильтров (SPEC-13 §О8): основная, звонок, сброс — в столбик.
   Ширина колонки не даёт поставить их в ряд, а порядок задан макетом. */
.ss-constructor .ss-filter__actions {
  display: flex;
  flex-direction: column;
  gap: 10px;
  margin-top: 20px;
  padding-top: 18px;
  border-top: 1px solid var(--ss-divider);
}
.ss-constructor .ss-filter__apply,
.ss-constructor .ss-filter__call {
  width: 100%;
  justify-content: center;
  min-height: 48px;           /* тач-цель ≥44px — инвариант доступности SPEC-07 */
}
/* Сброс — ссылка, а не третья кнопка: он уводит от выбранного, а не ведёт к нему.
   Видна ВСЕГДА (§О8), поэтому в неактивном состоянии держится тише остальных. */
.ss-constructor .ss-filter__actions .ss-filter__reset {
  margin-top: 2px;
  border: 0;
  padding: 4px 0;
  text-align: center;
  font-size: 13px;
}

/* ── Строка результатов: «Найдено N программ» и сортировка ── */
.ss-constructor .ss-catalog__heading { margin-bottom: 18px; }
.ss-catalog__meta {
  display: flex;
  align-items: center;
  justify-content: space-between;
  flex-wrap: wrap;
  gap: 12px;
  margin-bottom: 28px;
}
.ss-catalog__found {
  margin: 0;
  font-family: 'Manrope', sans-serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.08em;
  text-transform: uppercase;
  color: var(--ss-text-muted);
}
.ss-catalog__sort {
  display: flex;
  align-items: center;
  gap: 8px;
}
.ss-catalog__sort-select {
  width: auto;
  min-height: 40px;
  padding: 6px 34px 6px 12px;
  border-radius: 9px;
  border: 1px solid var(--ss-divider);
  background-color: var(--ss-card);
  color: var(--ss-text);
  font-family: 'Manrope', sans-serif;
  font-size: 14px;
}
.ss-catalog__sort-select:focus {
  border-color: var(--ss-amber);
  box-shadow: none;
}
/* Кнопку отправки прячет JS (`hidden`), когда список умеет применяться сам.
   Без JS она остаётся видимой — это единственный способ применить сортировку. */
.ss-catalog__sort-go { white-space: nowrap; }

@media (max-width: 575.98px) {
  /* На узком экране строка складывается в два ряда, и список занимает всю ширину:
     ужатый select с длинной подписью «Сначала дешёвые» обрезает текст. */
  .ss-catalog__meta { flex-direction: column; align-items: stretch; }
  .ss-catalog__sort-select { width: 100%; }
}

/* ── Модалка «Заказать звонок» ──
   Оформление повторяет модалку записи из подвала, но классами, а не инлайновыми
   стилями: та писалась до дизайн-системы и держит цвета в атрибутах style. */
.ss-callback-modal__content {
  background: var(--ss-card);
  color: var(--ss-text);
  border: 1px solid rgba(201, 168, 115, 0.25);
  border-radius: 16px;
}
.ss-callback-modal__header {
  position: relative;
  padding: 26px 30px 12px;
  border-bottom: 1px solid rgba(201, 168, 115, 0.18);
}
.ss-callback-modal__title {
  margin: 0;
  font-size: 24px;
  font-style: italic;
  color: var(--ss-accent);
}
.ss-callback-modal__header .btn-close {
  position: absolute;
  top: 18px;
  right: 22px;
}
.ss-callback-modal__body { padding: 22px 30px 28px; }
.ss-callback-modal__lede {
  margin: 0 0 18px;
  font-size: 14px;
  color: var(--ss-text-muted);
}
.ss-callback-form .form-label {
  font-family: 'Manrope', sans-serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ss-text-muted);
  margin-bottom: 6px;   /* M20-9 (8px) перенесён в @@SEC:M20-9@@ — на 1440 не должен меняться (Н-2) */
}
.ss-callback-form .form-control {
  min-height: 48px;           /* тач-цель ≥44px — инвариант доступности SPEC-07 */
  border-radius: 10px;
}
.ss-callback-consent {
  margin-top: 16px;
  font-size: 13px;
  color: var(--ss-text-muted);
}
.ss-callback-consent input { margin-right: 6px; }
/* @@/SEC:X2@@ */

/* ═══════════════════════════════════════════════════════════════════════════
   @@SEC:X3@@ — сертификат: включатели форматов и доставки, «Кому» отдельно
   от доставки (SPEC-13, S3)
   ═══════════════════════════════════════════════════════════════════════════ */

/* Ни одного активного формата — вместо конструктора управляемая область
   (include/cert-offline.php). Колонка узкая и центрированная: это одна мысль в
   три строки, а не блок-конструктор, и на всю ширину она читается как ошибка
   вёрстки. Собственных цветов и рамок нет — фон секции и типографика общие. */
.ss-cert-offline {
  max-width: 720px;
  margin: 0 auto;
  text-align: center;
}

/* Группы формата видны не всегда: `data-physical-only` и `data-electronic-only`
   гасятся инлайном — и из PHP до первого клика, и из JS при переключении. Своего
   правила `display` у них здесь нет намеренно: два источника видимости у одного
   узла — тот случай, когда потом никто не знает, какой из них главный. */
/* @@/SEC:X3@@ */

/* ═══════════════════════════════════════════════════════════════════════════
   @@SEC:X4@@ — «Наши документы» на странице «О SPA СОЛЬ» (SPEC-13, S4)

   Секция заведена оркестратором пустой до старта волны 2 — по той же причине,
   что X1–X3 перед волной 1 (инцидент 02.09.2026): сессия правит свой маркер
   точечно и не дописывает хвост файла поверх соседа.
   ═══════════════════════════════════════════════════════════════════════════ */

/* Ряд карточек документов. Один документ центрируется ЭТИМ ЖЕ flex-рядом
   (justify-content: center на единственном элементе даёт центр без отдельной
   ветки вёрстки под «один документ» — приёмка П5 просит «по центру, как
   сейчас»); несколько документов оборачиваются в центрированную ленту. */
.ss-docs__grid {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 40px 48px;
  margin-top: 8px;
}
.ss-docs__card {
  width: 220px;
  max-width: 100%;
}
.ss-docs__thumb {
  display: block;
  border-radius: 8px;
  overflow: hidden;
  box-shadow: 0 12px 32px rgba(0, 0, 0, 0.3);
}
.ss-docs__thumb img {
  display: block;
  width: 100%;
}
/* Скана нет — плейсхолдер держит пропорции скана PDF (портрет), а не квадрат:
   на месте документа не должно быть пятна произвольной формы. */
.ss-docs__thumb-empty {
  aspect-ratio: 220 / 311;
}
.ss-docs__name {
  margin: 12px 0 0;
  font-weight: 600;
}
/* ⛔ КЛАСС НА ССЫЛКЕ, А НЕ ПОТОМОК-СЕЛЕКТОР (правка ревизии 14.09.2026, находка
   Д3). `.ss-docs__name a` (специфичность 0,1,1) проигрывал общему контентному
   правилу «Контентные ссылки» выше по файлу — `.ss-section .ss-container p
   a:not([class])` (0,3,2): голая ссылка внутри `.ss-section .ss-container p`
   красилась терракотовым и подчёркивалась (замер getComputedStyle на живой
   вёрстке: color rgb(162,75,43), text-decoration underline вместо inherit/
   none). `:not([class])` перестаёт совпадать сам по себе, как только у ссылки
   есть класс, — компонент красит свою ссылку по конвенции проекта («Компоненты
   .ss-* красят ссылки своими классами», врезка там же), не соревнуясь
   специфичностью. */
.ss-docs__link {
  color: inherit;
  text-decoration: none;
}
.ss-docs__link:hover,
.ss-docs__link:focus-visible {
  color: var(--ss-amber);
}
.ss-docs__caption {
  margin: 4px 0 0;
  font-size: 13px;
}
/* Раньше стояла под каждой карточкой (8px); теперь одна под всей лентой
   (правка ревизии, находка Д-мелочь — см. врезку в block.php) — отступ
   больше, это уже не подпись строки, а закрывающая реплика секции. */
.ss-docs__hint {
  margin: 24px 0 0;
  font-size: 13px;
}
/* @@/SEC:X4@@ */

/* @@SEC:V9@@ Карта за согласие (В9, 14.09.2026).
   Заглушка занимает ту же площадь, что и карта: без этого блок контактов
   на /kontakty/ схлопывался бы до высоты текста, и правка согласия читалась
   бы как поломка вёрстки. */
.ss-map__stub {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 28px;
  text-align: center;
  background: var(--ss-card);
}
.ss-map__stub-text {
  max-width: 34ch;
  margin: 0;
  color: var(--ss-text-muted);
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
}
.ss-map__stub-link {
  color: var(--ss-text);
  font-size: 14px;
  text-decoration: underline;
  text-decoration-color: var(--ss-accent);
}
/* @@/SEC:V9@@ */

/* @@SEC:EMBED@@ Чужая врезка за согласие (находка 1 обхода 16.09.2026).
   Заглушка занимает площадь ролика — иначе текст пака схлопывается и правка
   согласия читается как поломка вёрстки (тот же довод, что у карты).

   ⛔ ПРОПОРЦИЯ ЗАДАЁТСЯ ЗДЕСЬ, А НЕ БЕРЁТСЯ У РЕДАКТОРА. Врезку заказчик
   вставляет как придётся: у пака #612 рамка обёрнута в классический
   `height:0; padding-bottom:56.25%`, а следующая может приехать голой. Своя
   `aspect-ratio` держит площадь в обоих случаях; внутри обёртки-пропорции она
   совпадает с ней пиксель в пиксель. */
.ss-embed {
  position: relative;
  width: 100%;
  aspect-ratio: 16 / 9;
  margin: 24px 0;
  overflow: hidden;
  border-radius: 10px;
  background: var(--ss-card);
}
.ss-embed iframe {
  position: absolute;
  inset: 0;
  width: 100%;
  height: 100%;
  border: 0;
}
.ss-embed__stub {
  position: absolute;
  inset: 0;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  gap: 14px;
  padding: 24px;
  text-align: center;
}
/* Значок ролика — свой, треугольником на CSS. ⛔ Миниатюра у YouTube
   (img.youtube.com/vi/<id>/…) была бы тем же запросом третьей стороне до
   согласия, только картинкой: защита, делающая ровно то, от чего защищает. */
.ss-embed__icon {
  display: block;
  width: 56px;
  height: 56px;
  border-radius: 50%;
  border: 2px solid var(--ss-accent);
  position: relative;
  flex: none;
}
.ss-embed__icon::after {
  content: "";
  position: absolute;
  top: 50%;
  left: 54%;
  transform: translate(-50%, -50%);
  border-style: solid;
  border-width: 9px 0 9px 15px;
  border-color: transparent transparent transparent var(--ss-accent);
}
.ss-embed__text {
  max-width: 38ch;
  margin: 0;
  color: var(--ss-text-muted);
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
}
.ss-embed__link {
  color: var(--ss-text);
  font-size: 14px;
  text-decoration: underline;
  text-decoration-color: var(--ss-accent);
}
/* ⛔ УЗКИЙ ЭКРАН: ВЫСОТА ОТПУСКАЕТСЯ, А НЕ ПОДГОНЯЕТСЯ. Замер 16.09.2026 на
   390px: содержимое заглушки обрезано на 2px в коробке 342×192. Подогнать
   шрифты под 192px значит починить ровно 390px и сломать 320px (там на то же
   содержимое остаётся 153px) и любой текст длиннее нынешнего: имя сервиса
   в заглушку подставляется, а «ВКонтакте» и «Rutube» разной длины.
   Поэтому на узком заглушка стоит В ПОТОКЕ и растёт по содержимому, а
   пропорцию 16:9 держит уже сам вставленный ролик — ему-то она и нужна. */
@media (max-width: 575.98px) {
  .ss-embed { aspect-ratio: auto; }
  .ss-embed__stub { position: static; gap: 10px; padding: 16px; }
  .ss-embed iframe { position: static; width: 100%; height: auto; aspect-ratio: 16 / 9; }
  .ss-embed__icon { display: none; }
  .ss-embed__text { font-size: 14px; }
}
/* @@/SEC:EMBED@@ */

/* ============================================================
   @@SEC:AUTH@@ ── Формы входа (SPEC-16) ── строка S1, 16.09.2026.

   ⚠️ Секция дописана В КОНЕЦ файла, как @@SEC:W1@@…@@SEC:EMBED@@ выше:
   theme.css правят разные спеки, и владение объявлено РАЗДЕЛОМ, а не
   файлом (Р369 от 16.09.2026). Ничего выше не тронуто.

   ⛔ ОТСТУП СЧИТАЕТСЯ ОТ ПЕРЕМЕННЫХ, А НЕ ОТ ЧИСЛА. Вендорный вывод формы
   падает в `.site-content` голым блоком, без обложки и без секции, и потому
   начинается с y=0 — под fixed-шапкой. Собственный `padding` секции
   (`clamp(70px, 9vw, 130px)`) закрывает дефект только на широком экране:
   на 390px это 70px против шапки в 93px, то есть поле логина остаётся
   перекрытым. Поэтому отступ задан явно и складывается из трёх слагаемых:
     --bx-panel-h   — полоса админ-панели Битрикса (её ведёт header.php);
                      без неё дефект возвращается под администратором —
                      портфельный класс «админ-панель под шапкой»;
     --ss-header-h  — высота шапки;
     +40px          — воздух между шапкой и карточкой.
   ⚠️ `--ss-header-h` в проекте НИКЕМ не объявлена — её читает только
   `.ss-rx-agg` (с запасным значением 88px). Здесь запасное значение 93px:
   это ФАКТИЧЕСКАЯ высота `.ss-header`, снятая браузером 16.09.2026 на 1280
   и 390px (18px padding сверху и снизу + логотип). Расхождение 88/93
   намеренно не правится из этой секции: `.ss-rx-agg` — чужое владение,
   и объявление переменной изменило бы его поведение молча.
   ============================================================ */
.ss-auth-section {
  padding-top: calc(var(--bx-panel-h, 0px) + var(--ss-header-h, 93px) + 40px);
}
.ss-auth {
  max-width: 460px;
  margin: 0 auto;
  background: var(--ss-card);
  border-radius: 18px;
  padding: 32px;
  box-shadow: 0 14px 40px rgba(58, 47, 40, 0.10);
}
.ss-auth__title {
  font-family: 'Cormorant Garamond', serif;
  font-size: clamp(28px, 3vw, 38px);
  margin-bottom: 8px;
}
.ss-auth__note {
  color: var(--ss-text-muted);
  font-size: 15px;
  margin-bottom: 24px;
}
.ss-auth__form .form-label {
  font-family: 'Manrope', sans-serif;
  font-size: 13px;
  font-weight: 600;
  letter-spacing: 0.02em;
  color: var(--ss-text-muted);
  margin-bottom: 6px;   /* M20-9 (8px) перенесён в @@SEC:M20-9@@ — на 1440 не должен меняться (Н-2) */
}
.ss-auth__form .form-control {
  min-height: 48px;   /* тач-цель ≥44px — инвариант доступности SPEC-07 */
  border-radius: 10px;
}
.ss-auth__hint {
  margin: 8px 0 0;
  font-size: 13px;
  color: var(--ss-text-muted);
}
.ss-auth__captcha img {
  display: block;
  margin-bottom: 12px;
  border-radius: 8px;
}
.ss-auth__remember {
  display: flex;
  align-items: center;
  gap: 10px;
}
/* Тач-цель самого чекбокса — не только подписи рядом с ним. */
.ss-auth__remember .form-check-input {
  width: 20px;
  height: 20px;
  margin: 0;
  flex: 0 0 auto;
}
.ss-auth__remember .form-check-label {
  font-size: 15px;
  cursor: pointer;
}
.ss-auth__submit {
  width: 100%;
  min-height: 48px;
  margin-top: 8px;
}
.ss-auth__links {
  margin: 18px 0 0;
  text-align: center;
  font-size: 15px;
}
.ss-auth__links a {
  color: var(--ss-text);
  text-decoration: underline;
  text-decoration-color: var(--ss-accent);
}
.ss-auth__links a:hover { color: var(--ss-accent); }
/* Сообщение ядра («Неверный логин или пароль») — в языке сайта, а не
   вендорным `div.errortext`. */
.ss-auth__message {
  border-radius: 10px;
  padding: 12px 16px;
  margin-bottom: 18px;
  font-size: 15px;
}
.ss-auth__message--error {
  background: rgba(176, 58, 46, 0.08);
  color: #8E2B22;
}
.ss-auth__message--ok {
  background: rgba(58, 124, 74, 0.08);
  color: #2F6B3C;
}
@media (max-width: 575.98px) {
  .ss-auth { padding: 24px 20px; }
}
/* @@/SEC:AUTH@@ */

/* ═══════════════════════════════════════════════════════════════════════════
   @@SEC:S4@@ ── Поиск в шапке: иконка меню и модальное окно (SPEC-15, S4)
   17.09.2026. Решение министра: «Поиск — на мобильной версии есть, на десктопной
   нет. Нужна иконка последним пунктом меню. При клике модальное окно широкое
   с поиском прямо в нем. Программы в поиске в результатах выдавать в том же
   стиле и наполнении как в списке программ а не просто ссылкой на нее».

   ⚠️ Секция дописана В КОНЕЦ файла, как @@SEC:AUTH@@ и прочие выше: theme.css
   целиком не переписывается (02.09.2026 переписывание из устаревшей копии молча
   стёрло строку соседа).
   ═══════════════════════════════════════════════════════════════════════════ */

/* ── Иконка последним пунктом меню ──
   Размеры считаны из бюджета строки шапки выше: пункт меню на широком экране
   занимает 14px кегля + 14px отступов с каждой стороны. Иконка встаёт в тот же
   строй — 34px по ширине против ~110px у текстового пункта, и на бюджет давит
   меньше любого слова. ⚠️ Правку ширины сверять scripts/header-audit.js:
   строка шапки НИКОГДА не переполняется, это правило с замером. */
.ss-nav-search {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 34px;
  height: 34px;
  padding: 0;
  margin-left: 2px;
  background: transparent;
  border: 1px solid transparent;
  border-radius: 50%;
  color: var(--ss-text);
  cursor: pointer;
  transition: color 0.2s, border-color 0.2s, background 0.2s;
}
.ss-nav-search:hover,
.ss-nav-search:focus-visible {
  color: var(--ss-terracotta);
  border-color: rgba(201, 168, 115, 0.45);
  background: rgba(201, 168, 115, 0.08);
}
@media (min-width: 1200px) and (max-width: 1379.98px) {
  .ss-nav-search { width: 30px; height: 30px; margin-left: 0; }
}

/* ── Бюджет строки шапки: лестница отступов сдвинута на полосу вверх ──
   ⛔ ЭТО ПРОДОЛЖЕНИЕ ПРАВИЛА ИЗ ШАПКИ ФАЙЛА, А НЕ НОВОЕ РЕШЕНИЕ. Там объявлено:
   «строка НИКОГДА не переполняется, состав редеет по важности». Иконка поиска
   добавила меню 36px, и две полосы вышли за норму запаса: на 1600–1799 отступы
   пунктов оставались полными (14px), на 1500–1599 — промежуточными (9px).

   Замер (playwright, домашняя страница, с иконкой):
     полоса 1600–1799: было 0px запаса и ПЕРЕКРЫТАЯ иконка → стало 44–235px;
     полоса 1500–1599: было 0px и перекрытие → стало 8–42px, перекрытие снято.
   Остаток на самой ширине 1500 добран порогом значков соцсетей (см. ниже).

   ⚠️ Правила стоят ПОСЛЕ базовых полос 1200–1599 / 1200–1379: специфичность у них
   одинаковая, и решает порядок в файле. Перенесёшь выше — база победит, а замер
   останется прежним: дефект вернётся молча. */
@media (min-width: 1600px) and (max-width: 1799.98px) {
  .ss-nav-link { padding: 8px 9px; font-size: 13px; }
}
@media (min-width: 1500px) and (max-width: 1599.98px) {
  .ss-nav-link { padding: 8px 6px; font-size: 12.5px; }
}
[data-theme="dark"] .ss-nav-search { color: var(--ss-text-on-dark); }
[data-theme="dark"] .ss-nav-search:hover { color: var(--ss-amber); }

/* ── Окно поиска ── */
.site-modal-search .search-modal__header {
  position: relative;
  padding: 28px 32px 20px;
  border-bottom: 1px solid rgba(201, 168, 115, 0.18);
}
.site-modal-search .search-modal__title {
  color: var(--ss-accent);
  font-size: 26px;
  font-style: italic;
  margin: 0 0 16px;
}
.site-modal-search .search-modal__form { margin: 0; }

/* Выдача прокручивается внутри окна, а не растит его вниз: шесть строк программ
   с описанием и кнопками на ноутбуке 768px по высоте не помещаются, и без
   ограничения кнопка «Показать все» уезжает за нижний край экрана вместе
   с концом окна. 60vh оставляет видимыми шапку окна и поле ввода. */
.site-modal-search .search-modal__body {
  padding: 8px 32px 28px;
  max-height: 60vh;
  overflow-y: auto;
}
.site-modal-search .search-modal__hint {
  margin: 16px 0 0;
  color: var(--ss-text-muted);
}
.site-modal-search .search-modal__body[data-ss-state="loading"] { opacity: 0.45; }

/* ── Выдача во врезке ──
   ⛔ ОГРАНИЧЕНИЙ ШИРИНЫ ЗДЕСЬ ДВА, И СНИМАТЬ НАДО ОБА. `.ss-menu-list--rich`
   ограничена 900px (колонка лендинга пакета), а корень `.ss-search` — 860px
   (колонка страницы выдачи). Снял одно — и ничего не изменилось: строка
   упирается во второе. Замер в окне на 1600px после снятия ТОЛЬКО первого:
   тело окна 1138px, а `.ss-search`, `ul`, `li` и сама строка — все по 860px,
   при `max-width: none` на списке. Полоса пустоты справа шириной 278px
   и была той причиной, по которой окно делали широким.
   ⚠️ Оба ограничения законны на своих местах и снимаются ТОЛЬКО во врезке:
   на странице /search/ строка длиной во весь экран читается хуже. */
.ss-search--bare { max-width: none; }
.ss-search--bare .ss-menu-list--rich { max-width: none; }
.ss-search-modal__all {
  margin: 20px 0 0;
  text-align: center;
}

/* ── Строка программы внутри выдачи ──
   У обычного результата поиска свой разделитель сверху и отступы (.ss-search-item);
   у строки программы рамка и отступы уже есть — свои, из .ss-menu-row--rich.
   Оставить оба значило бы нарисовать рамку внутри разделителя. */
.ss-search-item--program {
  padding: 10px 0;
  border-top: 0;
}
.ss-search-item--program + .ss-search-item { border-top: 0; }

/* ═══════════════════════════════════════════════════════════════════════════
   @@SEC:A3@@ — раздел «Статьи»: одна колонка, карточка-строка, чипы и догрузка
   (SPEC-17, строка A3, 17.09.2026)

   ⚠️ Секция дописана В КОНЕЦ файла, как @@SEC:W1@@…@@SEC:AUTH@@ выше: theme.css
   правят слоями поверх, а не внутри чужих секций — так правка видна диффом целиком
   и снимается целиком же.

   Что здесь решается и почему именно так:
   · Список — не сетка. Прежняя карточка жила в `col-12 col-sm-6 col-lg-4` и была
     колонкой: заголовок, анонс и CTA столбиком. Строка списка устроена иначе —
     текст слева, дата справа, — поэтому у неё свои классы (`ss-article-row*`),
     а не переопределение `ss-article-card*`. Старые классы НЕ удалены: карточкой
     сетки рисуются связанные статьи на детальной.
   · Дата — не «мелкий текст справа», а второй столбец: на телефоне она уезжает
     НАД заголовком, иначе строка ломается пополам на 320px.
   · Цвета берутся переменными дизайн-системы (инвариант 6 спеки): новых тонов
     здесь не заводится ни одного.
   ══════════════════════════════════════════════════════════════════════════ */

/* Полоса фильтра: чипы слева, поиск справа; на узком — друг под другом. */
.ss-articles-bar {
  display: flex;
  flex-wrap: wrap;
  align-items: center;
  justify-content: space-between;
  gap: 16px;
  margin-bottom: 2rem;
}
.ss-articles-chips { flex: 1 1 auto; }
.ss-articles-search {
  display: flex;
  gap: 8px;
  flex: 0 1 320px;
}
.ss-articles-search__input {
  flex: 1 1 auto;
  min-width: 0;
  padding: 10px 16px;
  border: 1px solid var(--ss-divider);
  border-radius: 999px;
  background: var(--ss-card);
  color: var(--ss-text);
  font-size: 14px;
  line-height: 1.2;
}
.ss-articles-search__input::placeholder { color: var(--ss-text-muted); }
.ss-articles-search__input:focus {
  outline: 2px solid var(--ss-accent);
  outline-offset: 2px;
  border-color: var(--ss-accent);
}
.ss-articles-search__go {
  padding: 10px 20px;
  border: 1px solid var(--ss-accent);
  border-radius: 999px;
  background: var(--ss-accent);
  color: #fff;
  font-size: 14px;
  line-height: 1.2;
  cursor: pointer;
  transition: opacity .2s ease;
}
.ss-articles-search__go:hover { opacity: .88; }

/* Список в одну колонку. */
.ss-articles-list {
  display: flex;
  flex-direction: column;
  gap: 1.25rem;
}
.ss-article-row {
  display: flex;
  align-items: flex-start;
  gap: 1.5rem;
  padding: 1.75rem 1.9rem;
  background: var(--ss-card);
  border: 1px solid var(--ss-divider);
  border-radius: 14px;
  transition: border-color .3s ease, box-shadow .3s ease, transform .3s ease;
}
.ss-article-row:hover {
  border-color: var(--ss-accent);
  box-shadow: 0 14px 34px rgba(58, 47, 40, .12);
  transform: translateY(-2px);
}
.ss-article-row__main { flex: 1 1 auto; min-width: 0; }
.ss-article-row__kicker {
  display: block;
  font-size: 12px;
  letter-spacing: .14em;
  text-transform: uppercase;
  color: var(--ss-amber);
  margin-bottom: .6rem;
}
.ss-article-row__title {
  font-size: 1.5rem;
  line-height: 1.25;
  margin: 0 0 .7rem;
}
/* Ссылка заголовка красится как текст: это элемент интерфейса, а не редакторская
   ссылка в тексте. Класс у неё обязателен — см. комментарий в шаблоне. */
.ss-article-row__link {
  color: var(--ss-text);
  text-decoration: none;
  transition: color .25s ease;
}
.ss-article-row__link:hover { color: var(--ss-accent); }
.ss-article-row__teaser {
  color: var(--ss-text-muted);
  font-size: var(--ss-copy-size);
  line-height: var(--ss-copy-leading);
  margin: 0 0 1rem;
}
.ss-article-row__cta {
  display: inline-block;
  color: var(--ss-accent);
  font-weight: 600;
  font-size: .95rem;
  text-decoration: none;
}
.ss-article-row__cta:hover { text-decoration: underline; }
.ss-article-row__aside { flex: 0 0 auto; padding-top: .15rem; }
.ss-article-row__date {
  display: block;
  white-space: nowrap;
  font-size: .9rem;
  color: var(--ss-text-muted);
}

/* Догрузка. */
.ss-articles-more {
  display: flex;
  flex-direction: column;
  align-items: center;
  gap: .9rem;
  margin-top: 2.25rem;
}
.ss-articles-more__count {
  margin: 0;
  font-size: .9rem;
  color: var(--ss-text-muted);
}
.ss-articles-more__btn {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  min-height: 48px;           /* тач-цель: не меньше 44px (лист T2) */
  padding: 12px 32px;
  border: 1px solid var(--ss-accent);
  border-radius: 999px;
  background: transparent;
  color: var(--ss-accent);
  font-weight: 600;
  font-size: .97rem;
  text-decoration: none;
  transition: background .25s ease, color .25s ease;
}
.ss-articles-more__btn:hover {
  background: var(--ss-accent);
  color: #fff;
}

@media (max-width: 575.98px) {
  /* Дата над заголовком: на 320px два столбца ломают строку пополам. */
  .ss-article-row {
    flex-direction: column-reverse;
    align-items: stretch;
    gap: .75rem;
    padding: 1.4rem 1.25rem;
  }
  .ss-article-row__aside { padding-top: 0; }
  .ss-article-row__title { font-size: 1.28rem; }
  /* M20-11, снятие красноты МР-3 (п.4): flex-basis:100% один не держал строку —
     у .ss-articles-search нет собственного min-width, и браузер считал
     автоматический минимум по содержимому (input+кнопка «Найти»), а не по
     100% строки — на 320 это давало 297px вместо 272 (выезд на 1px, 7 адресов
     /articles/*). Тот же приём, что уже стоит у .ss-articles-search__input
     ниже по каскаду (min-width:0) — только теперь и у самого flex-контейнера.
     Проверено подменой правила в браузере: без min-width:0 297/321, с ним 272/296
     (out/wave-mobile-2026-09-22/m20-11-krasnota/articles-test-fix.js). */
  .ss-articles-search { flex: 1 1 100%; min-width: 0; }
}

/* ── @@SEC:M20-2@@ — баннер согласия на телефоне: высота ≤25% окна
   (SPEC-20, строка M20-2, 23.09.2026)

   ⚠️ Секция дописана В КОНЕЦ файла, как @@SEC:W1@@…@@SEC:A3@@ выше: theme.css
   правят слоями поверх, а не внутри чужих секций.

   Механика согласия (id, hidden, скрипт в footer.php) НЕ трогается ни строкой —
   здесь только вид: отступы, кегль и высота кнопок. `display`/`visibility`/
   `position` у `#ssCookieBanner` намеренно не заданы — показом/скрытием
   по-прежнему управляет атрибут `hidden` из скрипта, эта секция его не видит.

   Владение диапазоном 3986–4017 (старый блок) здесь не трогается — новые
   правила побеждают его каскадом: theme.css — последний и единственный лист
   стилей на странице (header.php:227-237), а внутри одного файла при равной
   специфичности выигрывает более поздний источник. Ровно так же эти правила
   встают поверх ДВУХ чужих строк вне диапазона M20-2 — `theme.css:756`
   (`.ss-cookie__actions .btn{flex:1 1 100%}`, фикс переполнения 02.09.2026)
   и `theme.css:4016` (`flex:1 1 auto`, внутри диапазона 3986-4017): свойство
   `flex` этой секцией не переопределяется — перенос кнопок на 320px остаётся
   их поведением, здесь только сокращаются отступы, кегль и высота кнопок.

   Числа (окно 800, первый гость, `out/wave-mobile-2026-09-22/m20-2/`):
   было 283/283/262px (35%/35%/33%) на 320/360/390 → стало 142/125/125px
   (запас до потолка 200px: 58/75/75px). Кнопки — ровно 44px (мин. тач-цель,
   И-4), кегль текста и кнопок — 13px (не меньше порога M20-9). */
@media (max-width: 575.98px) {
  #ssCookieBanner.ss-cookie { padding: 10px 10px; gap: 6px; }
  #ssCookieBanner .ss-cookie__text { font-size: 13px; line-height: 1.35; }
  #ssCookieBanner .ss-cookie__actions { gap: 6px; }
  #ssCookieBanner .ss-cookie__actions .btn { padding: 8px 10px; font-size: 13px; line-height: 1.25; min-height: 44px; }
}

/* ── @@SEC:M20-3@@ — точки обложки программы не перехватывают «Записаться»
   на телефоне (SPEC-20, строка M20-3, 23.09.2026)

   ⚠️ Секция дописана В КОНЕЦ файла, тем же приёмом, что @@SEC:M20-2@@ выше:
   правим слоями поверх, а не внутри чужих секций (3681-3685 — см. правку
   там же, эта секция — вторая часть починки; 5760-5773 НЕ тронуты, см. ниже).

   МЕХАНИКА (кто с кем сталкивается — прочитано из кода, не из силуэта):
   1. site.js:659-661 рисует `.ss-pack-hero__dots.ss-pack-hero__dots--desk`
      ПОСЛЕДНИМ ребёнком секции `<section class="ss-program-hero has-photo
      has-slideshow">` — рядом с `.ss-container`, а не внутри него.
   2. Базовое правило (theme.css:3681, правка этим же заходом) — контейнер
      точек теперь `pointer-events:none`, кнопки-точки `pointer-events:auto`.
      Это снимает перехват ПОЛОСОЙ (была `left:0;right:0`, съедала клик по
      всей ширине) — но НЕ снимает перехват самими 44×44-кнопками там, где
      они физически стоят над кнопкой «Записаться»: живой замер показал
      кандидата `button.ss-pack-hero__dot` в списке перехватчиков ДО этой
      секции (out/wave-mobile-2026-09-22/m20-3/posle-pointer-events-only.txt,
      «1 из 5» → «3 из 5» после одного pointer-events, не «5 из 5»).
   3. Секция `.ss-program-hero` кладёт текст (крошки/заголовок/лид/бейджи/
      строка действий) ЦЕНТРИРОВАННЫМ блоком (`display:flex;align-items:
      center`) внутри вертикального паддинга 118/34px (телефон,
      theme.css:6637-6646) — я этот блок не трогаю, он не в моём владении.

   ⛔⛔ ПЕРВАЯ РЕДАКЦИЯ (bottom:170px у самих точек) БЫЛА ОПРОВЕРГНУТА
   координатором по скриншоту 390-dlinnaya-posle.png: первая точка легла
   ПРЯМО НА бейдж «СЕМЕЙНЫЕ» — не компромисс, а новый видимый дефект.
   Причина: единый `bottom`-отступ КОНКУРИРУЕТ с центрированным текстом за
   одну и ту же вертикальную полосу — замер по 13 адресам показал, что
   диапазон «не задеть кнопку короткой страницы» (≥154px) и «не задеть
   бейджи длинной» (≤124px) не пересекаются НИ ПРИ КАКОМ едином числе.

   РЕДАКЦИЯ 2 — ЗАРЕЗЕРВИРОВАТЬ МЕСТО, А НЕ ПОДБИРАТЬ ЧИСЛО. Вместо того чтобы
   ставить точки поверх текста, увеличиваем `padding-bottom` героя ровно на
   высоту точек + зазор (44px + 12px = 56px), а точки оставляем на исходном
   `bottom:16px` (база, 3681, не тронута). Паддинг в CSS НИКОГДА не занимается
   контентом — flex `align-items:center` центрирует `.ss-container` внутри
   content-box, который по определению меньше на величину padding с обеих
   сторон; выросший padding-bottom либо сдвигает центрированный текст вверх
   (короткие страницы, есть слак), либо заставляет секцию вырасти РОВНО на
   добавку (длинные страницы, слака нет, `box-sizing:border-box` — приезжает
   из Bootstrap Reboot, `vendor/bootstrap/bootstrap.min.css`, — на это не
   влияет: паддинг пуст от контента при любом box-sizing). Итог: резерв не
   зависит от длины текста НИ НА ОДНОЙ странице — в отличие от абсолютного
   bottom, который конкурировал с текстом только на части страниц.
   Было `padding: 118px 0 34px` (`.ss-program-hero.has-photo`, 6641, чужое
   владение, не трогаю) → здесь ТОЛЬКО `padding-bottom` перебит для страниц
   с точками (`.has-slideshow`, точнее и уже, чем `.has-photo`: последнее
   бывает и без точек, — 34+56=90px, снизу оставляет карман строго под точки.

   ⛔ `min-height`/`align-items` НЕ СХЛОПЫВАЮТ РЕЗЕРВ — проверено, а не
   предположено (наказ координатора). `min-height:70vh` — floor ОБЩЕЙ высоты
   (border-box), а не потолок content-box: рост padding-bottom либо съедает
   слак центрирования (короткие страницы), либо требует роста самой секции
   (длинные) — в обоих случаях 90px внизу остаются буквально пустыми,
   подтверждено геометрией на 13 адресах после правки (см. ниже).

   ДОКАЗАНО ГЕОМЕТРИЕЙ (out/wave-mobile-2026-09-22/m20-3/geom-posle-redakcii-2.txt,
   13 адресов × 320/390): у каждой точки на каждом адресе пересечение с
   прямоугольниками кнопки «Записаться», бейджей, цены и текста лида = 0;
   top полосы точек ≥ bottom строки действий + 8px на любой длине карточки.
   dots-selfcheck (центр точки → сама точка, клик меняет кадр) — 4 адреса ×
   3 ширины, без изменений в самой проверке.

   ⛔ ЗАКРЕПЛЁННАЯ ШАПКА не участвует в расчёте вовсе: точки не сдвинуты
   от базового bottom:16px, `.ss-header` кончается на 93px от верха — далеко
   от нижнего края героя на любой высоте (`header-geom-do-pravki.txt`). */
@media (max-width: 767.98px) {
  .ss-program-hero.has-slideshow { padding-bottom: 90px; }
}

/* ── @@SEC:M20-4@@ — шапка на телефоне несёт «Позвонить», цели не меньше 44×44
   (SPEC-20, строка M20-4, 23.09.2026)

   Было на 320/360/390 (`out/wave-mobile-2026-09-22/m20-4/progon-do.txt`): в шапке
   две цели — логотип и кнопка меню 40×41, телефона нет (кнопка «Позвонить» стояла
   с `d-none d-md-inline-flex`). Разметку открыл header.php; здесь только размер.
   Надпись «Позвонить» ниже 1380px уже скрыта (@media выше) — на телефоне это значок.
   Место есть: на 320 между логотипом (до 179px) и меню (с 252px) 73px под 44px. */
@media (max-width: 767.98px) {
  .ss-header .ss-header-call,
  .ss-header .ss-burger {
    display: inline-flex;
    align-items: center;
    justify-content: center;
    min-width: 44px;
    min-height: 44px;
  }
  .ss-header .ss-header-call { padding: 0 14px; }
}

/* ── @@SEC:M20-5@@ — панель меню на телефоне: запись первой, адрес и часы внизу,
   цели не меньше 40×40 (SPEC-20, строка M20-5, 23.09.2026)

   Было (`out/wave-mobile-2026-09-22/m20-5/progon-do.txt`): крестик 32×32, номер
   телефона строкой 25px, пункты меню 35px. Панель живёт только ниже 1200px
   (бургер d-xl-none), поэтому правила без @media. */
#mobileMenu .btn-close {
  box-sizing: border-box;
  width: 44px;
  height: 44px;
  padding: 0;
  background-position: center;
}
#mobileMenu .ss-mobile-cta { display: grid; gap: 8px; margin-bottom: 24px; }
#mobileMenu .ss-mobile-cta .btn { min-height: 48px; display: inline-flex; align-items: center; justify-content: center; }
#mobileMenu .ss-mobile-cta__tel {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 44px;
  font-family: 'Manrope', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 19px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  line-height: 1.4;
  color: var(--ss-accent);
  text-decoration: none;
}
/* Значки соцсетей/мессенджеров под телефоном (запрос заказчика 05.10.2026).
   Панель меню светлая (--ss-bg), поэтому цвет марки — --ss-accent, как у значков
   в блоке «Контакты», а не --ss-amber из подвала (тот для тёмного фона).
   Тач-цель 44×44 — инвариант доступности; на глаз значок 22px, остальное
   добирается кружком. Перенос разрешён: при шести соцсетях на 320px ряд может
   не уложиться в одну строку. */
#mobileMenu .ss-mobile-msgr {
  display: flex;
  flex-wrap: wrap;
  justify-content: center;
  gap: 4px;
}
#mobileMenu .ss-mobile-msgr a {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 44px;
  height: 44px;
  border-radius: 50%;
  color: var(--ss-accent);
  transition: background 0.18s ease, color 0.18s ease;
}
#mobileMenu .ss-mobile-msgr a:hover,
#mobileMenu .ss-mobile-msgr a:focus-visible {
  background: rgba(139, 111, 63, 0.12);
  color: var(--ss-terracotta);
}
#mobileMenu .ss-mobile-msgr svg { width: 22px; height: 22px; }
/* Мобильные корневые разделы: два независимых действия вместо
   маленького плюса внутри единой кнопки. Название — ссылка, стрелка —
   отдельная тач-цель 52x52. Работает на телефонах и планшетах <1200px. */
#mobileMenu .ss-mobile-split {
  display: flex;
  align-items: stretch;
  border: 1px solid var(--ss-text);
  border-radius: 999px;
  overflow: hidden;
  background: var(--ss-card);
  color: var(--ss-text);
}
#mobileMenu .ss-mobile-split__link {
  display: flex;
  flex: 1 1 auto;
  align-items: center;
  min-width: 0;
  min-height: 52px;
  padding: 10px 10px 10px 20px;
  color: inherit;
  text-decoration: none;
  font-size: 16px;
  line-height: 1.4;
}
#mobileMenu .ss-mobile-split__toggle {
  display: flex;
  flex: 0 0 52px;
  align-items: center;
  justify-content: center;
  width: 52px;
  min-height: 52px;
  padding: 0;
  border: 0;
  border-left: 1px solid var(--ss-divider);
  border-radius: 0;
  background: transparent;
  color: inherit;
  cursor: pointer;
}
#mobileMenu .ss-mobile-split__toggle svg {
  transition: transform 0.18s ease;
}
#mobileMenu .ss-mobile-split__toggle[aria-expanded="true"] svg {
  transform: rotate(180deg);
}
#mobileMenu .ss-mobile-split:has(.ss-mobile-split__toggle[aria-expanded="true"]) {
  background: var(--ss-text);
  color: var(--ss-card);
}
#mobileMenu .ss-mobile-split:has(.ss-mobile-split__toggle[aria-expanded="true"]) .ss-mobile-split__toggle {
  border-left-color: rgba(255,255,255,0.28);
}
#mobileMenu .ss-mobile-split__link:hover,
#mobileMenu .ss-mobile-split__toggle:hover {
  background: rgba(201,166,107,0.12);
}
#mobileMenu .ss-mobile-split__link:focus-visible,
#mobileMenu .ss-mobile-split__toggle:focus-visible {
  outline: 3px solid var(--ss-terracotta);
  outline-offset: -3px;
}
@media (prefers-reduced-motion: reduce) {
  #mobileMenu .ss-mobile-split__toggle svg { transition: none; }
}
#mobileMenu .ss-mobile-nav a.ss-nav-link { display: flex; align-items: center; min-height: 44px; }
#mobileMenu .ss-mobile-nav li.py-1,
#mobileMenu .ss-mobile-nav li.py-2 { padding-top: 0 !important; padding-bottom: 0 !important; }
#mobileMenu .ss-mobile-contacts {
  margin-top: 24px;
  padding-top: 16px;
  border-top: 1px solid rgba(201, 168, 115, 0.18);
  font-size: 15px;
  line-height: 1.45;
}

/* ── @@SEC:MR2-BARER@@ — находки барьера МР-2 (SPEC-20 §12, 23.09.2026)
   Н-2: на светлой шапке (не поверх обложки или после прокрутки) значок «Позвонить»
   красился `--ss-amber` — 1.89:1 к фону кнопки. На телефоне берём цвет бургера
   рядом (`--ss-accent`, 4.13:1), чтобы две соседние кнопки читались одинаково.
   Только ниже 768px: широкий экран не трогаем (И-7).
   Н-1: у первого гостя баннер согласия (до 142px на телефоне, @@SEC:M20-2@@) лежал
   поверх адреса и часов внизу панели — даём телу панели запас снизу, пока баннер
   показан. Показом баннера управляет атрибут `hidden` — на него и смотрим. */
@media (max-width: 767.98px) {
  .ss-header:not(.on-hero) .ss-header-call,
  .ss-header.on-hero.is-scrolled .ss-header-call {
    color: var(--ss-accent);
    border-color: var(--ss-accent);
  }
}
body:has(#ssCookieBanner:not([hidden])) #mobileMenu .offcanvas-body { padding-bottom: 170px; }

/* ── @@SEC:M20-6@@ — кнопка «наверх» ОТМЕНЕНА на телефоне (SPEC-20, строка
   M20-6, 23.09.2026, решение министра 22.09 19:2x)

   Не «спрятать у подвала» — переставленная заслонка остаётся заслонкой
   (Д-4, §1.5): круг ложился поверх цены, кнопки «Забронировать», ссылок
   подвала на всех обойдённых страницах (`m3/zond-naverh.txt`, `m6/pod-krugom.js`).
   Правило здесь обязано перебивать инлайн-стиль независимо от того, что решит
   выставить `js/site.js` — отсюда `!important` и ID-селектор, а не класс.
   Выше 768px кнопка не трогается (И-7, `#scrollToTop` работает как раньше). */
@media (max-width: 767.98px) {
  #scrollToTop { display: none !important; }
}

/* ── @@SEC:M20-9@@ — заслонки сняты, текст читается (SPEC-20, строка M20-9,
   23.09.2026, итерация 2 — 23.09.2026 по возврату барьера МР-3). Дельта владения
   объявлена оркестратором 23.09 к «Итогу M20-8»
   (`out/wave-mobile-2026-09-22/m5-8/porogi-i-spisok.md`, разделы 2.1/2.2/4/5):
   15 селекторов «мелкая цель» — ни один не был в списке М20-9 письменно.
   ⛔ Только ниже 768px — на 1440 CTA-ссылки, бейджи и шрифты работают как раньше (И-7);
   правило здесь не перебивает базовые размеры, а лишь добавляет запас снизу
   и сверху там, где базовый бокс упирался в CEL_MIN=24 (WCAG 2.2 SC 2.5.8 AA,
   §1.2 спеки, m5-8/porogi-i-spisok.md §1.2).
   ⛔ Итерация 1 (ef59ea4) правила шрифт 11→12px и зазор 6→8px НА МЕСТЕ (в базовых
   правилах, вне медиазапроса) — барьер МР-3 (Н-2) поймал регресс на 1440: 282/282
   адресов изменились. Все такие правки перенесены СЮДА, база возвращена к исходным
   11px/6px/.68rem — на 1440 идентично состоянию до ef59ea4. */
@media (max-width: 767.98px) {
  /* Мелкий шрифт <12px (SPEC-20 §7 МР-3 п.4) — было 11px/.68rem. Перенесено сюда
     из базовых правил итерацией 2 (см. врезку выше, Н-2). .ss-zone-note сюда не
     входит: у него свой мобильный override чуть выше по файлу (@media у
     .ss-zones-stage, «Восемь названий зон…») — там же и его 12px, трогать
     дважды один и тот же переход незачем. */
  .ss-banya-type,
  .ss-program-label,
  .ss-cmp__type,
  .ss-hero-stat__label {
    font-size: 12px;
  }
  .ss-menu-row__badge { font-size: .75rem; }

  /* .ss-about-spec__label — тот же перенос шрифта 11→12px, НО барьер МР-3 (Б-1)
     нашёл: при 12px и прежнем letter-spacing:0.16em подпись «ДЛИТЕЛЬНОСТЬ» выходит
     на 7px за рамку карточки на 320 у 8 программ, «ВМЕСТИМОСТЬ» у бань — в 1.9px
     от рамки (меньше требуемых 8px запаса). Задание запретило возвращать шрифт
     ниже 12px — снимаем теснотой трекинга. letter-spacing 0.16em→0.04em (только
     телефон): «Длительность» на /program/mechta/ — зазор до рамки 320
     -7px→+10.2px (kraj-kartochki.js), «Вместимость» на банях — 1.9px→17.7px.
     Побочный эффект той же правки — Н-3: «Зона и уход» переставало влезать в
     1 строку на 320 у 8 программ (letter-spacing 0.16em ловил перенос по словам
     на границе), тем же трекингом возвращается в 1 строку. */
  .ss-about-spec__label {
    font-size: 12px;
    letter-spacing: 0.04em;
  }

  /* Зазор label↔input ≥8px (SPEC-20 §7 МР-3 п.6) — было 6px. Перенесено сюда
     итерацией 2 (Н-2): база формы больше не трогает 1440. */
  .ss-lead-form .form-label,
  .ss-callback-form .form-label,
  .ss-auth__form .form-label {
    margin-bottom: 8px;
  }

  /* Отдельные CTA-ссылки без padding — впритык или чуть ниже 24px по высоте.
     display:inline-block переводит их в собственный блок: паддинг раздвигает
     бокс предсказуемо в обе стороны, не наезжая на соседние строки. */
  .ss-promo-card__more,     /* 90.5×21.6 → +6 */
  .ss-map__stub-link,       /* 167×22.4 → +6 */
  .ss-contact-link,         /* 116.8×22 и 110×22 → +6 (blocks/contacts/block.php) */
  .ss-cmp__more,            /* 120×20 → +6 */
  .ss-docs__link,           /* 78×22 → +6 */
  .ss-back-link,            /* 167×22 → +6 (banya/arenda-bani «‹‹‹ банный комплекс») */
  .ss-auth__links a {       /* 117×21 → +6 (Н-4 барьера МР-3, «Забыли пароль?» /auth/) */
    display: inline-block;
    padding: 3px 0;
  }
  .ss-rules-foot__cta {     /* 240×22.4 → +6; уже inline-flex, паддинг просто добавляется */
    padding: 3px 0;
  }

  /* Точки слайдера (зоны — 8×8/10×10 активная, галерея программы — 10×10):
     ЗАДАНИЕ — «визуально точки не увеличивать, зону касания расширять
     псевдоэлементом». ::before кладёт невидимый 24×24 квадрат по центру
     видимой точки — сама точка не меняется ни размером, ни цветом.
     position:relative на кнопке ничего не сдвигает (кнопка и так в потоке),
     нужен только как якорь для absolute у ::before.
     ⚠️ Шаг между точками (gap) раздвинут ДО 24px+: при прежних 7–8px зоны
     24×24 соседних точек перекрывались бы больше чем наполовину, и хит-тест
     на границе зоны попадал бы в чужую точку (замерено m20-9/hit-test-tochki.js
     до этой правки — 3 из 4 сторон, а не 4 из 4). Сами точки не увеличены —
     только просвет между ними, это не тот размер, который запретило задание. */
  .ss-zones-stage .slick-dots { gap: 16px; }
  .ss-program-gallery .slick-dots { gap: 16px; }  /* было 14px — см. Н-1 ниже: с 12 фото 14px не помещался в окно */
  /* Диаметр точки галереи программы 10px→8px — тот же размер, что уже стоит у
     точек зоны (.ss-zones-stage, строка выше), с тем же gap:16px и тем же успешным
     хит-тестом (D=диаметр+gap=24px). У зоны фото ≤8, дефицит окна не проявлялся;
     у галереи программы бывает 12 (Н-1) — при неизменных 10px диаметр+14px gap
     ряд 274px физически не входит в окно 272px ни при каком трюке с ::before
     (псевдоэлемент в раскладке flex не участвует, окно/шаг задают только сами
     точки). 8px — тот же ход, что и в зоне: диаметр меньше, но не «увеличен». */
  .ss-program-gallery .slick-dots li button {
    width: 8px;
    height: 8px;
  }
  .ss-zones-stage .slick-dots li button,
  .ss-program-gallery .slick-dots li button {
    position: relative;
  }
  .ss-zones-stage .slick-dots li button::before,
  .ss-program-gallery .slick-dots li button::before {
    content: '';
    position: absolute;
    top: 50%;
    left: 50%;
    width: 24px;
    height: 24px;
    transform: translate(-50%, -50%);
    /* видимость намеренно нулевая: это зона касания, не вторая точка */
  }

  /* Н-1 барьера МР-3 (иcходная правка, для памяти хода): у галереи программы
     фото — до 12 штук (6 адресов: aromaty-altaya[2], duet[-lyuks], solo,
     yaponiya-do-6-chelovek). При 12 точках и прежних 10px+14px ряд (274px)
     физически не входил в окно 272px на 320 — «последняя точка срезана»
     (обрезающий предок .ss-program-gallery{overflow:hidden} режет её). Диаметр
     снижен до 8px выше (тот же ход, что у .ss-zones-stage) — ряд
     12×8+11×16=272px, ровно по ширине окна, без запаса. Крайние две зоны
     тогда получили несимметричную зону (наружу — 0, внутрь — 16px) ВО ВСЕХ
     галереях на ВСЕХ ширинах ≤767 — не только у тех 6-с-12-точками на 320,
     где это единственно необходимо. */

  /* M20-11, снятие красноты МР-3 (п.1, повторный барьер mr3-barer-2/tochki2.js):
     опровергнуто «4/4 на всех 12 точках» — прибор исполнителя засчитывал
     попадание в li-предка, а не строго в кнопку. Строгий хит-тест (в саму
     button, elementFromPoint === button || button.contains(...)) даёт 3 из 4:
     наружная сторона (влево у первой точки, вправо у последней) не бьётся —
     зона там 0px, не 24×24. Дефект был во ВСЕХ 143 галереях на ВСЕХ трёх
     ширинах (858 строк tochki-do.tsv, все 3/4), а не только в тех 6 адресах
     с 12 точками, для которых асимметрия вообще нужна.
     Правка сужает несимметричную зону РОВНО до случая, где она структурно
     обязательна: `:first-child:nth-last-child(12)` / `:last-child:nth-child(12)`
     — селектор ловит только строку ИЗ 12 точек (единственная длина, при
     которой ряд ровно 272px без запаса), и только ≤359.98px — на 360/390
     контейнер (312/342px) шире ряда (272px) на 20/35px, зоне есть куда расти
     наружу без среза `.ss-program-gallery{overflow:hidden}` (проверено ниже
     новым блоком @media). Во всех остальных случаях (меньше точек, шире 360)
     первая/последняя точка теперь получает БАЗОВУЮ симметричную зону 24×24
     (правило чуть выше, `li button::before`) — 4 из 4, без асимметрии вообще:
     специфичных правил для них больше нет, они просто не переопределяются.
     Первичка — out/wave-mobile-2026-09-22/m20-11-krasnota/tochki.js,
     tochki-do.tsv (до) / tochki-posle.tsv (после). */
}

/* Крайняя точка ряда из 12 (6 адресов, см. выше) остаётся асимметричной —
   но ТОЛЬКО там, где 272px ряд занимает контейнер без запаса: ≤359.98px.
   На 360+ этот блок не действует — работает общая симметричная зона выше. */
@media (max-width: 359.98px) {
  .ss-program-gallery .slick-dots li:first-child:nth-last-child(12) button::before {
    left: 0;
    width: 16px;
    transform: translateY(-50%);
  }
  .ss-program-gallery .slick-dots li:last-child:nth-child(12) button::before {
    left: auto;
    right: 0;
    width: 16px;
    transform: translateY(-50%);
  }

  /* M20-11, снятие красноты МР-3 (п.2): активная точка растёт из ЦЕНТРА
     (.slick-active{transform:scale(1.2)}, базовое правило вне медиазапроса,
     строка ~2725) — у 8px кружка это ±0.8px в каждую сторону. Для первой/
     последней точки РЯДА ИЗ 12 на 320 центр стоит впритык к краю ряда (0px
     запаса, см. врезку выше), и 0.8px роста наружу срезает `.ss-program-
     gallery{overflow:hidden}` (barrier mr3-barer-2/tochki2-razbor.txt:
     SREZ L0.8 на всех 6 адресах).
     Ход правки (две неудачные попытки, третья рабочая — записано, чтобы не
     повторять): (1) сдвинуть transform-origin к внутреннему краю кружка —
     ОТКЛОНЕНА: origin отличный от центра масштабирует ::before (зону касания,
     дочерний бокс в том же трансформированном контексте) НЕСИММЕТРИЧНО
     относительно кнопки, R-луч (tochki.js) упал с 3/4 на 2/4. (2) жёсткий
     сдвиг после масштаба (`translateX(0.8px) scale(1.2)`, порядок важен —
     внешний translateX работает в уже отмасштабированных пикселях) —
     сдвигает кнопку и ::before НА ОДНО расстояние, их взаимная геометрия не
     меняется, но R по-прежнему мимо: эффективная (хит-тестируемая) ширина
     зоны ограничена НЕ её СОБСТВЕННЫМ размером, а зоной СОСЕДНЕЙ точки —
     активная кнопка получает свой stacking context (сам transform его
     создаёт) с z-index:auto, и как более ранний DOM-сосед проигрывает
     более позднему в точке перекрытия (diag-akt2.js: elementFromPoint
     отдавал сосбственно button соседа на x≥~39, зона соседа НЕПОДВИЖНА
     и начинается ровно там независимо от сдвига активной точки).
     (3) добавлен `z-index:1` — тот же сдвиг + приоритет в стеке, зона
     активной точки красится ПОВЕРХ зоны соседа в перекрытии и получает
     полный эффективный охват (diag-akt2.js: R-луч снова в зоне с запасом
     ~3px, SREZ по-прежнему 0 — оба измерения из tochki.js подтверждают:
     R 4/4, SREZ 0, out/wave-mobile-2026-09-22/m20-11-krasnota/tochki-posle3.tsv).
     Только эти 6 адресов и только ≤359.98px: на 360+ до края есть 20px+
     запаса, трогать нечего (И-7 иначе задело бы лишнее). */
  .ss-program-gallery .slick-dots li:first-child:nth-last-child(12).slick-active button {
    transform: translateX(0.8px) scale(1.2);
    z-index: 1;
  }
  .ss-program-gallery .slick-dots li:last-child:nth-child(12).slick-active button {
    transform: translateX(-0.8px) scale(1.2);
    z-index: 1;
  }
}

/* ═════════════════════════════════════════════════════════════════════════════
   @@SEC:LEDE-T26@@ — подводка на обложке программы: порог по ТЗ (SPEC-20,
   строка M20-10б / T26, 23.09.2026). Решение министра 23.09.2026 22:5x:
   «порог прибора по ТЗ + правка вида».

   ЗАЧЕМ ОТДЕЛЬНО ОТ @@SEC:W1@@. Та секция ставит базовый вид подводки; здесь —
   ТОЛЬКО перегрузка под порог ТЗ (SPEC-12:216 — ≤3 строк на ширинах <700,
   ≤2 на ≥700; прежний порог прибора был мягче: ≤4/≤3, находку не ловил).
   Секция дописана В КОНЕЦ ФАЙЛА тем же приёмом, что у @@SEC:M20-9@@ и соседей
   выше: @@SEC:W1@@ не тронут ни строкой, каскад решает порядком источника —
   при равной специфичности позднее правило побеждает.

   ЗАМЕР ПЕРЕД ПРАВКОЙ (весь sitemap.xml, 215 адресов `/program/`, 207 с
   непустой подводкой, playwright, порог как в приборе):
     • 1440 — было `max-width:33rem`(528px): 110 из 207 программ на 3 строках
       (нужно ≤2). Подбор ширины (см. `out/wave-mobile-2026-09-22/m20-10b/`):
       0 провалов начинается с 688px, взято 704px (44rem) с запасом.
       max-width — это ПОТОЛОК, а не заданная ширина: на телефоне, где
       контейнер уже 272–342px, число 44rem ничего не меняет, поэтому одно
       правило без медиазапроса безопасно для обеих групп ширин.
     • 320/390 — было `font-size:0.96rem`(15.36px): 148 из 207 (320) и 118 из
       207 (390) шире трёх строк. Кегль ужат до РАЗРЕШЁННОГО ПОЛА в задании —
       14px (0.875rem). Ширина колонки на телефоне и так максимальна
       (`max-width:none` у @@SEC:W1@@, во всю ширину контейнера) — расширить
       её нечем в рамках трёх разрешённых рычагов (кегль/межстрочный/
       max-width) без выхода текста за отступ контейнера, а такого хода
       задание не называло.
     • ⚠️ ПОЛНОСТЬЮ НЕ ДОБИРАЕТ на телефоне даже на полу: при 14px остаётся
       138 из 207 (320) и 67 из 207 (390) шире трёх строк — включая «Бодрость»
       (137 знаков) и «Аромат лотоса» (140): у обеих 4 строки на 320 и на 390
       и после ужатия кегля. Контрольный расчёт (не применяется, только чтобы
       показать масштаб зазора): ноль провалов на 320 потребовал бы кегль
       ≈9.5px — на порядок ниже пола читаемости. Дело не в вёрстке этой
       секции: подводка обрезана до 140 знаков по границе слова
       (`spasol_program_excerpt($text, 140)`, `init.php:662`) безотносительно
       ширины экрана, а сама функция и её вызов — не во владении этой строки.
       Донесено министру числами, не выдано за «исполнено».
   Первичка — `out/wave-mobile-2026-09-22/m20-10b/*.json` (подбор порогов) и
   `program-detail-audit-all.txt` (полный прогон после этой правки).

   ⭐ ИТЕРАЦИЯ 2 (24.09.2026). Решение министра 23.09.2026 23:5x — квизом:
   «короче выжимка на телефоне». Абзац выше остаётся как первичка того, ПОЧЕМУ
   кегль 14px не решал задачу (пол читаемости упёрся раньше, чем длина текста
   перестала мешать) — вывод «дело не в вёрстке» и привёл к решению короче
   текст. Правка этой итерации:
     • Мобильное сужение кегля (0.875rem) СНЯТО — на ≤767.98px снова действует
       базовое правило @@SEC:W1@@ (`font-size: 0.96rem`), никем не отменённое.
     • Шаблон (`template.php`) выводит ДВЕ выжимки — `--short` (79 знаков) и
       `--full` (140, как было) — переключатель здесь, в CSS, а не в PHP.
       79 — измеренный потолок: на живой колонке 272px (320×0.96rem) 0 из 207
       строк длиннее трёх при пределе 79, 2 из 207 уже при 80, 25 из 207 при
       89 (=79+10). Способ измерения — подмена textContent реального узла
       `.ss-program-hero__lede` на живой странице в цикле по всем 207 текстам
       (без 207 перезагрузок), сверено с фактом итерации 1 (148 из 207 на
       пределе 140 при этом же кегле — число совпало день в день).
       Первичка — `out/wave-mobile-2026-09-22/m20-10b-i2/limit-search-coarse.json`,
       `limit-search-fine.json`, `plus10-check.json` (артефакты волны, вне git,
       Р389). Способ перепрогона — там же, `search-limit.js`/`search-limit-fine.js`/
       `check-plus10.js`: playwright открывает живую страницу программы один раз,
       дальше в цикле подменяет `textContent` узла `.ss-program-hero__lede` на
       каждый из 207 текстов (без 207 перезагрузок) и меряет высоту/line-height.
     • Совпавшая (короткий исходник) выжимка выходит БЕЗ модификатора — видна
       всегда, обе половины ниже её не касаются. */
.ss-program-hero__lede {
  max-width: 44rem;
}
@media (max-width: 767.98px) {
  .ss-program-hero__lede--full {
    display: none;
  }
}
@media (min-width: 768px) {
  .ss-program-hero__lede--short {
    display: none;
  }
}
/* @@/SEC:LEDE-T26@@ */

/* ═════════════════════════════════════════════════════════════════════════════
   @@SEC:M20-11-VID@@ — МР-4 спеки SPEC-20: четыре недочёта мобильного вида
   перед словом «мобильная версия готова» (решение министра 29.09.2026 15:4x).
   Секция дописана в конец файла, ничего выше не правит (тот же приём, что у
   @@SEC:S5@@ и соседей) — ТОЛЬКО телефонные медиазапросы, 1440/800 не задеты.
   Первичка и разбор по каждому пункту — out/wave-mobile-2026-09-22/m20-11-vid/.
   ═════════════════════════════════════════════════════════════════════════════ */

/* ── П.1: заголовок героя программы без предела высоты уносил кнопку
   «Записаться» за первый экран (800px) на 320 у /program/massazh-thalion-s-
   morskim-kalciem/ — единственного адреса из 215 с патологически длинным
   названием («Массаж с морским кальцием THALION (концентрат (гель) морского
   кальция) и Маска "Морской кальций"», 97 знаков): 9 строк (378px) на 320,
   кнопка y=802…855 при границе экрана 800. Замер всех 215 адресов на 320
   (h1-lines-320.json) — у следующего по длине названия 5 строк (210px),
   кнопка на y≈696…749, глубоко внутри экрана. Правило общее (по содержимому,
   не по адресу): ограничиваем заголовок героя ШЕСТЬЮ строками — 214 из 215
   программ это не касается вовсе (максимум у них 5), тот же приём «минимум
   текста поверх фото», которым уже урезана выжимка ниже героя (@@SEC:LEDE-
   T26@@). Текст остаётся в DOM целиком — скринридер читает без потерь,
   визуально усечение только у одного адреса из 215. */
@media (max-width: 767.98px) {
  .ss-program-hero .ss-title-hero {
    display: -webkit-box;
    -webkit-line-clamp: 6;
    -webkit-box-orient: vertical;
    overflow: hidden;
  }
}

/* ── П.2: «Зона и уход» (@@SEC:S8@@, .ss-about-spec__value.is-long) в 2-колоночной
   сетке 360/390 получает лишь половину строки (119/134px) — длинный перечень
   («Тело · Пилинг · СПА-обертывание · Баня и уходы хаммам») даже 16-кеглем не
   умещается в 2 строки (3–4), а при нечётном числе окошек третья карточка к
   тому же виснет в строке одна (силуэт §1.6 спеки, Д-5). На 320 та же карточка
   уже в одну колонку (правило ≤359.98px выше по файлу) — 240px хватает на 2
   строки, 0 из 1440 замеренных значений. Правило по содержимому (:has), не по
   адресу и не по ширине огулом: в одну колонку уходит целиком СТРАНИЦА, у
   которой такое длинное значение есть, — программы с коротким «Зона и уход»
   (178 из 215) 2-колоночную раскладку на 360/390 не теряют ни на пиксель.
   Диапазон ≤390px — ровно ширины замера (320/360/390); выше не трогаем, не
   измерено.
   ⚠️ Селектор бьёт ИМЕННО по `.ss-about-spec__value--zone` (модификатор
   шаблона, template.php, сидит на том же <dd>, что и `.is-long`), а не по
   голому `.is-long`: `.is-long` ложно взводится и у «Стоимости» — `&nbsp;`-
   разделители тысяч не раскрываются strip_tags()'ом и «от 3 450 ₽» считается
   длиннее 22 знаков (см. комментарий у шаблона). Без --zone это правило
   сужало бы сетку и там, где сама «Зона и уход» короткая, — задело бы
   страницы с четырёхзначной ценой сверх найденных 37/27 адресов. Проверено
   замером: 5 контрольных адресов с короткой зоной, но 4-значной ценой
   (zona-batch-posle.json, 360_control/390_control) сетку не теряют. */
@media (max-width: 390px) {
  .ss-program-specs:has(.ss-about-spec__value--zone.is-long) .ss-about-specs {
    grid-template-columns: minmax(0, 1fr);
  }
}

/* ── П.3: фото блока сравнения бань (@@SEC:S3b@@, .ss-cmp__photo) несимметрично
   на телефоне — зазор 1px слева / 28–29px справа на 320/360/390 (banya-badge.js,
   cmp-diag2.js). Причина — глобальный `img{max-width:100%}` (строка 101) гасит
   ЗАДУМАННЫЙ edge-to-edge bleed `calc(100% + 28px)` у мобильного override
   (строка 5760, внутри `@media (max-width: 575px)`): отрицательный margin-left
   честно прижимает левый край к рамке карточки, а max-width обрезает ширину до
   content-box (100%) раньше, чем calc успевает её раздвинуть — вправо фото не
   дотягивает ровно на то же значение, что должен был прибавить calc. Правка —
   только для этого класса и только в диапазоне, где сам calc(100%+28px) уже
   активен (≤575px, тот же порог, что у строки 5755); на 800/1440 у `.ss-cmp__photo`
   действуют другие calc-формулы (36px/32px) вне этого диапазона — не задеты. */
@media (max-width: 575px) {
  .ss-cmp__photo { max-width: none; }
}
/* @@/SEC:M20-11-VID@@ */

/* ── @@SEC:AKTSII-SPLIT-HERO@@ — текст слева, полный кадр справа.
   Пропорции колонок 40/60; высота по содержимому, без обрезки изображения.
   Свободное место над и под кадром сохраняет общий фон обложки. */
.ss-promo-hero{display:grid;margin-top:calc(var(--bx-panel-h, 0px) + var(--ss-header-h, 93px));grid-template-columns:minmax(0,2fr) minmax(0,3fr);background:var(--ss-dark-panel);color:var(--ss-text-on-dark)}
.ss-promo-hero:not(.has-photo){grid-template-columns:1fr}
.ss-promo-hero__text{display:flex;align-items:center;min-width:0;padding:96px 0;overflow-wrap:anywhere}
.ss-promo-hero__text>.ss-container{width:100%}
.ss-promo-hero__photo{align-self:center;min-width:0;margin:0;background:var(--ss-dark-panel)}
.ss-promo-hero__photo img{position:static;display:block;width:100%;height:auto}
.ss-promo-hero .ss-title-hero,
.ss-promo-hero .ss-lede{color:var(--ss-text-on-dark)}
.ss-promo-hero .ss-overline{color:var(--ss-amber)}
@media (max-width: 767.98px){
  .ss-promo-hero{grid-template-columns:1fr}
  .ss-promo-hero__text{padding:64px 0 48px}
}
/* @@/SEC:AKTSII-SPLIT-HERO@@ */

/* ── Сквозной блок контактов: данные читаются прямым шрифтом ────────────────
   Телефон и адрес — данные, которые читают посимвольно. Декоративная гарнитура
   остаётся у заголовка секции; значения используют тот же Manrope, что футер. */
.ss-contact-details {
  display: grid;
  grid-template-columns: minmax(0, 1fr) minmax(0, 1fr);
  gap: 22px 28px;
  margin: 0 0 28px;
}
.ss-contact-item { min-width: 0; }
.ss-contact-item--address,
.ss-contact-item--phones { grid-column: 1 / -1; }
.ss-contact-item .ss-form-label-group { margin-bottom: 6px; }
.ss-contact-address,
.ss-contact-value {
  margin: 0;
  font-family: 'Manrope', sans-serif;
  font-size: 16px;
  line-height: 1.55;
  color: var(--ss-text);
}
.ss-contact-address {
  font-size: 18px;
  font-weight: 500;
  line-height: 1.45;
}
.ss-contact-meta {
  display: block;
  margin-top: 4px;
  color: var(--ss-text-muted);
  font-size: 14px;
}
.ss-contact-phones {
  display: flex;
  flex-direction: column;
  align-items: flex-start;
  gap: 8px;
}
.ss-contact-phone {
  display: inline-flex;
  align-items: baseline;
  gap: 10px;
  min-height: 36px;
  color: var(--ss-text);
  font-family: 'Manrope', sans-serif;
  font-size: 18px;
  font-weight: 600;
  font-variant-numeric: tabular-nums;
  letter-spacing: 0.01em;
  line-height: 1.3;
  text-decoration: none;
  text-decoration-thickness: 1px;
  text-underline-offset: 4px;
}
.ss-contact-phone--main {
  color: var(--ss-copper);
  font-size: clamp(20px, 1.55vw, 22px);
  font-weight: 600;
}
/* Оба телефона одного размера — по просьбе заказчика 20.10.2026. Цвет основного
   (медный) по-прежнему выделяет его, размер — один на оба. */
.ss-contact-phone--extra {
  font-size: clamp(20px, 1.55vw, 22px);
}
.ss-contact-phone__caption {
  min-width: 112px;
  color: var(--ss-text-muted);
  font-size: 12px;
  font-weight: 500;
  letter-spacing: 0.1em;
  text-transform: uppercase;
}
.ss-contact-phone:hover,
.ss-contact-phone:focus-visible,
.ss-contact-email:hover,
.ss-contact-email:focus-visible {
  color: var(--ss-copper);
  text-decoration: underline;
}
.ss-contact-phone:focus-visible,
.ss-contact-email:focus-visible {
  border-radius: 4px;
  outline: 2px solid var(--ss-copper);
  outline-offset: 4px;
}
.ss-contact-email {
  color: var(--ss-text);
  font-family: 'Manrope', sans-serif;
  font-size: 16px;
  font-weight: 500;
  overflow-wrap: anywhere;
  text-decoration-color: var(--ss-copper);
  text-underline-offset: 3px;
}
@media (max-width: 575.98px) {
  .ss-contact-details { grid-template-columns: 1fr; gap: 18px; }
  .ss-contact-item--address,
  .ss-contact-item--phones { grid-column: auto; }
  .ss-contact-phone { align-items: flex-start; flex-direction: column; gap: 1px; }
  .ss-contact-phone__caption { min-width: 0; }
}

/* Расширенный список текстовых отзывов на /otzyvy/: карточки раскрываются
   порциями, полный текст читается в одной доступной Bootstrap-модалке. */
.ss-rx-card[hidden] { display: none; }
.ss-rx-card__actions {
  display: inline-flex;
  align-items: center;
  justify-content: flex-end;
  flex-wrap: wrap;
  gap: 8px 16px;
  margin-left: auto;
}
button.ss-rx-card__more {
  appearance: none;
  border: 0;
  padding: 0;
  background: transparent;
  cursor: pointer;
}
.ss-rx-more-wrap { text-align: center; }
.ss-rx-more { min-width: 220px; justify-content: center; }
.ss-review-modal .modal-content {
  border: 1px solid var(--ss-divider);
  border-radius: 18px;
  background: var(--ss-card);
  box-shadow: 0 18px 60px rgba(58, 47, 40, 0.18);
}
.ss-review-modal .modal-header {
  align-items: flex-start;
  padding: 24px 28px 18px;
  border-bottom-color: var(--ss-divider);
}
.ss-review-modal .modal-title {
  color: var(--ss-text);
  font-size: 30px;
  line-height: 1.15;
}
.ss-review-modal__meta {
  margin: 5px 0 0;
  color: var(--ss-text-muted);
  font: 13px/1.45 'Manrope', sans-serif;
}
.ss-review-modal .modal-body { padding: 24px 28px 30px; }
.ss-review-modal__text {
  margin: 0;
  color: var(--ss-text);
  font: 15px/1.75 'Manrope', sans-serif;
  white-space: pre-line;
}
@media (max-width: 575.98px) {
  .ss-rx-card__actions { justify-content: flex-start; margin-left: 0; width: 100%; }
  .ss-review-modal .modal-header { padding: 20px 20px 16px; }
  .ss-review-modal .modal-body { padding: 20px 20px 24px; }
  .ss-review-modal .modal-title { font-size: 26px; }
}

/* Выбор одной или нескольких программ для подарочного сертификата. */
.ss-cert-program-selection {
  font-family: 'Manrope', sans-serif;
}
.ss-cert-program-selected {
  display: flex;
  flex-wrap: wrap;
  gap: 8px;
  min-height: 58px;
  padding: 10px;
  border: 1px solid var(--ss-divider);
  border-radius: 12px;
  background: var(--ss-card);
}
.ss-cert-program-selected__empty {
  align-self: center;
  padding: 0 8px;
  color: var(--ss-text-muted);
  font-size: 14px;
}
.ss-cert-program-selected__item {
  display: inline-flex;
  align-items: center;
  gap: 8px;
  padding: 8px 8px 8px 12px;
  border-radius: 999px;
  background: var(--ss-bg-alt);
  color: var(--ss-text);
  font-size: 14px;
  line-height: 1.35;
}
.ss-cert-program-selected__remove {
  display: inline-flex;
  align-items: center;
  justify-content: center;
  width: 28px;
  height: 28px;
  padding: 0;
  border: 0;
  border-radius: 50%;
  background: rgba(139, 111, 63, 0.12);
  color: var(--ss-accent);
  font-size: 20px;
  line-height: 1;
  cursor: pointer;
}
.ss-cert-program-selected__remove:hover,
.ss-cert-program-selected__remove:focus-visible { background: rgba(139, 111, 63, 0.22); }
.ss-cert-program-picker { margin-top: 12px; }
.ss-cert-program-picker > summary {
  display: inline-flex;
  list-style: none;
  cursor: pointer;
}
.ss-cert-program-picker > summary::-webkit-details-marker { display: none; }
.ss-cert-program-picker__panel {
  margin-top: 10px;
  padding: 14px;
  border: 1px solid var(--ss-divider);
  border-radius: 12px;
  background: var(--ss-card);
}
.ss-cert-program-search { display: block; margin-bottom: 10px; }
.ss-cert-program-options {
  display: grid;
  gap: 4px;
  max-height: 320px;
  overflow-y: auto;
  overscroll-behavior: contain;
}
.ss-cert-program-option {
  display: flex;
  align-items: flex-start;
  gap: 10px;
  padding: 9px 10px;
  border-radius: 8px;
  cursor: pointer;
}
.ss-cert-program-option:hover { background: var(--ss-bg-alt); }
.ss-cert-program-option[hidden] { display: none; }
.ss-cert-program-option input { flex: none; margin-top: 4px; }
.ss-cert-program-option span { min-width: 0; }
.ss-cert-program-option strong { display: block; font-size: 14px; font-weight: 600; }
.ss-cert-program-option small { display: block; margin-top: 2px; color: var(--ss-text-muted); font-size: 12px; }
.ss-cert-program-selection__note { margin: 9px 0 0; color: var(--ss-text-muted); font-size: 12px; }
@media (max-width: 575.98px) {
  .ss-cert-program-picker > summary { width: 100%; justify-content: center; }
  .ss-cert-program-selected__item { width: 100%; justify-content: space-between; border-radius: 10px; }
}
.ss-cert-program-selected__total {
  flex-basis: 100%;
  padding: 8px 8px 2px;
  color: var(--ss-text);
  font-size: 15px;
  font-weight: 600;
  text-align: right;
}

/* iOS увеличивает страницу при фокусе на поле с кеглем меньше 16px.
   На телефоне держим единый безопасный размер у основных контролов сайта. */
@media (max-width: 767.98px) {
  .ss-input,
  .ss-articles-search__input,
  .ss-catalog__sort-select {
    font-size: 16px;
  }
}

/* ── Таблицы из редактора в описаниях программ (приёмка, 13.10.2026) ── */
/* В DETAIL_TEXT сохранились таблицы с width/border/cellpadding из старой CMS.
   Выправляем только витрину программ: данные ИБ 43 не изменяем. */
.ss-program-desc table {
  width: 100% !important;
  max-width: 720px !important;
  height: auto !important;
  margin: 12px 0 28px;
  border: 1px solid var(--ss-divider) !important;
  border-collapse: separate !important;
  border-spacing: 0 !important;
  border-radius: 12px;
  overflow: hidden;
  background: var(--ss-card);
  table-layout: auto;
}
.ss-program-desc table col { width: auto !important; }
.ss-program-desc table th,
.ss-program-desc table td {
  width: auto !important;
  height: auto !important;
  padding: 14px 18px !important;
  border: 0 !important;
  border-bottom: 1px solid var(--ss-divider) !important;
  background: transparent;
  color: var(--ss-text);
  font-family: 'Manrope', -apple-system, BlinkMacSystemFont, sans-serif;
  font-size: 14px;
  line-height: 1.45;
  font-weight: 400;
  vertical-align: middle;
}
.ss-program-desc table tr:last-child > th,
.ss-program-desc table tr:last-child > td { border-bottom: 0 !important; }
.ss-program-desc table tr:first-child > th,
.ss-program-desc table tr:first-child > td {
  background: var(--ss-bg-alt);
  color: var(--ss-text-muted);
  font-size: 12px;
  font-weight: 600;
}
.ss-program-desc table tr > th:not(:first-child),
.ss-program-desc table tr > td:not(:first-child) {
  text-align: right !important;
  white-space: nowrap;
  font-variant-numeric: tabular-nums;
}
.ss-program-desc table tr:not(:first-child) > td:not(:first-child) {
  font-weight: 600;
}
.ss-program-desc table :is(th, td) p { margin: 0; }
@media (max-width: 575.98px) {
  .ss-program-desc table { max-width: 100% !important; }
  .ss-program-desc table th,
  .ss-program-desc table td { padding: 10px 7px !important; font-size: 12px; }
  .ss-program-desc table tr:first-child > th,
  .ss-program-desc table tr:first-child > td { font-size: 11px; }
}
