/* ============================================================
   RELAXMANIA v2 — редизайн 2
   Стиль: тёплая органика. Терракота, песок и крем вместо
   холодного шалфея, скруглённые формы и мягкие тени вместо
   плоских линий. Крупная типографика и высокий контраст
   унаследованы — это не про минимализм, а про доступность.
   Фирменный зелёный логотипа — второй акцент, не основной.

   Цвета, кегли и отступы — только из assets/css/tokens.css.
   ============================================================ */

@import url("assets/css/tokens.css");

/* ============================================================
   БАЗА
   ============================================================ */

*,*::before,*::after{box-sizing:border-box}

html{
  scroll-behavior:smooth;
  -webkit-text-size-adjust:100%;text-size-adjust:100%;
}
@media (prefers-reduced-motion:reduce){html{scroll-behavior:auto}}

body{
  margin:0;
  background:var(--bg);
  color:var(--text);
  font-family:var(--font-body);
  font-size:var(--t-body);
  line-height:var(--lh-body);
  -webkit-font-smoothing:antialiased;
  overflow-x:hidden;
}

img{max-width:100%;display:block}

.wrap{
  max-width:var(--w-page);
  margin-inline:auto;
  padding-inline:var(--pad-page);
}

/* Ссылка «к содержимому» — первое, что получает клавиатура */
.skip{
  position:absolute;left:var(--sp-4);top:-100px;z-index:100;
  background:var(--bg-invert);color:var(--text-invert);
  padding:var(--sp-3) var(--sp-6);text-decoration:none;
  transition:top var(--dur) var(--ease);
}
.skip:focus{top:var(--sp-4)}

/* Единое кольцо фокуса. Нигде не убираем контур без замены. */
:focus-visible{outline:var(--ring);outline-offset:var(--ring-offset)}

/* Заголовок не должен уезжать под липкую шапку при переходе по якорю */
section[id]{scroll-margin-top:96px}

/* Фирменная деталь — уголковые скобки из логотипа */
.frame{position:relative}
.frame::before,.frame::after{
  content:"";position:absolute;width:42px;height:42px;
  border:1px solid var(--brand);opacity:.55;pointer-events:none;
}
.frame::before{top:0;left:0;border-right:0;border-bottom:0}
.frame::after{bottom:0;right:0;border-left:0;border-top:0}

/* ============================================================
   ТИПОГРАФИКА
   ============================================================ */

h1,h2,h3{
  font-family:var(--font-display);
  font-weight:300;margin:0;
  line-height:var(--lh-heading);
  color:var(--text);
}
h1{font-size:var(--t-hero);line-height:var(--lh-tight);letter-spacing:var(--ls-hero)}
h2{font-size:var(--t-h2)}
h3{font-size:var(--t-h3);font-weight:400}

p{margin:0 0 1em;max-width:var(--w-text)}
p:last-child{margin-bottom:0}

.eyebrow{
  font-family:var(--font-body);
  font-size:var(--t-label);font-weight:500;
  letter-spacing:var(--ls-label);text-transform:uppercase;
  color:var(--brand-ink);
  margin:0 0 var(--sp-6);
}
/* Канон без кикера: подпись-«эйбрау» над заголовком раздела — запрещённый
   паттерн (craft-floor). Ярлыки-подписи вне заголовков (блок контактов,
   форма отзыва) остаются — это не кикер, а подпись поля. */
.band__text>.eyebrow,.sect__head>.eyebrow,.hero__grid>div>.eyebrow{display:none}
.lede{
  font-size:var(--t-lede);
  color:var(--text-muted);
  max-width:52ch;
}
.mark{
  font-family:var(--font-body);font-weight:700;
  letter-spacing:.22em;text-transform:uppercase;line-height:1;
}
.mark-sub{
  font-family:var(--font-display);font-style:italic;font-size:.7rem;
  letter-spacing:.1em;color:var(--text-muted);margin-top:var(--sp-2);
}

/* ============================================================
   КНОПКИ
   Все кликабельные элементы — не меньше 44px по высоте.
   ============================================================ */

.btn{
  display:inline-flex;align-items:center;justify-content:center;gap:.5em;
  min-height:var(--tap);
  padding:.9em 2em;
  font-family:var(--font-body);font-size:var(--t-small);
  font-weight:500;letter-spacing:.03em;
  border:1px solid transparent;border-radius:var(--radius);
  text-decoration:none;cursor:pointer;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease),
             border-color var(--dur) var(--ease),transform var(--dur) var(--ease),
             box-shadow var(--dur) var(--ease);
}
.btn:hover{transform:translateY(-2px);box-shadow:var(--shadow-md)}

.btn--solid{background:var(--bg-invert);color:var(--text-invert);border-color:var(--bg-invert)}
.btn--solid:hover{background:var(--g-700);border-color:var(--g-700)}

.btn--dark{border-color:var(--brand-ink);color:var(--brand-ink);background:transparent}
.btn--dark:hover{background:var(--brand-ink);color:var(--text-invert)}

.btn--light{background:var(--bg-raised);color:var(--text);border-color:var(--bg-raised)}
.btn--light:hover{background:var(--s-100);border-color:var(--s-100)}

.btn--outline{border-color:var(--line-invert);color:var(--text-invert);background:transparent}
.btn--outline:hover{border-color:var(--text-invert);background:rgba(255,255,255,.12)}

/* ============================================================
   ШАПКА
   ============================================================ */

.nav{
  position:sticky;top:0;z-index:50;
  background:var(--bg);
  border-bottom:1px solid var(--line-soft);
}
@supports (backdrop-filter:blur(4px)){
  .nav{background:color-mix(in srgb,var(--bg) 90%,transparent);backdrop-filter:blur(14px)}
}

.nav__in{display:flex;align-items:center;gap:var(--sp-6);height:82px}
.nav__logo{text-decoration:none;color:var(--text);display:flex;align-items:center;min-height:var(--tap)}
.nav__logo .mark{font-size:1.22rem}

.nav__links{
  display:flex;gap:var(--sp-6);list-style:none;
  margin:0 0 0 auto;padding:0;
}
.nav__links a{
  display:flex;align-items:center;min-height:var(--tap);
  text-decoration:none;font-size:var(--t-small);color:var(--text-muted);
  white-space:nowrap;
  border-bottom:1px solid transparent;
  transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.nav__links a:hover{color:var(--text);border-color:var(--brand)}
/* Текущий раздел при скролле — тот же язык, что hover (цвет + линия),
   но не исчезает при уводе мыши. Ставится/снимается JS-скроллспаем. */
.nav__links a.is-active{color:var(--text);border-color:var(--brand)}

/* 8 пунктов меню читались одной сплошной лентой — разбиваем на две
   смысловые группы (услуги / инфо+действие) разделителем перед
   «Цены», первым пунктом второй группы, и выделяем «Запись» как
   единственное действие среди ссылок-якорей. */
.nav__links li:has(> a[href="#price"]){
  /* Слева от границы уже есть родной gap контейнера (--sp-6) — чтобы
     линия легла посередине между группами, а не впритык к «Цены»,
     справа нужен ровно такой же отступ, без своего margin-left. */
  padding-left:var(--sp-6);
  border-left:1px solid var(--line-soft);
}
.nav__links a[href="#zapis"]{color:var(--brand-ink);font-weight:600}

/* Телефон в шапке — главный призыв к действию, виден выше сгиба */
.nav__cta{
  display:inline-flex;align-items:center;gap:.5em;
  min-height:var(--tap);padding:.6em 1.3em;border-radius:var(--radius-pill);
  background:var(--bg-invert);color:var(--text-invert);
  text-decoration:none;font-size:var(--t-small);font-weight:500;
  white-space:nowrap;
  transition:background var(--dur) var(--ease);
}
.nav__cta:hover{background:var(--g-700)}
.nav__cta svg{width:16px;height:16px;flex:0 0 auto}

.burger{
  display:none;background:none;border:0;color:var(--text);
  width:var(--tap);height:var(--tap);margin-left:auto;
  align-items:center;justify-content:center;cursor:pointer;padding:0;
}
.burger svg{width:26px;height:26px}

/* ============================================================
   ГЕРОЙ
   Светлый, с очень крупным заголовком. Тёмный текст на светлом
   фоне даёт 14.8:1 — прежний белый на зелёном давал 3.68:1.
   ============================================================ */

.hero{background:var(--bg);border-bottom:1px solid var(--line-soft);overflow:hidden;position:relative}
.hero__in{padding-block:clamp(3rem,1.5rem + 6vw,6.5rem)}
/* Текст и кнопки — обычная grid-раскладка внутри .wrap, ровно как
   в v1: без calc(100vw...), без flex-центрирования через паддинги.
   Пропорция колонок (1.15fr/.85fr) держит текстовую колонку нужной
   ширины даже когда .hero__vis ниже выходит из потока (см. медиа-
   запрос) — явные fr-колонки не зависят от того, есть ли в них
   позиционированный контент. */
.hero__grid{
  display:grid;grid-template-columns:1.15fr .85fr;
  gap:var(--gap-grid);align-items:center;
}
.hero h1{margin-bottom:var(--sp-6)}
.hero h1 em{font-style:italic;color:var(--brand-ink)}
.hero .lede{max-width:46ch}

.hero__actions{display:flex;flex-wrap:wrap;gap:var(--sp-3);margin-top:var(--sp-12)}

.hero__meta{
  display:flex;flex-wrap:wrap;gap:var(--sp-12);
  margin-top:var(--sp-16);padding-top:var(--sp-6);
  border-top:1px solid var(--line);
  font-size:var(--t-small);color:var(--text-muted);
}
.hero__meta b{
  display:block;color:var(--text);font-weight:500;
  font-family:var(--font-display);font-size:1.24rem;
  margin-bottom:.15rem;
}

/* Без фото (SVG-рисунок вместо art--photo) герой ведёт себя как в v1 —
   рисунок по центру своей колонки. */
.hero__vis{
  display:flex;align-items:center;justify-content:center;
  position:relative;
}
.hero__vis::before{
  content:"";position:absolute;inset:6%;z-index:-1;border-radius:var(--radius-pill);
  background:radial-gradient(closest-side,var(--g-300) 0%,transparent 72%);
  opacity:.4;transform:translateY(14px);filter:blur(22px);
}
.hero__vis .art--photo{max-width:380px;aspect-ratio:3/4}

/* Фото — фон ВСЕГО героя (edge-to-edge), а не только правой колонки.
   Раньше это делалось через position:absolute;inset:0 относительно
   .hero, что ломалось из-за глубины вложенности/масштабирования.
   Теперь — классический full-bleed приём (100vw + отрицательный
   margin-left): картинка «выбегает» на всю ширину окна независимо
   от родителей, а .hero__copy при этом вообще не трогается и
   остаётся тем же grid-элементом, что и без фото — её позиция
   не зависит от того, где и как позиционировано фото. Только на
   десктопе (на мобиле фото — блок над текстом). */
@media (min-width:901px){
  .hero:has(.art--photo) .hero__vis{
    position:absolute;top:0;bottom:0;left:50%;
    width:100vw;margin-left:-50vw;z-index:0;
  }
  .hero:has(.art--photo) .hero__vis .art--photo{
    position:absolute;inset:0;margin:0;
    width:100%;height:100%;max-width:none;
    aspect-ratio:auto;object-fit:cover;
    border-radius:0;box-shadow:none;
  }
  /* hero__copy сам по себе не позиционирован — без явного z-index
     он красится в общем порядке раньше позиционированных потомков
     (даже с z-index:0 на них), поэтому фото оказывалось поверх
     текста несмотря на z-index:0 на hero__vis. */
  .hero:has(.art--photo) .hero__copy{position:relative;z-index:1}
  .hero:has(.art--photo) .hero__vis::after{
    content:"";position:absolute;inset:0;
    background:linear-gradient(90deg,
      var(--s-50) 0%, var(--s-50) 38%,
      rgba(251,246,238,.55) 60%,
      rgba(251,246,238,.1) 78%,
      transparent 92%);
  }
}

/* ============================================================
   ИЛЛЮСТРАЦИИ
   ============================================================ */

.art{width:100%;height:auto;margin-inline:auto;display:block}
.art--hero{max-width:400px}
.art--band{max-width:380px}

/* ------------------------------------------------------------
   Система обводки для всех фирменных рисунков.
   Ровно три уровня — толщина не задаётся у отдельных фигур,
   а наследуется от слоя. Смешать произвольные значения
   физически невозможно.
   ------------------------------------------------------------ */
.art{--ill-1:2.6;--ill-2:1.6;--ill-3:1.1}
.art .l-fill{fill:currentColor;stroke:none;opacity:.075}   /* мягкий объём */
.art .l-1{stroke-width:var(--ill-1)}                       /* главный контур */
.art .l-2{stroke-width:var(--ill-2)}                       /* конструкция */
.art .l-3{stroke-width:var(--ill-3);opacity:.5}            /* детали */

/* На маленьком кадре тонкие линии пропадают — подтягиваем */
@media (max-width:900px){
  .art{--ill-1:3.4;--ill-2:2.2;--ill-3:1.6}
}

/* ------------------------------------------------------------
   2,5D НА ПРОКРУТКЕ — бочка, стол, кресло.
   render.js помечает эти три рисунка классом art--depth и на
   каждый скролл/resize пишет в них --sy (от -1 до 1: насколько
   центр рисунка выше или ниже центра экрана).

   Открытка целиком слегка наклоняется (rotateX/rotateY на самом
   <svg>, в перспективе родителя), а слои обводки — контур,
   конструкция, детали, объёмная заливка — разъезжаются по Z
   с разной силой, так что при наклоне становится видно расстояние
   между ними. Это не настоящая 3D-модель (это плоский фирменный
   рисунок), а параллакс-эффект такой же природы, как в 2,5D играх. */
.hero__vis:has(.art--depth),.band__art:has(.art--depth){perspective:1400px}
.art--depth{
  transform-style:preserve-3d;
  transform:rotateX(calc(var(--sy,0) * -7deg)) rotateY(calc(var(--sy,0) * 4deg));
  transition:transform 90ms linear;
  will-change:transform;
}
.art--depth .l-fill{transform:translateZ(-8px)}
.art--depth .l-1{transform:translateZ(2px)}
.art--depth .l-2{transform:translateZ(11px) translateY(calc(var(--sy,0) * -3px))}
.art--depth .l-3{transform:translateZ(20px) translateY(calc(var(--sy,0) * -6px))}

@media (prefers-reduced-motion:reduce){
  .art--depth{transform:none;transition:none}
  .art--depth .l-fill,.art--depth .l-1,.art--depth .l-2,.art--depth .l-3{transform:none}
  /* Пар и разминающие руки — бесконечный, не критичный для смысла луп,
     а не единичный авторский момент, поэтому его выключаем по правилу. */
  .steam path,.knead{animation:none;opacity:.7;transform:none}
}

.art--photo{
  max-width:460px;width:100%;height:auto;
  object-fit:cover;aspect-ratio:4/5;background:var(--bg-sunken);
  border-radius:var(--radius-lg);box-shadow:var(--shadow-md);
}
.art-ph{
  aspect-ratio:4/5;width:100%;max-width:340px;
  border:1px dashed currentColor;opacity:.5;border-radius:var(--radius-lg);
  display:flex;align-items:center;justify-content:center;
  font-size:var(--t-small);text-align:center;padding:var(--sp-4);
}

/* Пар и разминающие руки */
.steam path{
  fill:none;stroke:currentColor;stroke-width:1.4;stroke-linecap:round;
  opacity:0;animation:rise 7.5s ease-in-out infinite;
}
.steam path:nth-child(2){animation-delay:2.5s}
.steam path:nth-child(3){animation-delay:5s}
.steam{transform-box:fill-box;transform-origin:center bottom}
@keyframes rise{
  0%{opacity:0;transform:translateY(12px) scaleX(.88)}
  25%{opacity:.8}
  65%{opacity:.35}
  100%{opacity:0;transform:translateY(-42px) scaleX(1.2)}
}
.knead{animation:knead 4s ease-in-out infinite;transform-box:fill-box;transform-origin:center}
.knead--late{animation-delay:2s}
@keyframes knead{0%,100%{transform:translateY(0)}50%{transform:translateY(5px)}}

/* ============================================================
   ПОЛОСЫ УСЛУГ
   ============================================================ */

.band{padding-block:var(--gap-section);border-bottom:1px solid var(--line-soft)}
.band--light{background:var(--bg)}
.band--beige{background:var(--bg-sunken)}

/* Тёмная полоса: белый текст на фирменном зелёном #4C583C — 7.59:1 */
.band--green{background:var(--bg-invert);border-bottom-color:transparent}
.band--green h2,.band--green .band__text{color:var(--text-invert)}
.band--green .eyebrow{color:rgba(255,255,255,.78)}
.band--green .band__text p{color:var(--text-invert-muted)}
.band--green .spec{border-color:var(--line-invert)}
.band--green .spec dt{color:rgba(255,255,255,.75)}
.band--green .spec dd{color:var(--text-invert)}

.band__grid{
  display:grid;grid-template-columns:.8fr 1.2fr;
  gap:var(--gap-grid);align-items:stretch;
}
.band--flip .band__art{order:2}
.band__art{display:flex;justify-content:center}
.band__text h2{margin-bottom:var(--sp-6)}
.band__text p{color:var(--text-muted);max-width:50ch}

/* Фото в полосе услуг подгоняется под высоту текстовой колонки, а не
   наоборот. Просто "height:100%" не годится: в CSS Grid высота
   auto-строки считается ДО стретча, по собственной (натуральной)
   высоте каждого элемента — а натуральная высота фото по его
   исходному соотношению сторон и так уже задаёт высоту строки,
   стретч тут ничего не меняет. Поэтому фото убрано из потока
   (position:absolute): у .band__art не остаётся своей натуральной
   высоты, строку целиком задаёт текстовая колонка, а после стретча
   фото просто заполняет получившуюся высоту через inset:0 +
   object-fit:cover. Только на двух колонках; на мобильной раскладке
   в один столбец возвращается обычное соотношение 4:5. */
@media (min-width:901px){
  /* Скругление и тень — на контейнере, а не на самом фото: фото
     заполняет контейнер вплотную (inset:0), поэтому его собственная
     тень рисовалась бы прямо на границе overflow:hidden родителя и
     обрезалась бы им же. На контейнере то же overflow:hidden клипает
     фото по скруглённым углам корректно, а box-shadow элемента не
     обрезается его же собственным overflow:hidden. */
  .band__art{
    position:relative;overflow:hidden;width:100%;max-width:460px;margin-inline:auto;
    border-radius:var(--radius-lg);box-shadow:var(--shadow-md);
  }
  .band__art .art--photo{
    position:absolute;inset:0;margin:0;
    width:100%;height:100%;max-width:none;
    aspect-ratio:auto;object-fit:cover;
    border-radius:0;box-shadow:none;
  }
}

/* Кедровая бочка — фото без тени, по отдельному запросу (только
   этот блок, кресло и ручной массаж тень сохраняют). */
#bochka .band__art{box-shadow:none}
#bochka .art--photo{box-shadow:none}

.spec{
  display:flex;flex-wrap:wrap;gap:var(--sp-12);
  margin:var(--sp-8) 0;padding-top:var(--sp-6);
  border-top:1px solid var(--line);
}
.spec div{margin:0}
.spec dt{
  font-size:var(--t-label);letter-spacing:var(--ls-label);
  text-transform:uppercase;color:var(--text-muted);margin-bottom:.35rem;
}
.spec dd{
  margin:0;font-family:var(--font-display);
  font-size:1.7rem;line-height:1.1;color:var(--text);
  font-variant-numeric:tabular-nums;
}

/* ============================================================
   СЕКЦИИ
   ============================================================ */

.sect{padding-block:var(--gap-section)}
.sect--line{border-top:1px solid var(--line-soft)}
.sect__head{max-width:60ch;margin-bottom:var(--gap-grid)}
.sect__head h2{margin-bottom:var(--sp-4)}

/* ---- ШАГИ ----
   Раньше номер шага был просто текстом, всплывающим над верхней
   границей — правильно, но нейтрально, не читалось как единый путь.
   Теперь номер — залитая пилюля (тот же приём, что у primary-кнопки:
   --bg-invert/--text-invert), а на широком экране, где все 4 шага
   стоят в один ряд, через них проходит сквозная линия — путь визита
   от встречи до отдыха. На брейкпоинтах, где ряд рвётся на несколько
   строк (см. ниже), сквозная линия перестаёт быть смежной, поэтому
   там возвращается индивидуальная верхняя граница на каждый шаг. */
.ritual{display:grid;grid-template-columns:repeat(4,1fr);gap:var(--gap-grid)}
.step{position:relative}
.step__n{
  position:relative;z-index:1;
  display:inline-flex;align-items:center;justify-content:center;
  width:3.2rem;height:3.2rem;margin-bottom:var(--sp-4);
  border-radius:var(--radius-pill);
  background:var(--bg-invert);color:var(--text-invert);
  /* 1.75rem — задокументированный в DESIGN.md размер именно для
     номера шага в «Четыре шага» (Numeral hierarchy), пилюля
     подогнана под него, а не наоборот. */
  font-family:var(--font-display);font-size:1.75rem;line-height:1;
}
.step h3{margin-bottom:var(--sp-2)}
.step p{font-size:var(--t-small);color:var(--text-muted)}

@media (min-width:1025px){
  /* Сплошная линия имеет смысл, только пока «Четыре шага» стоят в
     один ряд — а это ломается уже на 1024px (см. .ritual в блоке
     max-width:1024px ниже), а не на обычном брейкпоинте 900px. */
  .ritual{position:relative}
  /* Линия идёт по вертикальному центру пилюли (top:1.6rem = половина
     высоты 3.2rem) и красится под ней за счёт обычного порядка
     отрисовки — не нужен отдельный приём с обводкой-«разрывом». */
  .ritual::before{
    content:'';position:absolute;top:1.6rem;left:0;right:0;height:1px;
    background:var(--line);
    /* Линия — это путь визита, а не просто разделитель: она
       дорисовывается слева направо после того, как блок появился
       (задержка чуть больше длительности .reveal), а не возникает
       вместе с ним разом. Один авторский момент на весь сайт, не
       очередной generic fade-up. */
    transform:scaleX(0);transform-origin:left;
    transition:transform 650ms var(--ease) .3s;
  }
  .ritual.in::before{transform:scaleX(1)}
}
@media (prefers-reduced-motion:reduce){
  .ritual::before{transform:none;transition:none}
}

/* ---- КАРТОЧКИ ---- */
.extras{display:grid;gap:var(--sp-6)}
.extras--1{grid-template-columns:1fr}
.extras--2{grid-template-columns:repeat(2,1fr)}
.extras--3{grid-template-columns:repeat(3,1fr)}
.extras--4{grid-template-columns:repeat(4,1fr)}

.extra{
  background:var(--bg-raised);
  border:1px solid var(--line-soft);border-radius:var(--radius-lg);
  padding:var(--sp-8);overflow:hidden;
  display:flex;flex-direction:column;
  transition:border-color var(--dur) var(--ease),transform var(--dur) var(--ease),
             box-shadow var(--dur) var(--ease);
}
.extra:hover{border-color:var(--brand);transform:translateY(-4px);box-shadow:var(--shadow-md)}
.extra h3{margin-bottom:var(--sp-3)}
.extra p{color:var(--text-muted);font-size:var(--t-small);margin-bottom:var(--sp-8)}
/* Список пунктов ритуала вместо одного плотного абзаца с <br> —
   каждый пункт читается отдельно, а не сливается в сплошной текст.
   Маркер — галочка терракотового цвета (точечное исключение из
   единственного фирменного акцента, см. tokens.css). */
.extra__list{
  display:flex;flex-direction:column;gap:.55em;
  margin:0 0 var(--sp-8);list-style:none;padding:0;
  color:var(--text-muted);font-size:var(--t-small);line-height:1.5;
}
.extra__list li{display:flex;align-items:flex-start;gap:.6em}
.extra__list li svg{
  width:16px;height:16px;flex:0 0 auto;margin-top:.2em;
  color:var(--terracotta-600);
}
.extra__img{
  width:calc(100% + var(--sp-8) * 2);
  margin:calc(var(--sp-8) * -1) calc(var(--sp-8) * -1) var(--sp-6);
  aspect-ratio:16/10;object-fit:cover;
}
.extra__foot{
  margin-top:auto;display:flex;justify-content:space-between;
  align-items:baseline;gap:var(--sp-4);
  padding-top:var(--sp-4);border-top:1px solid var(--line-soft);
  font-size:var(--t-small);color:var(--text-muted);
}
.extra__foot b{
  font-family:var(--font-display);font-size:1.4rem;
  font-weight:400;color:var(--text);
}

/* ---- ОТЗЫВЫ ----
   Соцдоказательство перед призывом к действию. Карусель — та же
   механика, что и у фотогалереи (.gal / .gal__track / wireGalleries),
   поэтому листается стрелками и не ограничена числом отзывов. */
.gal.reviews-car{--gal-gap:var(--sp-6)}
.reviews-car .gal__track{align-items:stretch}
.reviews-car.gal--fits .review{flex:1 1 0}

.review{
  flex:0 0 calc((100% - var(--gal-peek) - (var(--gal-cols,3) - 1) * var(--gal-gap)) / var(--gal-cols,3));
  scroll-snap-align:start;
  border-top:2px solid var(--brand);
  padding-top:var(--sp-6);
  display:flex;flex-direction:column;
  transition:filter var(--dur-slow) var(--ease),opacity var(--dur-slow) var(--ease);
}
.review.is-dim{filter:blur(3px);opacity:.45}
.review blockquote{
  margin:0 0 var(--sp-6);
  font-family:var(--font-display);
  font-size:1.22rem;line-height:1.5;color:var(--text);
}
.review blockquote::before{content:"«"}
.review blockquote::after{content:"»"}
.review__who{
  margin-top:auto;display:flex;align-items:center;gap:var(--sp-3);
  font-size:var(--t-small);color:var(--text-muted);
}
.review__ava{
  width:42px;height:42px;flex:0 0 auto;border-radius:50%;
  object-fit:cover;background:var(--bg-sunken);
}
.review__ava--icon{
  display:flex;align-items:center;justify-content:center;
  color:var(--text-muted);border:1px solid var(--line-soft);
}
.review__ava--icon svg{width:22px;height:22px}
.review__who b{display:block;color:var(--text);font-weight:500}
.reviews-note{
  margin-top:var(--sp-8);font-size:var(--t-small);color:var(--text-muted);
}
.reviews-leave{
  margin-top:var(--gap-grid);padding-top:var(--gap-grid);
  border-top:1px solid var(--line-soft);max-width:640px;
}
.reviews-leave>.eyebrow{margin-bottom:var(--sp-4)}
.reviews-form textarea{min-height:140px}

/* ---- ПРАЙС ----
   Меню spa-курорта: группа услуг — отдельная карточка с собственной
   рамкой. Группы теперь вкладки (видна одна за раз, кнопки-пилюли
   сверху) — при 6 группах и ~28 позициях список всех разом был самым
   длинным местом на странице. */
.price-tabs__nav{
  display:flex;flex-wrap:wrap;gap:var(--sp-2);
  margin-bottom:var(--sp-8);
}
.price-tabs__btn{
  min-height:var(--tap);padding:.55em 1.25em;
  font-family:var(--font-body);font-size:var(--t-small);font-weight:500;
  border:1px solid var(--line-soft);border-radius:var(--radius-pill);
  background:var(--bg-raised);color:var(--text-muted);cursor:pointer;
  transition:background var(--dur) var(--ease),color var(--dur) var(--ease),
             border-color var(--dur) var(--ease);
}
.price-tabs__btn:hover{border-color:var(--brand-ink);color:var(--text)}
.price-tabs__btn[aria-selected="true"]{
  background:var(--bg-invert);border-color:var(--bg-invert);color:var(--text-invert);
}
.price-group{
  background:var(--bg-raised);border:1px solid var(--line-soft);
  border-radius:var(--radius-lg);padding:var(--sp-8);
}
.price-group h3{
  font-family:var(--font-display);font-style:italic;font-weight:400;
  font-size:1.32rem;letter-spacing:0;
  text-transform:none;color:var(--text);margin-bottom:var(--sp-2);
  padding-bottom:var(--sp-4);border-bottom:1px solid var(--brand);
}
.price-list{list-style:none;margin:0;padding:0}
.price-list li{
  display:flex;align-items:baseline;gap:var(--sp-3);
  padding:var(--sp-3) 0;border-bottom:1px solid var(--line-soft);
}
.price-list li:last-child{border-bottom:0}
.price-list .nm{color:var(--text)}
.price-list .nm small{
  display:block;color:var(--text-muted);
  font-size:var(--t-small);margin-top:.15rem;
}
.price-list .dots{
  flex:1 1 auto;border-bottom:1px dotted var(--s-400);
  transform:translateY(-4px);
}
.price-list .pr{
  font-family:var(--font-display);font-size:1.3rem;
  white-space:nowrap;color:var(--text);
  /* Табличные цифры — одинаковая ширина цифр, чтобы «20 р.» и «110 р.»
     не отличались посимвольной шириной при сравнении цен глазами. */
  font-variant-numeric:tabular-nums;
}
.price-note{margin-top:var(--sp-8);font-size:var(--t-small);color:var(--text-muted)}

/* ============================================================
   ФОРМА
   ============================================================ */

.two{display:grid;grid-template-columns:1fr 1fr;gap:var(--gap-grid);align-items:start}

.form{display:grid;gap:var(--sp-6)}
.field label{
  display:block;font-size:var(--t-label);
  letter-spacing:.1em;text-transform:uppercase;
  color:var(--text-muted);margin-bottom:var(--sp-2);
}
.field input:not([type=checkbox]),.field select,.field textarea{
  width:100%;min-height:var(--tap);
  font-family:var(--font-body);font-size:var(--t-body);
  color:var(--text);background:var(--bg-raised);
  border:1px solid var(--line);border-radius:var(--radius);
  padding:.8em 1em;
  transition:border-color var(--dur) var(--ease),box-shadow var(--dur) var(--ease);
}
.field textarea{resize:vertical;min-height:110px;line-height:var(--lh-body)}
.field input:focus,.field select:focus,.field textarea:focus{
  outline:none;border-color:var(--focus);
  box-shadow:0 0 0 3px color-mix(in srgb,var(--focus) 22%,transparent);
}
.field select{
  appearance:none;
  background-image:linear-gradient(45deg,transparent 50%,var(--text-muted) 50%),
                   linear-gradient(135deg,var(--text-muted) 50%,transparent 50%);
  background-position:calc(100% - 20px) 54%,calc(100% - 14px) 54%;
  background-size:6px 6px;background-repeat:no-repeat;
}

/* Ошибка живёт рядом со своим полем, а не общей строкой внизу */
.field.is-bad input,.field.is-bad textarea,.field.is-bad select{
  border-color:var(--danger);background:var(--danger-bg);
}
.field__err{
  display:none;margin-top:var(--sp-2);
  font-size:var(--t-small);color:var(--danger);
}
.field.is-bad .field__err{display:flex;align-items:center;gap:.4em}
.field__err svg{width:15px;height:15px;flex:0 0 auto}

/* Предупреждение о противопоказаниях — всегда видно над кнопкой отправки,
   не только мелким текстом в «Контактах» ниже формы (PRODUCT.md требует
   этого явно). Не переиспользуем danger-стиль field__err — это не ошибка
   ввода, а постоянное предупреждение, поэтому нейтральный тёплый тон. */
.form-notice{
  display:flex;align-items:flex-start;gap:.6em;
  background:var(--bg-sunken);border:1px solid var(--line-soft);
  border-radius:var(--radius);padding:var(--sp-4) var(--sp-6);
  margin:0;font-size:var(--t-small);color:var(--text-muted);
}
.form-notice svg{width:18px;height:18px;flex:0 0 auto;margin-top:.15em;color:var(--brand-ink)}

/* label.consent (не просто .consent): этот label — потомок .field, и
   ".field label" (специфичность 0,1,1) иначе перебивает обычный класс
   ".consent" (0,1,0) — чекбокс рендерился как аптекстовый label-текст
   (uppercase, шрифт-.72rem), а не как flex-строка. */
label.consent{
  display:flex;gap:var(--sp-3);align-items:center;
  font-size:var(--t-small);line-height:1.45;color:var(--text-muted);
  text-transform:none;letter-spacing:normal;margin-bottom:0;
  cursor:pointer;padding:var(--sp-2) 0;
}
label.consent input{
  width:20px;height:20px;
  accent-color:var(--brand-ink);flex:0 0 auto;cursor:pointer;
}
label.consent.is-bad{color:var(--danger)}

.form-status{
  font-size:var(--t-small);min-height:1.4em;margin:0;
  color:var(--brand-ink);
}
.form-status.is-bad{color:var(--danger)}
/* Успех — весом и цветом, не цветной рамкой (её не даёт craft-floor) */
.form-status.is-ok{color:var(--brand-ink);font-weight:600}

.btn[aria-busy="true"]{opacity:.65;pointer-events:none}

/* ---- КОНТАКТЫ ---- */
.contact-block+.contact-block{
  margin-top:var(--sp-8);padding-top:var(--sp-8);
  border-top:1px solid var(--line-soft);
}
.contact-block .eyebrow{margin-bottom:var(--sp-3)}
/* Отдельно стоящая ссылка — полноценная зона нажатия, не строчка в 17px */
.contact-block a{
  display:inline-flex;align-items:center;min-height:var(--tap);
  color:var(--text);text-decoration:none;
  border-bottom:1px solid var(--line);
  transition:color var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.contact-block a:hover{color:var(--brand-ink);border-color:var(--brand)}
.big-link{
  display:inline-flex;align-items:center;gap:.5rem;min-height:var(--tap);
  font-family:var(--font-display);
  /* Было clamp(1.5rem…2.05rem) — крупнее самого большого числа в
     системе (цены/шаги), выбивалось из общего ритма. Опустили до
     --t-h3 — того же масштаба, что заголовки карточек — ссылка
     всё ещё крупнее body-текста и легко читается, но не спорит
     с остальной типографикой страницы. */
  font-size:var(--t-h3);line-height:1.3;
  font-variant-numeric:tabular-nums;
}
/* В «Как записаться» каждая big-link-ссылка стоит последней строкой
   в своём .contact-block — собственное подчёркивание ссылки почти
   вплотную к разделителю следующего под-блока (.contact-block+
   .contact-block, своя верхняя линия), визуально сливались в двойную
   черту. В «Где нас найти» такой соседней линии нет — там подчёркивание
   оставляем. */
.contact-block a.big-link--plain{border-bottom:0}
/* Иконка в em — растёт вместе с адаптивным clamp() самой ссылки,
   а не остаётся мелкой точкой рядом с крупной цифрой/текстом. */
.big-link svg{width:.62em;height:.62em;flex:0 0 auto}
.hours{list-style:none;margin:0;padding:0;font-size:var(--t-body)}
.hours li{
  display:flex;justify-content:space-between;gap:var(--sp-8);
  padding:var(--sp-2) 0;color:var(--text-muted);max-width:340px;
  border-bottom:1px solid var(--line-soft);
}
.hours li b{color:var(--text);font-weight:500}

.map-slot{
  margin-top:var(--gap-grid);border:1px solid var(--line);border-radius:var(--radius-lg);
  aspect-ratio:16/6;min-height:260px;overflow:hidden;
  display:flex;align-items:center;justify-content:center;
  text-align:center;padding:var(--sp-6);
  background:var(--bg-raised);color:var(--text-muted);font-size:var(--t-small);
}
.map-slot iframe{width:100%;height:100%;border:0;display:block}

/* ============================================================
   ГАЛЕРЕЯ-КАРУСЕЛЬ
   ============================================================ */

.gal{position:relative;--gal-cols:var(--cols,4);--gal-gap:10px}

.gal__track{
  --gal-peek:64px;
  display:flex;gap:var(--gal-gap);
  overflow-x:auto;overscroll-behavior-x:contain;
  scroll-snap-type:x proximity;scroll-behavior:smooth;
  scrollbar-width:none;-ms-overflow-style:none;
}
.gal__track::-webkit-scrollbar{display:none}
@media (prefers-reduced-motion:reduce){.gal__track{scroll-behavior:auto}}

.gal--fits .gal__track{--gal-peek:0px}
.gal--fits .gal__cell{flex:1 1 0}
.gal--fits .gal__nav{display:none}

.gal__cell{
  flex:0 0 calc((100% - var(--gal-peek) - (var(--gal-cols,4) - 1) * var(--gal-gap)) / var(--gal-cols,4));
  aspect-ratio:1;position:relative;overflow:hidden;border-radius:var(--radius);
  margin:0;padding:0;border:0;background:none;
  scroll-snap-align:start;cursor:zoom-in;
  transition:filter var(--dur-slow) var(--ease),opacity var(--dur-slow) var(--ease);
}
.gal__cell img{
  width:100%;height:100%;object-fit:cover;display:block;
  transition:transform 500ms var(--ease);
}
.gal__cell:hover img{transform:scale(1.05)}
.gal__cell.is-dim{filter:blur(3px);opacity:.45}
.gal__cell.is-dim img{transform:none}

.gal__nav{
  position:absolute;top:50%;z-index:2;transform:translateY(-50%);
  width:var(--tap);height:var(--tap);padding:0;border-radius:var(--radius-pill);
  border:1px solid var(--line);background:var(--bg-raised);
  color:var(--text);cursor:pointer;box-shadow:var(--shadow-sm);
  display:flex;align-items:center;justify-content:center;
  transition:background var(--dur) var(--ease),opacity var(--dur) var(--ease),
             visibility var(--dur) var(--ease),box-shadow var(--dur) var(--ease);
}
.gal__nav:hover{background:var(--bg-sunken);box-shadow:var(--shadow-md)}
.gal__nav svg{width:19px;height:19px}
.gal__nav--prev{left:-16px}
.gal__nav--next{right:-16px}
.gal.is-start .gal__nav--prev,.gal.is-end .gal__nav--next{opacity:0;visibility:hidden}

.gal--empty .gal__cell{
  background:var(--bg-raised);border:1px solid var(--line-soft);cursor:default;
  display:flex;align-items:center;justify-content:center;
  color:var(--text-muted);font-size:var(--t-small);text-align:center;padding:var(--sp-3);
}

/* ---- ПРОСМОТР ВО ВЕСЬ ЭКРАН ---- */
.lb{
  position:fixed;inset:0;z-index:100;
  background:rgba(30,22,15,.96);
  display:flex;align-items:center;justify-content:center;
  padding:clamp(60px,8vw,80px) clamp(14px,5vw,90px);
  animation:lb-in var(--dur) var(--ease);
}
.lb[hidden]{display:none}
@keyframes lb-in{from{opacity:0}to{opacity:1}}
html.lb-open{overflow:hidden}

.lb__fig{
  margin:0;display:flex;flex-direction:column;align-items:center;
  gap:var(--sp-4);max-width:100%;max-height:100%;
}
.lb__fig img{max-width:100%;max-height:78vh;width:auto;height:auto;object-fit:contain;border-radius:var(--radius)}
.lb__cap{color:rgba(255,255,255,.75);font-size:var(--t-small);letter-spacing:.04em;text-align:center}

.lb__close,.lb__nav{
  position:absolute;padding:0;cursor:pointer;
  min-width:var(--tap);min-height:var(--tap);
  border:1px solid rgba(255,255,255,.32);
  background:rgba(255,255,255,.1);color:var(--white);
  display:flex;align-items:center;justify-content:center;
  transition:background var(--dur) var(--ease),border-color var(--dur) var(--ease);
}
.lb__close:hover,.lb__nav:hover{background:rgba(255,255,255,.22);border-color:rgba(255,255,255,.65)}
.lb__close{top:18px;right:18px}
.lb__close svg{width:20px;height:20px}
.lb__nav{top:50%;transform:translateY(-50%);height:60px}
.lb__nav svg{width:22px;height:22px}
.lb__nav--prev{left:14px}
.lb__nav--next{right:14px}
.lb--single .lb__nav{display:none}
.lb :focus-visible{outline:2px solid var(--white);outline-offset:2px}

/* ============================================================
   СВОБОДНЫЙ ТЕКСТ
   ============================================================ */

.rich{max-width:var(--w-text);color:var(--text-muted)}
.rich p{margin-bottom:1.1em}
.rich b,.rich strong{color:var(--text);font-weight:500}
.rich a{color:var(--brand-ink)}

/* ============================================================
   ПОДВАЛ
   ============================================================ */

.foot{
  background:var(--bg-invert);color:var(--text-invert);
  padding-block:var(--sp-16) var(--sp-8);
  font-size:var(--t-small);
}
.foot .eyebrow{color:rgba(255,255,255,.75)}
.foot p{color:var(--text-invert-muted)}
.foot .mark-sub{color:var(--text-invert-muted)}
/* Ссылки подвала — тоже полноценные зоны нажатия */
.foot a{
  display:inline-flex;align-items:center;min-height:var(--tap);
  color:var(--text-invert);
}
.foot .body a,.warnbox a{display:inline;min-height:0}

.foot__top{
  display:flex;flex-wrap:wrap;justify-content:space-between;
  gap:var(--sp-12);margin-bottom:var(--sp-12);
}
.foot__nav{list-style:none;margin:0;padding:0;display:grid;gap:var(--sp-2)}
.foot__nav a{
  display:inline-flex;align-items:center;min-height:var(--tap);
  text-decoration:none;color:var(--text-invert-muted);
  transition:color var(--dur) var(--ease);
}
.foot__nav a:hover{color:var(--text-invert)}

details{border-top:1px solid var(--line-invert);padding:var(--sp-2) 0}
summary{
  cursor:pointer;font-size:var(--t-small);color:var(--text-invert);
  list-style:none;display:flex;justify-content:space-between;
  align-items:center;gap:var(--sp-4);min-height:var(--tap);
}
summary::-webkit-details-marker{display:none}
summary::after{content:"+";font-size:1.2rem;line-height:1}
details[open] summary::after{content:"–"}
details .body{
  padding-top:var(--sp-3);font-size:var(--t-small);
  line-height:1.75;max-width:70ch;color:var(--text-invert-muted);
}
details .body b{color:var(--text-invert)}
.warnbox{
  color:var(--text-invert);background:rgba(255,255,255,.14);
  padding:var(--sp-3) var(--sp-4);margin-top:var(--sp-4);
}

.foot__base{
  margin-top:var(--sp-12);padding-top:var(--sp-6);
  border-top:1px solid var(--line-invert);
  display:flex;flex-wrap:wrap;justify-content:space-between;
  gap:var(--sp-4);font-size:var(--t-small);color:var(--text-invert-muted);
}

/* ============================================================
   НИЖНЯЯ ПАНЕЛЬ СВЯЗИ (телефоны)
   ============================================================ */

.callbar{display:none}
.callbar__btn{
  display:flex;align-items:center;justify-content:center;gap:.5em;
  min-height:58px;padding:0 var(--sp-3);text-decoration:none;
  font-family:var(--font-body);font-size:var(--t-body);font-weight:500;
  background:var(--bg-raised);color:var(--text);
}
.callbar__btn--main{background:var(--bg-invert);color:var(--text-invert)}
.callbar__btn svg{width:18px;height:18px;flex:0 0 auto}

/* ============================================================
   ПОЯВЛЕНИЕ ПРИ ПРОКРУТКЕ
   ============================================================ */

.reveal{
  opacity:0;transform:translateY(18px);
  /* Было 600ms — за порогом «избегать дольше 500ms для UI-анимаций». */
  transition:opacity 450ms var(--ease),transform 450ms var(--ease);
}
.reveal.in{opacity:1;transform:none}

/* Без скриптов и при отключённом движении содержимое видно сразу */
@media (prefers-reduced-motion:reduce){
  .reveal{opacity:1;transform:none;transition:none}
}
.no-js .reveal{opacity:1;transform:none}

/* ============================================================
   АДАПТИВ — контрольные ширины 375 / 768 / 1024 / 1440
   ============================================================ */

@media (max-width:1024px){
  .ritual{grid-template-columns:repeat(2,1fr)}
  /* Сквозная линия работала только в один ряд — тут шаги уже стоят
     в 2×2, ряд рвётся, поэтому возвращаем прежний приём: своя
     верхняя граница на каждый шаг, пилюля с номером лежит на ней. */
  .step{padding-top:2.7rem;border-top:1px solid var(--line)}
  .step__n{position:absolute;top:-1.6rem;left:0;margin-bottom:0}
  .extras--3,.extras--4{grid-template-columns:repeat(2,1fr)}
  .gal.reviews-car{--gal-cols:2}
  .review{border-top-width:1px}
}

@media (max-width:900px){
  .nav__in{height:68px}
  .nav__cta span{display:none}
  .nav__cta{padding:.6em .9em}
  .nav__links{
    display:none;position:absolute;top:68px;left:0;right:0;
    flex-direction:column;gap:0;margin:0;
    background:var(--bg);border-bottom:1px solid var(--line);
    padding:0 var(--pad-page) var(--sp-4);
    max-height:calc(100dvh - 68px);overflow-y:auto;
  }
  .nav__links.open{display:flex}
  .nav__links a{
    display:flex;width:100%;padding:var(--sp-3) 0;
    font-size:var(--t-lede);border-bottom:1px solid var(--line-soft);
  }
  /* В вертикальном меню левая граница-разделитель бессмысленна —
     переносим её наверх, как дополнительный отступ перед группой. */
  .nav__links li:has(> a[href="#price"]){
    margin-left:0;padding-left:0;border-left:0;
    margin-top:var(--sp-3);
  }
  .burger{display:flex}
  section[id]{scroll-margin-top:76px}

  .hero__grid{grid-template-columns:1fr}
  /* На одной колонке .hero__vis больше не тянется по высоте от
     соседа (стретч работает только между колонками одной строки) —
     задаём соотношение сторон явно, чтобы full-bleed фото было во
     что вписаться. */
  .hero__vis{order:-1;aspect-ratio:4/3}
  .art--hero{max-width:200px}
  .art--band{max-width:220px}
  .art--hero.art--wide,.art--band.art--wide{max-width:260px}

  .band__grid{grid-template-columns:1fr;gap:var(--sp-8)}
  .band--flip .band__art{order:0}
  .two,.price-grid{grid-template-columns:1fr}
  .extras--2,.extras--3,.extras--4{grid-template-columns:1fr}

  .gal{--gal-cols:2}
  .gal.reviews-car{--gal-cols:1}
  .gal__track{--gal-peek:48px}
  .gal__nav--prev{left:-8px}
  .gal__nav--next{right:-8px}

  .frame::before,.frame::after{width:26px;height:26px}
  .hours li{max-width:none}
  .map-slot{aspect-ratio:4/3;min-height:0}

  .callbar{
    display:grid;grid-template-columns:1.5fr 1fr;gap:1px;
    position:fixed;left:0;right:0;bottom:0;z-index:60;
    background:var(--line);
    padding-bottom:env(safe-area-inset-bottom);
    box-shadow:0 -8px 26px rgba(43,33,24,.16);
  }
  body{padding-bottom:calc(58px + env(safe-area-inset-bottom))}
}

@media (max-width:560px){
  .ritual{grid-template-columns:1fr}
  .hero__actions{flex-direction:column;align-items:stretch}
  .hero__actions .btn,.band__text .btn{width:100%}
  .hero__meta{flex-direction:column;gap:var(--sp-6);margin-top:var(--sp-12)}
  .spec{gap:var(--sp-8)}
  .spec dd{font-size:1.45rem}

  /* точки-выноски съедают место на узком экране */
  .price-list li{flex-wrap:wrap;justify-content:space-between;gap:var(--sp-2)}
  .price-list .dots{display:none}
  .price-list .nm{flex:1 1 auto;min-width:0}
  .price-list .pr{flex:0 0 auto}

  .foot__top{gap:var(--sp-8)}
}

/* ============================================================
   ПЕЧАТЬ — прайс и контакты часто печатают
   ============================================================ */

@media print{
  .nav,.callbar,.gal__nav,.lb,.skip,.hero__vis,.band__art,.map-slot{display:none!important}
  body{background:#fff;color:#000;padding:0}
  .reveal{opacity:1;transform:none}
  .sect,.band{padding-block:1.5rem;border:0}
  a[href^="http"]::after{content:" (" attr(href) ")";font-size:.8em}
  /* Прайс на печати — все категории разом, не только открытая вкладка */
  .price-tabs__nav{display:none!important}
  .price-tabs__panel{display:block!important}
  .price-group+.price-group{margin-top:1.5rem}
}
